From 86bdf981e37d4b028f4e555d7e0b1e76324f23b3 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 12 Jun 2026 11:39:34 +0000
Subject: [PATCH 01/23] chore(internal): codegen related update
---
.stats.yml | 8 +-
api.md | 4 +
src/cloudflare/_client.py | 38 +
src/cloudflare/resources/ai/models/models.py | 18 +
.../resources/ai_gateway/provider_configs.py | 16 +-
.../cloudforce_one/binary_storage.py | 10 +-
src/cloudflare/resources/d1/api.md | 2 +-
.../resources/d1/database/database.py | 39 +-
.../resources/email_sending/email_sending.py | 18 +-
src/cloudflare/resources/flagship/__init__.py | 33 +
src/cloudflare/resources/flagship/api.md | 69 ++
.../resources/flagship/apps/__init__.py | 47 +
.../resources/flagship/apps/apps.py | 657 ++++++++++
.../resources/flagship/apps/evaluate.py | 225 ++++
.../resources/flagship/apps/flags/__init__.py | 33 +
.../flagship/apps/flags/changelog.py | 242 ++++
.../resources/flagship/apps/flags/flags.py | 878 +++++++++++++
src/cloudflare/resources/flagship/flagship.py | 102 ++
src/cloudflare/resources/iam/__init__.py | 14 +
src/cloudflare/resources/iam/api.md | 12 +-
src/cloudflare/resources/iam/iam.py | 16 +-
.../iam/{oauth_scopes => }/oauth_scopes.py | 14 +-
.../resources/iam/oauth_scopes/__init__.py | 19 -
.../resources/iam/oauth_scopes/api.md | 11 -
.../resources/logpush/datasets/fields.py | 2 +
.../resources/logpush/datasets/jobs.py | 2 +
src/cloudflare/resources/logpush/jobs.py | 2 +
.../managed_transforms/managed_transforms.py | 10 +-
.../origin_tls_compliance_modes}/__init__.py | 0
.../access/ai_controls/mcp/servers.py | 16 +
src/cloudflare/resources/zero_trust/api.md | 137 ++
.../resources/zero_trust/dlp/__init__.py | 42 +
.../resources/zero_trust/dlp/data_classes.py | 620 +++++++++
.../dlp/data_tag_categories/__init__.py | 33 +
.../data_tag_categories.py | 658 ++++++++++
.../dlp/data_tag_categories/data_tags.py | 648 ++++++++++
.../resources/zero_trust/dlp/dlp.py | 96 ++
.../dlp/sensitivity_groups/__init__.py | 33 +
.../dlp/sensitivity_groups/levels/__init__.py | 33 +
.../dlp/sensitivity_groups/levels/levels.py | 712 +++++++++++
.../dlp/sensitivity_groups/levels/order.py | 303 +++++
.../sensitivity_groups/sensitivity_groups.py | 668 ++++++++++
.../tunnels/warp_connector/__init__.py | 14 +
.../tunnels/warp_connector/configurations.py | 344 +++++
.../tunnels/warp_connector/warp_connector.py | 32 +
src/cloudflare/types/ai/model_list_params.py | 10 +
.../types/ai_gateway/log_delete_params.py | 1 +
.../types/ai_gateway/log_list_params.py | 1 +
.../provider_config_create_params.py | 8 +-
src/cloudflare/types/d1/__init__.py | 1 +
.../types/d1/database_get_params.py | 31 +
.../email_sending_send_params.py | 10 +-
.../email_sending_send_raw_response.py | 3 +
.../email_sending_send_response.py | 3 +
src/cloudflare/types/flagship/__init__.py | 11 +
.../types/flagship/app_create_params.py | 14 +
.../types/flagship/app_create_response.py | 21 +
.../types/flagship/app_delete_response.py | 9 +
.../types/flagship/app_get_response.py | 21 +
.../types/flagship/app_list_response.py | 21 +
.../types/flagship/app_update_params.py | 14 +
.../types/flagship/app_update_response.py | 21 +
.../types/flagship/apps/__init__.py | 14 +
.../flagship/apps/evaluate_get_params.py | 23 +
.../flagship/apps/evaluate_get_response.py | 20 +
.../types/flagship/apps/flag_create_params.py | 350 ++++++
.../flagship/apps/flag_create_response.py | 331 +++++
.../flagship/apps/flag_delete_response.py | 9 +
.../types/flagship/apps/flag_get_response.py | 331 +++++
.../types/flagship/apps/flag_list_params.py | 18 +
.../types/flagship/apps/flag_list_response.py | 331 +++++
.../types/flagship/apps/flag_update_params.py | 353 ++++++
.../flagship/apps/flag_update_response.py | 331 +++++
.../types/flagship/apps/flags/__init__.py | 6 +
.../apps/flags/changelog_list_params.py | 21 +
.../apps/flags/changelog_list_response.py | 1046 ++++++++++++++++
src/cloudflare/types/iam/__init__.py | 1 +
.../oauth_scope_list_response.py | 2 +-
.../types/logpush/job_create_params.py | 1 +
src/cloudflare/types/logpush/logpush_job.py | 1 +
.../managed_transform_edit_params.py | 4 +-
.../types/organizations/organization.py | 11 +-
.../__init__.py | 2 -
.../ai_controls/mcp/portal_create_response.py | 3 +
.../ai_controls/mcp/portal_list_response.py | 3 +
.../ai_controls/mcp/portal_read_response.py | 3 +
.../ai_controls/mcp/portal_update_response.py | 3 +
.../ai_controls/mcp/server_create_params.py | 3 +
.../ai_controls/mcp/server_create_response.py | 3 +
.../ai_controls/mcp/server_delete_response.py | 3 +
.../ai_controls/mcp/server_list_response.py | 3 +
.../ai_controls/mcp/server_read_response.py | 3 +
.../ai_controls/mcp/server_update_params.py | 3 +
.../ai_controls/mcp/server_update_response.py | 3 +
.../types/zero_trust/dlp/__init__.py | 18 +
.../dlp/data_class_create_params.py | 34 +
.../dlp/data_class_create_response.py | 36 +
.../zero_trust/dlp/data_class_get_response.py | 36 +
.../dlp/data_class_list_response.py | 36 +
.../dlp/data_class_update_params.py | 34 +
.../dlp/data_class_update_response.py | 36 +
.../dlp/data_tag_categories/__init__.py | 10 +
.../data_tag_create_params.py | 16 +
.../data_tag_create_response.py | 20 +
.../data_tag_get_response.py | 20 +
.../data_tag_list_response.py | 20 +
.../data_tag_update_params.py | 18 +
.../data_tag_update_response.py | 20 +
.../dlp/data_tag_category_create_params.py | 27 +
.../dlp/data_tag_category_create_response.py | 36 +
.../dlp/data_tag_category_get_response.py | 36 +
.../dlp/data_tag_category_list_response.py | 36 +
.../dlp/data_tag_category_update_params.py | 36 +
.../dlp/data_tag_category_update_response.py | 36 +
.../dlp/sensitivity_group_create_params.py | 27 +
.../dlp/sensitivity_group_create_response.py | 36 +
.../dlp/sensitivity_group_get_response.py | 36 +
.../dlp/sensitivity_group_list_response.py | 36 +
.../dlp/sensitivity_group_update_params.py | 36 +
.../dlp/sensitivity_group_update_response.py | 36 +
.../dlp/sensitivity_groups/__init__.py | 10 +
.../sensitivity_groups/level_create_params.py | 16 +
.../level_create_response.py | 20 +
.../sensitivity_groups/level_get_response.py | 20 +
.../sensitivity_groups/level_list_response.py | 20 +
.../sensitivity_groups/level_update_params.py | 18 +
.../level_update_response.py | 20 +
.../dlp/sensitivity_groups/levels/__init__.py | 7 +
.../levels/order_get_response.py | 16 +
.../levels/order_update_params.py | 15 +
.../levels/order_update_response.py | 16 +
.../tunnels/warp_connector/__init__.py | 3 +
.../configuration_get_response.py | 71 ++
.../configuration_update_params.py | 66 +
.../configuration_update_response.py | 71 ++
tests/api_resources/ai/test_models.py | 2 +
.../ai_gateway/test_provider_configs.py | 28 +-
tests/api_resources/d1/test_database.py | 18 +
tests/api_resources/flagship/__init__.py | 1 +
tests/api_resources/flagship/apps/__init__.py | 1 +
.../flagship/apps/flags/__init__.py | 1 +
.../flagship/apps/flags/test_changelog.py | 167 +++
.../flagship/apps/test_evaluate.py | 150 +++
.../api_resources/flagship/apps/test_flags.py | 1103 +++++++++++++++++
tests/api_resources/flagship/test_apps.py | 497 ++++++++
tests/api_resources/iam/test_oauth_scopes.py | 2 +-
.../origin_tls_compliance_modes/__init__.py | 1 +
tests/api_resources/test_email_sending.py | 12 +-
.../api_resources/test_managed_transforms.py | 88 +-
.../workers/observability/test_queries.py | 4 +-
.../observability/test_shared_queries.py | 4 +-
.../workers/observability/test_telemetry.py | 16 +-
.../access/ai_controls/mcp/test_servers.py | 4 +
.../dlp/data_tag_categories/__init__.py | 1 +
.../dlp/data_tag_categories/test_data_tags.py | 634 ++++++++++
.../dlp/sensitivity_groups/__init__.py | 1 +
.../dlp/sensitivity_groups/levels/__init__.py | 1 +
.../sensitivity_groups/levels/test_order.py | 229 ++++
.../dlp/sensitivity_groups/test_levels.py | 634 ++++++++++
.../zero_trust/dlp/test_data_classes.py | 612 +++++++++
.../dlp/test_data_tag_categories.py | 544 ++++++++
.../zero_trust/dlp/test_sensitivity_groups.py | 544 ++++++++
.../warp_connector/test_configurations.py | 249 ++++
163 files changed, 16865 insertions(+), 209 deletions(-)
create mode 100644 src/cloudflare/resources/flagship/__init__.py
create mode 100644 src/cloudflare/resources/flagship/api.md
create mode 100644 src/cloudflare/resources/flagship/apps/__init__.py
create mode 100644 src/cloudflare/resources/flagship/apps/apps.py
create mode 100644 src/cloudflare/resources/flagship/apps/evaluate.py
create mode 100644 src/cloudflare/resources/flagship/apps/flags/__init__.py
create mode 100644 src/cloudflare/resources/flagship/apps/flags/changelog.py
create mode 100644 src/cloudflare/resources/flagship/apps/flags/flags.py
create mode 100644 src/cloudflare/resources/flagship/flagship.py
rename src/cloudflare/resources/iam/{oauth_scopes => }/oauth_scopes.py (92%)
delete mode 100644 src/cloudflare/resources/iam/oauth_scopes/__init__.py
delete mode 100644 src/cloudflare/resources/iam/oauth_scopes/api.md
rename {tests/api_resources/iam/oauth_scopes => src/cloudflare/resources/origin_tls_compliance_modes}/__init__.py (100%)
create mode 100644 src/cloudflare/resources/zero_trust/dlp/data_classes.py
create mode 100644 src/cloudflare/resources/zero_trust/dlp/data_tag_categories/__init__.py
create mode 100644 src/cloudflare/resources/zero_trust/dlp/data_tag_categories/data_tag_categories.py
create mode 100644 src/cloudflare/resources/zero_trust/dlp/data_tag_categories/data_tags.py
create mode 100644 src/cloudflare/resources/zero_trust/dlp/sensitivity_groups/__init__.py
create mode 100644 src/cloudflare/resources/zero_trust/dlp/sensitivity_groups/levels/__init__.py
create mode 100644 src/cloudflare/resources/zero_trust/dlp/sensitivity_groups/levels/levels.py
create mode 100644 src/cloudflare/resources/zero_trust/dlp/sensitivity_groups/levels/order.py
create mode 100644 src/cloudflare/resources/zero_trust/dlp/sensitivity_groups/sensitivity_groups.py
create mode 100644 src/cloudflare/resources/zero_trust/tunnels/warp_connector/configurations.py
create mode 100644 src/cloudflare/types/d1/database_get_params.py
create mode 100644 src/cloudflare/types/flagship/__init__.py
create mode 100644 src/cloudflare/types/flagship/app_create_params.py
create mode 100644 src/cloudflare/types/flagship/app_create_response.py
create mode 100644 src/cloudflare/types/flagship/app_delete_response.py
create mode 100644 src/cloudflare/types/flagship/app_get_response.py
create mode 100644 src/cloudflare/types/flagship/app_list_response.py
create mode 100644 src/cloudflare/types/flagship/app_update_params.py
create mode 100644 src/cloudflare/types/flagship/app_update_response.py
create mode 100644 src/cloudflare/types/flagship/apps/__init__.py
create mode 100644 src/cloudflare/types/flagship/apps/evaluate_get_params.py
create mode 100644 src/cloudflare/types/flagship/apps/evaluate_get_response.py
create mode 100644 src/cloudflare/types/flagship/apps/flag_create_params.py
create mode 100644 src/cloudflare/types/flagship/apps/flag_create_response.py
create mode 100644 src/cloudflare/types/flagship/apps/flag_delete_response.py
create mode 100644 src/cloudflare/types/flagship/apps/flag_get_response.py
create mode 100644 src/cloudflare/types/flagship/apps/flag_list_params.py
create mode 100644 src/cloudflare/types/flagship/apps/flag_list_response.py
create mode 100644 src/cloudflare/types/flagship/apps/flag_update_params.py
create mode 100644 src/cloudflare/types/flagship/apps/flag_update_response.py
create mode 100644 src/cloudflare/types/flagship/apps/flags/__init__.py
create mode 100644 src/cloudflare/types/flagship/apps/flags/changelog_list_params.py
create mode 100644 src/cloudflare/types/flagship/apps/flags/changelog_list_response.py
rename src/cloudflare/types/iam/{oauth_scopes => }/oauth_scope_list_response.py (95%)
rename src/cloudflare/types/{iam/oauth_scopes => origin_tls_compliance_modes}/__init__.py (57%)
create mode 100644 src/cloudflare/types/zero_trust/dlp/data_class_create_params.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/data_class_create_response.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/data_class_get_response.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/data_class_list_response.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/data_class_update_params.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/data_class_update_response.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/data_tag_categories/__init__.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/data_tag_categories/data_tag_create_params.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/data_tag_categories/data_tag_create_response.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/data_tag_categories/data_tag_get_response.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/data_tag_categories/data_tag_list_response.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/data_tag_categories/data_tag_update_params.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/data_tag_categories/data_tag_update_response.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/data_tag_category_create_params.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/data_tag_category_create_response.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/data_tag_category_get_response.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/data_tag_category_list_response.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/data_tag_category_update_params.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/data_tag_category_update_response.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/sensitivity_group_create_params.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/sensitivity_group_create_response.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/sensitivity_group_get_response.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/sensitivity_group_list_response.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/sensitivity_group_update_params.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/sensitivity_group_update_response.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/sensitivity_groups/__init__.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/sensitivity_groups/level_create_params.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/sensitivity_groups/level_create_response.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/sensitivity_groups/level_get_response.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/sensitivity_groups/level_list_response.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/sensitivity_groups/level_update_params.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/sensitivity_groups/level_update_response.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/sensitivity_groups/levels/__init__.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/sensitivity_groups/levels/order_get_response.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/sensitivity_groups/levels/order_update_params.py
create mode 100644 src/cloudflare/types/zero_trust/dlp/sensitivity_groups/levels/order_update_response.py
create mode 100644 src/cloudflare/types/zero_trust/tunnels/warp_connector/configuration_get_response.py
create mode 100644 src/cloudflare/types/zero_trust/tunnels/warp_connector/configuration_update_params.py
create mode 100644 src/cloudflare/types/zero_trust/tunnels/warp_connector/configuration_update_response.py
create mode 100644 tests/api_resources/flagship/__init__.py
create mode 100644 tests/api_resources/flagship/apps/__init__.py
create mode 100644 tests/api_resources/flagship/apps/flags/__init__.py
create mode 100644 tests/api_resources/flagship/apps/flags/test_changelog.py
create mode 100644 tests/api_resources/flagship/apps/test_evaluate.py
create mode 100644 tests/api_resources/flagship/apps/test_flags.py
create mode 100644 tests/api_resources/flagship/test_apps.py
create mode 100644 tests/api_resources/origin_tls_compliance_modes/__init__.py
create mode 100644 tests/api_resources/zero_trust/dlp/data_tag_categories/__init__.py
create mode 100644 tests/api_resources/zero_trust/dlp/data_tag_categories/test_data_tags.py
create mode 100644 tests/api_resources/zero_trust/dlp/sensitivity_groups/__init__.py
create mode 100644 tests/api_resources/zero_trust/dlp/sensitivity_groups/levels/__init__.py
create mode 100644 tests/api_resources/zero_trust/dlp/sensitivity_groups/levels/test_order.py
create mode 100644 tests/api_resources/zero_trust/dlp/sensitivity_groups/test_levels.py
create mode 100644 tests/api_resources/zero_trust/dlp/test_data_classes.py
create mode 100644 tests/api_resources/zero_trust/dlp/test_data_tag_categories.py
create mode 100644 tests/api_resources/zero_trust/dlp/test_sensitivity_groups.py
create mode 100644 tests/api_resources/zero_trust/tunnels/warp_connector/test_configurations.py
diff --git a/.stats.yml b/.stats.yml
index 41b5b15dd67..c8a83c41f1b 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 2329
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-884b4b7d2d826afd303115f717021363d35e76d0819f4822e9faf6c577ea66ca.yml
-openapi_spec_hash: 4fc7ac1b97d37c76f38db408ab2ed0cd
-config_hash: 1fe0cc702fafe448e633d379a5633326
+configured_endpoints: 2376
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-f63166c7c5fb3e729ec074f8dc759d35278ec33e71d77f31b2ccbfd9bf139b64.yml
+openapi_spec_hash: 8f069d1e288250bf1dcb466b696cd11c
+config_hash: ec0647c69ef9d049d1e12e9ddb0673ee
diff --git a/api.md b/api.md
index 4616608b0dd..843cf80894a 100644
--- a/api.md
+++ b/api.md
@@ -191,6 +191,8 @@ from cloudflare.types import (
# [OriginPostQuantumEncryption](src/cloudflare/resources/origin_post_quantum_encryption/api.md)
+# [OriginTLSComplianceModes](src/cloudflare/resources/origin_tls_compliance_modes/api.md)
+
# [GoogleTagGateway](src/cloudflare/resources/google_tag_gateway/api.md)
# [Zaraz](src/cloudflare/resources/zaraz/api.md)
@@ -211,6 +213,8 @@ from cloudflare.types import (
# [AIGateway](src/cloudflare/resources/ai_gateway/api.md)
+# [Flagship](src/cloudflare/resources/flagship/api.md)
+
# [IAM](src/cloudflare/resources/iam/api.md)
# [CloudConnector](src/cloudflare/resources/cloud_connector/api.md)
diff --git a/src/cloudflare/_client.py b/src/cloudflare/_client.py
index cc7761c131a..a336d47db52 100644
--- a/src/cloudflare/_client.py
+++ b/src/cloudflare/_client.py
@@ -74,6 +74,7 @@
aisearch,
alerting,
firewall,
+ flagship,
rulesets,
snippets,
spectrum,
@@ -187,6 +188,7 @@
from .resources.aisearch.aisearch import AISearchResource, AsyncAISearchResource
from .resources.alerting.alerting import AlertingResource, AsyncAlertingResource
from .resources.firewall.firewall import FirewallResource, AsyncFirewallResource
+ from .resources.flagship.flagship import FlagshipResource, AsyncFlagshipResource
from .resources.rulesets.rulesets import RulesetsResource, AsyncRulesetsResource
from .resources.snippets.snippets import SnippetsResource, AsyncSnippetsResource
from .resources.spectrum.spectrum import SpectrumResource, AsyncSpectrumResource
@@ -956,6 +958,12 @@ def ai_gateway(self) -> AIGatewayResource:
return AIGatewayResource(self)
+ @cached_property
+ def flagship(self) -> FlagshipResource:
+ from .resources.flagship import FlagshipResource
+
+ return FlagshipResource(self)
+
@cached_property
def iam(self) -> IAMResource:
from .resources.iam import IAMResource
@@ -1890,6 +1898,12 @@ def ai_gateway(self) -> AsyncAIGatewayResource:
return AsyncAIGatewayResource(self)
+ @cached_property
+ def flagship(self) -> AsyncFlagshipResource:
+ from .resources.flagship import AsyncFlagshipResource
+
+ return AsyncFlagshipResource(self)
+
@cached_property
def iam(self) -> AsyncIAMResource:
from .resources.iam import AsyncIAMResource
@@ -2746,6 +2760,12 @@ def ai_gateway(self) -> ai_gateway.AIGatewayResourceWithRawResponse:
return AIGatewayResourceWithRawResponse(self._client.ai_gateway)
+ @cached_property
+ def flagship(self) -> flagship.FlagshipResourceWithRawResponse:
+ from .resources.flagship import FlagshipResourceWithRawResponse
+
+ return FlagshipResourceWithRawResponse(self._client.flagship)
+
@cached_property
def iam(self) -> iam.IAMResourceWithRawResponse:
from .resources.iam import IAMResourceWithRawResponse
@@ -3429,6 +3449,12 @@ def ai_gateway(self) -> ai_gateway.AsyncAIGatewayResourceWithRawResponse:
return AsyncAIGatewayResourceWithRawResponse(self._client.ai_gateway)
+ @cached_property
+ def flagship(self) -> flagship.AsyncFlagshipResourceWithRawResponse:
+ from .resources.flagship import AsyncFlagshipResourceWithRawResponse
+
+ return AsyncFlagshipResourceWithRawResponse(self._client.flagship)
+
@cached_property
def iam(self) -> iam.AsyncIAMResourceWithRawResponse:
from .resources.iam import AsyncIAMResourceWithRawResponse
@@ -4112,6 +4138,12 @@ def ai_gateway(self) -> ai_gateway.AIGatewayResourceWithStreamingResponse:
return AIGatewayResourceWithStreamingResponse(self._client.ai_gateway)
+ @cached_property
+ def flagship(self) -> flagship.FlagshipResourceWithStreamingResponse:
+ from .resources.flagship import FlagshipResourceWithStreamingResponse
+
+ return FlagshipResourceWithStreamingResponse(self._client.flagship)
+
@cached_property
def iam(self) -> iam.IAMResourceWithStreamingResponse:
from .resources.iam import IAMResourceWithStreamingResponse
@@ -4803,6 +4835,12 @@ def ai_gateway(self) -> ai_gateway.AsyncAIGatewayResourceWithStreamingResponse:
return AsyncAIGatewayResourceWithStreamingResponse(self._client.ai_gateway)
+ @cached_property
+ def flagship(self) -> flagship.AsyncFlagshipResourceWithStreamingResponse:
+ from .resources.flagship import AsyncFlagshipResourceWithStreamingResponse
+
+ return AsyncFlagshipResourceWithStreamingResponse(self._client.flagship)
+
@cached_property
def iam(self) -> iam.AsyncIAMResourceWithStreamingResponse:
from .resources.iam import AsyncIAMResourceWithStreamingResponse
diff --git a/src/cloudflare/resources/ai/models/models.py b/src/cloudflare/resources/ai/models/models.py
index 5621ade6509..1ddff92d0fa 100644
--- a/src/cloudflare/resources/ai/models/models.py
+++ b/src/cloudflare/resources/ai/models/models.py
@@ -62,6 +62,7 @@ def list(
author: str | Omit = omit,
format: Literal["openrouter"] | Omit = omit,
hide_experimental: bool | Omit = omit,
+ include_deprecated: bool | Omit = omit,
page: int | Omit = omit,
per_page: int | Omit = omit,
search: str | Omit = omit,
@@ -85,6 +86,13 @@ def list(
hide_experimental: Filter to hide experimental models
+ include_deprecated: If true, include models whose planned_deprecation_date is in the past — but only
+ within a three-month grace window after that date. Models whose
+ planned_deprecation_date is more than three months in the past remain hidden
+ regardless of this flag. Future planned-deprecation dates are always included
+ regardless of this flag. Defaults to false, preserving the existing behavior of
+ hiding all past-dated deprecations.
+
search: Search
source: Filter by Source Id
@@ -114,6 +122,7 @@ def list(
"author": author,
"format": format,
"hide_experimental": hide_experimental,
+ "include_deprecated": include_deprecated,
"page": page,
"per_page": per_page,
"search": search,
@@ -158,6 +167,7 @@ def list(
author: str | Omit = omit,
format: Literal["openrouter"] | Omit = omit,
hide_experimental: bool | Omit = omit,
+ include_deprecated: bool | Omit = omit,
page: int | Omit = omit,
per_page: int | Omit = omit,
search: str | Omit = omit,
@@ -181,6 +191,13 @@ def list(
hide_experimental: Filter to hide experimental models
+ include_deprecated: If true, include models whose planned_deprecation_date is in the past — but only
+ within a three-month grace window after that date. Models whose
+ planned_deprecation_date is more than three months in the past remain hidden
+ regardless of this flag. Future planned-deprecation dates are always included
+ regardless of this flag. Defaults to false, preserving the existing behavior of
+ hiding all past-dated deprecations.
+
search: Search
source: Filter by Source Id
@@ -210,6 +227,7 @@ def list(
"author": author,
"format": format,
"hide_experimental": hide_experimental,
+ "include_deprecated": include_deprecated,
"page": page,
"per_page": per_page,
"search": search,
diff --git a/src/cloudflare/resources/ai_gateway/provider_configs.py b/src/cloudflare/resources/ai_gateway/provider_configs.py
index a78fb449c59..9453969bacc 100644
--- a/src/cloudflare/resources/ai_gateway/provider_configs.py
+++ b/src/cloudflare/resources/ai_gateway/provider_configs.py
@@ -54,10 +54,10 @@ def create(
alias: str,
default_config: bool,
provider_slug: str,
- secret: str,
- secret_id: str,
rate_limit: float | Omit = omit,
rate_limit_period: float | Omit = omit,
+ secret: str | Omit = omit,
+ secret_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,
@@ -94,10 +94,10 @@ def create(
"alias": alias,
"default_config": default_config,
"provider_slug": provider_slug,
- "secret": secret,
- "secret_id": secret_id,
"rate_limit": rate_limit,
"rate_limit_period": rate_limit_period,
+ "secret": secret,
+ "secret_id": secret_id,
},
provider_config_create_params.ProviderConfigCreateParams,
),
@@ -195,10 +195,10 @@ async def create(
alias: str,
default_config: bool,
provider_slug: str,
- secret: str,
- secret_id: str,
rate_limit: float | Omit = omit,
rate_limit_period: float | Omit = omit,
+ secret: str | Omit = omit,
+ secret_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,
@@ -235,10 +235,10 @@ async def create(
"alias": alias,
"default_config": default_config,
"provider_slug": provider_slug,
- "secret": secret,
- "secret_id": secret_id,
"rate_limit": rate_limit,
"rate_limit_period": rate_limit_period,
+ "secret": secret,
+ "secret_id": secret_id,
},
provider_config_create_params.ProviderConfigCreateParams,
),
diff --git a/src/cloudflare/resources/cloudforce_one/binary_storage.py b/src/cloudflare/resources/cloudforce_one/binary_storage.py
index 230d4a60cfe..32b57eb19ec 100644
--- a/src/cloudflare/resources/cloudforce_one/binary_storage.py
+++ b/src/cloudflare/resources/cloudforce_one/binary_storage.py
@@ -57,7 +57,8 @@ def create(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> BinaryStorageCreateResponse:
"""
- Posts a file to Binary Storage
+ Uploads a binary file to Cloudforce One's binary database for malware analysis
+ and threat intelligence correlation.
Args:
account_id: Account ID.
@@ -103,7 +104,7 @@ def get(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> None:
"""
- Retrieves a file from Binary Storage
+ Retrieves a binary file from the Cloudforce One binary storage for analysis.
Args:
account_id: Account ID.
@@ -165,7 +166,8 @@ async def create(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> BinaryStorageCreateResponse:
"""
- Posts a file to Binary Storage
+ Uploads a binary file to Cloudforce One's binary database for malware analysis
+ and threat intelligence correlation.
Args:
account_id: Account ID.
@@ -211,7 +213,7 @@ async def get(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> None:
"""
- Retrieves a file from Binary Storage
+ Retrieves a binary file from the Cloudforce One binary storage for analysis.
Args:
account_id: Account ID.
diff --git a/src/cloudflare/resources/d1/api.md b/src/cloudflare/resources/d1/api.md
index 74dbc31770d..460ca20787d 100644
--- a/src/cloudflare/resources/d1/api.md
+++ b/src/cloudflare/resources/d1/api.md
@@ -28,7 +28,7 @@ Methods:
- client.d1.database.delete(database_id, \*, account_id) -> object
- client.d1.database.edit(database_id, \*, account_id, \*\*params) -> D1
- client.d1.database.export(database_id, \*, account_id, \*\*params) -> DatabaseExportResponse
-- client.d1.database.get(database_id, \*, account_id) -> D1
+- client.d1.database.get(database_id, \*, account_id, \*\*params) -> D1
- client.d1.database.import\_(database_id, \*, account_id, \*\*params) -> DatabaseImportResponse
- client.d1.database.query(database_id, \*, account_id, \*\*params) -> SyncSinglePage[QueryResult]
- client.d1.database.raw(database_id, \*, account_id, \*\*params) -> SyncSinglePage[DatabaseRawResponse]
diff --git a/src/cloudflare/resources/d1/database/database.py b/src/cloudflare/resources/d1/database/database.py
index 63cf7cad106..0141f6796cb 100644
--- a/src/cloudflare/resources/d1/database/database.py
+++ b/src/cloudflare/resources/d1/database/database.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import Type, Iterable, Optional, cast
+from typing import List, Type, Iterable, Optional, cast
from typing_extensions import Literal, overload
import httpx
@@ -11,6 +11,7 @@
from ...._utils import path_template, required_args, maybe_transform, async_maybe_transform
from ...._compat import cached_property
from ....types.d1 import (
+ database_get_params,
database_raw_params,
database_edit_params,
database_list_params,
@@ -409,6 +410,20 @@ def get(
database_id: str,
*,
account_id: str,
+ fields: List[
+ Literal[
+ "uuid",
+ "name",
+ "created_at",
+ "version",
+ "jurisdiction",
+ "num_tables",
+ "file_size",
+ "running_in_region",
+ "read_replication",
+ ]
+ ]
+ | 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,
@@ -424,6 +439,9 @@ def get(
database_id: D1 database identifier (UUID).
+ fields: Comma-separated list of fields to include in the response. When omitted, all
+ fields are returned.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -445,6 +463,7 @@ def get(
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
+ query=maybe_transform({"fields": fields}, database_get_params.DatabaseGetParams),
post_parser=ResultWrapper[D1]._unwrapper,
),
cast_to=cast(Type[D1], ResultWrapper[D1]),
@@ -1209,6 +1228,20 @@ async def get(
database_id: str,
*,
account_id: str,
+ fields: List[
+ Literal[
+ "uuid",
+ "name",
+ "created_at",
+ "version",
+ "jurisdiction",
+ "num_tables",
+ "file_size",
+ "running_in_region",
+ "read_replication",
+ ]
+ ]
+ | 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,
@@ -1224,6 +1257,9 @@ async def get(
database_id: D1 database identifier (UUID).
+ fields: Comma-separated list of fields to include in the response. When omitted, all
+ fields are returned.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -1245,6 +1281,7 @@ async def get(
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
+ query=await async_maybe_transform({"fields": fields}, database_get_params.DatabaseGetParams),
post_parser=ResultWrapper[D1]._unwrapper,
),
cast_to=cast(Type[D1], ResultWrapper[D1]),
diff --git a/src/cloudflare/resources/email_sending/email_sending.py b/src/cloudflare/resources/email_sending/email_sending.py
index ec16a873dba..e8b7baab48d 100644
--- a/src/cloudflare/resources/email_sending/email_sending.py
+++ b/src/cloudflare/resources/email_sending/email_sending.py
@@ -63,7 +63,6 @@ def send(
account_id: str,
from_: email_sending_send_params.From,
subject: str,
- to: Union[str, SequenceNotStr[str]],
attachments: Iterable[email_sending_send_params.Attachment] | Omit = omit,
bcc: Union[str, SequenceNotStr[str]] | Omit = omit,
cc: Union[str, SequenceNotStr[str]] | Omit = omit,
@@ -71,6 +70,7 @@ def send(
html: str | Omit = omit,
reply_to: email_sending_send_params.ReplyTo | Omit = omit,
text: str | Omit = omit,
+ to: Union[str, SequenceNotStr[str]] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -88,8 +88,6 @@ def send(
subject: Email subject line.
- to: Recipient(s). A single email string or an array of email strings.
-
attachments: File attachments and inline images.
bcc: BCC recipient(s). A single email string or an array of email strings.
@@ -106,6 +104,9 @@ def send(
text: Plain text body of the email. At least one of text or html must be provided
(non-empty).
+ to: Recipient(s). Optional if cc or bcc is provided. A single email string or an
+ array of email strings.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -122,7 +123,6 @@ def send(
{
"from_": from_,
"subject": subject,
- "to": to,
"attachments": attachments,
"bcc": bcc,
"cc": cc,
@@ -130,6 +130,7 @@ def send(
"html": html,
"reply_to": reply_to,
"text": text,
+ "to": to,
},
email_sending_send_params.EmailSendingSendParams,
),
@@ -233,7 +234,6 @@ async def send(
account_id: str,
from_: email_sending_send_params.From,
subject: str,
- to: Union[str, SequenceNotStr[str]],
attachments: Iterable[email_sending_send_params.Attachment] | Omit = omit,
bcc: Union[str, SequenceNotStr[str]] | Omit = omit,
cc: Union[str, SequenceNotStr[str]] | Omit = omit,
@@ -241,6 +241,7 @@ async def send(
html: str | Omit = omit,
reply_to: email_sending_send_params.ReplyTo | Omit = omit,
text: str | Omit = omit,
+ to: Union[str, SequenceNotStr[str]] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -258,8 +259,6 @@ async def send(
subject: Email subject line.
- to: Recipient(s). A single email string or an array of email strings.
-
attachments: File attachments and inline images.
bcc: BCC recipient(s). A single email string or an array of email strings.
@@ -276,6 +275,9 @@ async def send(
text: Plain text body of the email. At least one of text or html must be provided
(non-empty).
+ to: Recipient(s). Optional if cc or bcc is provided. A single email string or an
+ array of email strings.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -292,7 +294,6 @@ async def send(
{
"from_": from_,
"subject": subject,
- "to": to,
"attachments": attachments,
"bcc": bcc,
"cc": cc,
@@ -300,6 +301,7 @@ async def send(
"html": html,
"reply_to": reply_to,
"text": text,
+ "to": to,
},
email_sending_send_params.EmailSendingSendParams,
),
diff --git a/src/cloudflare/resources/flagship/__init__.py b/src/cloudflare/resources/flagship/__init__.py
new file mode 100644
index 00000000000..ca22677f98e
--- /dev/null
+++ b/src/cloudflare/resources/flagship/__init__.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .apps import (
+ AppsResource,
+ AsyncAppsResource,
+ AppsResourceWithRawResponse,
+ AsyncAppsResourceWithRawResponse,
+ AppsResourceWithStreamingResponse,
+ AsyncAppsResourceWithStreamingResponse,
+)
+from .flagship import (
+ FlagshipResource,
+ AsyncFlagshipResource,
+ FlagshipResourceWithRawResponse,
+ AsyncFlagshipResourceWithRawResponse,
+ FlagshipResourceWithStreamingResponse,
+ AsyncFlagshipResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "AppsResource",
+ "AsyncAppsResource",
+ "AppsResourceWithRawResponse",
+ "AsyncAppsResourceWithRawResponse",
+ "AppsResourceWithStreamingResponse",
+ "AsyncAppsResourceWithStreamingResponse",
+ "FlagshipResource",
+ "AsyncFlagshipResource",
+ "FlagshipResourceWithRawResponse",
+ "AsyncFlagshipResourceWithRawResponse",
+ "FlagshipResourceWithStreamingResponse",
+ "AsyncFlagshipResourceWithStreamingResponse",
+]
diff --git a/src/cloudflare/resources/flagship/api.md b/src/cloudflare/resources/flagship/api.md
new file mode 100644
index 00000000000..2deee29aaaa
--- /dev/null
+++ b/src/cloudflare/resources/flagship/api.md
@@ -0,0 +1,69 @@
+# Flagship
+
+## Apps
+
+Types:
+
+```python
+from cloudflare.types.flagship import (
+ AppCreateResponse,
+ AppUpdateResponse,
+ AppListResponse,
+ AppDeleteResponse,
+ AppGetResponse,
+)
+```
+
+Methods:
+
+- client.flagship.apps.create(\*, account_id, \*\*params) -> AppCreateResponse
+- client.flagship.apps.update(app_id, \*, account_id, \*\*params) -> AppUpdateResponse
+- client.flagship.apps.list(\*, account_id) -> SyncSinglePage[AppListResponse]
+- client.flagship.apps.delete(app_id, \*, account_id) -> AppDeleteResponse
+- client.flagship.apps.get(app_id, \*, account_id) -> AppGetResponse
+
+### Flags
+
+Types:
+
+```python
+from cloudflare.types.flagship.apps import (
+ FlagCreateResponse,
+ FlagUpdateResponse,
+ FlagListResponse,
+ FlagDeleteResponse,
+ FlagGetResponse,
+)
+```
+
+Methods:
+
+- client.flagship.apps.flags.create(app_id, \*, account_id, \*\*params) -> FlagCreateResponse
+- client.flagship.apps.flags.update(flag_key, \*, account_id, app_id, \*\*params) -> FlagUpdateResponse
+- client.flagship.apps.flags.list(app_id, \*, account_id, \*\*params) -> SyncCursorPaginationAfter[FlagListResponse]
+- client.flagship.apps.flags.delete(flag_key, \*, account_id, app_id) -> FlagDeleteResponse
+- client.flagship.apps.flags.get(flag_key, \*, account_id, app_id) -> FlagGetResponse
+
+#### Changelog
+
+Types:
+
+```python
+from cloudflare.types.flagship.apps.flags import ChangelogListResponse
+```
+
+Methods:
+
+- client.flagship.apps.flags.changelog.list(flag_key, \*, account_id, app_id, \*\*params) -> SyncCursorPaginationAfter[ChangelogListResponse]
+
+### Evaluate
+
+Types:
+
+```python
+from cloudflare.types.flagship.apps import EvaluateGetResponse
+```
+
+Methods:
+
+- client.flagship.apps.evaluate.get(app_id, \*, account_id, \*\*params) -> EvaluateGetResponse
diff --git a/src/cloudflare/resources/flagship/apps/__init__.py b/src/cloudflare/resources/flagship/apps/__init__.py
new file mode 100644
index 00000000000..a4eed827a91
--- /dev/null
+++ b/src/cloudflare/resources/flagship/apps/__init__.py
@@ -0,0 +1,47 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .apps import (
+ AppsResource,
+ AsyncAppsResource,
+ AppsResourceWithRawResponse,
+ AsyncAppsResourceWithRawResponse,
+ AppsResourceWithStreamingResponse,
+ AsyncAppsResourceWithStreamingResponse,
+)
+from .flags import (
+ FlagsResource,
+ AsyncFlagsResource,
+ FlagsResourceWithRawResponse,
+ AsyncFlagsResourceWithRawResponse,
+ FlagsResourceWithStreamingResponse,
+ AsyncFlagsResourceWithStreamingResponse,
+)
+from .evaluate import (
+ EvaluateResource,
+ AsyncEvaluateResource,
+ EvaluateResourceWithRawResponse,
+ AsyncEvaluateResourceWithRawResponse,
+ EvaluateResourceWithStreamingResponse,
+ AsyncEvaluateResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "FlagsResource",
+ "AsyncFlagsResource",
+ "FlagsResourceWithRawResponse",
+ "AsyncFlagsResourceWithRawResponse",
+ "FlagsResourceWithStreamingResponse",
+ "AsyncFlagsResourceWithStreamingResponse",
+ "EvaluateResource",
+ "AsyncEvaluateResource",
+ "EvaluateResourceWithRawResponse",
+ "AsyncEvaluateResourceWithRawResponse",
+ "EvaluateResourceWithStreamingResponse",
+ "AsyncEvaluateResourceWithStreamingResponse",
+ "AppsResource",
+ "AsyncAppsResource",
+ "AppsResourceWithRawResponse",
+ "AsyncAppsResourceWithRawResponse",
+ "AppsResourceWithStreamingResponse",
+ "AsyncAppsResourceWithStreamingResponse",
+]
diff --git a/src/cloudflare/resources/flagship/apps/apps.py b/src/cloudflare/resources/flagship/apps/apps.py
new file mode 100644
index 00000000000..80a923ef5e9
--- /dev/null
+++ b/src/cloudflare/resources/flagship/apps/apps.py
@@ -0,0 +1,657 @@
+# 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 .evaluate import (
+ EvaluateResource,
+ AsyncEvaluateResource,
+ EvaluateResourceWithRawResponse,
+ AsyncEvaluateResourceWithRawResponse,
+ EvaluateResourceWithStreamingResponse,
+ AsyncEvaluateResourceWithStreamingResponse,
+)
+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 .flags.flags import (
+ FlagsResource,
+ AsyncFlagsResource,
+ FlagsResourceWithRawResponse,
+ AsyncFlagsResourceWithRawResponse,
+ FlagsResourceWithStreamingResponse,
+ AsyncFlagsResourceWithStreamingResponse,
+)
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from ...._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ...._wrappers import ResultWrapper
+from ....pagination import SyncSinglePage, AsyncSinglePage
+from ...._base_client import AsyncPaginator, make_request_options
+from ....types.flagship import app_create_params, app_update_params
+from ....types.flagship.app_get_response import AppGetResponse
+from ....types.flagship.app_list_response import AppListResponse
+from ....types.flagship.app_create_response import AppCreateResponse
+from ....types.flagship.app_delete_response import AppDeleteResponse
+from ....types.flagship.app_update_response import AppUpdateResponse
+
+__all__ = ["AppsResource", "AsyncAppsResource"]
+
+
+class AppsResource(SyncAPIResource):
+ @cached_property
+ def flags(self) -> FlagsResource:
+ return FlagsResource(self._client)
+
+ @cached_property
+ def evaluate(self) -> EvaluateResource:
+ return EvaluateResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AppsResourceWithRawResponse:
+ """
+ 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 AppsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AppsResourceWithStreamingResponse:
+ """
+ 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 AppsResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ *,
+ account_id: str,
+ name: 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,
+ ) -> AppCreateResponse:
+ """Creates an app.
+
+ The returned `id` is used in all subsequent flag, changelog, and
+ evaluation requests.
+
+ Args:
+ account_id: Cloudflare account ID.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._post(
+ path_template("/accounts/{account_id}/flagship/apps", account_id=account_id),
+ body=maybe_transform({"name": name}, app_create_params.AppCreateParams),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[AppCreateResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[AppCreateResponse], ResultWrapper[AppCreateResponse]),
+ )
+
+ def update(
+ self,
+ app_id: str,
+ *,
+ account_id: str,
+ name: 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,
+ ) -> AppUpdateResponse:
+ """Updates an app.
+
+ Only `name` is mutable.
+
+ Args:
+ account_id: Cloudflare account ID.
+
+ app_id: App 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 app_id:
+ raise ValueError(f"Expected a non-empty value for `app_id` but received {app_id!r}")
+ return self._put(
+ path_template("/accounts/{account_id}/flagship/apps/{app_id}", account_id=account_id, app_id=app_id),
+ body=maybe_transform({"name": name}, app_update_params.AppUpdateParams),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[AppUpdateResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[AppUpdateResponse], ResultWrapper[AppUpdateResponse]),
+ )
+
+ def list(
+ 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[AppListResponse]:
+ """Lists all apps in the account.
+
+ Returns identity and audit fields only — flag
+ definitions are not included.
+
+ Args:
+ account_id: Cloudflare account ID.
+
+ 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}/flagship/apps", account_id=account_id),
+ page=SyncSinglePage[AppListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=AppListResponse,
+ )
+
+ def delete(
+ self,
+ app_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,
+ ) -> AppDeleteResponse:
+ """Deletes an app and all its flags and changelog history.
+
+ Returns 409 if any
+ Worker still references this app via a Flagship binding.
+
+ Args:
+ account_id: Cloudflare account ID.
+
+ app_id: App 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 app_id:
+ raise ValueError(f"Expected a non-empty value for `app_id` but received {app_id!r}")
+ return self._delete(
+ path_template("/accounts/{account_id}/flagship/apps/{app_id}", account_id=account_id, app_id=app_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[AppDeleteResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[AppDeleteResponse], ResultWrapper[AppDeleteResponse]),
+ )
+
+ def get(
+ self,
+ app_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,
+ ) -> AppGetResponse:
+ """Returns an app's name and audit fields.
+
+ Flag definitions are not included.
+
+ Args:
+ account_id: Cloudflare account ID.
+
+ app_id: App 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 app_id:
+ raise ValueError(f"Expected a non-empty value for `app_id` but received {app_id!r}")
+ return self._get(
+ path_template("/accounts/{account_id}/flagship/apps/{app_id}", account_id=account_id, app_id=app_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[AppGetResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[AppGetResponse], ResultWrapper[AppGetResponse]),
+ )
+
+
+class AsyncAppsResource(AsyncAPIResource):
+ @cached_property
+ def flags(self) -> AsyncFlagsResource:
+ return AsyncFlagsResource(self._client)
+
+ @cached_property
+ def evaluate(self) -> AsyncEvaluateResource:
+ return AsyncEvaluateResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncAppsResourceWithRawResponse:
+ """
+ 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 AsyncAppsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncAppsResourceWithStreamingResponse:
+ """
+ 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 AsyncAppsResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ *,
+ account_id: str,
+ name: 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,
+ ) -> AppCreateResponse:
+ """Creates an app.
+
+ The returned `id` is used in all subsequent flag, changelog, and
+ evaluation requests.
+
+ Args:
+ account_id: Cloudflare account ID.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return await self._post(
+ path_template("/accounts/{account_id}/flagship/apps", account_id=account_id),
+ body=await async_maybe_transform({"name": name}, app_create_params.AppCreateParams),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[AppCreateResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[AppCreateResponse], ResultWrapper[AppCreateResponse]),
+ )
+
+ async def update(
+ self,
+ app_id: str,
+ *,
+ account_id: str,
+ name: 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,
+ ) -> AppUpdateResponse:
+ """Updates an app.
+
+ Only `name` is mutable.
+
+ Args:
+ account_id: Cloudflare account ID.
+
+ app_id: App 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 app_id:
+ raise ValueError(f"Expected a non-empty value for `app_id` but received {app_id!r}")
+ return await self._put(
+ path_template("/accounts/{account_id}/flagship/apps/{app_id}", account_id=account_id, app_id=app_id),
+ body=await async_maybe_transform({"name": name}, app_update_params.AppUpdateParams),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[AppUpdateResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[AppUpdateResponse], ResultWrapper[AppUpdateResponse]),
+ )
+
+ def list(
+ 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[AppListResponse, AsyncSinglePage[AppListResponse]]:
+ """Lists all apps in the account.
+
+ Returns identity and audit fields only — flag
+ definitions are not included.
+
+ Args:
+ account_id: Cloudflare account ID.
+
+ 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}/flagship/apps", account_id=account_id),
+ page=AsyncSinglePage[AppListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=AppListResponse,
+ )
+
+ async def delete(
+ self,
+ app_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,
+ ) -> AppDeleteResponse:
+ """Deletes an app and all its flags and changelog history.
+
+ Returns 409 if any
+ Worker still references this app via a Flagship binding.
+
+ Args:
+ account_id: Cloudflare account ID.
+
+ app_id: App 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 app_id:
+ raise ValueError(f"Expected a non-empty value for `app_id` but received {app_id!r}")
+ return await self._delete(
+ path_template("/accounts/{account_id}/flagship/apps/{app_id}", account_id=account_id, app_id=app_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[AppDeleteResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[AppDeleteResponse], ResultWrapper[AppDeleteResponse]),
+ )
+
+ async def get(
+ self,
+ app_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,
+ ) -> AppGetResponse:
+ """Returns an app's name and audit fields.
+
+ Flag definitions are not included.
+
+ Args:
+ account_id: Cloudflare account ID.
+
+ app_id: App 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 app_id:
+ raise ValueError(f"Expected a non-empty value for `app_id` but received {app_id!r}")
+ return await self._get(
+ path_template("/accounts/{account_id}/flagship/apps/{app_id}", account_id=account_id, app_id=app_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[AppGetResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[AppGetResponse], ResultWrapper[AppGetResponse]),
+ )
+
+
+class AppsResourceWithRawResponse:
+ def __init__(self, apps: AppsResource) -> None:
+ self._apps = apps
+
+ self.create = to_raw_response_wrapper(
+ apps.create,
+ )
+ self.update = to_raw_response_wrapper(
+ apps.update,
+ )
+ self.list = to_raw_response_wrapper(
+ apps.list,
+ )
+ self.delete = to_raw_response_wrapper(
+ apps.delete,
+ )
+ self.get = to_raw_response_wrapper(
+ apps.get,
+ )
+
+ @cached_property
+ def flags(self) -> FlagsResourceWithRawResponse:
+ return FlagsResourceWithRawResponse(self._apps.flags)
+
+ @cached_property
+ def evaluate(self) -> EvaluateResourceWithRawResponse:
+ return EvaluateResourceWithRawResponse(self._apps.evaluate)
+
+
+class AsyncAppsResourceWithRawResponse:
+ def __init__(self, apps: AsyncAppsResource) -> None:
+ self._apps = apps
+
+ self.create = async_to_raw_response_wrapper(
+ apps.create,
+ )
+ self.update = async_to_raw_response_wrapper(
+ apps.update,
+ )
+ self.list = async_to_raw_response_wrapper(
+ apps.list,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ apps.delete,
+ )
+ self.get = async_to_raw_response_wrapper(
+ apps.get,
+ )
+
+ @cached_property
+ def flags(self) -> AsyncFlagsResourceWithRawResponse:
+ return AsyncFlagsResourceWithRawResponse(self._apps.flags)
+
+ @cached_property
+ def evaluate(self) -> AsyncEvaluateResourceWithRawResponse:
+ return AsyncEvaluateResourceWithRawResponse(self._apps.evaluate)
+
+
+class AppsResourceWithStreamingResponse:
+ def __init__(self, apps: AppsResource) -> None:
+ self._apps = apps
+
+ self.create = to_streamed_response_wrapper(
+ apps.create,
+ )
+ self.update = to_streamed_response_wrapper(
+ apps.update,
+ )
+ self.list = to_streamed_response_wrapper(
+ apps.list,
+ )
+ self.delete = to_streamed_response_wrapper(
+ apps.delete,
+ )
+ self.get = to_streamed_response_wrapper(
+ apps.get,
+ )
+
+ @cached_property
+ def flags(self) -> FlagsResourceWithStreamingResponse:
+ return FlagsResourceWithStreamingResponse(self._apps.flags)
+
+ @cached_property
+ def evaluate(self) -> EvaluateResourceWithStreamingResponse:
+ return EvaluateResourceWithStreamingResponse(self._apps.evaluate)
+
+
+class AsyncAppsResourceWithStreamingResponse:
+ def __init__(self, apps: AsyncAppsResource) -> None:
+ self._apps = apps
+
+ self.create = async_to_streamed_response_wrapper(
+ apps.create,
+ )
+ self.update = async_to_streamed_response_wrapper(
+ apps.update,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ apps.list,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ apps.delete,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ apps.get,
+ )
+
+ @cached_property
+ def flags(self) -> AsyncFlagsResourceWithStreamingResponse:
+ return AsyncFlagsResourceWithStreamingResponse(self._apps.flags)
+
+ @cached_property
+ def evaluate(self) -> AsyncEvaluateResourceWithStreamingResponse:
+ return AsyncEvaluateResourceWithStreamingResponse(self._apps.evaluate)
diff --git a/src/cloudflare/resources/flagship/apps/evaluate.py b/src/cloudflare/resources/flagship/apps/evaluate.py
new file mode 100644
index 00000000000..11506c1e865
--- /dev/null
+++ b/src/cloudflare/resources/flagship/apps/evaluate.py
@@ -0,0 +1,225 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+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 ...._base_client import make_request_options
+from ....types.flagship.apps import evaluate_get_params
+from ....types.flagship.apps.evaluate_get_response import EvaluateGetResponse
+
+__all__ = ["EvaluateResource", "AsyncEvaluateResource"]
+
+
+class EvaluateResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> EvaluateResourceWithRawResponse:
+ """
+ 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 EvaluateResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> EvaluateResourceWithStreamingResponse:
+ """
+ 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 EvaluateResourceWithStreamingResponse(self)
+
+ def get(
+ self,
+ app_id: str,
+ *,
+ account_id: str,
+ flag_key: str,
+ targeting_key: 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,
+ ) -> EvaluateGetResponse:
+ """Evaluates a flag against the provided context.
+
+ Pass context attributes as query
+ parameters; boolean and numeric strings are coerced automatically. For
+ low-latency in-Worker evaluation, prefer the Flagship binding over this
+ endpoint.
+
+ Args:
+ account_id: Cloudflare account ID.
+
+ app_id: App identifier.
+
+ flag_key: The flag key to evaluate.
+
+ targeting_key: Context targeting key (per OpenFeature spec); used for percentage rollout
+ bucketing.
+
+ 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 app_id:
+ raise ValueError(f"Expected a non-empty value for `app_id` but received {app_id!r}")
+ return self._get(
+ path_template(
+ "/accounts/{account_id}/flagship/apps/{app_id}/evaluate", account_id=account_id, app_id=app_id
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "flag_key": flag_key,
+ "targeting_key": targeting_key,
+ },
+ evaluate_get_params.EvaluateGetParams,
+ ),
+ ),
+ cast_to=EvaluateGetResponse,
+ )
+
+
+class AsyncEvaluateResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncEvaluateResourceWithRawResponse:
+ """
+ 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 AsyncEvaluateResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncEvaluateResourceWithStreamingResponse:
+ """
+ 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 AsyncEvaluateResourceWithStreamingResponse(self)
+
+ async def get(
+ self,
+ app_id: str,
+ *,
+ account_id: str,
+ flag_key: str,
+ targeting_key: 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,
+ ) -> EvaluateGetResponse:
+ """Evaluates a flag against the provided context.
+
+ Pass context attributes as query
+ parameters; boolean and numeric strings are coerced automatically. For
+ low-latency in-Worker evaluation, prefer the Flagship binding over this
+ endpoint.
+
+ Args:
+ account_id: Cloudflare account ID.
+
+ app_id: App identifier.
+
+ flag_key: The flag key to evaluate.
+
+ targeting_key: Context targeting key (per OpenFeature spec); used for percentage rollout
+ bucketing.
+
+ 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 app_id:
+ raise ValueError(f"Expected a non-empty value for `app_id` but received {app_id!r}")
+ return await self._get(
+ path_template(
+ "/accounts/{account_id}/flagship/apps/{app_id}/evaluate", account_id=account_id, app_id=app_id
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "flag_key": flag_key,
+ "targeting_key": targeting_key,
+ },
+ evaluate_get_params.EvaluateGetParams,
+ ),
+ ),
+ cast_to=EvaluateGetResponse,
+ )
+
+
+class EvaluateResourceWithRawResponse:
+ def __init__(self, evaluate: EvaluateResource) -> None:
+ self._evaluate = evaluate
+
+ self.get = to_raw_response_wrapper(
+ evaluate.get,
+ )
+
+
+class AsyncEvaluateResourceWithRawResponse:
+ def __init__(self, evaluate: AsyncEvaluateResource) -> None:
+ self._evaluate = evaluate
+
+ self.get = async_to_raw_response_wrapper(
+ evaluate.get,
+ )
+
+
+class EvaluateResourceWithStreamingResponse:
+ def __init__(self, evaluate: EvaluateResource) -> None:
+ self._evaluate = evaluate
+
+ self.get = to_streamed_response_wrapper(
+ evaluate.get,
+ )
+
+
+class AsyncEvaluateResourceWithStreamingResponse:
+ def __init__(self, evaluate: AsyncEvaluateResource) -> None:
+ self._evaluate = evaluate
+
+ self.get = async_to_streamed_response_wrapper(
+ evaluate.get,
+ )
diff --git a/src/cloudflare/resources/flagship/apps/flags/__init__.py b/src/cloudflare/resources/flagship/apps/flags/__init__.py
new file mode 100644
index 00000000000..5a0f215d818
--- /dev/null
+++ b/src/cloudflare/resources/flagship/apps/flags/__init__.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .flags import (
+ FlagsResource,
+ AsyncFlagsResource,
+ FlagsResourceWithRawResponse,
+ AsyncFlagsResourceWithRawResponse,
+ FlagsResourceWithStreamingResponse,
+ AsyncFlagsResourceWithStreamingResponse,
+)
+from .changelog import (
+ ChangelogResource,
+ AsyncChangelogResource,
+ ChangelogResourceWithRawResponse,
+ AsyncChangelogResourceWithRawResponse,
+ ChangelogResourceWithStreamingResponse,
+ AsyncChangelogResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "ChangelogResource",
+ "AsyncChangelogResource",
+ "ChangelogResourceWithRawResponse",
+ "AsyncChangelogResourceWithRawResponse",
+ "ChangelogResourceWithStreamingResponse",
+ "AsyncChangelogResourceWithStreamingResponse",
+ "FlagsResource",
+ "AsyncFlagsResource",
+ "FlagsResourceWithRawResponse",
+ "AsyncFlagsResourceWithRawResponse",
+ "FlagsResourceWithStreamingResponse",
+ "AsyncFlagsResourceWithStreamingResponse",
+]
diff --git a/src/cloudflare/resources/flagship/apps/flags/changelog.py b/src/cloudflare/resources/flagship/apps/flags/changelog.py
new file mode 100644
index 00000000000..f1e8f2624dd
--- /dev/null
+++ b/src/cloudflare/resources/flagship/apps/flags/changelog.py
@@ -0,0 +1,242 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Any, cast
+
+import httpx
+
+from ....._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ....._utils import path_template, 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 .....pagination import SyncCursorPaginationAfter, AsyncCursorPaginationAfter
+from ....._base_client import AsyncPaginator, make_request_options
+from .....types.flagship.apps.flags import changelog_list_params
+from .....types.flagship.apps.flags.changelog_list_response import ChangelogListResponse
+
+__all__ = ["ChangelogResource", "AsyncChangelogResource"]
+
+
+class ChangelogResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> ChangelogResourceWithRawResponse:
+ """
+ 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 ChangelogResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> ChangelogResourceWithStreamingResponse:
+ """
+ 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 ChangelogResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ flag_key: str,
+ *,
+ account_id: str,
+ app_id: str,
+ cursor: str | Omit = omit,
+ limit: 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,
+ ) -> SyncCursorPaginationAfter[ChangelogListResponse]:
+ """Returns the audit history for a flag, newest first.
+
+ Each entry includes the
+ event type and full flag state after the change; `update` entries include a
+ field-level diff. Capped at 200 entries per flag.
+
+ Args:
+ account_id: Cloudflare account ID.
+
+ app_id: App identifier.
+
+ flag_key: Flag key (slug).
+
+ cursor: Pagination cursor from a previous response.
+
+ limit: Max items to return (1–200).
+
+ 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 app_id:
+ raise ValueError(f"Expected a non-empty value for `app_id` but received {app_id!r}")
+ if not flag_key:
+ raise ValueError(f"Expected a non-empty value for `flag_key` but received {flag_key!r}")
+ return self._get_api_list(
+ path_template(
+ "/accounts/{account_id}/flagship/apps/{app_id}/flags/{flag_key}/changelog",
+ account_id=account_id,
+ app_id=app_id,
+ flag_key=flag_key,
+ ),
+ page=SyncCursorPaginationAfter[ChangelogListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "cursor": cursor,
+ "limit": limit,
+ },
+ changelog_list_params.ChangelogListParams,
+ ),
+ ),
+ model=cast(Any, ChangelogListResponse), # Union types cannot be passed in as arguments in the type system
+ )
+
+
+class AsyncChangelogResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncChangelogResourceWithRawResponse:
+ """
+ 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 AsyncChangelogResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncChangelogResourceWithStreamingResponse:
+ """
+ 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 AsyncChangelogResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ flag_key: str,
+ *,
+ account_id: str,
+ app_id: str,
+ cursor: str | Omit = omit,
+ limit: 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,
+ ) -> AsyncPaginator[ChangelogListResponse, AsyncCursorPaginationAfter[ChangelogListResponse]]:
+ """Returns the audit history for a flag, newest first.
+
+ Each entry includes the
+ event type and full flag state after the change; `update` entries include a
+ field-level diff. Capped at 200 entries per flag.
+
+ Args:
+ account_id: Cloudflare account ID.
+
+ app_id: App identifier.
+
+ flag_key: Flag key (slug).
+
+ cursor: Pagination cursor from a previous response.
+
+ limit: Max items to return (1–200).
+
+ 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 app_id:
+ raise ValueError(f"Expected a non-empty value for `app_id` but received {app_id!r}")
+ if not flag_key:
+ raise ValueError(f"Expected a non-empty value for `flag_key` but received {flag_key!r}")
+ return self._get_api_list(
+ path_template(
+ "/accounts/{account_id}/flagship/apps/{app_id}/flags/{flag_key}/changelog",
+ account_id=account_id,
+ app_id=app_id,
+ flag_key=flag_key,
+ ),
+ page=AsyncCursorPaginationAfter[ChangelogListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "cursor": cursor,
+ "limit": limit,
+ },
+ changelog_list_params.ChangelogListParams,
+ ),
+ ),
+ model=cast(Any, ChangelogListResponse), # Union types cannot be passed in as arguments in the type system
+ )
+
+
+class ChangelogResourceWithRawResponse:
+ def __init__(self, changelog: ChangelogResource) -> None:
+ self._changelog = changelog
+
+ self.list = to_raw_response_wrapper(
+ changelog.list,
+ )
+
+
+class AsyncChangelogResourceWithRawResponse:
+ def __init__(self, changelog: AsyncChangelogResource) -> None:
+ self._changelog = changelog
+
+ self.list = async_to_raw_response_wrapper(
+ changelog.list,
+ )
+
+
+class ChangelogResourceWithStreamingResponse:
+ def __init__(self, changelog: ChangelogResource) -> None:
+ self._changelog = changelog
+
+ self.list = to_streamed_response_wrapper(
+ changelog.list,
+ )
+
+
+class AsyncChangelogResourceWithStreamingResponse:
+ def __init__(self, changelog: AsyncChangelogResource) -> None:
+ self._changelog = changelog
+
+ self.list = async_to_streamed_response_wrapper(
+ changelog.list,
+ )
diff --git a/src/cloudflare/resources/flagship/apps/flags/flags.py b/src/cloudflare/resources/flagship/apps/flags/flags.py
new file mode 100644
index 00000000000..8c3cfa2c65f
--- /dev/null
+++ b/src/cloudflare/resources/flagship/apps/flags/flags.py
@@ -0,0 +1,878 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Dict, Type, Union, Iterable, Optional, cast
+from typing_extensions import Literal
+
+import httpx
+
+from .changelog import (
+ ChangelogResource,
+ AsyncChangelogResource,
+ ChangelogResourceWithRawResponse,
+ AsyncChangelogResourceWithRawResponse,
+ ChangelogResourceWithStreamingResponse,
+ AsyncChangelogResourceWithStreamingResponse,
+)
+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 .....pagination import SyncCursorPaginationAfter, AsyncCursorPaginationAfter
+from ....._base_client import AsyncPaginator, make_request_options
+from .....types.flagship.apps import flag_list_params, flag_create_params, flag_update_params
+from .....types.flagship.apps.flag_get_response import FlagGetResponse
+from .....types.flagship.apps.flag_list_response import FlagListResponse
+from .....types.flagship.apps.flag_create_response import FlagCreateResponse
+from .....types.flagship.apps.flag_delete_response import FlagDeleteResponse
+from .....types.flagship.apps.flag_update_response import FlagUpdateResponse
+
+__all__ = ["FlagsResource", "AsyncFlagsResource"]
+
+
+class FlagsResource(SyncAPIResource):
+ @cached_property
+ def changelog(self) -> ChangelogResource:
+ return ChangelogResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> FlagsResourceWithRawResponse:
+ """
+ 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 FlagsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> FlagsResourceWithStreamingResponse:
+ """
+ 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 FlagsResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ app_id: str,
+ *,
+ account_id: str,
+ default_variation: str,
+ enabled: bool,
+ key: str,
+ rules: Iterable[flag_create_params.Rule],
+ variations: Dict[str, Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]],
+ description: Optional[str] | Omit = omit,
+ type: Literal["boolean", "string", "number", "json"] | 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,
+ ) -> FlagCreateResponse:
+ """Creates a flag.
+
+ Returns 409 if the key already exists. `type` is inferred from
+ variation values and may be omitted.
+
+ Args:
+ account_id: Cloudflare account ID.
+
+ app_id: App identifier.
+
+ default_variation: Variation served when no rule matches or the flag is disabled. Must be a key in
+ `variations`.
+
+ enabled: When false, the flag bypasses all rules and always serves `default_variation`.
+
+ key: Unique identifier for the flag within an app. Used in all evaluation and SDK
+ calls.
+
+ rules: Targeting rules evaluated in ascending `priority`; the first matching rule wins.
+ An empty array means the flag always serves `default_variation`.
+
+ variations: Map of variation name to value. All values must be the same type (boolean,
+ string, number, or JSON object/array). Each serialized value must be 10KB or
+ smaller.
+
+ type: Value type of the flag's variations. Inferred from the variation values on
+ write, so it may be omitted in requests.
+
+ 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 app_id:
+ raise ValueError(f"Expected a non-empty value for `app_id` but received {app_id!r}")
+ return self._post(
+ path_template("/accounts/{account_id}/flagship/apps/{app_id}/flags", account_id=account_id, app_id=app_id),
+ body=maybe_transform(
+ {
+ "default_variation": default_variation,
+ "enabled": enabled,
+ "key": key,
+ "rules": rules,
+ "variations": variations,
+ "description": description,
+ "type": type,
+ },
+ flag_create_params.FlagCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[FlagCreateResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[FlagCreateResponse], ResultWrapper[FlagCreateResponse]),
+ )
+
+ def update(
+ self,
+ flag_key: str,
+ *,
+ account_id: str,
+ app_id: str,
+ default_variation: str,
+ enabled: bool,
+ key: str,
+ rules: Iterable[flag_update_params.Rule],
+ variations: Dict[str, Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]],
+ description: Optional[str] | Omit = omit,
+ type: Literal["boolean", "string", "number", "json"] | 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,
+ ) -> FlagUpdateResponse:
+ """Replaces the entire flag definition.
+
+ Omitted fields are dropped, not preserved —
+ read before writing. Each update appends a changelog entry.
+
+ Args:
+ account_id: Cloudflare account ID.
+
+ app_id: App identifier.
+
+ flag_key: Flag key (slug).
+
+ default_variation: Variation served when no rule matches or the flag is disabled. Must be a key in
+ `variations`.
+
+ enabled: When false, the flag bypasses all rules and always serves `default_variation`.
+
+ key: Unique identifier for the flag within an app. Used in all evaluation and SDK
+ calls.
+
+ rules: Targeting rules evaluated in ascending `priority`; the first matching rule wins.
+ An empty array means the flag always serves `default_variation`.
+
+ variations: Map of variation name to value. All values must be the same type (boolean,
+ string, number, or JSON object/array). Each serialized value must be 10KB or
+ smaller.
+
+ type: Value type of the flag's variations. Inferred from the variation values on
+ write, so it may be omitted in requests.
+
+ 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 app_id:
+ raise ValueError(f"Expected a non-empty value for `app_id` but received {app_id!r}")
+ if not flag_key:
+ raise ValueError(f"Expected a non-empty value for `flag_key` but received {flag_key!r}")
+ return self._put(
+ path_template(
+ "/accounts/{account_id}/flagship/apps/{app_id}/flags/{flag_key}",
+ account_id=account_id,
+ app_id=app_id,
+ flag_key=flag_key,
+ ),
+ body=maybe_transform(
+ {
+ "default_variation": default_variation,
+ "enabled": enabled,
+ "key": key,
+ "rules": rules,
+ "variations": variations,
+ "description": description,
+ "type": type,
+ },
+ flag_update_params.FlagUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[FlagUpdateResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[FlagUpdateResponse], ResultWrapper[FlagUpdateResponse]),
+ )
+
+ def list(
+ self,
+ app_id: str,
+ *,
+ account_id: str,
+ cursor: str | Omit = omit,
+ limit: 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,
+ ) -> SyncCursorPaginationAfter[FlagListResponse]:
+ """Lists an app's flags ordered by key.
+
+ Pass `cursor` from `result_info` to page
+ forward; a null cursor indicates the last page.
+
+ Args:
+ account_id: Cloudflare account ID.
+
+ app_id: App identifier.
+
+ cursor: Pagination cursor from a previous response.
+
+ limit: Max items to return (1–200).
+
+ 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 app_id:
+ raise ValueError(f"Expected a non-empty value for `app_id` but received {app_id!r}")
+ return self._get_api_list(
+ path_template("/accounts/{account_id}/flagship/apps/{app_id}/flags", account_id=account_id, app_id=app_id),
+ page=SyncCursorPaginationAfter[FlagListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "cursor": cursor,
+ "limit": limit,
+ },
+ flag_list_params.FlagListParams,
+ ),
+ ),
+ model=FlagListResponse,
+ )
+
+ def delete(
+ self,
+ flag_key: str,
+ *,
+ account_id: str,
+ app_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,
+ ) -> FlagDeleteResponse:
+ """Permanently deletes a flag.
+
+ Subsequent evaluations fall back to the
+ caller-supplied default. Cannot be undone.
+
+ Args:
+ account_id: Cloudflare account ID.
+
+ app_id: App identifier.
+
+ flag_key: Flag key (slug).
+
+ 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 app_id:
+ raise ValueError(f"Expected a non-empty value for `app_id` but received {app_id!r}")
+ if not flag_key:
+ raise ValueError(f"Expected a non-empty value for `flag_key` but received {flag_key!r}")
+ return self._delete(
+ path_template(
+ "/accounts/{account_id}/flagship/apps/{app_id}/flags/{flag_key}",
+ account_id=account_id,
+ app_id=app_id,
+ flag_key=flag_key,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[FlagDeleteResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[FlagDeleteResponse], ResultWrapper[FlagDeleteResponse]),
+ )
+
+ def get(
+ self,
+ flag_key: str,
+ *,
+ account_id: str,
+ app_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,
+ ) -> FlagGetResponse:
+ """
+ Returns the full flag definition including rules, variations, and audit fields.
+
+ Args:
+ account_id: Cloudflare account ID.
+
+ app_id: App identifier.
+
+ flag_key: Flag key (slug).
+
+ 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 app_id:
+ raise ValueError(f"Expected a non-empty value for `app_id` but received {app_id!r}")
+ if not flag_key:
+ raise ValueError(f"Expected a non-empty value for `flag_key` but received {flag_key!r}")
+ return self._get(
+ path_template(
+ "/accounts/{account_id}/flagship/apps/{app_id}/flags/{flag_key}",
+ account_id=account_id,
+ app_id=app_id,
+ flag_key=flag_key,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[FlagGetResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[FlagGetResponse], ResultWrapper[FlagGetResponse]),
+ )
+
+
+class AsyncFlagsResource(AsyncAPIResource):
+ @cached_property
+ def changelog(self) -> AsyncChangelogResource:
+ return AsyncChangelogResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncFlagsResourceWithRawResponse:
+ """
+ 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 AsyncFlagsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncFlagsResourceWithStreamingResponse:
+ """
+ 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 AsyncFlagsResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ app_id: str,
+ *,
+ account_id: str,
+ default_variation: str,
+ enabled: bool,
+ key: str,
+ rules: Iterable[flag_create_params.Rule],
+ variations: Dict[str, Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]],
+ description: Optional[str] | Omit = omit,
+ type: Literal["boolean", "string", "number", "json"] | 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,
+ ) -> FlagCreateResponse:
+ """Creates a flag.
+
+ Returns 409 if the key already exists. `type` is inferred from
+ variation values and may be omitted.
+
+ Args:
+ account_id: Cloudflare account ID.
+
+ app_id: App identifier.
+
+ default_variation: Variation served when no rule matches or the flag is disabled. Must be a key in
+ `variations`.
+
+ enabled: When false, the flag bypasses all rules and always serves `default_variation`.
+
+ key: Unique identifier for the flag within an app. Used in all evaluation and SDK
+ calls.
+
+ rules: Targeting rules evaluated in ascending `priority`; the first matching rule wins.
+ An empty array means the flag always serves `default_variation`.
+
+ variations: Map of variation name to value. All values must be the same type (boolean,
+ string, number, or JSON object/array). Each serialized value must be 10KB or
+ smaller.
+
+ type: Value type of the flag's variations. Inferred from the variation values on
+ write, so it may be omitted in requests.
+
+ 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 app_id:
+ raise ValueError(f"Expected a non-empty value for `app_id` but received {app_id!r}")
+ return await self._post(
+ path_template("/accounts/{account_id}/flagship/apps/{app_id}/flags", account_id=account_id, app_id=app_id),
+ body=await async_maybe_transform(
+ {
+ "default_variation": default_variation,
+ "enabled": enabled,
+ "key": key,
+ "rules": rules,
+ "variations": variations,
+ "description": description,
+ "type": type,
+ },
+ flag_create_params.FlagCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[FlagCreateResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[FlagCreateResponse], ResultWrapper[FlagCreateResponse]),
+ )
+
+ async def update(
+ self,
+ flag_key: str,
+ *,
+ account_id: str,
+ app_id: str,
+ default_variation: str,
+ enabled: bool,
+ key: str,
+ rules: Iterable[flag_update_params.Rule],
+ variations: Dict[str, Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]],
+ description: Optional[str] | Omit = omit,
+ type: Literal["boolean", "string", "number", "json"] | 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,
+ ) -> FlagUpdateResponse:
+ """Replaces the entire flag definition.
+
+ Omitted fields are dropped, not preserved —
+ read before writing. Each update appends a changelog entry.
+
+ Args:
+ account_id: Cloudflare account ID.
+
+ app_id: App identifier.
+
+ flag_key: Flag key (slug).
+
+ default_variation: Variation served when no rule matches or the flag is disabled. Must be a key in
+ `variations`.
+
+ enabled: When false, the flag bypasses all rules and always serves `default_variation`.
+
+ key: Unique identifier for the flag within an app. Used in all evaluation and SDK
+ calls.
+
+ rules: Targeting rules evaluated in ascending `priority`; the first matching rule wins.
+ An empty array means the flag always serves `default_variation`.
+
+ variations: Map of variation name to value. All values must be the same type (boolean,
+ string, number, or JSON object/array). Each serialized value must be 10KB or
+ smaller.
+
+ type: Value type of the flag's variations. Inferred from the variation values on
+ write, so it may be omitted in requests.
+
+ 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 app_id:
+ raise ValueError(f"Expected a non-empty value for `app_id` but received {app_id!r}")
+ if not flag_key:
+ raise ValueError(f"Expected a non-empty value for `flag_key` but received {flag_key!r}")
+ return await self._put(
+ path_template(
+ "/accounts/{account_id}/flagship/apps/{app_id}/flags/{flag_key}",
+ account_id=account_id,
+ app_id=app_id,
+ flag_key=flag_key,
+ ),
+ body=await async_maybe_transform(
+ {
+ "default_variation": default_variation,
+ "enabled": enabled,
+ "key": key,
+ "rules": rules,
+ "variations": variations,
+ "description": description,
+ "type": type,
+ },
+ flag_update_params.FlagUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[FlagUpdateResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[FlagUpdateResponse], ResultWrapper[FlagUpdateResponse]),
+ )
+
+ def list(
+ self,
+ app_id: str,
+ *,
+ account_id: str,
+ cursor: str | Omit = omit,
+ limit: 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,
+ ) -> AsyncPaginator[FlagListResponse, AsyncCursorPaginationAfter[FlagListResponse]]:
+ """Lists an app's flags ordered by key.
+
+ Pass `cursor` from `result_info` to page
+ forward; a null cursor indicates the last page.
+
+ Args:
+ account_id: Cloudflare account ID.
+
+ app_id: App identifier.
+
+ cursor: Pagination cursor from a previous response.
+
+ limit: Max items to return (1–200).
+
+ 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 app_id:
+ raise ValueError(f"Expected a non-empty value for `app_id` but received {app_id!r}")
+ return self._get_api_list(
+ path_template("/accounts/{account_id}/flagship/apps/{app_id}/flags", account_id=account_id, app_id=app_id),
+ page=AsyncCursorPaginationAfter[FlagListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "cursor": cursor,
+ "limit": limit,
+ },
+ flag_list_params.FlagListParams,
+ ),
+ ),
+ model=FlagListResponse,
+ )
+
+ async def delete(
+ self,
+ flag_key: str,
+ *,
+ account_id: str,
+ app_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,
+ ) -> FlagDeleteResponse:
+ """Permanently deletes a flag.
+
+ Subsequent evaluations fall back to the
+ caller-supplied default. Cannot be undone.
+
+ Args:
+ account_id: Cloudflare account ID.
+
+ app_id: App identifier.
+
+ flag_key: Flag key (slug).
+
+ 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 app_id:
+ raise ValueError(f"Expected a non-empty value for `app_id` but received {app_id!r}")
+ if not flag_key:
+ raise ValueError(f"Expected a non-empty value for `flag_key` but received {flag_key!r}")
+ return await self._delete(
+ path_template(
+ "/accounts/{account_id}/flagship/apps/{app_id}/flags/{flag_key}",
+ account_id=account_id,
+ app_id=app_id,
+ flag_key=flag_key,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[FlagDeleteResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[FlagDeleteResponse], ResultWrapper[FlagDeleteResponse]),
+ )
+
+ async def get(
+ self,
+ flag_key: str,
+ *,
+ account_id: str,
+ app_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,
+ ) -> FlagGetResponse:
+ """
+ Returns the full flag definition including rules, variations, and audit fields.
+
+ Args:
+ account_id: Cloudflare account ID.
+
+ app_id: App identifier.
+
+ flag_key: Flag key (slug).
+
+ 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 app_id:
+ raise ValueError(f"Expected a non-empty value for `app_id` but received {app_id!r}")
+ if not flag_key:
+ raise ValueError(f"Expected a non-empty value for `flag_key` but received {flag_key!r}")
+ return await self._get(
+ path_template(
+ "/accounts/{account_id}/flagship/apps/{app_id}/flags/{flag_key}",
+ account_id=account_id,
+ app_id=app_id,
+ flag_key=flag_key,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[FlagGetResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[FlagGetResponse], ResultWrapper[FlagGetResponse]),
+ )
+
+
+class FlagsResourceWithRawResponse:
+ def __init__(self, flags: FlagsResource) -> None:
+ self._flags = flags
+
+ self.create = to_raw_response_wrapper(
+ flags.create,
+ )
+ self.update = to_raw_response_wrapper(
+ flags.update,
+ )
+ self.list = to_raw_response_wrapper(
+ flags.list,
+ )
+ self.delete = to_raw_response_wrapper(
+ flags.delete,
+ )
+ self.get = to_raw_response_wrapper(
+ flags.get,
+ )
+
+ @cached_property
+ def changelog(self) -> ChangelogResourceWithRawResponse:
+ return ChangelogResourceWithRawResponse(self._flags.changelog)
+
+
+class AsyncFlagsResourceWithRawResponse:
+ def __init__(self, flags: AsyncFlagsResource) -> None:
+ self._flags = flags
+
+ self.create = async_to_raw_response_wrapper(
+ flags.create,
+ )
+ self.update = async_to_raw_response_wrapper(
+ flags.update,
+ )
+ self.list = async_to_raw_response_wrapper(
+ flags.list,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ flags.delete,
+ )
+ self.get = async_to_raw_response_wrapper(
+ flags.get,
+ )
+
+ @cached_property
+ def changelog(self) -> AsyncChangelogResourceWithRawResponse:
+ return AsyncChangelogResourceWithRawResponse(self._flags.changelog)
+
+
+class FlagsResourceWithStreamingResponse:
+ def __init__(self, flags: FlagsResource) -> None:
+ self._flags = flags
+
+ self.create = to_streamed_response_wrapper(
+ flags.create,
+ )
+ self.update = to_streamed_response_wrapper(
+ flags.update,
+ )
+ self.list = to_streamed_response_wrapper(
+ flags.list,
+ )
+ self.delete = to_streamed_response_wrapper(
+ flags.delete,
+ )
+ self.get = to_streamed_response_wrapper(
+ flags.get,
+ )
+
+ @cached_property
+ def changelog(self) -> ChangelogResourceWithStreamingResponse:
+ return ChangelogResourceWithStreamingResponse(self._flags.changelog)
+
+
+class AsyncFlagsResourceWithStreamingResponse:
+ def __init__(self, flags: AsyncFlagsResource) -> None:
+ self._flags = flags
+
+ self.create = async_to_streamed_response_wrapper(
+ flags.create,
+ )
+ self.update = async_to_streamed_response_wrapper(
+ flags.update,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ flags.list,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ flags.delete,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ flags.get,
+ )
+
+ @cached_property
+ def changelog(self) -> AsyncChangelogResourceWithStreamingResponse:
+ return AsyncChangelogResourceWithStreamingResponse(self._flags.changelog)
diff --git a/src/cloudflare/resources/flagship/flagship.py b/src/cloudflare/resources/flagship/flagship.py
new file mode 100644
index 00000000000..bd49736bd76
--- /dev/null
+++ b/src/cloudflare/resources/flagship/flagship.py
@@ -0,0 +1,102 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from ..._compat import cached_property
+from .apps.apps import (
+ AppsResource,
+ AsyncAppsResource,
+ AppsResourceWithRawResponse,
+ AsyncAppsResourceWithRawResponse,
+ AppsResourceWithStreamingResponse,
+ AsyncAppsResourceWithStreamingResponse,
+)
+from ..._resource import SyncAPIResource, AsyncAPIResource
+
+__all__ = ["FlagshipResource", "AsyncFlagshipResource"]
+
+
+class FlagshipResource(SyncAPIResource):
+ @cached_property
+ def apps(self) -> AppsResource:
+ return AppsResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> FlagshipResourceWithRawResponse:
+ """
+ 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 FlagshipResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> FlagshipResourceWithStreamingResponse:
+ """
+ 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 FlagshipResourceWithStreamingResponse(self)
+
+
+class AsyncFlagshipResource(AsyncAPIResource):
+ @cached_property
+ def apps(self) -> AsyncAppsResource:
+ return AsyncAppsResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncFlagshipResourceWithRawResponse:
+ """
+ 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 AsyncFlagshipResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncFlagshipResourceWithStreamingResponse:
+ """
+ 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 AsyncFlagshipResourceWithStreamingResponse(self)
+
+
+class FlagshipResourceWithRawResponse:
+ def __init__(self, flagship: FlagshipResource) -> None:
+ self._flagship = flagship
+
+ @cached_property
+ def apps(self) -> AppsResourceWithRawResponse:
+ return AppsResourceWithRawResponse(self._flagship.apps)
+
+
+class AsyncFlagshipResourceWithRawResponse:
+ def __init__(self, flagship: AsyncFlagshipResource) -> None:
+ self._flagship = flagship
+
+ @cached_property
+ def apps(self) -> AsyncAppsResourceWithRawResponse:
+ return AsyncAppsResourceWithRawResponse(self._flagship.apps)
+
+
+class FlagshipResourceWithStreamingResponse:
+ def __init__(self, flagship: FlagshipResource) -> None:
+ self._flagship = flagship
+
+ @cached_property
+ def apps(self) -> AppsResourceWithStreamingResponse:
+ return AppsResourceWithStreamingResponse(self._flagship.apps)
+
+
+class AsyncFlagshipResourceWithStreamingResponse:
+ def __init__(self, flagship: AsyncFlagshipResource) -> None:
+ self._flagship = flagship
+
+ @cached_property
+ def apps(self) -> AsyncAppsResourceWithStreamingResponse:
+ return AsyncAppsResourceWithStreamingResponse(self._flagship.apps)
diff --git a/src/cloudflare/resources/iam/__init__.py b/src/cloudflare/resources/iam/__init__.py
index ced345df6f5..ca346183fa2 100644
--- a/src/cloudflare/resources/iam/__init__.py
+++ b/src/cloudflare/resources/iam/__init__.py
@@ -24,6 +24,14 @@
UserGroupsResourceWithStreamingResponse,
AsyncUserGroupsResourceWithStreamingResponse,
)
+from .oauth_scopes import (
+ OAuthScopesResource,
+ AsyncOAuthScopesResource,
+ OAuthScopesResourceWithRawResponse,
+ AsyncOAuthScopesResourceWithRawResponse,
+ OAuthScopesResourceWithStreamingResponse,
+ AsyncOAuthScopesResourceWithStreamingResponse,
+)
from .oauth_clients import (
OAuthClientsResource,
AsyncOAuthClientsResource,
@@ -80,6 +88,12 @@
"AsyncOAuthClientsResourceWithRawResponse",
"OAuthClientsResourceWithStreamingResponse",
"AsyncOAuthClientsResourceWithStreamingResponse",
+ "OAuthScopesResource",
+ "AsyncOAuthScopesResource",
+ "OAuthScopesResourceWithRawResponse",
+ "AsyncOAuthScopesResourceWithRawResponse",
+ "OAuthScopesResourceWithStreamingResponse",
+ "AsyncOAuthScopesResourceWithStreamingResponse",
"IAMResource",
"AsyncIAMResource",
"IAMResourceWithRawResponse",
diff --git a/src/cloudflare/resources/iam/api.md b/src/cloudflare/resources/iam/api.md
index 419403b71f8..96ce4622426 100644
--- a/src/cloudflare/resources/iam/api.md
+++ b/src/cloudflare/resources/iam/api.md
@@ -129,4 +129,14 @@ Methods:
- client.iam.oauth_clients.get(oauth_client_id, \*, account_id) -> Optional[OAuthClientGetResponse]
- client.iam.oauth_clients.rotate_secret(oauth_client_id, \*, account_id) -> Optional[OAuthClientRotateSecretResponse]
-## [OAuthScopes](src/cloudflare/resources/iam/api.md)
+## OAuthScopes
+
+Types:
+
+```python
+from cloudflare.types.iam import OAuthScopeListResponse
+```
+
+Methods:
+
+- client.iam.oauth_scopes.list() -> SyncSinglePage[OAuthScopeListResponse]
diff --git a/src/cloudflare/resources/iam/iam.py b/src/cloudflare/resources/iam/iam.py
index b5ec435a1af..14e695fa66a 100644
--- a/src/cloudflare/resources/iam/iam.py
+++ b/src/cloudflare/resources/iam/iam.py
@@ -12,6 +12,14 @@
)
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
+from .oauth_scopes import (
+ OAuthScopesResource,
+ AsyncOAuthScopesResource,
+ OAuthScopesResourceWithRawResponse,
+ AsyncOAuthScopesResourceWithRawResponse,
+ OAuthScopesResourceWithStreamingResponse,
+ AsyncOAuthScopesResourceWithStreamingResponse,
+)
from .oauth_clients import (
OAuthClientsResource,
AsyncOAuthClientsResource,
@@ -44,14 +52,6 @@
UserGroupsResourceWithStreamingResponse,
AsyncUserGroupsResourceWithStreamingResponse,
)
-from .oauth_scopes.oauth_scopes import (
- OAuthScopesResource,
- AsyncOAuthScopesResource,
- OAuthScopesResourceWithRawResponse,
- AsyncOAuthScopesResourceWithRawResponse,
- OAuthScopesResourceWithStreamingResponse,
- AsyncOAuthScopesResourceWithStreamingResponse,
-)
__all__ = ["IAMResource", "AsyncIAMResource"]
diff --git a/src/cloudflare/resources/iam/oauth_scopes/oauth_scopes.py b/src/cloudflare/resources/iam/oauth_scopes.py
similarity index 92%
rename from src/cloudflare/resources/iam/oauth_scopes/oauth_scopes.py
rename to src/cloudflare/resources/iam/oauth_scopes.py
index bd577be711c..0f0e026ca4c 100644
--- a/src/cloudflare/resources/iam/oauth_scopes/oauth_scopes.py
+++ b/src/cloudflare/resources/iam/oauth_scopes.py
@@ -4,18 +4,18 @@
import httpx
-from ...._types import Body, Query, Headers, NotGiven, not_given
-from ...._compat import cached_property
-from ...._resource import SyncAPIResource, AsyncAPIResource
-from ...._response import (
+from ..._types import Body, Query, Headers, NotGiven, not_given
+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 ....pagination import SyncSinglePage, AsyncSinglePage
-from ...._base_client import AsyncPaginator, make_request_options
-from ....types.iam.oauth_scopes.oauth_scope_list_response import OAuthScopeListResponse
+from ...pagination import SyncSinglePage, AsyncSinglePage
+from ..._base_client import AsyncPaginator, make_request_options
+from ...types.iam.oauth_scope_list_response import OAuthScopeListResponse
__all__ = ["OAuthScopesResource", "AsyncOAuthScopesResource"]
diff --git a/src/cloudflare/resources/iam/oauth_scopes/__init__.py b/src/cloudflare/resources/iam/oauth_scopes/__init__.py
deleted file mode 100644
index 72d5598565f..00000000000
--- a/src/cloudflare/resources/iam/oauth_scopes/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from .oauth_scopes import (
- OAuthScopesResource,
- AsyncOAuthScopesResource,
- OAuthScopesResourceWithRawResponse,
- AsyncOAuthScopesResourceWithRawResponse,
- OAuthScopesResourceWithStreamingResponse,
- AsyncOAuthScopesResourceWithStreamingResponse,
-)
-
-__all__ = [
- "OAuthScopesResource",
- "AsyncOAuthScopesResource",
- "OAuthScopesResourceWithRawResponse",
- "AsyncOAuthScopesResourceWithRawResponse",
- "OAuthScopesResourceWithStreamingResponse",
- "AsyncOAuthScopesResourceWithStreamingResponse",
-]
diff --git a/src/cloudflare/resources/iam/oauth_scopes/api.md b/src/cloudflare/resources/iam/oauth_scopes/api.md
deleted file mode 100644
index 47eebcae48e..00000000000
--- a/src/cloudflare/resources/iam/oauth_scopes/api.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# OAuthScopes
-
-Types:
-
-```python
-from cloudflare.types.iam.oauth_scopes import OAuthScopeListResponse
-```
-
-Methods:
-
-- client.iam.oauth_scopes.list() -> SyncSinglePage[OAuthScopeListResponse]
diff --git a/src/cloudflare/resources/logpush/datasets/fields.py b/src/cloudflare/resources/logpush/datasets/fields.py
index 905b3f0fcb0..cc9ccbdc799 100644
--- a/src/cloudflare/resources/logpush/datasets/fields.py
+++ b/src/cloudflare/resources/logpush/datasets/fields.py
@@ -77,6 +77,7 @@ def get(
"turnstile_events",
"warp_config_changes",
"warp_toggle_changes",
+ "websocket_analytics",
"workers_trace_events",
"zaraz_events",
"zero_trust_network_sessions",
@@ -198,6 +199,7 @@ async def get(
"turnstile_events",
"warp_config_changes",
"warp_toggle_changes",
+ "websocket_analytics",
"workers_trace_events",
"zaraz_events",
"zero_trust_network_sessions",
diff --git a/src/cloudflare/resources/logpush/datasets/jobs.py b/src/cloudflare/resources/logpush/datasets/jobs.py
index d229ba4c636..d13702627d3 100644
--- a/src/cloudflare/resources/logpush/datasets/jobs.py
+++ b/src/cloudflare/resources/logpush/datasets/jobs.py
@@ -78,6 +78,7 @@ def get(
"turnstile_events",
"warp_config_changes",
"warp_toggle_changes",
+ "websocket_analytics",
"workers_trace_events",
"zaraz_events",
"zero_trust_network_sessions",
@@ -194,6 +195,7 @@ def get(
"turnstile_events",
"warp_config_changes",
"warp_toggle_changes",
+ "websocket_analytics",
"workers_trace_events",
"zaraz_events",
"zero_trust_network_sessions",
diff --git a/src/cloudflare/resources/logpush/jobs.py b/src/cloudflare/resources/logpush/jobs.py
index 8c62a706d68..0b8265db678 100644
--- a/src/cloudflare/resources/logpush/jobs.py
+++ b/src/cloudflare/resources/logpush/jobs.py
@@ -87,6 +87,7 @@ def create(
"turnstile_events",
"warp_config_changes",
"warp_toggle_changes",
+ "websocket_analytics",
"workers_trace_events",
"zaraz_events",
"zero_trust_network_sessions",
@@ -594,6 +595,7 @@ async def create(
"turnstile_events",
"warp_config_changes",
"warp_toggle_changes",
+ "websocket_analytics",
"workers_trace_events",
"zaraz_events",
"zero_trust_network_sessions",
diff --git a/src/cloudflare/resources/managed_transforms/managed_transforms.py b/src/cloudflare/resources/managed_transforms/managed_transforms.py
index cb1fd1cd1b8..259a392cd9a 100644
--- a/src/cloudflare/resources/managed_transforms/managed_transforms.py
+++ b/src/cloudflare/resources/managed_transforms/managed_transforms.py
@@ -6,7 +6,7 @@
import httpx
-from ..._types import Body, Query, Headers, NoneType, NotGiven, not_given
+from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
@@ -124,8 +124,8 @@ def edit(
self,
*,
zone_id: str,
- managed_request_headers: Iterable[managed_transform_edit_params.ManagedRequestHeader],
- managed_response_headers: Iterable[managed_transform_edit_params.ManagedResponseHeader],
+ managed_request_headers: Iterable[managed_transform_edit_params.ManagedRequestHeader] | Omit = omit,
+ managed_response_headers: Iterable[managed_transform_edit_params.ManagedResponseHeader] | 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,
@@ -272,8 +272,8 @@ async def edit(
self,
*,
zone_id: str,
- managed_request_headers: Iterable[managed_transform_edit_params.ManagedRequestHeader],
- managed_response_headers: Iterable[managed_transform_edit_params.ManagedResponseHeader],
+ managed_request_headers: Iterable[managed_transform_edit_params.ManagedRequestHeader] | Omit = omit,
+ managed_response_headers: Iterable[managed_transform_edit_params.ManagedResponseHeader] | 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,
diff --git a/tests/api_resources/iam/oauth_scopes/__init__.py b/src/cloudflare/resources/origin_tls_compliance_modes/__init__.py
similarity index 100%
rename from tests/api_resources/iam/oauth_scopes/__init__.py
rename to src/cloudflare/resources/origin_tls_compliance_modes/__init__.py
diff --git a/src/cloudflare/resources/zero_trust/access/ai_controls/mcp/servers.py b/src/cloudflare/resources/zero_trust/access/ai_controls/mcp/servers.py
index 3c874c8e772..a8333e30d00 100644
--- a/src/cloudflare/resources/zero_trust/access/ai_controls/mcp/servers.py
+++ b/src/cloudflare/resources/zero_trust/access/ai_controls/mcp/servers.py
@@ -62,6 +62,7 @@ def create(
auth_credentials: str | Omit = omit,
description: Optional[str] | Omit = omit,
is_shared_oauth_callback_enabled: bool | Omit = omit,
+ secure_web_gateway: bool | Omit = omit,
updated_prompts: Iterable[server_create_params.UpdatedPrompt] | Omit = omit,
updated_tools: Iterable[server_create_params.UpdatedTool] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -83,6 +84,8 @@ def create(
servers default to false from migration until explicitly updated. Effective
behavior is gated by the gateway worker's per-env rollout mode KV key.
+ secure_web_gateway: Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -104,6 +107,7 @@ def create(
"auth_credentials": auth_credentials,
"description": description,
"is_shared_oauth_callback_enabled": is_shared_oauth_callback_enabled,
+ "secure_web_gateway": secure_web_gateway,
"updated_prompts": updated_prompts,
"updated_tools": updated_tools,
},
@@ -128,6 +132,7 @@ def update(
description: Optional[str] | Omit = omit,
is_shared_oauth_callback_enabled: bool | Omit = omit,
name: str | Omit = omit,
+ secure_web_gateway: bool | Omit = omit,
updated_prompts: Iterable[server_update_params.UpdatedPrompt] | Omit = omit,
updated_tools: Iterable[server_update_params.UpdatedTool] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -149,6 +154,8 @@ def update(
servers default to false from migration until explicitly updated. Effective
behavior is gated by the gateway worker's per-env rollout mode KV key.
+ secure_web_gateway: Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -169,6 +176,7 @@ def update(
"description": description,
"is_shared_oauth_callback_enabled": is_shared_oauth_callback_enabled,
"name": name,
+ "secure_web_gateway": secure_web_gateway,
"updated_prompts": updated_prompts,
"updated_tools": updated_tools,
},
@@ -395,6 +403,7 @@ async def create(
auth_credentials: str | Omit = omit,
description: Optional[str] | Omit = omit,
is_shared_oauth_callback_enabled: bool | Omit = omit,
+ secure_web_gateway: bool | Omit = omit,
updated_prompts: Iterable[server_create_params.UpdatedPrompt] | Omit = omit,
updated_tools: Iterable[server_create_params.UpdatedTool] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -416,6 +425,8 @@ async def create(
servers default to false from migration until explicitly updated. Effective
behavior is gated by the gateway worker's per-env rollout mode KV key.
+ secure_web_gateway: Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -437,6 +448,7 @@ async def create(
"auth_credentials": auth_credentials,
"description": description,
"is_shared_oauth_callback_enabled": is_shared_oauth_callback_enabled,
+ "secure_web_gateway": secure_web_gateway,
"updated_prompts": updated_prompts,
"updated_tools": updated_tools,
},
@@ -461,6 +473,7 @@ async def update(
description: Optional[str] | Omit = omit,
is_shared_oauth_callback_enabled: bool | Omit = omit,
name: str | Omit = omit,
+ secure_web_gateway: bool | Omit = omit,
updated_prompts: Iterable[server_update_params.UpdatedPrompt] | Omit = omit,
updated_tools: Iterable[server_update_params.UpdatedTool] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -482,6 +495,8 @@ async def update(
servers default to false from migration until explicitly updated. Effective
behavior is gated by the gateway worker's per-env rollout mode KV key.
+ secure_web_gateway: Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -502,6 +517,7 @@ async def update(
"description": description,
"is_shared_oauth_callback_enabled": is_shared_oauth_callback_enabled,
"name": name,
+ "secure_web_gateway": secure_web_gateway,
"updated_prompts": updated_prompts,
"updated_tools": updated_tools,
},
diff --git a/src/cloudflare/resources/zero_trust/api.md b/src/cloudflare/resources/zero_trust/api.md
index 14f6d3f5e57..e635ba306be 100644
--- a/src/cloudflare/resources/zero_trust/api.md
+++ b/src/cloudflare/resources/zero_trust/api.md
@@ -1351,6 +1351,22 @@ Methods:
- client.zero_trust.tunnels.warp_connector.failover.update(tunnel_id, \*, account_id, \*\*params) -> object
+#### Configurations
+
+Types:
+
+```python
+from cloudflare.types.zero_trust.tunnels.warp_connector import (
+ ConfigurationUpdateResponse,
+ ConfigurationGetResponse,
+)
+```
+
+Methods:
+
+- client.zero_trust.tunnels.warp_connector.configurations.update(tunnel_id, \*, account_id, \*\*params) -> Optional[ConfigurationUpdateResponse]
+- client.zero_trust.tunnels.warp_connector.configurations.get(tunnel_id, \*, account_id) -> Optional[ConfigurationGetResponse]
+
## ConnectivitySettings
Types:
@@ -1658,6 +1674,127 @@ Methods:
- client.zero_trust.dlp.entries.integration.delete(entry_id, \*, account_id) -> object
- client.zero_trust.dlp.entries.integration.get(entry_id, \*, account_id) -> Optional[IntegrationGetResponse]
+### SensitivityGroups
+
+Types:
+
+```python
+from cloudflare.types.zero_trust.dlp import (
+ SensitivityGroupCreateResponse,
+ SensitivityGroupUpdateResponse,
+ SensitivityGroupListResponse,
+ SensitivityGroupGetResponse,
+)
+```
+
+Methods:
+
+- client.zero_trust.dlp.sensitivity_groups.create(\*, account_id, \*\*params) -> Optional[SensitivityGroupCreateResponse]
+- client.zero_trust.dlp.sensitivity_groups.update(sensitivity_group_id, \*, account_id, \*\*params) -> Optional[SensitivityGroupUpdateResponse]
+- client.zero_trust.dlp.sensitivity_groups.list(\*, account_id) -> SyncSinglePage[SensitivityGroupListResponse]
+- client.zero_trust.dlp.sensitivity_groups.delete(sensitivity_group_id, \*, account_id) -> object
+- client.zero_trust.dlp.sensitivity_groups.get(sensitivity_group_id, \*, account_id) -> Optional[SensitivityGroupGetResponse]
+
+#### Levels
+
+Types:
+
+```python
+from cloudflare.types.zero_trust.dlp.sensitivity_groups import (
+ LevelCreateResponse,
+ LevelUpdateResponse,
+ LevelListResponse,
+ LevelGetResponse,
+)
+```
+
+Methods:
+
+- client.zero_trust.dlp.sensitivity_groups.levels.create(sensitivity_group_id, \*, account_id, \*\*params) -> Optional[LevelCreateResponse]
+- client.zero_trust.dlp.sensitivity_groups.levels.update(sensitivity_level_id, \*, account_id, sensitivity_group_id, \*\*params) -> Optional[LevelUpdateResponse]
+- client.zero_trust.dlp.sensitivity_groups.levels.list(sensitivity_group_id, \*, account_id) -> SyncSinglePage[LevelListResponse]
+- client.zero_trust.dlp.sensitivity_groups.levels.delete(sensitivity_level_id, \*, account_id, sensitivity_group_id) -> object
+- client.zero_trust.dlp.sensitivity_groups.levels.get(sensitivity_level_id, \*, account_id, sensitivity_group_id) -> Optional[LevelGetResponse]
+
+##### Order
+
+Types:
+
+```python
+from cloudflare.types.zero_trust.dlp.sensitivity_groups.levels import (
+ OrderUpdateResponse,
+ OrderGetResponse,
+)
+```
+
+Methods:
+
+- client.zero_trust.dlp.sensitivity_groups.levels.order.update(sensitivity_group_id, \*, account_id, \*\*params) -> Optional[OrderUpdateResponse]
+- client.zero_trust.dlp.sensitivity_groups.levels.order.get(sensitivity_group_id, \*, account_id) -> Optional[OrderGetResponse]
+
+### DataTagCategories
+
+Types:
+
+```python
+from cloudflare.types.zero_trust.dlp import (
+ DataTagCategoryCreateResponse,
+ DataTagCategoryUpdateResponse,
+ DataTagCategoryListResponse,
+ DataTagCategoryGetResponse,
+)
+```
+
+Methods:
+
+- client.zero_trust.dlp.data_tag_categories.create(\*, account_id, \*\*params) -> Optional[DataTagCategoryCreateResponse]
+- client.zero_trust.dlp.data_tag_categories.update(category_id, \*, account_id, \*\*params) -> Optional[DataTagCategoryUpdateResponse]
+- client.zero_trust.dlp.data_tag_categories.list(\*, account_id) -> SyncSinglePage[DataTagCategoryListResponse]
+- client.zero_trust.dlp.data_tag_categories.delete(category_id, \*, account_id) -> object
+- client.zero_trust.dlp.data_tag_categories.get(category_id, \*, account_id) -> Optional[DataTagCategoryGetResponse]
+
+#### DataTags
+
+Types:
+
+```python
+from cloudflare.types.zero_trust.dlp.data_tag_categories import (
+ DataTagCreateResponse,
+ DataTagUpdateResponse,
+ DataTagListResponse,
+ DataTagGetResponse,
+)
+```
+
+Methods:
+
+- client.zero_trust.dlp.data_tag_categories.data_tags.create(category_id, \*, account_id, \*\*params) -> Optional[DataTagCreateResponse]
+- client.zero_trust.dlp.data_tag_categories.data_tags.update(tag_id, \*, account_id, category_id, \*\*params) -> Optional[DataTagUpdateResponse]
+- client.zero_trust.dlp.data_tag_categories.data_tags.list(category_id, \*, account_id) -> SyncSinglePage[DataTagListResponse]
+- client.zero_trust.dlp.data_tag_categories.data_tags.delete(tag_id, \*, account_id, category_id) -> object
+- client.zero_trust.dlp.data_tag_categories.data_tags.get(tag_id, \*, account_id, category_id) -> Optional[DataTagGetResponse]
+
+### DataClasses
+
+Types:
+
+```python
+from cloudflare.types.zero_trust.dlp import (
+ DataClassCreateResponse,
+ DataClassUpdateResponse,
+ DataClassListResponse,
+ DataClassGetResponse,
+)
+```
+
+Methods:
+
+- client.zero_trust.dlp.data_classes.create(\*, account_id, \*\*params) -> Optional[DataClassCreateResponse]
+- client.zero_trust.dlp.data_classes.update(data_class_id, \*, account_id, \*\*params) -> Optional[DataClassUpdateResponse]
+- client.zero_trust.dlp.data_classes.list(\*, account_id) -> SyncSinglePage[DataClassListResponse]
+- client.zero_trust.dlp.data_classes.delete(data_class_id, \*, account_id) -> object
+- client.zero_trust.dlp.data_classes.get(data_class_id, \*, account_id) -> Optional[DataClassGetResponse]
+
## Gateway
Types:
diff --git a/src/cloudflare/resources/zero_trust/dlp/__init__.py b/src/cloudflare/resources/zero_trust/dlp/__init__.py
index 907b7ec87c1..480c8c50ccd 100644
--- a/src/cloudflare/resources/zero_trust/dlp/__init__.py
+++ b/src/cloudflare/resources/zero_trust/dlp/__init__.py
@@ -64,6 +64,14 @@
SettingsResourceWithStreamingResponse,
AsyncSettingsResourceWithStreamingResponse,
)
+from .data_classes import (
+ DataClassesResource,
+ AsyncDataClassesResource,
+ DataClassesResourceWithRawResponse,
+ AsyncDataClassesResourceWithRawResponse,
+ DataClassesResourceWithStreamingResponse,
+ AsyncDataClassesResourceWithStreamingResponse,
+)
from .payload_logs import (
PayloadLogsResource,
AsyncPayloadLogsResource,
@@ -72,6 +80,22 @@
PayloadLogsResourceWithStreamingResponse,
AsyncPayloadLogsResourceWithStreamingResponse,
)
+from .sensitivity_groups import (
+ SensitivityGroupsResource,
+ AsyncSensitivityGroupsResource,
+ SensitivityGroupsResourceWithRawResponse,
+ AsyncSensitivityGroupsResourceWithRawResponse,
+ SensitivityGroupsResourceWithStreamingResponse,
+ AsyncSensitivityGroupsResourceWithStreamingResponse,
+)
+from .data_tag_categories import (
+ DataTagCategoriesResource,
+ AsyncDataTagCategoriesResource,
+ DataTagCategoriesResourceWithRawResponse,
+ AsyncDataTagCategoriesResourceWithRawResponse,
+ DataTagCategoriesResourceWithStreamingResponse,
+ AsyncDataTagCategoriesResourceWithStreamingResponse,
+)
from .custom_prompt_topics import (
CustomPromptTopicsResource,
AsyncCustomPromptTopicsResource,
@@ -136,6 +160,24 @@
"AsyncEntriesResourceWithRawResponse",
"EntriesResourceWithStreamingResponse",
"AsyncEntriesResourceWithStreamingResponse",
+ "SensitivityGroupsResource",
+ "AsyncSensitivityGroupsResource",
+ "SensitivityGroupsResourceWithRawResponse",
+ "AsyncSensitivityGroupsResourceWithRawResponse",
+ "SensitivityGroupsResourceWithStreamingResponse",
+ "AsyncSensitivityGroupsResourceWithStreamingResponse",
+ "DataTagCategoriesResource",
+ "AsyncDataTagCategoriesResource",
+ "DataTagCategoriesResourceWithRawResponse",
+ "AsyncDataTagCategoriesResourceWithRawResponse",
+ "DataTagCategoriesResourceWithStreamingResponse",
+ "AsyncDataTagCategoriesResourceWithStreamingResponse",
+ "DataClassesResource",
+ "AsyncDataClassesResource",
+ "DataClassesResourceWithRawResponse",
+ "AsyncDataClassesResourceWithRawResponse",
+ "DataClassesResourceWithStreamingResponse",
+ "AsyncDataClassesResourceWithStreamingResponse",
"DLPResource",
"AsyncDLPResource",
"DLPResourceWithRawResponse",
diff --git a/src/cloudflare/resources/zero_trust/dlp/data_classes.py b/src/cloudflare/resources/zero_trust/dlp/data_classes.py
new file mode 100644
index 00000000000..9fc2a9254a6
--- /dev/null
+++ b/src/cloudflare/resources/zero_trust/dlp/data_classes.py
@@ -0,0 +1,620 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Type, Iterable, Optional, cast
+
+import httpx
+
+from ...._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
+from ...._utils import path_template, maybe_transform, async_maybe_transform
+from ...._compat import cached_property
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from ...._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ...._wrappers import ResultWrapper
+from ....pagination import SyncSinglePage, AsyncSinglePage
+from ...._base_client import AsyncPaginator, make_request_options
+from ....types.zero_trust.dlp import data_class_create_params, data_class_update_params
+from ....types.zero_trust.dlp.data_class_get_response import DataClassGetResponse
+from ....types.zero_trust.dlp.data_class_list_response import DataClassListResponse
+from ....types.zero_trust.dlp.data_class_create_response import DataClassCreateResponse
+from ....types.zero_trust.dlp.data_class_update_response import DataClassUpdateResponse
+
+__all__ = ["DataClassesResource", "AsyncDataClassesResource"]
+
+
+class DataClassesResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> DataClassesResourceWithRawResponse:
+ """
+ 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 DataClassesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> DataClassesResourceWithStreamingResponse:
+ """
+ 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 DataClassesResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ *,
+ account_id: str,
+ data_tags: SequenceNotStr[str],
+ expression: str,
+ name: str,
+ sensitivity_levels: Iterable[data_class_create_params.SensitivityLevel],
+ description: 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,
+ ) -> Optional[DataClassCreateResponse]:
+ """
+ Creates a new data class
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._post(
+ path_template("/accounts/{account_id}/dlp/data_classes", account_id=account_id),
+ body=maybe_transform(
+ {
+ "data_tags": data_tags,
+ "expression": expression,
+ "name": name,
+ "sensitivity_levels": sensitivity_levels,
+ "description": description,
+ },
+ data_class_create_params.DataClassCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[DataClassCreateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[DataClassCreateResponse]], ResultWrapper[DataClassCreateResponse]),
+ )
+
+ def update(
+ self,
+ data_class_id: str,
+ *,
+ account_id: str,
+ data_tags: Optional[SequenceNotStr[str]] | Omit = omit,
+ description: Optional[str] | Omit = omit,
+ expression: Optional[str] | Omit = omit,
+ name: Optional[str] | Omit = omit,
+ sensitivity_levels: Optional[Iterable[data_class_update_params.SensitivityLevel]] | 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,
+ ) -> Optional[DataClassUpdateResponse]:
+ """
+ Update the attributes of a single data class
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not data_class_id:
+ raise ValueError(f"Expected a non-empty value for `data_class_id` but received {data_class_id!r}")
+ return self._put(
+ path_template(
+ "/accounts/{account_id}/dlp/data_classes/{data_class_id}",
+ account_id=account_id,
+ data_class_id=data_class_id,
+ ),
+ body=maybe_transform(
+ {
+ "data_tags": data_tags,
+ "description": description,
+ "expression": expression,
+ "name": name,
+ "sensitivity_levels": sensitivity_levels,
+ },
+ data_class_update_params.DataClassUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[DataClassUpdateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[DataClassUpdateResponse]], ResultWrapper[DataClassUpdateResponse]),
+ )
+
+ def list(
+ 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[DataClassListResponse]:
+ """
+ Retrieve all data classes in an account
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._get_api_list(
+ path_template("/accounts/{account_id}/dlp/data_classes", account_id=account_id),
+ page=SyncSinglePage[DataClassListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=DataClassListResponse,
+ )
+
+ def delete(
+ self,
+ data_class_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,
+ ) -> object:
+ """
+ Delete a single data class
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not data_class_id:
+ raise ValueError(f"Expected a non-empty value for `data_class_id` but received {data_class_id!r}")
+ return self._delete(
+ path_template(
+ "/accounts/{account_id}/dlp/data_classes/{data_class_id}",
+ account_id=account_id,
+ data_class_id=data_class_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[object]]._unwrapper,
+ ),
+ cast_to=cast(Type[object], ResultWrapper[object]),
+ )
+
+ def get(
+ self,
+ data_class_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[DataClassGetResponse]:
+ """
+ Retrieve a specific data class
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not data_class_id:
+ raise ValueError(f"Expected a non-empty value for `data_class_id` but received {data_class_id!r}")
+ return self._get(
+ path_template(
+ "/accounts/{account_id}/dlp/data_classes/{data_class_id}",
+ account_id=account_id,
+ data_class_id=data_class_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[DataClassGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[DataClassGetResponse]], ResultWrapper[DataClassGetResponse]),
+ )
+
+
+class AsyncDataClassesResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncDataClassesResourceWithRawResponse:
+ """
+ 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 AsyncDataClassesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncDataClassesResourceWithStreamingResponse:
+ """
+ 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 AsyncDataClassesResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ *,
+ account_id: str,
+ data_tags: SequenceNotStr[str],
+ expression: str,
+ name: str,
+ sensitivity_levels: Iterable[data_class_create_params.SensitivityLevel],
+ description: 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,
+ ) -> Optional[DataClassCreateResponse]:
+ """
+ Creates a new data class
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return await self._post(
+ path_template("/accounts/{account_id}/dlp/data_classes", account_id=account_id),
+ body=await async_maybe_transform(
+ {
+ "data_tags": data_tags,
+ "expression": expression,
+ "name": name,
+ "sensitivity_levels": sensitivity_levels,
+ "description": description,
+ },
+ data_class_create_params.DataClassCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[DataClassCreateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[DataClassCreateResponse]], ResultWrapper[DataClassCreateResponse]),
+ )
+
+ async def update(
+ self,
+ data_class_id: str,
+ *,
+ account_id: str,
+ data_tags: Optional[SequenceNotStr[str]] | Omit = omit,
+ description: Optional[str] | Omit = omit,
+ expression: Optional[str] | Omit = omit,
+ name: Optional[str] | Omit = omit,
+ sensitivity_levels: Optional[Iterable[data_class_update_params.SensitivityLevel]] | 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,
+ ) -> Optional[DataClassUpdateResponse]:
+ """
+ Update the attributes of a single data class
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not data_class_id:
+ raise ValueError(f"Expected a non-empty value for `data_class_id` but received {data_class_id!r}")
+ return await self._put(
+ path_template(
+ "/accounts/{account_id}/dlp/data_classes/{data_class_id}",
+ account_id=account_id,
+ data_class_id=data_class_id,
+ ),
+ body=await async_maybe_transform(
+ {
+ "data_tags": data_tags,
+ "description": description,
+ "expression": expression,
+ "name": name,
+ "sensitivity_levels": sensitivity_levels,
+ },
+ data_class_update_params.DataClassUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[DataClassUpdateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[DataClassUpdateResponse]], ResultWrapper[DataClassUpdateResponse]),
+ )
+
+ def list(
+ 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[DataClassListResponse, AsyncSinglePage[DataClassListResponse]]:
+ """
+ Retrieve all data classes in an account
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._get_api_list(
+ path_template("/accounts/{account_id}/dlp/data_classes", account_id=account_id),
+ page=AsyncSinglePage[DataClassListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=DataClassListResponse,
+ )
+
+ async def delete(
+ self,
+ data_class_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,
+ ) -> object:
+ """
+ Delete a single data class
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not data_class_id:
+ raise ValueError(f"Expected a non-empty value for `data_class_id` but received {data_class_id!r}")
+ return await self._delete(
+ path_template(
+ "/accounts/{account_id}/dlp/data_classes/{data_class_id}",
+ account_id=account_id,
+ data_class_id=data_class_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[object]]._unwrapper,
+ ),
+ cast_to=cast(Type[object], ResultWrapper[object]),
+ )
+
+ async def get(
+ self,
+ data_class_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[DataClassGetResponse]:
+ """
+ Retrieve a specific data class
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not data_class_id:
+ raise ValueError(f"Expected a non-empty value for `data_class_id` but received {data_class_id!r}")
+ return await self._get(
+ path_template(
+ "/accounts/{account_id}/dlp/data_classes/{data_class_id}",
+ account_id=account_id,
+ data_class_id=data_class_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[DataClassGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[DataClassGetResponse]], ResultWrapper[DataClassGetResponse]),
+ )
+
+
+class DataClassesResourceWithRawResponse:
+ def __init__(self, data_classes: DataClassesResource) -> None:
+ self._data_classes = data_classes
+
+ self.create = to_raw_response_wrapper(
+ data_classes.create,
+ )
+ self.update = to_raw_response_wrapper(
+ data_classes.update,
+ )
+ self.list = to_raw_response_wrapper(
+ data_classes.list,
+ )
+ self.delete = to_raw_response_wrapper(
+ data_classes.delete,
+ )
+ self.get = to_raw_response_wrapper(
+ data_classes.get,
+ )
+
+
+class AsyncDataClassesResourceWithRawResponse:
+ def __init__(self, data_classes: AsyncDataClassesResource) -> None:
+ self._data_classes = data_classes
+
+ self.create = async_to_raw_response_wrapper(
+ data_classes.create,
+ )
+ self.update = async_to_raw_response_wrapper(
+ data_classes.update,
+ )
+ self.list = async_to_raw_response_wrapper(
+ data_classes.list,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ data_classes.delete,
+ )
+ self.get = async_to_raw_response_wrapper(
+ data_classes.get,
+ )
+
+
+class DataClassesResourceWithStreamingResponse:
+ def __init__(self, data_classes: DataClassesResource) -> None:
+ self._data_classes = data_classes
+
+ self.create = to_streamed_response_wrapper(
+ data_classes.create,
+ )
+ self.update = to_streamed_response_wrapper(
+ data_classes.update,
+ )
+ self.list = to_streamed_response_wrapper(
+ data_classes.list,
+ )
+ self.delete = to_streamed_response_wrapper(
+ data_classes.delete,
+ )
+ self.get = to_streamed_response_wrapper(
+ data_classes.get,
+ )
+
+
+class AsyncDataClassesResourceWithStreamingResponse:
+ def __init__(self, data_classes: AsyncDataClassesResource) -> None:
+ self._data_classes = data_classes
+
+ self.create = async_to_streamed_response_wrapper(
+ data_classes.create,
+ )
+ self.update = async_to_streamed_response_wrapper(
+ data_classes.update,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ data_classes.list,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ data_classes.delete,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ data_classes.get,
+ )
diff --git a/src/cloudflare/resources/zero_trust/dlp/data_tag_categories/__init__.py b/src/cloudflare/resources/zero_trust/dlp/data_tag_categories/__init__.py
new file mode 100644
index 00000000000..97bdcf90c86
--- /dev/null
+++ b/src/cloudflare/resources/zero_trust/dlp/data_tag_categories/__init__.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .data_tags import (
+ DataTagsResource,
+ AsyncDataTagsResource,
+ DataTagsResourceWithRawResponse,
+ AsyncDataTagsResourceWithRawResponse,
+ DataTagsResourceWithStreamingResponse,
+ AsyncDataTagsResourceWithStreamingResponse,
+)
+from .data_tag_categories import (
+ DataTagCategoriesResource,
+ AsyncDataTagCategoriesResource,
+ DataTagCategoriesResourceWithRawResponse,
+ AsyncDataTagCategoriesResourceWithRawResponse,
+ DataTagCategoriesResourceWithStreamingResponse,
+ AsyncDataTagCategoriesResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "DataTagsResource",
+ "AsyncDataTagsResource",
+ "DataTagsResourceWithRawResponse",
+ "AsyncDataTagsResourceWithRawResponse",
+ "DataTagsResourceWithStreamingResponse",
+ "AsyncDataTagsResourceWithStreamingResponse",
+ "DataTagCategoriesResource",
+ "AsyncDataTagCategoriesResource",
+ "DataTagCategoriesResourceWithRawResponse",
+ "AsyncDataTagCategoriesResourceWithRawResponse",
+ "DataTagCategoriesResourceWithStreamingResponse",
+ "AsyncDataTagCategoriesResourceWithStreamingResponse",
+]
diff --git a/src/cloudflare/resources/zero_trust/dlp/data_tag_categories/data_tag_categories.py b/src/cloudflare/resources/zero_trust/dlp/data_tag_categories/data_tag_categories.py
new file mode 100644
index 00000000000..f8466fbe91f
--- /dev/null
+++ b/src/cloudflare/resources/zero_trust/dlp/data_tag_categories/data_tag_categories.py
@@ -0,0 +1,658 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Type, Iterable, Optional, cast
+
+import httpx
+
+from .data_tags import (
+ DataTagsResource,
+ AsyncDataTagsResource,
+ DataTagsResourceWithRawResponse,
+ AsyncDataTagsResourceWithRawResponse,
+ DataTagsResourceWithStreamingResponse,
+ AsyncDataTagsResourceWithStreamingResponse,
+)
+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 .....pagination import SyncSinglePage, AsyncSinglePage
+from ....._base_client import AsyncPaginator, make_request_options
+from .....types.zero_trust.dlp import data_tag_category_create_params, data_tag_category_update_params
+from .....types.zero_trust.dlp.data_tag_category_get_response import DataTagCategoryGetResponse
+from .....types.zero_trust.dlp.data_tag_category_list_response import DataTagCategoryListResponse
+from .....types.zero_trust.dlp.data_tag_category_create_response import DataTagCategoryCreateResponse
+from .....types.zero_trust.dlp.data_tag_category_update_response import DataTagCategoryUpdateResponse
+
+__all__ = ["DataTagCategoriesResource", "AsyncDataTagCategoriesResource"]
+
+
+class DataTagCategoriesResource(SyncAPIResource):
+ @cached_property
+ def data_tags(self) -> DataTagsResource:
+ return DataTagsResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> DataTagCategoriesResourceWithRawResponse:
+ """
+ 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 DataTagCategoriesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> DataTagCategoriesResourceWithStreamingResponse:
+ """
+ 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 DataTagCategoriesResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ *,
+ account_id: str,
+ name: str,
+ description: Optional[str] | Omit = omit,
+ tags: Iterable[data_tag_category_create_params.Tag] | Omit = omit,
+ template_id: 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,
+ ) -> Optional[DataTagCategoryCreateResponse]:
+ """Creates a new data tag category.
+
+ Args:
+ tags: Tags to create with the category.
+
+ Mutually exclusive with `template_id`.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._post(
+ path_template("/accounts/{account_id}/dlp/data_tag_categories", account_id=account_id),
+ body=maybe_transform(
+ {
+ "name": name,
+ "description": description,
+ "tags": tags,
+ "template_id": template_id,
+ },
+ data_tag_category_create_params.DataTagCategoryCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[DataTagCategoryCreateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[DataTagCategoryCreateResponse]], ResultWrapper[DataTagCategoryCreateResponse]),
+ )
+
+ def update(
+ self,
+ category_id: str,
+ *,
+ account_id: str,
+ description: Optional[str] | Omit = omit,
+ name: Optional[str] | Omit = omit,
+ tags: Optional[Iterable[data_tag_category_update_params.Tag]] | 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,
+ ) -> Optional[DataTagCategoryUpdateResponse]:
+ """
+ Update the attributes of a single data tag category.
+
+ Args:
+ tags: The desired final state of tags.
+
+ - `None` (omitted): no tag changes.
+ - `Some([])`: delete all tags.
+ - `Some([...])`: desired final set + order.
+
+ 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 category_id:
+ raise ValueError(f"Expected a non-empty value for `category_id` but received {category_id!r}")
+ return self._put(
+ path_template(
+ "/accounts/{account_id}/dlp/data_tag_categories/{category_id}",
+ account_id=account_id,
+ category_id=category_id,
+ ),
+ body=maybe_transform(
+ {
+ "description": description,
+ "name": name,
+ "tags": tags,
+ },
+ data_tag_category_update_params.DataTagCategoryUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[DataTagCategoryUpdateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[DataTagCategoryUpdateResponse]], ResultWrapper[DataTagCategoryUpdateResponse]),
+ )
+
+ def list(
+ 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[DataTagCategoryListResponse]:
+ """
+ Retrieve all data tag categories in an account
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._get_api_list(
+ path_template("/accounts/{account_id}/dlp/data_tag_categories", account_id=account_id),
+ page=SyncSinglePage[DataTagCategoryListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=DataTagCategoryListResponse,
+ )
+
+ def delete(
+ self,
+ category_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,
+ ) -> object:
+ """
+ Delete a single data tag category.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not category_id:
+ raise ValueError(f"Expected a non-empty value for `category_id` but received {category_id!r}")
+ return self._delete(
+ path_template(
+ "/accounts/{account_id}/dlp/data_tag_categories/{category_id}",
+ account_id=account_id,
+ category_id=category_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[object]]._unwrapper,
+ ),
+ cast_to=cast(Type[object], ResultWrapper[object]),
+ )
+
+ def get(
+ self,
+ category_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[DataTagCategoryGetResponse]:
+ """
+ Retrieve a specific data tag category.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not category_id:
+ raise ValueError(f"Expected a non-empty value for `category_id` but received {category_id!r}")
+ return self._get(
+ path_template(
+ "/accounts/{account_id}/dlp/data_tag_categories/{category_id}",
+ account_id=account_id,
+ category_id=category_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[DataTagCategoryGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[DataTagCategoryGetResponse]], ResultWrapper[DataTagCategoryGetResponse]),
+ )
+
+
+class AsyncDataTagCategoriesResource(AsyncAPIResource):
+ @cached_property
+ def data_tags(self) -> AsyncDataTagsResource:
+ return AsyncDataTagsResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncDataTagCategoriesResourceWithRawResponse:
+ """
+ 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 AsyncDataTagCategoriesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncDataTagCategoriesResourceWithStreamingResponse:
+ """
+ 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 AsyncDataTagCategoriesResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ *,
+ account_id: str,
+ name: str,
+ description: Optional[str] | Omit = omit,
+ tags: Iterable[data_tag_category_create_params.Tag] | Omit = omit,
+ template_id: 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,
+ ) -> Optional[DataTagCategoryCreateResponse]:
+ """Creates a new data tag category.
+
+ Args:
+ tags: Tags to create with the category.
+
+ Mutually exclusive with `template_id`.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return await self._post(
+ path_template("/accounts/{account_id}/dlp/data_tag_categories", account_id=account_id),
+ body=await async_maybe_transform(
+ {
+ "name": name,
+ "description": description,
+ "tags": tags,
+ "template_id": template_id,
+ },
+ data_tag_category_create_params.DataTagCategoryCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[DataTagCategoryCreateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[DataTagCategoryCreateResponse]], ResultWrapper[DataTagCategoryCreateResponse]),
+ )
+
+ async def update(
+ self,
+ category_id: str,
+ *,
+ account_id: str,
+ description: Optional[str] | Omit = omit,
+ name: Optional[str] | Omit = omit,
+ tags: Optional[Iterable[data_tag_category_update_params.Tag]] | 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,
+ ) -> Optional[DataTagCategoryUpdateResponse]:
+ """
+ Update the attributes of a single data tag category.
+
+ Args:
+ tags: The desired final state of tags.
+
+ - `None` (omitted): no tag changes.
+ - `Some([])`: delete all tags.
+ - `Some([...])`: desired final set + order.
+
+ 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 category_id:
+ raise ValueError(f"Expected a non-empty value for `category_id` but received {category_id!r}")
+ return await self._put(
+ path_template(
+ "/accounts/{account_id}/dlp/data_tag_categories/{category_id}",
+ account_id=account_id,
+ category_id=category_id,
+ ),
+ body=await async_maybe_transform(
+ {
+ "description": description,
+ "name": name,
+ "tags": tags,
+ },
+ data_tag_category_update_params.DataTagCategoryUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[DataTagCategoryUpdateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[DataTagCategoryUpdateResponse]], ResultWrapper[DataTagCategoryUpdateResponse]),
+ )
+
+ def list(
+ 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[DataTagCategoryListResponse, AsyncSinglePage[DataTagCategoryListResponse]]:
+ """
+ Retrieve all data tag categories in an account
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._get_api_list(
+ path_template("/accounts/{account_id}/dlp/data_tag_categories", account_id=account_id),
+ page=AsyncSinglePage[DataTagCategoryListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=DataTagCategoryListResponse,
+ )
+
+ async def delete(
+ self,
+ category_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,
+ ) -> object:
+ """
+ Delete a single data tag category.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not category_id:
+ raise ValueError(f"Expected a non-empty value for `category_id` but received {category_id!r}")
+ return await self._delete(
+ path_template(
+ "/accounts/{account_id}/dlp/data_tag_categories/{category_id}",
+ account_id=account_id,
+ category_id=category_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[object]]._unwrapper,
+ ),
+ cast_to=cast(Type[object], ResultWrapper[object]),
+ )
+
+ async def get(
+ self,
+ category_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[DataTagCategoryGetResponse]:
+ """
+ Retrieve a specific data tag category.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not category_id:
+ raise ValueError(f"Expected a non-empty value for `category_id` but received {category_id!r}")
+ return await self._get(
+ path_template(
+ "/accounts/{account_id}/dlp/data_tag_categories/{category_id}",
+ account_id=account_id,
+ category_id=category_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[DataTagCategoryGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[DataTagCategoryGetResponse]], ResultWrapper[DataTagCategoryGetResponse]),
+ )
+
+
+class DataTagCategoriesResourceWithRawResponse:
+ def __init__(self, data_tag_categories: DataTagCategoriesResource) -> None:
+ self._data_tag_categories = data_tag_categories
+
+ self.create = to_raw_response_wrapper(
+ data_tag_categories.create,
+ )
+ self.update = to_raw_response_wrapper(
+ data_tag_categories.update,
+ )
+ self.list = to_raw_response_wrapper(
+ data_tag_categories.list,
+ )
+ self.delete = to_raw_response_wrapper(
+ data_tag_categories.delete,
+ )
+ self.get = to_raw_response_wrapper(
+ data_tag_categories.get,
+ )
+
+ @cached_property
+ def data_tags(self) -> DataTagsResourceWithRawResponse:
+ return DataTagsResourceWithRawResponse(self._data_tag_categories.data_tags)
+
+
+class AsyncDataTagCategoriesResourceWithRawResponse:
+ def __init__(self, data_tag_categories: AsyncDataTagCategoriesResource) -> None:
+ self._data_tag_categories = data_tag_categories
+
+ self.create = async_to_raw_response_wrapper(
+ data_tag_categories.create,
+ )
+ self.update = async_to_raw_response_wrapper(
+ data_tag_categories.update,
+ )
+ self.list = async_to_raw_response_wrapper(
+ data_tag_categories.list,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ data_tag_categories.delete,
+ )
+ self.get = async_to_raw_response_wrapper(
+ data_tag_categories.get,
+ )
+
+ @cached_property
+ def data_tags(self) -> AsyncDataTagsResourceWithRawResponse:
+ return AsyncDataTagsResourceWithRawResponse(self._data_tag_categories.data_tags)
+
+
+class DataTagCategoriesResourceWithStreamingResponse:
+ def __init__(self, data_tag_categories: DataTagCategoriesResource) -> None:
+ self._data_tag_categories = data_tag_categories
+
+ self.create = to_streamed_response_wrapper(
+ data_tag_categories.create,
+ )
+ self.update = to_streamed_response_wrapper(
+ data_tag_categories.update,
+ )
+ self.list = to_streamed_response_wrapper(
+ data_tag_categories.list,
+ )
+ self.delete = to_streamed_response_wrapper(
+ data_tag_categories.delete,
+ )
+ self.get = to_streamed_response_wrapper(
+ data_tag_categories.get,
+ )
+
+ @cached_property
+ def data_tags(self) -> DataTagsResourceWithStreamingResponse:
+ return DataTagsResourceWithStreamingResponse(self._data_tag_categories.data_tags)
+
+
+class AsyncDataTagCategoriesResourceWithStreamingResponse:
+ def __init__(self, data_tag_categories: AsyncDataTagCategoriesResource) -> None:
+ self._data_tag_categories = data_tag_categories
+
+ self.create = async_to_streamed_response_wrapper(
+ data_tag_categories.create,
+ )
+ self.update = async_to_streamed_response_wrapper(
+ data_tag_categories.update,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ data_tag_categories.list,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ data_tag_categories.delete,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ data_tag_categories.get,
+ )
+
+ @cached_property
+ def data_tags(self) -> AsyncDataTagsResourceWithStreamingResponse:
+ return AsyncDataTagsResourceWithStreamingResponse(self._data_tag_categories.data_tags)
diff --git a/src/cloudflare/resources/zero_trust/dlp/data_tag_categories/data_tags.py b/src/cloudflare/resources/zero_trust/dlp/data_tag_categories/data_tags.py
new file mode 100644
index 00000000000..7fc038b172a
--- /dev/null
+++ b/src/cloudflare/resources/zero_trust/dlp/data_tag_categories/data_tags.py
@@ -0,0 +1,648 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Type, Optional, 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 .....pagination import SyncSinglePage, AsyncSinglePage
+from ....._base_client import AsyncPaginator, make_request_options
+from .....types.zero_trust.dlp.data_tag_categories import data_tag_create_params, data_tag_update_params
+from .....types.zero_trust.dlp.data_tag_categories.data_tag_get_response import DataTagGetResponse
+from .....types.zero_trust.dlp.data_tag_categories.data_tag_list_response import DataTagListResponse
+from .....types.zero_trust.dlp.data_tag_categories.data_tag_create_response import DataTagCreateResponse
+from .....types.zero_trust.dlp.data_tag_categories.data_tag_update_response import DataTagUpdateResponse
+
+__all__ = ["DataTagsResource", "AsyncDataTagsResource"]
+
+
+class DataTagsResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> DataTagsResourceWithRawResponse:
+ """
+ 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 DataTagsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> DataTagsResourceWithStreamingResponse:
+ """
+ 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 DataTagsResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ category_id: str,
+ *,
+ account_id: str,
+ name: str,
+ description: 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,
+ ) -> Optional[DataTagCreateResponse]:
+ """
+ Creates a new data tag.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not category_id:
+ raise ValueError(f"Expected a non-empty value for `category_id` but received {category_id!r}")
+ return self._post(
+ path_template(
+ "/accounts/{account_id}/dlp/data_tag_categories/{category_id}/data_tags",
+ account_id=account_id,
+ category_id=category_id,
+ ),
+ body=maybe_transform(
+ {
+ "name": name,
+ "description": description,
+ },
+ data_tag_create_params.DataTagCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[DataTagCreateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[DataTagCreateResponse]], ResultWrapper[DataTagCreateResponse]),
+ )
+
+ def update(
+ self,
+ tag_id: str,
+ *,
+ account_id: str,
+ category_id: str,
+ description: Optional[str] | 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,
+ ) -> Optional[DataTagUpdateResponse]:
+ """
+ Update the attributes of a single data tag.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not category_id:
+ raise ValueError(f"Expected a non-empty value for `category_id` but received {category_id!r}")
+ if not tag_id:
+ raise ValueError(f"Expected a non-empty value for `tag_id` but received {tag_id!r}")
+ return self._put(
+ path_template(
+ "/accounts/{account_id}/dlp/data_tag_categories/{category_id}/data_tags/{tag_id}",
+ account_id=account_id,
+ category_id=category_id,
+ tag_id=tag_id,
+ ),
+ body=maybe_transform(
+ {
+ "description": description,
+ "name": name,
+ },
+ data_tag_update_params.DataTagUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[DataTagUpdateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[DataTagUpdateResponse]], ResultWrapper[DataTagUpdateResponse]),
+ )
+
+ def list(
+ self,
+ category_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,
+ ) -> SyncSinglePage[DataTagListResponse]:
+ """
+ Retrieve all data tags in a data tag category
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not category_id:
+ raise ValueError(f"Expected a non-empty value for `category_id` but received {category_id!r}")
+ return self._get_api_list(
+ path_template(
+ "/accounts/{account_id}/dlp/data_tag_categories/{category_id}/data_tags",
+ account_id=account_id,
+ category_id=category_id,
+ ),
+ page=SyncSinglePage[DataTagListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=DataTagListResponse,
+ )
+
+ def delete(
+ self,
+ tag_id: str,
+ *,
+ account_id: str,
+ category_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,
+ ) -> object:
+ """
+ Delete a single data tag.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not category_id:
+ raise ValueError(f"Expected a non-empty value for `category_id` but received {category_id!r}")
+ if not tag_id:
+ raise ValueError(f"Expected a non-empty value for `tag_id` but received {tag_id!r}")
+ return self._delete(
+ path_template(
+ "/accounts/{account_id}/dlp/data_tag_categories/{category_id}/data_tags/{tag_id}",
+ account_id=account_id,
+ category_id=category_id,
+ tag_id=tag_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[object]]._unwrapper,
+ ),
+ cast_to=cast(Type[object], ResultWrapper[object]),
+ )
+
+ def get(
+ self,
+ tag_id: str,
+ *,
+ account_id: str,
+ category_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[DataTagGetResponse]:
+ """
+ Retrieve a specific data tag.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not category_id:
+ raise ValueError(f"Expected a non-empty value for `category_id` but received {category_id!r}")
+ if not tag_id:
+ raise ValueError(f"Expected a non-empty value for `tag_id` but received {tag_id!r}")
+ return self._get(
+ path_template(
+ "/accounts/{account_id}/dlp/data_tag_categories/{category_id}/data_tags/{tag_id}",
+ account_id=account_id,
+ category_id=category_id,
+ tag_id=tag_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[DataTagGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[DataTagGetResponse]], ResultWrapper[DataTagGetResponse]),
+ )
+
+
+class AsyncDataTagsResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncDataTagsResourceWithRawResponse:
+ """
+ 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 AsyncDataTagsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncDataTagsResourceWithStreamingResponse:
+ """
+ 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 AsyncDataTagsResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ category_id: str,
+ *,
+ account_id: str,
+ name: str,
+ description: 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,
+ ) -> Optional[DataTagCreateResponse]:
+ """
+ Creates a new data tag.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not category_id:
+ raise ValueError(f"Expected a non-empty value for `category_id` but received {category_id!r}")
+ return await self._post(
+ path_template(
+ "/accounts/{account_id}/dlp/data_tag_categories/{category_id}/data_tags",
+ account_id=account_id,
+ category_id=category_id,
+ ),
+ body=await async_maybe_transform(
+ {
+ "name": name,
+ "description": description,
+ },
+ data_tag_create_params.DataTagCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[DataTagCreateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[DataTagCreateResponse]], ResultWrapper[DataTagCreateResponse]),
+ )
+
+ async def update(
+ self,
+ tag_id: str,
+ *,
+ account_id: str,
+ category_id: str,
+ description: Optional[str] | 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,
+ ) -> Optional[DataTagUpdateResponse]:
+ """
+ Update the attributes of a single data tag.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not category_id:
+ raise ValueError(f"Expected a non-empty value for `category_id` but received {category_id!r}")
+ if not tag_id:
+ raise ValueError(f"Expected a non-empty value for `tag_id` but received {tag_id!r}")
+ return await self._put(
+ path_template(
+ "/accounts/{account_id}/dlp/data_tag_categories/{category_id}/data_tags/{tag_id}",
+ account_id=account_id,
+ category_id=category_id,
+ tag_id=tag_id,
+ ),
+ body=await async_maybe_transform(
+ {
+ "description": description,
+ "name": name,
+ },
+ data_tag_update_params.DataTagUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[DataTagUpdateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[DataTagUpdateResponse]], ResultWrapper[DataTagUpdateResponse]),
+ )
+
+ def list(
+ self,
+ category_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,
+ ) -> AsyncPaginator[DataTagListResponse, AsyncSinglePage[DataTagListResponse]]:
+ """
+ Retrieve all data tags in a data tag category
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not category_id:
+ raise ValueError(f"Expected a non-empty value for `category_id` but received {category_id!r}")
+ return self._get_api_list(
+ path_template(
+ "/accounts/{account_id}/dlp/data_tag_categories/{category_id}/data_tags",
+ account_id=account_id,
+ category_id=category_id,
+ ),
+ page=AsyncSinglePage[DataTagListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=DataTagListResponse,
+ )
+
+ async def delete(
+ self,
+ tag_id: str,
+ *,
+ account_id: str,
+ category_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,
+ ) -> object:
+ """
+ Delete a single data tag.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not category_id:
+ raise ValueError(f"Expected a non-empty value for `category_id` but received {category_id!r}")
+ if not tag_id:
+ raise ValueError(f"Expected a non-empty value for `tag_id` but received {tag_id!r}")
+ return await self._delete(
+ path_template(
+ "/accounts/{account_id}/dlp/data_tag_categories/{category_id}/data_tags/{tag_id}",
+ account_id=account_id,
+ category_id=category_id,
+ tag_id=tag_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[object]]._unwrapper,
+ ),
+ cast_to=cast(Type[object], ResultWrapper[object]),
+ )
+
+ async def get(
+ self,
+ tag_id: str,
+ *,
+ account_id: str,
+ category_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[DataTagGetResponse]:
+ """
+ Retrieve a specific data tag.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not category_id:
+ raise ValueError(f"Expected a non-empty value for `category_id` but received {category_id!r}")
+ if not tag_id:
+ raise ValueError(f"Expected a non-empty value for `tag_id` but received {tag_id!r}")
+ return await self._get(
+ path_template(
+ "/accounts/{account_id}/dlp/data_tag_categories/{category_id}/data_tags/{tag_id}",
+ account_id=account_id,
+ category_id=category_id,
+ tag_id=tag_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[DataTagGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[DataTagGetResponse]], ResultWrapper[DataTagGetResponse]),
+ )
+
+
+class DataTagsResourceWithRawResponse:
+ def __init__(self, data_tags: DataTagsResource) -> None:
+ self._data_tags = data_tags
+
+ self.create = to_raw_response_wrapper(
+ data_tags.create,
+ )
+ self.update = to_raw_response_wrapper(
+ data_tags.update,
+ )
+ self.list = to_raw_response_wrapper(
+ data_tags.list,
+ )
+ self.delete = to_raw_response_wrapper(
+ data_tags.delete,
+ )
+ self.get = to_raw_response_wrapper(
+ data_tags.get,
+ )
+
+
+class AsyncDataTagsResourceWithRawResponse:
+ def __init__(self, data_tags: AsyncDataTagsResource) -> None:
+ self._data_tags = data_tags
+
+ self.create = async_to_raw_response_wrapper(
+ data_tags.create,
+ )
+ self.update = async_to_raw_response_wrapper(
+ data_tags.update,
+ )
+ self.list = async_to_raw_response_wrapper(
+ data_tags.list,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ data_tags.delete,
+ )
+ self.get = async_to_raw_response_wrapper(
+ data_tags.get,
+ )
+
+
+class DataTagsResourceWithStreamingResponse:
+ def __init__(self, data_tags: DataTagsResource) -> None:
+ self._data_tags = data_tags
+
+ self.create = to_streamed_response_wrapper(
+ data_tags.create,
+ )
+ self.update = to_streamed_response_wrapper(
+ data_tags.update,
+ )
+ self.list = to_streamed_response_wrapper(
+ data_tags.list,
+ )
+ self.delete = to_streamed_response_wrapper(
+ data_tags.delete,
+ )
+ self.get = to_streamed_response_wrapper(
+ data_tags.get,
+ )
+
+
+class AsyncDataTagsResourceWithStreamingResponse:
+ def __init__(self, data_tags: AsyncDataTagsResource) -> None:
+ self._data_tags = data_tags
+
+ self.create = async_to_streamed_response_wrapper(
+ data_tags.create,
+ )
+ self.update = async_to_streamed_response_wrapper(
+ data_tags.update,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ data_tags.list,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ data_tags.delete,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ data_tags.get,
+ )
diff --git a/src/cloudflare/resources/zero_trust/dlp/dlp.py b/src/cloudflare/resources/zero_trust/dlp/dlp.py
index 491d1b18ba3..06cc451c89b 100644
--- a/src/cloudflare/resources/zero_trust/dlp/dlp.py
+++ b/src/cloudflare/resources/zero_trust/dlp/dlp.py
@@ -36,6 +36,14 @@
AsyncEmailResourceWithStreamingResponse,
)
from ...._resource import SyncAPIResource, AsyncAPIResource
+from .data_classes import (
+ DataClassesResource,
+ AsyncDataClassesResource,
+ DataClassesResourceWithRawResponse,
+ AsyncDataClassesResourceWithRawResponse,
+ DataClassesResourceWithStreamingResponse,
+ AsyncDataClassesResourceWithStreamingResponse,
+)
from .payload_logs import (
PayloadLogsResource,
AsyncPayloadLogsResource,
@@ -76,6 +84,22 @@
CustomPromptTopicsResourceWithStreamingResponse,
AsyncCustomPromptTopicsResourceWithStreamingResponse,
)
+from .sensitivity_groups.sensitivity_groups import (
+ SensitivityGroupsResource,
+ AsyncSensitivityGroupsResource,
+ SensitivityGroupsResourceWithRawResponse,
+ AsyncSensitivityGroupsResourceWithRawResponse,
+ SensitivityGroupsResourceWithStreamingResponse,
+ AsyncSensitivityGroupsResourceWithStreamingResponse,
+)
+from .data_tag_categories.data_tag_categories import (
+ DataTagCategoriesResource,
+ AsyncDataTagCategoriesResource,
+ DataTagCategoriesResourceWithRawResponse,
+ AsyncDataTagCategoriesResourceWithRawResponse,
+ DataTagCategoriesResourceWithStreamingResponse,
+ AsyncDataTagCategoriesResourceWithStreamingResponse,
+)
__all__ = ["DLPResource", "AsyncDLPResource"]
@@ -117,6 +141,18 @@ def limits(self) -> LimitsResource:
def entries(self) -> EntriesResource:
return EntriesResource(self._client)
+ @cached_property
+ def sensitivity_groups(self) -> SensitivityGroupsResource:
+ return SensitivityGroupsResource(self._client)
+
+ @cached_property
+ def data_tag_categories(self) -> DataTagCategoriesResource:
+ return DataTagCategoriesResource(self._client)
+
+ @cached_property
+ def data_classes(self) -> DataClassesResource:
+ return DataClassesResource(self._client)
+
@cached_property
def with_raw_response(self) -> DLPResourceWithRawResponse:
"""
@@ -174,6 +210,18 @@ def limits(self) -> AsyncLimitsResource:
def entries(self) -> AsyncEntriesResource:
return AsyncEntriesResource(self._client)
+ @cached_property
+ def sensitivity_groups(self) -> AsyncSensitivityGroupsResource:
+ return AsyncSensitivityGroupsResource(self._client)
+
+ @cached_property
+ def data_tag_categories(self) -> AsyncDataTagCategoriesResource:
+ return AsyncDataTagCategoriesResource(self._client)
+
+ @cached_property
+ def data_classes(self) -> AsyncDataClassesResource:
+ return AsyncDataClassesResource(self._client)
+
@cached_property
def with_raw_response(self) -> AsyncDLPResourceWithRawResponse:
"""
@@ -234,6 +282,18 @@ def limits(self) -> LimitsResourceWithRawResponse:
def entries(self) -> EntriesResourceWithRawResponse:
return EntriesResourceWithRawResponse(self._dlp.entries)
+ @cached_property
+ def sensitivity_groups(self) -> SensitivityGroupsResourceWithRawResponse:
+ return SensitivityGroupsResourceWithRawResponse(self._dlp.sensitivity_groups)
+
+ @cached_property
+ def data_tag_categories(self) -> DataTagCategoriesResourceWithRawResponse:
+ return DataTagCategoriesResourceWithRawResponse(self._dlp.data_tag_categories)
+
+ @cached_property
+ def data_classes(self) -> DataClassesResourceWithRawResponse:
+ return DataClassesResourceWithRawResponse(self._dlp.data_classes)
+
class AsyncDLPResourceWithRawResponse:
def __init__(self, dlp: AsyncDLPResource) -> None:
@@ -275,6 +335,18 @@ def limits(self) -> AsyncLimitsResourceWithRawResponse:
def entries(self) -> AsyncEntriesResourceWithRawResponse:
return AsyncEntriesResourceWithRawResponse(self._dlp.entries)
+ @cached_property
+ def sensitivity_groups(self) -> AsyncSensitivityGroupsResourceWithRawResponse:
+ return AsyncSensitivityGroupsResourceWithRawResponse(self._dlp.sensitivity_groups)
+
+ @cached_property
+ def data_tag_categories(self) -> AsyncDataTagCategoriesResourceWithRawResponse:
+ return AsyncDataTagCategoriesResourceWithRawResponse(self._dlp.data_tag_categories)
+
+ @cached_property
+ def data_classes(self) -> AsyncDataClassesResourceWithRawResponse:
+ return AsyncDataClassesResourceWithRawResponse(self._dlp.data_classes)
+
class DLPResourceWithStreamingResponse:
def __init__(self, dlp: DLPResource) -> None:
@@ -316,6 +388,18 @@ def limits(self) -> LimitsResourceWithStreamingResponse:
def entries(self) -> EntriesResourceWithStreamingResponse:
return EntriesResourceWithStreamingResponse(self._dlp.entries)
+ @cached_property
+ def sensitivity_groups(self) -> SensitivityGroupsResourceWithStreamingResponse:
+ return SensitivityGroupsResourceWithStreamingResponse(self._dlp.sensitivity_groups)
+
+ @cached_property
+ def data_tag_categories(self) -> DataTagCategoriesResourceWithStreamingResponse:
+ return DataTagCategoriesResourceWithStreamingResponse(self._dlp.data_tag_categories)
+
+ @cached_property
+ def data_classes(self) -> DataClassesResourceWithStreamingResponse:
+ return DataClassesResourceWithStreamingResponse(self._dlp.data_classes)
+
class AsyncDLPResourceWithStreamingResponse:
def __init__(self, dlp: AsyncDLPResource) -> None:
@@ -356,3 +440,15 @@ def limits(self) -> AsyncLimitsResourceWithStreamingResponse:
@cached_property
def entries(self) -> AsyncEntriesResourceWithStreamingResponse:
return AsyncEntriesResourceWithStreamingResponse(self._dlp.entries)
+
+ @cached_property
+ def sensitivity_groups(self) -> AsyncSensitivityGroupsResourceWithStreamingResponse:
+ return AsyncSensitivityGroupsResourceWithStreamingResponse(self._dlp.sensitivity_groups)
+
+ @cached_property
+ def data_tag_categories(self) -> AsyncDataTagCategoriesResourceWithStreamingResponse:
+ return AsyncDataTagCategoriesResourceWithStreamingResponse(self._dlp.data_tag_categories)
+
+ @cached_property
+ def data_classes(self) -> AsyncDataClassesResourceWithStreamingResponse:
+ return AsyncDataClassesResourceWithStreamingResponse(self._dlp.data_classes)
diff --git a/src/cloudflare/resources/zero_trust/dlp/sensitivity_groups/__init__.py b/src/cloudflare/resources/zero_trust/dlp/sensitivity_groups/__init__.py
new file mode 100644
index 00000000000..a35cbd54ac7
--- /dev/null
+++ b/src/cloudflare/resources/zero_trust/dlp/sensitivity_groups/__init__.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .levels import (
+ LevelsResource,
+ AsyncLevelsResource,
+ LevelsResourceWithRawResponse,
+ AsyncLevelsResourceWithRawResponse,
+ LevelsResourceWithStreamingResponse,
+ AsyncLevelsResourceWithStreamingResponse,
+)
+from .sensitivity_groups import (
+ SensitivityGroupsResource,
+ AsyncSensitivityGroupsResource,
+ SensitivityGroupsResourceWithRawResponse,
+ AsyncSensitivityGroupsResourceWithRawResponse,
+ SensitivityGroupsResourceWithStreamingResponse,
+ AsyncSensitivityGroupsResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "LevelsResource",
+ "AsyncLevelsResource",
+ "LevelsResourceWithRawResponse",
+ "AsyncLevelsResourceWithRawResponse",
+ "LevelsResourceWithStreamingResponse",
+ "AsyncLevelsResourceWithStreamingResponse",
+ "SensitivityGroupsResource",
+ "AsyncSensitivityGroupsResource",
+ "SensitivityGroupsResourceWithRawResponse",
+ "AsyncSensitivityGroupsResourceWithRawResponse",
+ "SensitivityGroupsResourceWithStreamingResponse",
+ "AsyncSensitivityGroupsResourceWithStreamingResponse",
+]
diff --git a/src/cloudflare/resources/zero_trust/dlp/sensitivity_groups/levels/__init__.py b/src/cloudflare/resources/zero_trust/dlp/sensitivity_groups/levels/__init__.py
new file mode 100644
index 00000000000..9a19a78ad5f
--- /dev/null
+++ b/src/cloudflare/resources/zero_trust/dlp/sensitivity_groups/levels/__init__.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .order import (
+ OrderResource,
+ AsyncOrderResource,
+ OrderResourceWithRawResponse,
+ AsyncOrderResourceWithRawResponse,
+ OrderResourceWithStreamingResponse,
+ AsyncOrderResourceWithStreamingResponse,
+)
+from .levels import (
+ LevelsResource,
+ AsyncLevelsResource,
+ LevelsResourceWithRawResponse,
+ AsyncLevelsResourceWithRawResponse,
+ LevelsResourceWithStreamingResponse,
+ AsyncLevelsResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "OrderResource",
+ "AsyncOrderResource",
+ "OrderResourceWithRawResponse",
+ "AsyncOrderResourceWithRawResponse",
+ "OrderResourceWithStreamingResponse",
+ "AsyncOrderResourceWithStreamingResponse",
+ "LevelsResource",
+ "AsyncLevelsResource",
+ "LevelsResourceWithRawResponse",
+ "AsyncLevelsResourceWithRawResponse",
+ "LevelsResourceWithStreamingResponse",
+ "AsyncLevelsResourceWithStreamingResponse",
+]
diff --git a/src/cloudflare/resources/zero_trust/dlp/sensitivity_groups/levels/levels.py b/src/cloudflare/resources/zero_trust/dlp/sensitivity_groups/levels/levels.py
new file mode 100644
index 00000000000..5e89ab26e98
--- /dev/null
+++ b/src/cloudflare/resources/zero_trust/dlp/sensitivity_groups/levels/levels.py
@@ -0,0 +1,712 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Type, Optional, cast
+
+import httpx
+
+from .order import (
+ OrderResource,
+ AsyncOrderResource,
+ OrderResourceWithRawResponse,
+ AsyncOrderResourceWithRawResponse,
+ OrderResourceWithStreamingResponse,
+ AsyncOrderResourceWithStreamingResponse,
+)
+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 ......pagination import SyncSinglePage, AsyncSinglePage
+from ......_base_client import AsyncPaginator, make_request_options
+from ......types.zero_trust.dlp.sensitivity_groups import level_create_params, level_update_params
+from ......types.zero_trust.dlp.sensitivity_groups.level_get_response import LevelGetResponse
+from ......types.zero_trust.dlp.sensitivity_groups.level_list_response import LevelListResponse
+from ......types.zero_trust.dlp.sensitivity_groups.level_create_response import LevelCreateResponse
+from ......types.zero_trust.dlp.sensitivity_groups.level_update_response import LevelUpdateResponse
+
+__all__ = ["LevelsResource", "AsyncLevelsResource"]
+
+
+class LevelsResource(SyncAPIResource):
+ @cached_property
+ def order(self) -> OrderResource:
+ return OrderResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> LevelsResourceWithRawResponse:
+ """
+ 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 LevelsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> LevelsResourceWithStreamingResponse:
+ """
+ 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 LevelsResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ sensitivity_group_id: str,
+ *,
+ account_id: str,
+ name: str,
+ description: 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,
+ ) -> Optional[LevelCreateResponse]:
+ """
+ Creates a new sensitivity level.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not sensitivity_group_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_group_id` but received {sensitivity_group_id!r}"
+ )
+ return self._post(
+ path_template(
+ "/accounts/{account_id}/dlp/sensitivity_groups/{sensitivity_group_id}/levels",
+ account_id=account_id,
+ sensitivity_group_id=sensitivity_group_id,
+ ),
+ body=maybe_transform(
+ {
+ "name": name,
+ "description": description,
+ },
+ level_create_params.LevelCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[LevelCreateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[LevelCreateResponse]], ResultWrapper[LevelCreateResponse]),
+ )
+
+ def update(
+ self,
+ sensitivity_level_id: str,
+ *,
+ account_id: str,
+ sensitivity_group_id: str,
+ description: Optional[str] | 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,
+ ) -> Optional[LevelUpdateResponse]:
+ """
+ Update the attributes of a single sensitivity level.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not sensitivity_group_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_group_id` but received {sensitivity_group_id!r}"
+ )
+ if not sensitivity_level_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_level_id` but received {sensitivity_level_id!r}"
+ )
+ return self._put(
+ path_template(
+ "/accounts/{account_id}/dlp/sensitivity_groups/{sensitivity_group_id}/levels/{sensitivity_level_id}",
+ account_id=account_id,
+ sensitivity_group_id=sensitivity_group_id,
+ sensitivity_level_id=sensitivity_level_id,
+ ),
+ body=maybe_transform(
+ {
+ "description": description,
+ "name": name,
+ },
+ level_update_params.LevelUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[LevelUpdateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[LevelUpdateResponse]], ResultWrapper[LevelUpdateResponse]),
+ )
+
+ def list(
+ self,
+ sensitivity_group_id: str,
+ *,
+ account_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> SyncSinglePage[LevelListResponse]:
+ """
+ Retrieve all sensitivity levels in a sensitivity group
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not sensitivity_group_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_group_id` but received {sensitivity_group_id!r}"
+ )
+ return self._get_api_list(
+ path_template(
+ "/accounts/{account_id}/dlp/sensitivity_groups/{sensitivity_group_id}/levels",
+ account_id=account_id,
+ sensitivity_group_id=sensitivity_group_id,
+ ),
+ page=SyncSinglePage[LevelListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=LevelListResponse,
+ )
+
+ def delete(
+ self,
+ sensitivity_level_id: str,
+ *,
+ account_id: str,
+ sensitivity_group_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,
+ ) -> object:
+ """
+ Delete a single sensitivity level.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not sensitivity_group_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_group_id` but received {sensitivity_group_id!r}"
+ )
+ if not sensitivity_level_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_level_id` but received {sensitivity_level_id!r}"
+ )
+ return self._delete(
+ path_template(
+ "/accounts/{account_id}/dlp/sensitivity_groups/{sensitivity_group_id}/levels/{sensitivity_level_id}",
+ account_id=account_id,
+ sensitivity_group_id=sensitivity_group_id,
+ sensitivity_level_id=sensitivity_level_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[object]]._unwrapper,
+ ),
+ cast_to=cast(Type[object], ResultWrapper[object]),
+ )
+
+ def get(
+ self,
+ sensitivity_level_id: str,
+ *,
+ account_id: str,
+ sensitivity_group_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[LevelGetResponse]:
+ """
+ Retrieve a specific sensitivity level.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not sensitivity_group_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_group_id` but received {sensitivity_group_id!r}"
+ )
+ if not sensitivity_level_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_level_id` but received {sensitivity_level_id!r}"
+ )
+ return self._get(
+ path_template(
+ "/accounts/{account_id}/dlp/sensitivity_groups/{sensitivity_group_id}/levels/{sensitivity_level_id}",
+ account_id=account_id,
+ sensitivity_group_id=sensitivity_group_id,
+ sensitivity_level_id=sensitivity_level_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[LevelGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[LevelGetResponse]], ResultWrapper[LevelGetResponse]),
+ )
+
+
+class AsyncLevelsResource(AsyncAPIResource):
+ @cached_property
+ def order(self) -> AsyncOrderResource:
+ return AsyncOrderResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncLevelsResourceWithRawResponse:
+ """
+ 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 AsyncLevelsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncLevelsResourceWithStreamingResponse:
+ """
+ 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 AsyncLevelsResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ sensitivity_group_id: str,
+ *,
+ account_id: str,
+ name: str,
+ description: 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,
+ ) -> Optional[LevelCreateResponse]:
+ """
+ Creates a new sensitivity level.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not sensitivity_group_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_group_id` but received {sensitivity_group_id!r}"
+ )
+ return await self._post(
+ path_template(
+ "/accounts/{account_id}/dlp/sensitivity_groups/{sensitivity_group_id}/levels",
+ account_id=account_id,
+ sensitivity_group_id=sensitivity_group_id,
+ ),
+ body=await async_maybe_transform(
+ {
+ "name": name,
+ "description": description,
+ },
+ level_create_params.LevelCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[LevelCreateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[LevelCreateResponse]], ResultWrapper[LevelCreateResponse]),
+ )
+
+ async def update(
+ self,
+ sensitivity_level_id: str,
+ *,
+ account_id: str,
+ sensitivity_group_id: str,
+ description: Optional[str] | 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,
+ ) -> Optional[LevelUpdateResponse]:
+ """
+ Update the attributes of a single sensitivity level.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not sensitivity_group_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_group_id` but received {sensitivity_group_id!r}"
+ )
+ if not sensitivity_level_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_level_id` but received {sensitivity_level_id!r}"
+ )
+ return await self._put(
+ path_template(
+ "/accounts/{account_id}/dlp/sensitivity_groups/{sensitivity_group_id}/levels/{sensitivity_level_id}",
+ account_id=account_id,
+ sensitivity_group_id=sensitivity_group_id,
+ sensitivity_level_id=sensitivity_level_id,
+ ),
+ body=await async_maybe_transform(
+ {
+ "description": description,
+ "name": name,
+ },
+ level_update_params.LevelUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[LevelUpdateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[LevelUpdateResponse]], ResultWrapper[LevelUpdateResponse]),
+ )
+
+ def list(
+ self,
+ sensitivity_group_id: str,
+ *,
+ account_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> AsyncPaginator[LevelListResponse, AsyncSinglePage[LevelListResponse]]:
+ """
+ Retrieve all sensitivity levels in a sensitivity group
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not sensitivity_group_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_group_id` but received {sensitivity_group_id!r}"
+ )
+ return self._get_api_list(
+ path_template(
+ "/accounts/{account_id}/dlp/sensitivity_groups/{sensitivity_group_id}/levels",
+ account_id=account_id,
+ sensitivity_group_id=sensitivity_group_id,
+ ),
+ page=AsyncSinglePage[LevelListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=LevelListResponse,
+ )
+
+ async def delete(
+ self,
+ sensitivity_level_id: str,
+ *,
+ account_id: str,
+ sensitivity_group_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,
+ ) -> object:
+ """
+ Delete a single sensitivity level.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not sensitivity_group_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_group_id` but received {sensitivity_group_id!r}"
+ )
+ if not sensitivity_level_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_level_id` but received {sensitivity_level_id!r}"
+ )
+ return await self._delete(
+ path_template(
+ "/accounts/{account_id}/dlp/sensitivity_groups/{sensitivity_group_id}/levels/{sensitivity_level_id}",
+ account_id=account_id,
+ sensitivity_group_id=sensitivity_group_id,
+ sensitivity_level_id=sensitivity_level_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[object]]._unwrapper,
+ ),
+ cast_to=cast(Type[object], ResultWrapper[object]),
+ )
+
+ async def get(
+ self,
+ sensitivity_level_id: str,
+ *,
+ account_id: str,
+ sensitivity_group_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[LevelGetResponse]:
+ """
+ Retrieve a specific sensitivity level.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not sensitivity_group_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_group_id` but received {sensitivity_group_id!r}"
+ )
+ if not sensitivity_level_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_level_id` but received {sensitivity_level_id!r}"
+ )
+ return await self._get(
+ path_template(
+ "/accounts/{account_id}/dlp/sensitivity_groups/{sensitivity_group_id}/levels/{sensitivity_level_id}",
+ account_id=account_id,
+ sensitivity_group_id=sensitivity_group_id,
+ sensitivity_level_id=sensitivity_level_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[LevelGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[LevelGetResponse]], ResultWrapper[LevelGetResponse]),
+ )
+
+
+class LevelsResourceWithRawResponse:
+ def __init__(self, levels: LevelsResource) -> None:
+ self._levels = levels
+
+ self.create = to_raw_response_wrapper(
+ levels.create,
+ )
+ self.update = to_raw_response_wrapper(
+ levels.update,
+ )
+ self.list = to_raw_response_wrapper(
+ levels.list,
+ )
+ self.delete = to_raw_response_wrapper(
+ levels.delete,
+ )
+ self.get = to_raw_response_wrapper(
+ levels.get,
+ )
+
+ @cached_property
+ def order(self) -> OrderResourceWithRawResponse:
+ return OrderResourceWithRawResponse(self._levels.order)
+
+
+class AsyncLevelsResourceWithRawResponse:
+ def __init__(self, levels: AsyncLevelsResource) -> None:
+ self._levels = levels
+
+ self.create = async_to_raw_response_wrapper(
+ levels.create,
+ )
+ self.update = async_to_raw_response_wrapper(
+ levels.update,
+ )
+ self.list = async_to_raw_response_wrapper(
+ levels.list,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ levels.delete,
+ )
+ self.get = async_to_raw_response_wrapper(
+ levels.get,
+ )
+
+ @cached_property
+ def order(self) -> AsyncOrderResourceWithRawResponse:
+ return AsyncOrderResourceWithRawResponse(self._levels.order)
+
+
+class LevelsResourceWithStreamingResponse:
+ def __init__(self, levels: LevelsResource) -> None:
+ self._levels = levels
+
+ self.create = to_streamed_response_wrapper(
+ levels.create,
+ )
+ self.update = to_streamed_response_wrapper(
+ levels.update,
+ )
+ self.list = to_streamed_response_wrapper(
+ levels.list,
+ )
+ self.delete = to_streamed_response_wrapper(
+ levels.delete,
+ )
+ self.get = to_streamed_response_wrapper(
+ levels.get,
+ )
+
+ @cached_property
+ def order(self) -> OrderResourceWithStreamingResponse:
+ return OrderResourceWithStreamingResponse(self._levels.order)
+
+
+class AsyncLevelsResourceWithStreamingResponse:
+ def __init__(self, levels: AsyncLevelsResource) -> None:
+ self._levels = levels
+
+ self.create = async_to_streamed_response_wrapper(
+ levels.create,
+ )
+ self.update = async_to_streamed_response_wrapper(
+ levels.update,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ levels.list,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ levels.delete,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ levels.get,
+ )
+
+ @cached_property
+ def order(self) -> AsyncOrderResourceWithStreamingResponse:
+ return AsyncOrderResourceWithStreamingResponse(self._levels.order)
diff --git a/src/cloudflare/resources/zero_trust/dlp/sensitivity_groups/levels/order.py b/src/cloudflare/resources/zero_trust/dlp/sensitivity_groups/levels/order.py
new file mode 100644
index 00000000000..e1bd512a92d
--- /dev/null
+++ b/src/cloudflare/resources/zero_trust/dlp/sensitivity_groups/levels/order.py
@@ -0,0 +1,303 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Type, Optional, cast
+
+import httpx
+
+from ......_types import Body, Query, Headers, NotGiven, SequenceNotStr, 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.zero_trust.dlp.sensitivity_groups.levels import order_update_params
+from ......types.zero_trust.dlp.sensitivity_groups.levels.order_get_response import OrderGetResponse
+from ......types.zero_trust.dlp.sensitivity_groups.levels.order_update_response import OrderUpdateResponse
+
+__all__ = ["OrderResource", "AsyncOrderResource"]
+
+
+class OrderResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> OrderResourceWithRawResponse:
+ """
+ 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 OrderResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> OrderResourceWithStreamingResponse:
+ """
+ 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 OrderResourceWithStreamingResponse(self)
+
+ def update(
+ self,
+ sensitivity_group_id: str,
+ *,
+ account_id: str,
+ level_ids: SequenceNotStr[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[OrderUpdateResponse]:
+ """
+ Set the ordering of levels within a sensitivity group.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not sensitivity_group_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_group_id` but received {sensitivity_group_id!r}"
+ )
+ return self._put(
+ path_template(
+ "/accounts/{account_id}/dlp/sensitivity_groups/{sensitivity_group_id}/level_order",
+ account_id=account_id,
+ sensitivity_group_id=sensitivity_group_id,
+ ),
+ body=maybe_transform({"level_ids": level_ids}, order_update_params.OrderUpdateParams),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[OrderUpdateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[OrderUpdateResponse]], ResultWrapper[OrderUpdateResponse]),
+ )
+
+ def get(
+ self,
+ sensitivity_group_id: str,
+ *,
+ account_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[OrderGetResponse]:
+ """
+ Retrieve the ordered list of level IDs for a sensitivity group.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not sensitivity_group_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_group_id` but received {sensitivity_group_id!r}"
+ )
+ return self._get(
+ path_template(
+ "/accounts/{account_id}/dlp/sensitivity_groups/{sensitivity_group_id}/level_order",
+ account_id=account_id,
+ sensitivity_group_id=sensitivity_group_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[OrderGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[OrderGetResponse]], ResultWrapper[OrderGetResponse]),
+ )
+
+
+class AsyncOrderResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncOrderResourceWithRawResponse:
+ """
+ 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 AsyncOrderResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncOrderResourceWithStreamingResponse:
+ """
+ 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 AsyncOrderResourceWithStreamingResponse(self)
+
+ async def update(
+ self,
+ sensitivity_group_id: str,
+ *,
+ account_id: str,
+ level_ids: SequenceNotStr[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[OrderUpdateResponse]:
+ """
+ Set the ordering of levels within a sensitivity group.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not sensitivity_group_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_group_id` but received {sensitivity_group_id!r}"
+ )
+ return await self._put(
+ path_template(
+ "/accounts/{account_id}/dlp/sensitivity_groups/{sensitivity_group_id}/level_order",
+ account_id=account_id,
+ sensitivity_group_id=sensitivity_group_id,
+ ),
+ body=await async_maybe_transform({"level_ids": level_ids}, order_update_params.OrderUpdateParams),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[OrderUpdateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[OrderUpdateResponse]], ResultWrapper[OrderUpdateResponse]),
+ )
+
+ async def get(
+ self,
+ sensitivity_group_id: str,
+ *,
+ account_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[OrderGetResponse]:
+ """
+ Retrieve the ordered list of level IDs for a sensitivity group.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not sensitivity_group_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_group_id` but received {sensitivity_group_id!r}"
+ )
+ return await self._get(
+ path_template(
+ "/accounts/{account_id}/dlp/sensitivity_groups/{sensitivity_group_id}/level_order",
+ account_id=account_id,
+ sensitivity_group_id=sensitivity_group_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[OrderGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[OrderGetResponse]], ResultWrapper[OrderGetResponse]),
+ )
+
+
+class OrderResourceWithRawResponse:
+ def __init__(self, order: OrderResource) -> None:
+ self._order = order
+
+ self.update = to_raw_response_wrapper(
+ order.update,
+ )
+ self.get = to_raw_response_wrapper(
+ order.get,
+ )
+
+
+class AsyncOrderResourceWithRawResponse:
+ def __init__(self, order: AsyncOrderResource) -> None:
+ self._order = order
+
+ self.update = async_to_raw_response_wrapper(
+ order.update,
+ )
+ self.get = async_to_raw_response_wrapper(
+ order.get,
+ )
+
+
+class OrderResourceWithStreamingResponse:
+ def __init__(self, order: OrderResource) -> None:
+ self._order = order
+
+ self.update = to_streamed_response_wrapper(
+ order.update,
+ )
+ self.get = to_streamed_response_wrapper(
+ order.get,
+ )
+
+
+class AsyncOrderResourceWithStreamingResponse:
+ def __init__(self, order: AsyncOrderResource) -> None:
+ self._order = order
+
+ self.update = async_to_streamed_response_wrapper(
+ order.update,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ order.get,
+ )
diff --git a/src/cloudflare/resources/zero_trust/dlp/sensitivity_groups/sensitivity_groups.py b/src/cloudflare/resources/zero_trust/dlp/sensitivity_groups/sensitivity_groups.py
new file mode 100644
index 00000000000..f51b444417b
--- /dev/null
+++ b/src/cloudflare/resources/zero_trust/dlp/sensitivity_groups/sensitivity_groups.py
@@ -0,0 +1,668 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Type, Iterable, Optional, 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 .levels.levels import (
+ LevelsResource,
+ AsyncLevelsResource,
+ LevelsResourceWithRawResponse,
+ AsyncLevelsResourceWithRawResponse,
+ LevelsResourceWithStreamingResponse,
+ AsyncLevelsResourceWithStreamingResponse,
+)
+from .....pagination import SyncSinglePage, AsyncSinglePage
+from ....._base_client import AsyncPaginator, make_request_options
+from .....types.zero_trust.dlp import sensitivity_group_create_params, sensitivity_group_update_params
+from .....types.zero_trust.dlp.sensitivity_group_get_response import SensitivityGroupGetResponse
+from .....types.zero_trust.dlp.sensitivity_group_list_response import SensitivityGroupListResponse
+from .....types.zero_trust.dlp.sensitivity_group_create_response import SensitivityGroupCreateResponse
+from .....types.zero_trust.dlp.sensitivity_group_update_response import SensitivityGroupUpdateResponse
+
+__all__ = ["SensitivityGroupsResource", "AsyncSensitivityGroupsResource"]
+
+
+class SensitivityGroupsResource(SyncAPIResource):
+ @cached_property
+ def levels(self) -> LevelsResource:
+ return LevelsResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> SensitivityGroupsResourceWithRawResponse:
+ """
+ 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 SensitivityGroupsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> SensitivityGroupsResourceWithStreamingResponse:
+ """
+ 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 SensitivityGroupsResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ *,
+ account_id: str,
+ name: str,
+ description: Optional[str] | Omit = omit,
+ levels: Iterable[sensitivity_group_create_params.Level] | Omit = omit,
+ template_id: 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,
+ ) -> Optional[SensitivityGroupCreateResponse]:
+ """
+ Creates a new sensitivity group.
+
+ Args:
+ levels: Levels to create with the group. Mutually exclusive with `template_id`.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._post(
+ path_template("/accounts/{account_id}/dlp/sensitivity_groups", account_id=account_id),
+ body=maybe_transform(
+ {
+ "name": name,
+ "description": description,
+ "levels": levels,
+ "template_id": template_id,
+ },
+ sensitivity_group_create_params.SensitivityGroupCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[SensitivityGroupCreateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[SensitivityGroupCreateResponse]], ResultWrapper[SensitivityGroupCreateResponse]),
+ )
+
+ def update(
+ self,
+ sensitivity_group_id: str,
+ *,
+ account_id: str,
+ description: Optional[str] | Omit = omit,
+ levels: Optional[Iterable[sensitivity_group_update_params.Level]] | 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,
+ ) -> Optional[SensitivityGroupUpdateResponse]:
+ """
+ Update the attributes of a single sensitivity group.
+
+ Args:
+ levels: The desired final state of levels.
+
+ - `None` (omitted): no level changes.
+ - `Some([])`: delete all levels.
+ - `Some([...])`: desired final set + order.
+
+ 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 sensitivity_group_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_group_id` but received {sensitivity_group_id!r}"
+ )
+ return self._put(
+ path_template(
+ "/accounts/{account_id}/dlp/sensitivity_groups/{sensitivity_group_id}",
+ account_id=account_id,
+ sensitivity_group_id=sensitivity_group_id,
+ ),
+ body=maybe_transform(
+ {
+ "description": description,
+ "levels": levels,
+ "name": name,
+ },
+ sensitivity_group_update_params.SensitivityGroupUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[SensitivityGroupUpdateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[SensitivityGroupUpdateResponse]], ResultWrapper[SensitivityGroupUpdateResponse]),
+ )
+
+ def list(
+ 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[SensitivityGroupListResponse]:
+ """
+ Retrieve all sensitivity groups in an account
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._get_api_list(
+ path_template("/accounts/{account_id}/dlp/sensitivity_groups", account_id=account_id),
+ page=SyncSinglePage[SensitivityGroupListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=SensitivityGroupListResponse,
+ )
+
+ def delete(
+ self,
+ sensitivity_group_id: str,
+ *,
+ account_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> object:
+ """
+ Delete a single sensitivity group.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not sensitivity_group_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_group_id` but received {sensitivity_group_id!r}"
+ )
+ return self._delete(
+ path_template(
+ "/accounts/{account_id}/dlp/sensitivity_groups/{sensitivity_group_id}",
+ account_id=account_id,
+ sensitivity_group_id=sensitivity_group_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[object]]._unwrapper,
+ ),
+ cast_to=cast(Type[object], ResultWrapper[object]),
+ )
+
+ def get(
+ self,
+ sensitivity_group_id: str,
+ *,
+ account_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[SensitivityGroupGetResponse]:
+ """
+ Retrieve a specific sensitivity group.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not sensitivity_group_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_group_id` but received {sensitivity_group_id!r}"
+ )
+ return self._get(
+ path_template(
+ "/accounts/{account_id}/dlp/sensitivity_groups/{sensitivity_group_id}",
+ account_id=account_id,
+ sensitivity_group_id=sensitivity_group_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[SensitivityGroupGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[SensitivityGroupGetResponse]], ResultWrapper[SensitivityGroupGetResponse]),
+ )
+
+
+class AsyncSensitivityGroupsResource(AsyncAPIResource):
+ @cached_property
+ def levels(self) -> AsyncLevelsResource:
+ return AsyncLevelsResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncSensitivityGroupsResourceWithRawResponse:
+ """
+ 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 AsyncSensitivityGroupsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncSensitivityGroupsResourceWithStreamingResponse:
+ """
+ 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 AsyncSensitivityGroupsResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ *,
+ account_id: str,
+ name: str,
+ description: Optional[str] | Omit = omit,
+ levels: Iterable[sensitivity_group_create_params.Level] | Omit = omit,
+ template_id: 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,
+ ) -> Optional[SensitivityGroupCreateResponse]:
+ """
+ Creates a new sensitivity group.
+
+ Args:
+ levels: Levels to create with the group. Mutually exclusive with `template_id`.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return await self._post(
+ path_template("/accounts/{account_id}/dlp/sensitivity_groups", account_id=account_id),
+ body=await async_maybe_transform(
+ {
+ "name": name,
+ "description": description,
+ "levels": levels,
+ "template_id": template_id,
+ },
+ sensitivity_group_create_params.SensitivityGroupCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[SensitivityGroupCreateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[SensitivityGroupCreateResponse]], ResultWrapper[SensitivityGroupCreateResponse]),
+ )
+
+ async def update(
+ self,
+ sensitivity_group_id: str,
+ *,
+ account_id: str,
+ description: Optional[str] | Omit = omit,
+ levels: Optional[Iterable[sensitivity_group_update_params.Level]] | 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,
+ ) -> Optional[SensitivityGroupUpdateResponse]:
+ """
+ Update the attributes of a single sensitivity group.
+
+ Args:
+ levels: The desired final state of levels.
+
+ - `None` (omitted): no level changes.
+ - `Some([])`: delete all levels.
+ - `Some([...])`: desired final set + order.
+
+ 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 sensitivity_group_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_group_id` but received {sensitivity_group_id!r}"
+ )
+ return await self._put(
+ path_template(
+ "/accounts/{account_id}/dlp/sensitivity_groups/{sensitivity_group_id}",
+ account_id=account_id,
+ sensitivity_group_id=sensitivity_group_id,
+ ),
+ body=await async_maybe_transform(
+ {
+ "description": description,
+ "levels": levels,
+ "name": name,
+ },
+ sensitivity_group_update_params.SensitivityGroupUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[SensitivityGroupUpdateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[SensitivityGroupUpdateResponse]], ResultWrapper[SensitivityGroupUpdateResponse]),
+ )
+
+ def list(
+ 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[SensitivityGroupListResponse, AsyncSinglePage[SensitivityGroupListResponse]]:
+ """
+ Retrieve all sensitivity groups in an account
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._get_api_list(
+ path_template("/accounts/{account_id}/dlp/sensitivity_groups", account_id=account_id),
+ page=AsyncSinglePage[SensitivityGroupListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=SensitivityGroupListResponse,
+ )
+
+ async def delete(
+ self,
+ sensitivity_group_id: str,
+ *,
+ account_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> object:
+ """
+ Delete a single sensitivity group.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not sensitivity_group_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_group_id` but received {sensitivity_group_id!r}"
+ )
+ return await self._delete(
+ path_template(
+ "/accounts/{account_id}/dlp/sensitivity_groups/{sensitivity_group_id}",
+ account_id=account_id,
+ sensitivity_group_id=sensitivity_group_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[object]]._unwrapper,
+ ),
+ cast_to=cast(Type[object], ResultWrapper[object]),
+ )
+
+ async def get(
+ self,
+ sensitivity_group_id: str,
+ *,
+ account_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[SensitivityGroupGetResponse]:
+ """
+ Retrieve a specific sensitivity group.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not sensitivity_group_id:
+ raise ValueError(
+ f"Expected a non-empty value for `sensitivity_group_id` but received {sensitivity_group_id!r}"
+ )
+ return await self._get(
+ path_template(
+ "/accounts/{account_id}/dlp/sensitivity_groups/{sensitivity_group_id}",
+ account_id=account_id,
+ sensitivity_group_id=sensitivity_group_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[SensitivityGroupGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[SensitivityGroupGetResponse]], ResultWrapper[SensitivityGroupGetResponse]),
+ )
+
+
+class SensitivityGroupsResourceWithRawResponse:
+ def __init__(self, sensitivity_groups: SensitivityGroupsResource) -> None:
+ self._sensitivity_groups = sensitivity_groups
+
+ self.create = to_raw_response_wrapper(
+ sensitivity_groups.create,
+ )
+ self.update = to_raw_response_wrapper(
+ sensitivity_groups.update,
+ )
+ self.list = to_raw_response_wrapper(
+ sensitivity_groups.list,
+ )
+ self.delete = to_raw_response_wrapper(
+ sensitivity_groups.delete,
+ )
+ self.get = to_raw_response_wrapper(
+ sensitivity_groups.get,
+ )
+
+ @cached_property
+ def levels(self) -> LevelsResourceWithRawResponse:
+ return LevelsResourceWithRawResponse(self._sensitivity_groups.levels)
+
+
+class AsyncSensitivityGroupsResourceWithRawResponse:
+ def __init__(self, sensitivity_groups: AsyncSensitivityGroupsResource) -> None:
+ self._sensitivity_groups = sensitivity_groups
+
+ self.create = async_to_raw_response_wrapper(
+ sensitivity_groups.create,
+ )
+ self.update = async_to_raw_response_wrapper(
+ sensitivity_groups.update,
+ )
+ self.list = async_to_raw_response_wrapper(
+ sensitivity_groups.list,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ sensitivity_groups.delete,
+ )
+ self.get = async_to_raw_response_wrapper(
+ sensitivity_groups.get,
+ )
+
+ @cached_property
+ def levels(self) -> AsyncLevelsResourceWithRawResponse:
+ return AsyncLevelsResourceWithRawResponse(self._sensitivity_groups.levels)
+
+
+class SensitivityGroupsResourceWithStreamingResponse:
+ def __init__(self, sensitivity_groups: SensitivityGroupsResource) -> None:
+ self._sensitivity_groups = sensitivity_groups
+
+ self.create = to_streamed_response_wrapper(
+ sensitivity_groups.create,
+ )
+ self.update = to_streamed_response_wrapper(
+ sensitivity_groups.update,
+ )
+ self.list = to_streamed_response_wrapper(
+ sensitivity_groups.list,
+ )
+ self.delete = to_streamed_response_wrapper(
+ sensitivity_groups.delete,
+ )
+ self.get = to_streamed_response_wrapper(
+ sensitivity_groups.get,
+ )
+
+ @cached_property
+ def levels(self) -> LevelsResourceWithStreamingResponse:
+ return LevelsResourceWithStreamingResponse(self._sensitivity_groups.levels)
+
+
+class AsyncSensitivityGroupsResourceWithStreamingResponse:
+ def __init__(self, sensitivity_groups: AsyncSensitivityGroupsResource) -> None:
+ self._sensitivity_groups = sensitivity_groups
+
+ self.create = async_to_streamed_response_wrapper(
+ sensitivity_groups.create,
+ )
+ self.update = async_to_streamed_response_wrapper(
+ sensitivity_groups.update,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ sensitivity_groups.list,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ sensitivity_groups.delete,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ sensitivity_groups.get,
+ )
+
+ @cached_property
+ def levels(self) -> AsyncLevelsResourceWithStreamingResponse:
+ return AsyncLevelsResourceWithStreamingResponse(self._sensitivity_groups.levels)
diff --git a/src/cloudflare/resources/zero_trust/tunnels/warp_connector/__init__.py b/src/cloudflare/resources/zero_trust/tunnels/warp_connector/__init__.py
index 834481ac382..f5b86e89d63 100644
--- a/src/cloudflare/resources/zero_trust/tunnels/warp_connector/__init__.py
+++ b/src/cloudflare/resources/zero_trust/tunnels/warp_connector/__init__.py
@@ -32,6 +32,14 @@
ConnectionsResourceWithStreamingResponse,
AsyncConnectionsResourceWithStreamingResponse,
)
+from .configurations import (
+ ConfigurationsResource,
+ AsyncConfigurationsResource,
+ ConfigurationsResourceWithRawResponse,
+ AsyncConfigurationsResourceWithRawResponse,
+ ConfigurationsResourceWithStreamingResponse,
+ AsyncConfigurationsResourceWithStreamingResponse,
+)
from .warp_connector import (
WARPConnectorResource,
AsyncWARPConnectorResource,
@@ -66,6 +74,12 @@
"AsyncFailoverResourceWithRawResponse",
"FailoverResourceWithStreamingResponse",
"AsyncFailoverResourceWithStreamingResponse",
+ "ConfigurationsResource",
+ "AsyncConfigurationsResource",
+ "ConfigurationsResourceWithRawResponse",
+ "AsyncConfigurationsResourceWithRawResponse",
+ "ConfigurationsResourceWithStreamingResponse",
+ "AsyncConfigurationsResourceWithStreamingResponse",
"WARPConnectorResource",
"AsyncWARPConnectorResource",
"WARPConnectorResourceWithRawResponse",
diff --git a/src/cloudflare/resources/zero_trust/tunnels/warp_connector/configurations.py b/src/cloudflare/resources/zero_trust/tunnels/warp_connector/configurations.py
new file mode 100644
index 00000000000..ca3c763cf2a
--- /dev/null
+++ b/src/cloudflare/resources/zero_trust/tunnels/warp_connector/configurations.py
@@ -0,0 +1,344 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+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, 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.zero_trust.tunnels.warp_connector import configuration_update_params
+from .....types.zero_trust.tunnels.warp_connector.configuration_get_response import ConfigurationGetResponse
+from .....types.zero_trust.tunnels.warp_connector.configuration_update_response import ConfigurationUpdateResponse
+
+__all__ = ["ConfigurationsResource", "AsyncConfigurationsResource"]
+
+
+class ConfigurationsResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> ConfigurationsResourceWithRawResponse:
+ """
+ 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 ConfigurationsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> ConfigurationsResourceWithStreamingResponse:
+ """
+ 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 ConfigurationsResourceWithStreamingResponse(self)
+
+ def update(
+ self,
+ tunnel_id: str,
+ *,
+ account_id: str,
+ ha_mode: Literal["none", "disabled", "aws", "local"],
+ config: Optional[configuration_update_params.Config] | 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,
+ ) -> Optional[ConfigurationUpdateResponse]:
+ """
+ Adds or updates the high-availability configuration for a WARP Connector tunnel.
+
+ Args:
+ account_id: Identifier.
+
+ tunnel_id: UUID of the tunnel.
+
+ ha_mode: High-availability mode for the WARP Connector tunnel. `none` means HA is enabled
+ but no provider is configured yet (newly created tunnels default to this).
+ `disabled` means HA is explicitly turned off. `aws` uses AWS ENI move for
+ failover. `local` uses virtual IPs (VIPs) on the local interface.
+
+ config: Provider-specific configuration. Required shape depends on ha_mode. For `aws`,
+ must contain `fnr_id`. For `local`, must contain `vips`. For `none` and
+ `disabled`, must be empty or omitted.
+
+ 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 tunnel_id:
+ raise ValueError(f"Expected a non-empty value for `tunnel_id` but received {tunnel_id!r}")
+ return self._put(
+ path_template(
+ "/accounts/{account_id}/warp_connector/{tunnel_id}/configurations",
+ account_id=account_id,
+ tunnel_id=tunnel_id,
+ ),
+ body=maybe_transform(
+ {
+ "ha_mode": ha_mode,
+ "config": config,
+ },
+ configuration_update_params.ConfigurationUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[ConfigurationUpdateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[ConfigurationUpdateResponse]], ResultWrapper[ConfigurationUpdateResponse]),
+ )
+
+ def get(
+ self,
+ tunnel_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[ConfigurationGetResponse]:
+ """
+ Gets the high-availability configuration for a WARP Connector tunnel.
+
+ Args:
+ account_id: Identifier.
+
+ tunnel_id: UUID of the tunnel.
+
+ 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 tunnel_id:
+ raise ValueError(f"Expected a non-empty value for `tunnel_id` but received {tunnel_id!r}")
+ return self._get(
+ path_template(
+ "/accounts/{account_id}/warp_connector/{tunnel_id}/configurations",
+ account_id=account_id,
+ tunnel_id=tunnel_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[ConfigurationGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[ConfigurationGetResponse]], ResultWrapper[ConfigurationGetResponse]),
+ )
+
+
+class AsyncConfigurationsResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncConfigurationsResourceWithRawResponse:
+ """
+ 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 AsyncConfigurationsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncConfigurationsResourceWithStreamingResponse:
+ """
+ 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 AsyncConfigurationsResourceWithStreamingResponse(self)
+
+ async def update(
+ self,
+ tunnel_id: str,
+ *,
+ account_id: str,
+ ha_mode: Literal["none", "disabled", "aws", "local"],
+ config: Optional[configuration_update_params.Config] | 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,
+ ) -> Optional[ConfigurationUpdateResponse]:
+ """
+ Adds or updates the high-availability configuration for a WARP Connector tunnel.
+
+ Args:
+ account_id: Identifier.
+
+ tunnel_id: UUID of the tunnel.
+
+ ha_mode: High-availability mode for the WARP Connector tunnel. `none` means HA is enabled
+ but no provider is configured yet (newly created tunnels default to this).
+ `disabled` means HA is explicitly turned off. `aws` uses AWS ENI move for
+ failover. `local` uses virtual IPs (VIPs) on the local interface.
+
+ config: Provider-specific configuration. Required shape depends on ha_mode. For `aws`,
+ must contain `fnr_id`. For `local`, must contain `vips`. For `none` and
+ `disabled`, must be empty or omitted.
+
+ 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 tunnel_id:
+ raise ValueError(f"Expected a non-empty value for `tunnel_id` but received {tunnel_id!r}")
+ return await self._put(
+ path_template(
+ "/accounts/{account_id}/warp_connector/{tunnel_id}/configurations",
+ account_id=account_id,
+ tunnel_id=tunnel_id,
+ ),
+ body=await async_maybe_transform(
+ {
+ "ha_mode": ha_mode,
+ "config": config,
+ },
+ configuration_update_params.ConfigurationUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[ConfigurationUpdateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[ConfigurationUpdateResponse]], ResultWrapper[ConfigurationUpdateResponse]),
+ )
+
+ async def get(
+ self,
+ tunnel_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[ConfigurationGetResponse]:
+ """
+ Gets the high-availability configuration for a WARP Connector tunnel.
+
+ Args:
+ account_id: Identifier.
+
+ tunnel_id: UUID of the tunnel.
+
+ 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 tunnel_id:
+ raise ValueError(f"Expected a non-empty value for `tunnel_id` but received {tunnel_id!r}")
+ return await self._get(
+ path_template(
+ "/accounts/{account_id}/warp_connector/{tunnel_id}/configurations",
+ account_id=account_id,
+ tunnel_id=tunnel_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[ConfigurationGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[ConfigurationGetResponse]], ResultWrapper[ConfigurationGetResponse]),
+ )
+
+
+class ConfigurationsResourceWithRawResponse:
+ def __init__(self, configurations: ConfigurationsResource) -> None:
+ self._configurations = configurations
+
+ self.update = to_raw_response_wrapper(
+ configurations.update,
+ )
+ self.get = to_raw_response_wrapper(
+ configurations.get,
+ )
+
+
+class AsyncConfigurationsResourceWithRawResponse:
+ def __init__(self, configurations: AsyncConfigurationsResource) -> None:
+ self._configurations = configurations
+
+ self.update = async_to_raw_response_wrapper(
+ configurations.update,
+ )
+ self.get = async_to_raw_response_wrapper(
+ configurations.get,
+ )
+
+
+class ConfigurationsResourceWithStreamingResponse:
+ def __init__(self, configurations: ConfigurationsResource) -> None:
+ self._configurations = configurations
+
+ self.update = to_streamed_response_wrapper(
+ configurations.update,
+ )
+ self.get = to_streamed_response_wrapper(
+ configurations.get,
+ )
+
+
+class AsyncConfigurationsResourceWithStreamingResponse:
+ def __init__(self, configurations: AsyncConfigurationsResource) -> None:
+ self._configurations = configurations
+
+ self.update = async_to_streamed_response_wrapper(
+ configurations.update,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ configurations.get,
+ )
diff --git a/src/cloudflare/resources/zero_trust/tunnels/warp_connector/warp_connector.py b/src/cloudflare/resources/zero_trust/tunnels/warp_connector/warp_connector.py
index 7d70a1335c5..d6f5d4609b5 100644
--- a/src/cloudflare/resources/zero_trust/tunnels/warp_connector/warp_connector.py
+++ b/src/cloudflare/resources/zero_trust/tunnels/warp_connector/warp_connector.py
@@ -52,6 +52,14 @@
)
from ....._wrappers import ResultWrapper
from .....pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray
+from .configurations import (
+ ConfigurationsResource,
+ AsyncConfigurationsResource,
+ ConfigurationsResourceWithRawResponse,
+ AsyncConfigurationsResourceWithRawResponse,
+ ConfigurationsResourceWithStreamingResponse,
+ AsyncConfigurationsResourceWithStreamingResponse,
+)
from ....._base_client import AsyncPaginator, make_request_options
from .....types.zero_trust.tunnels import (
warp_connector_edit_params,
@@ -84,6 +92,10 @@ def connectors(self) -> ConnectorsResource:
def failover(self) -> FailoverResource:
return FailoverResource(self._client)
+ @cached_property
+ def configurations(self) -> ConfigurationsResource:
+ return ConfigurationsResource(self._client)
+
@cached_property
def with_raw_response(self) -> WARPConnectorResourceWithRawResponse:
"""
@@ -411,6 +423,10 @@ def connectors(self) -> AsyncConnectorsResource:
def failover(self) -> AsyncFailoverResource:
return AsyncFailoverResource(self._client)
+ @cached_property
+ def configurations(self) -> AsyncConfigurationsResource:
+ return AsyncConfigurationsResource(self._client)
+
@cached_property
def with_raw_response(self) -> AsyncWARPConnectorResourceWithRawResponse:
"""
@@ -757,6 +773,10 @@ def connectors(self) -> ConnectorsResourceWithRawResponse:
def failover(self) -> FailoverResourceWithRawResponse:
return FailoverResourceWithRawResponse(self._warp_connector.failover)
+ @cached_property
+ def configurations(self) -> ConfigurationsResourceWithRawResponse:
+ return ConfigurationsResourceWithRawResponse(self._warp_connector.configurations)
+
class AsyncWARPConnectorResourceWithRawResponse:
def __init__(self, warp_connector: AsyncWARPConnectorResource) -> None:
@@ -794,6 +814,10 @@ def connectors(self) -> AsyncConnectorsResourceWithRawResponse:
def failover(self) -> AsyncFailoverResourceWithRawResponse:
return AsyncFailoverResourceWithRawResponse(self._warp_connector.failover)
+ @cached_property
+ def configurations(self) -> AsyncConfigurationsResourceWithRawResponse:
+ return AsyncConfigurationsResourceWithRawResponse(self._warp_connector.configurations)
+
class WARPConnectorResourceWithStreamingResponse:
def __init__(self, warp_connector: WARPConnectorResource) -> None:
@@ -831,6 +855,10 @@ def connectors(self) -> ConnectorsResourceWithStreamingResponse:
def failover(self) -> FailoverResourceWithStreamingResponse:
return FailoverResourceWithStreamingResponse(self._warp_connector.failover)
+ @cached_property
+ def configurations(self) -> ConfigurationsResourceWithStreamingResponse:
+ return ConfigurationsResourceWithStreamingResponse(self._warp_connector.configurations)
+
class AsyncWARPConnectorResourceWithStreamingResponse:
def __init__(self, warp_connector: AsyncWARPConnectorResource) -> None:
@@ -867,3 +895,7 @@ def connectors(self) -> AsyncConnectorsResourceWithStreamingResponse:
@cached_property
def failover(self) -> AsyncFailoverResourceWithStreamingResponse:
return AsyncFailoverResourceWithStreamingResponse(self._warp_connector.failover)
+
+ @cached_property
+ def configurations(self) -> AsyncConfigurationsResourceWithStreamingResponse:
+ return AsyncConfigurationsResourceWithStreamingResponse(self._warp_connector.configurations)
diff --git a/src/cloudflare/types/ai/model_list_params.py b/src/cloudflare/types/ai/model_list_params.py
index 2ec44072002..84ce606a9c8 100644
--- a/src/cloudflare/types/ai/model_list_params.py
+++ b/src/cloudflare/types/ai/model_list_params.py
@@ -22,6 +22,16 @@ class ModelListParams(TypedDict, total=False):
hide_experimental: bool
"""Filter to hide experimental models"""
+ include_deprecated: bool
+ """
+ If true, include models whose planned_deprecation_date is in the past — but only
+ within a three-month grace window after that date. Models whose
+ planned_deprecation_date is more than three months in the past remain hidden
+ regardless of this flag. Future planned-deprecation dates are always included
+ regardless of this flag. Defaults to false, preserving the existing behavior of
+ hiding all past-dated deprecations.
+ """
+
page: int
per_page: int
diff --git a/src/cloudflare/types/ai_gateway/log_delete_params.py b/src/cloudflare/types/ai_gateway/log_delete_params.py
index 2aa8a530b71..fa42000fc92 100644
--- a/src/cloudflare/types/ai_gateway/log_delete_params.py
+++ b/src/cloudflare/types/ai_gateway/log_delete_params.py
@@ -60,6 +60,7 @@ class Filter(TypedDict, total=False):
"wholesale",
"compatibilityMode",
"dlp_action",
+ "user_agent",
]
]
diff --git a/src/cloudflare/types/ai_gateway/log_list_params.py b/src/cloudflare/types/ai_gateway/log_list_params.py
index b20feb3ae78..0eeed5259c2 100644
--- a/src/cloudflare/types/ai_gateway/log_list_params.py
+++ b/src/cloudflare/types/ai_gateway/log_list_params.py
@@ -98,6 +98,7 @@ class Filter(TypedDict, total=False):
"wholesale",
"compatibilityMode",
"dlp_action",
+ "user_agent",
]
]
diff --git a/src/cloudflare/types/ai_gateway/provider_config_create_params.py b/src/cloudflare/types/ai_gateway/provider_config_create_params.py
index fecfe448bcb..76c75003e2f 100644
--- a/src/cloudflare/types/ai_gateway/provider_config_create_params.py
+++ b/src/cloudflare/types/ai_gateway/provider_config_create_params.py
@@ -16,10 +16,10 @@ class ProviderConfigCreateParams(TypedDict, total=False):
provider_slug: Required[str]
- secret: Required[str]
-
- secret_id: Required[str]
-
rate_limit: float
rate_limit_period: float
+
+ secret: str
+
+ secret_id: str
diff --git a/src/cloudflare/types/d1/__init__.py b/src/cloudflare/types/d1/__init__.py
index fcfb2c53a47..1d5002ba295 100644
--- a/src/cloudflare/types/d1/__init__.py
+++ b/src/cloudflare/types/d1/__init__.py
@@ -4,6 +4,7 @@
from .d1 import D1 as D1
from .query_result import QueryResult as QueryResult
+from .database_get_params import DatabaseGetParams as DatabaseGetParams
from .database_raw_params import DatabaseRawParams as DatabaseRawParams
from .database_edit_params import DatabaseEditParams as DatabaseEditParams
from .database_list_params import DatabaseListParams as DatabaseListParams
diff --git a/src/cloudflare/types/d1/database_get_params.py b/src/cloudflare/types/d1/database_get_params.py
new file mode 100644
index 00000000000..67ebf979734
--- /dev/null
+++ b/src/cloudflare/types/d1/database_get_params.py
@@ -0,0 +1,31 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import List
+from typing_extensions import Literal, Required, TypedDict
+
+__all__ = ["DatabaseGetParams"]
+
+
+class DatabaseGetParams(TypedDict, total=False):
+ account_id: Required[str]
+ """Account identifier tag."""
+
+ fields: List[
+ Literal[
+ "uuid",
+ "name",
+ "created_at",
+ "version",
+ "jurisdiction",
+ "num_tables",
+ "file_size",
+ "running_in_region",
+ "read_replication",
+ ]
+ ]
+ """Comma-separated list of fields to include in the response.
+
+ When omitted, all fields are returned.
+ """
diff --git a/src/cloudflare/types/email_sending/email_sending_send_params.py b/src/cloudflare/types/email_sending/email_sending_send_params.py
index bcbf2c2decc..8c873cce304 100644
--- a/src/cloudflare/types/email_sending/email_sending_send_params.py
+++ b/src/cloudflare/types/email_sending/email_sending_send_params.py
@@ -30,9 +30,6 @@ class EmailSendingSendParams(TypedDict, total=False):
subject: Required[str]
"""Email subject line."""
- to: Required[Union[str, SequenceNotStr[str]]]
- """Recipient(s). A single email string or an array of email strings."""
-
attachments: Iterable[Attachment]
"""File attachments and inline images."""
@@ -60,6 +57,13 @@ class EmailSendingSendParams(TypedDict, total=False):
At least one of text or html must be provided (non-empty).
"""
+ to: Union[str, SequenceNotStr[str]]
+ """Recipient(s).
+
+ Optional if cc or bcc is provided. A single email string or an array of email
+ strings.
+ """
+
class FromEmailSendingEmailAddressObject(TypedDict, total=False):
address: Required[str]
diff --git a/src/cloudflare/types/email_sending/email_sending_send_raw_response.py b/src/cloudflare/types/email_sending/email_sending_send_raw_response.py
index df569aa94ca..6bf17fb7f17 100644
--- a/src/cloudflare/types/email_sending/email_sending_send_raw_response.py
+++ b/src/cloudflare/types/email_sending/email_sending_send_raw_response.py
@@ -11,6 +11,9 @@ class EmailSendingSendRawResponse(BaseModel):
delivered: List[str]
"""Email addresses to which the message was delivered immediately."""
+ message_id: str
+ """Message ID of the sent email."""
+
permanent_bounces: List[str]
"""Email addresses that permanently bounced."""
diff --git a/src/cloudflare/types/email_sending/email_sending_send_response.py b/src/cloudflare/types/email_sending/email_sending_send_response.py
index f7b6e7776e7..3f86e3d16a8 100644
--- a/src/cloudflare/types/email_sending/email_sending_send_response.py
+++ b/src/cloudflare/types/email_sending/email_sending_send_response.py
@@ -11,6 +11,9 @@ class EmailSendingSendResponse(BaseModel):
delivered: List[str]
"""Email addresses to which the message was delivered immediately."""
+ message_id: str
+ """Message ID of the sent email."""
+
permanent_bounces: List[str]
"""Email addresses that permanently bounced."""
diff --git a/src/cloudflare/types/flagship/__init__.py b/src/cloudflare/types/flagship/__init__.py
new file mode 100644
index 00000000000..6038866274f
--- /dev/null
+++ b/src/cloudflare/types/flagship/__init__.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .app_get_response import AppGetResponse as AppGetResponse
+from .app_create_params import AppCreateParams as AppCreateParams
+from .app_list_response import AppListResponse as AppListResponse
+from .app_update_params import AppUpdateParams as AppUpdateParams
+from .app_create_response import AppCreateResponse as AppCreateResponse
+from .app_delete_response import AppDeleteResponse as AppDeleteResponse
+from .app_update_response import AppUpdateResponse as AppUpdateResponse
diff --git a/src/cloudflare/types/flagship/app_create_params.py b/src/cloudflare/types/flagship/app_create_params.py
new file mode 100644
index 00000000000..266e8d4c3b1
--- /dev/null
+++ b/src/cloudflare/types/flagship/app_create_params.py
@@ -0,0 +1,14 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["AppCreateParams"]
+
+
+class AppCreateParams(TypedDict, total=False):
+ account_id: Required[str]
+ """Cloudflare account ID."""
+
+ name: Required[str]
diff --git a/src/cloudflare/types/flagship/app_create_response.py b/src/cloudflare/types/flagship/app_create_response.py
new file mode 100644
index 00000000000..23a750af5eb
--- /dev/null
+++ b/src/cloudflare/types/flagship/app_create_response.py
@@ -0,0 +1,21 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from ..._models import BaseModel
+
+__all__ = ["AppCreateResponse"]
+
+
+class AppCreateResponse(BaseModel):
+ id: str
+
+ created_at: str
+
+ name: str
+
+ updated_at: str
+
+ updated_by: str
+ """
+ Email of the actor who last modified the app, or `edge-gateway` for
+ gateway-authenticated changes.
+ """
diff --git a/src/cloudflare/types/flagship/app_delete_response.py b/src/cloudflare/types/flagship/app_delete_response.py
new file mode 100644
index 00000000000..3f99ac0d9eb
--- /dev/null
+++ b/src/cloudflare/types/flagship/app_delete_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from ..._models import BaseModel
+
+__all__ = ["AppDeleteResponse"]
+
+
+class AppDeleteResponse(BaseModel):
+ id: str
diff --git a/src/cloudflare/types/flagship/app_get_response.py b/src/cloudflare/types/flagship/app_get_response.py
new file mode 100644
index 00000000000..58532d83a4d
--- /dev/null
+++ b/src/cloudflare/types/flagship/app_get_response.py
@@ -0,0 +1,21 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from ..._models import BaseModel
+
+__all__ = ["AppGetResponse"]
+
+
+class AppGetResponse(BaseModel):
+ id: str
+
+ created_at: str
+
+ name: str
+
+ updated_at: str
+
+ updated_by: str
+ """
+ Email of the actor who last modified the app, or `edge-gateway` for
+ gateway-authenticated changes.
+ """
diff --git a/src/cloudflare/types/flagship/app_list_response.py b/src/cloudflare/types/flagship/app_list_response.py
new file mode 100644
index 00000000000..2b3b464e8bf
--- /dev/null
+++ b/src/cloudflare/types/flagship/app_list_response.py
@@ -0,0 +1,21 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from ..._models import BaseModel
+
+__all__ = ["AppListResponse"]
+
+
+class AppListResponse(BaseModel):
+ id: str
+
+ created_at: str
+
+ name: str
+
+ updated_at: str
+
+ updated_by: str
+ """
+ Email of the actor who last modified the app, or `edge-gateway` for
+ gateway-authenticated changes.
+ """
diff --git a/src/cloudflare/types/flagship/app_update_params.py b/src/cloudflare/types/flagship/app_update_params.py
new file mode 100644
index 00000000000..b364f3c1c11
--- /dev/null
+++ b/src/cloudflare/types/flagship/app_update_params.py
@@ -0,0 +1,14 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["AppUpdateParams"]
+
+
+class AppUpdateParams(TypedDict, total=False):
+ account_id: Required[str]
+ """Cloudflare account ID."""
+
+ name: str
diff --git a/src/cloudflare/types/flagship/app_update_response.py b/src/cloudflare/types/flagship/app_update_response.py
new file mode 100644
index 00000000000..1902f9b1235
--- /dev/null
+++ b/src/cloudflare/types/flagship/app_update_response.py
@@ -0,0 +1,21 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from ..._models import BaseModel
+
+__all__ = ["AppUpdateResponse"]
+
+
+class AppUpdateResponse(BaseModel):
+ id: str
+
+ created_at: str
+
+ name: str
+
+ updated_at: str
+
+ updated_by: str
+ """
+ Email of the actor who last modified the app, or `edge-gateway` for
+ gateway-authenticated changes.
+ """
diff --git a/src/cloudflare/types/flagship/apps/__init__.py b/src/cloudflare/types/flagship/apps/__init__.py
new file mode 100644
index 00000000000..4c134d33630
--- /dev/null
+++ b/src/cloudflare/types/flagship/apps/__init__.py
@@ -0,0 +1,14 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .flag_list_params import FlagListParams as FlagListParams
+from .flag_get_response import FlagGetResponse as FlagGetResponse
+from .flag_create_params import FlagCreateParams as FlagCreateParams
+from .flag_list_response import FlagListResponse as FlagListResponse
+from .flag_update_params import FlagUpdateParams as FlagUpdateParams
+from .evaluate_get_params import EvaluateGetParams as EvaluateGetParams
+from .flag_create_response import FlagCreateResponse as FlagCreateResponse
+from .flag_delete_response import FlagDeleteResponse as FlagDeleteResponse
+from .flag_update_response import FlagUpdateResponse as FlagUpdateResponse
+from .evaluate_get_response import EvaluateGetResponse as EvaluateGetResponse
diff --git a/src/cloudflare/types/flagship/apps/evaluate_get_params.py b/src/cloudflare/types/flagship/apps/evaluate_get_params.py
new file mode 100644
index 00000000000..1f1fd3e4fc6
--- /dev/null
+++ b/src/cloudflare/types/flagship/apps/evaluate_get_params.py
@@ -0,0 +1,23 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, Annotated, TypedDict
+
+from ...._utils import PropertyInfo
+
+__all__ = ["EvaluateGetParams"]
+
+
+class EvaluateGetParams(TypedDict, total=False):
+ account_id: Required[str]
+ """Cloudflare account ID."""
+
+ flag_key: Required[Annotated[str, PropertyInfo(alias="flagKey")]]
+ """The flag key to evaluate."""
+
+ targeting_key: Annotated[str, PropertyInfo(alias="targetingKey")]
+ """
+ Context targeting key (per OpenFeature spec); used for percentage rollout
+ bucketing.
+ """
diff --git a/src/cloudflare/types/flagship/apps/evaluate_get_response.py b/src/cloudflare/types/flagship/apps/evaluate_get_response.py
new file mode 100644
index 00000000000..899d6ed5a60
--- /dev/null
+++ b/src/cloudflare/types/flagship/apps/evaluate_get_response.py
@@ -0,0 +1,20 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict, List, Union, Optional
+from typing_extensions import Literal
+
+from pydantic import Field as FieldInfo
+
+from ...._models import BaseModel
+
+__all__ = ["EvaluateGetResponse"]
+
+
+class EvaluateGetResponse(BaseModel):
+ flag_key: str = FieldInfo(alias="flagKey")
+
+ reason: Literal["TARGETING_MATCH", "DEFAULT", "DISABLED", "SPLIT"]
+
+ variant: str
+
+ value: Union[Optional[str], float, bool, Dict[str, object], List[object], None] = None
diff --git a/src/cloudflare/types/flagship/apps/flag_create_params.py b/src/cloudflare/types/flagship/apps/flag_create_params.py
new file mode 100644
index 00000000000..48a200f4366
--- /dev/null
+++ b/src/cloudflare/types/flagship/apps/flag_create_params.py
@@ -0,0 +1,350 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Dict, Union, Iterable, Optional
+from typing_extensions import Literal, Required, TypeAlias, TypedDict
+
+from ...._types import SequenceNotStr
+
+__all__ = [
+ "FlagCreateParams",
+ "Rule",
+ "RuleCondition",
+ "RuleConditionUnionMember0",
+ "RuleConditionUnionMember1",
+ "RuleConditionUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1",
+ "RuleConditionUnionMember1ClauseUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "RuleRollout",
+]
+
+
+class FlagCreateParams(TypedDict, total=False):
+ account_id: Required[str]
+ """Cloudflare account ID."""
+
+ default_variation: Required[str]
+ """Variation served when no rule matches or the flag is disabled.
+
+ Must be a key in `variations`.
+ """
+
+ enabled: Required[bool]
+ """When false, the flag bypasses all rules and always serves `default_variation`."""
+
+ key: Required[str]
+ """Unique identifier for the flag within an app.
+
+ Used in all evaluation and SDK calls.
+ """
+
+ rules: Required[Iterable[Rule]]
+ """Targeting rules evaluated in ascending `priority`; the first matching rule wins.
+
+ An empty array means the flag always serves `default_variation`.
+ """
+
+ variations: Required[Dict[str, Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]]]
+ """Map of variation name to value.
+
+ All values must be the same type (boolean, string, number, or JSON
+ object/array). Each serialized value must be 10KB or smaller.
+ """
+
+ description: Optional[str]
+
+ type: Literal["boolean", "string", "number", "json"]
+ """Value type of the flag's variations.
+
+ Inferred from the variation values on write, so it may be omitted in requests.
+ """
+
+
+class RuleConditionUnionMember0(TypedDict, total=False):
+ attribute: Required[str]
+
+ operator: Required[
+ Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+ ]
+
+ value: Required[object]
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember0(TypedDict, total=False):
+ attribute: Required[str]
+
+ operator: Required[
+ Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+ ]
+
+ value: Required[object]
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0(TypedDict, total=False):
+ attribute: Required[str]
+
+ operator: Required[
+ Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+ ]
+
+ value: Required[object]
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(TypedDict, total=False):
+ attribute: Required[str]
+
+ operator: Required[
+ Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+ ]
+
+ value: Required[object]
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(
+ TypedDict, total=False
+):
+ attribute: Required[str]
+
+ operator: Required[
+ Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+ ]
+
+ value: Required[object]
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(
+ TypedDict, total=False
+):
+ attribute: Required[str]
+
+ operator: Required[
+ Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+ ]
+
+ value: Required[object]
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(
+ TypedDict, total=False
+):
+ clauses: Required[SequenceNotStr[Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]]]
+
+ logical_operator: Required[Literal["AND", "OR"]]
+
+
+RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(
+ TypedDict, total=False
+):
+ clauses: Required[
+ Iterable[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause
+ ]
+ ]
+
+ logical_operator: Required[Literal["AND", "OR"]]
+
+
+RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(TypedDict, total=False):
+ clauses: Required[Iterable[RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause]]
+
+ logical_operator: Required[Literal["AND", "OR"]]
+
+
+RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1(TypedDict, total=False):
+ clauses: Required[Iterable[RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause]]
+
+ logical_operator: Required[Literal["AND", "OR"]]
+
+
+RuleConditionUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class RuleConditionUnionMember1ClauseUnionMember1(TypedDict, total=False):
+ clauses: Required[Iterable[RuleConditionUnionMember1ClauseUnionMember1Clause]]
+
+ logical_operator: Required[Literal["AND", "OR"]]
+
+
+RuleConditionUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember0, RuleConditionUnionMember1ClauseUnionMember1
+]
+
+
+class RuleConditionUnionMember1(TypedDict, total=False):
+ clauses: Required[Iterable[RuleConditionUnionMember1Clause]]
+
+ logical_operator: Required[Literal["AND", "OR"]]
+
+
+RuleCondition: TypeAlias = Union[RuleConditionUnionMember0, RuleConditionUnionMember1]
+
+
+class RuleRollout(TypedDict, total=False):
+ percentage: Required[float]
+ """Percentage of matching traffic (0–100) served this variation.
+
+ For multi-way splits, use cumulative upper bounds across rules (e.g. 30, 70,
+ 100).
+ """
+
+ attribute: str
+ """Context attribute used for sticky bucketing.
+
+ Defaults to `targetingKey`. If absent at evaluation time, bucketing is random
+ per request.
+ """
+
+
+class Rule(TypedDict, total=False):
+ conditions: Required[Iterable[RuleCondition]]
+ """Conditions the context must satisfy for this rule to match.
+
+ An empty array matches all contexts.
+ """
+
+ priority: Required[int]
+ """Evaluation order; lower numbers are evaluated first.
+
+ Must be unique across the flag's rules.
+ """
+
+ serve_variation: Required[str]
+ """Variation served when this rule matches. Must be a key in `variations`."""
+
+ rollout: RuleRollout
diff --git a/src/cloudflare/types/flagship/apps/flag_create_response.py b/src/cloudflare/types/flagship/apps/flag_create_response.py
new file mode 100644
index 00000000000..ea5206d0713
--- /dev/null
+++ b/src/cloudflare/types/flagship/apps/flag_create_response.py
@@ -0,0 +1,331 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict, List, Union, Optional
+from typing_extensions import Literal, TypeAlias
+
+from ...._models import BaseModel
+
+__all__ = [
+ "FlagCreateResponse",
+ "Rule",
+ "RuleCondition",
+ "RuleConditionUnionMember0",
+ "RuleConditionUnionMember1",
+ "RuleConditionUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1",
+ "RuleConditionUnionMember1ClauseUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "RuleRollout",
+]
+
+
+class RuleConditionUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(
+ BaseModel
+):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(
+ BaseModel
+):
+ clauses: List[Union[Optional[str], float, bool, Dict[str, object], List[object]]]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause
+ ]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+RuleConditionUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class RuleConditionUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[RuleConditionUnionMember1ClauseUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+RuleConditionUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember0, RuleConditionUnionMember1ClauseUnionMember1
+]
+
+
+class RuleConditionUnionMember1(BaseModel):
+ clauses: List[RuleConditionUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+RuleCondition: TypeAlias = Union[RuleConditionUnionMember0, RuleConditionUnionMember1]
+
+
+class RuleRollout(BaseModel):
+ percentage: float
+ """Percentage of matching traffic (0–100) served this variation.
+
+ For multi-way splits, use cumulative upper bounds across rules (e.g. 30, 70,
+ 100).
+ """
+
+ attribute: Optional[str] = None
+ """Context attribute used for sticky bucketing.
+
+ Defaults to `targetingKey`. If absent at evaluation time, bucketing is random
+ per request.
+ """
+
+
+class Rule(BaseModel):
+ conditions: List[RuleCondition]
+ """Conditions the context must satisfy for this rule to match.
+
+ An empty array matches all contexts.
+ """
+
+ priority: int
+ """Evaluation order; lower numbers are evaluated first.
+
+ Must be unique across the flag's rules.
+ """
+
+ serve_variation: str
+ """Variation served when this rule matches. Must be a key in `variations`."""
+
+ rollout: Optional[RuleRollout] = None
+
+
+class FlagCreateResponse(BaseModel):
+ default_variation: str
+ """Variation served when no rule matches or the flag is disabled.
+
+ Must be a key in `variations`.
+ """
+
+ enabled: bool
+ """When false, the flag bypasses all rules and always serves `default_variation`."""
+
+ key: str
+ """Unique identifier for the flag within an app.
+
+ Used in all evaluation and SDK calls.
+ """
+
+ rules: List[Rule]
+ """Targeting rules evaluated in ascending `priority`; the first matching rule wins.
+
+ An empty array means the flag always serves `default_variation`.
+ """
+
+ variations: Dict[str, Union[Optional[str], float, bool, Dict[str, object], List[object]]]
+ """Map of variation name to value.
+
+ All values must be the same type (boolean, string, number, or JSON
+ object/array). Each serialized value must be 10KB or smaller.
+ """
+
+ description: Optional[str] = None
+
+ type: Optional[Literal["boolean", "string", "number", "json"]] = None
+ """Value type of the flag's variations.
+
+ Inferred from the variation values on write, so it may be omitted in requests.
+ """
+
+ updated_at: Optional[str] = None
+
+ updated_by: Optional[str] = None
diff --git a/src/cloudflare/types/flagship/apps/flag_delete_response.py b/src/cloudflare/types/flagship/apps/flag_delete_response.py
new file mode 100644
index 00000000000..c6d62095ed4
--- /dev/null
+++ b/src/cloudflare/types/flagship/apps/flag_delete_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from ...._models import BaseModel
+
+__all__ = ["FlagDeleteResponse"]
+
+
+class FlagDeleteResponse(BaseModel):
+ key: str
diff --git a/src/cloudflare/types/flagship/apps/flag_get_response.py b/src/cloudflare/types/flagship/apps/flag_get_response.py
new file mode 100644
index 00000000000..b565ecd5679
--- /dev/null
+++ b/src/cloudflare/types/flagship/apps/flag_get_response.py
@@ -0,0 +1,331 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict, List, Union, Optional
+from typing_extensions import Literal, TypeAlias
+
+from ...._models import BaseModel
+
+__all__ = [
+ "FlagGetResponse",
+ "Rule",
+ "RuleCondition",
+ "RuleConditionUnionMember0",
+ "RuleConditionUnionMember1",
+ "RuleConditionUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1",
+ "RuleConditionUnionMember1ClauseUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "RuleRollout",
+]
+
+
+class RuleConditionUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(
+ BaseModel
+):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(
+ BaseModel
+):
+ clauses: List[Union[Optional[str], float, bool, Dict[str, object], List[object]]]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause
+ ]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+RuleConditionUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class RuleConditionUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[RuleConditionUnionMember1ClauseUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+RuleConditionUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember0, RuleConditionUnionMember1ClauseUnionMember1
+]
+
+
+class RuleConditionUnionMember1(BaseModel):
+ clauses: List[RuleConditionUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+RuleCondition: TypeAlias = Union[RuleConditionUnionMember0, RuleConditionUnionMember1]
+
+
+class RuleRollout(BaseModel):
+ percentage: float
+ """Percentage of matching traffic (0–100) served this variation.
+
+ For multi-way splits, use cumulative upper bounds across rules (e.g. 30, 70,
+ 100).
+ """
+
+ attribute: Optional[str] = None
+ """Context attribute used for sticky bucketing.
+
+ Defaults to `targetingKey`. If absent at evaluation time, bucketing is random
+ per request.
+ """
+
+
+class Rule(BaseModel):
+ conditions: List[RuleCondition]
+ """Conditions the context must satisfy for this rule to match.
+
+ An empty array matches all contexts.
+ """
+
+ priority: int
+ """Evaluation order; lower numbers are evaluated first.
+
+ Must be unique across the flag's rules.
+ """
+
+ serve_variation: str
+ """Variation served when this rule matches. Must be a key in `variations`."""
+
+ rollout: Optional[RuleRollout] = None
+
+
+class FlagGetResponse(BaseModel):
+ default_variation: str
+ """Variation served when no rule matches or the flag is disabled.
+
+ Must be a key in `variations`.
+ """
+
+ enabled: bool
+ """When false, the flag bypasses all rules and always serves `default_variation`."""
+
+ key: str
+ """Unique identifier for the flag within an app.
+
+ Used in all evaluation and SDK calls.
+ """
+
+ rules: List[Rule]
+ """Targeting rules evaluated in ascending `priority`; the first matching rule wins.
+
+ An empty array means the flag always serves `default_variation`.
+ """
+
+ variations: Dict[str, Union[Optional[str], float, bool, Dict[str, object], List[object]]]
+ """Map of variation name to value.
+
+ All values must be the same type (boolean, string, number, or JSON
+ object/array). Each serialized value must be 10KB or smaller.
+ """
+
+ description: Optional[str] = None
+
+ type: Optional[Literal["boolean", "string", "number", "json"]] = None
+ """Value type of the flag's variations.
+
+ Inferred from the variation values on write, so it may be omitted in requests.
+ """
+
+ updated_at: Optional[str] = None
+
+ updated_by: Optional[str] = None
diff --git a/src/cloudflare/types/flagship/apps/flag_list_params.py b/src/cloudflare/types/flagship/apps/flag_list_params.py
new file mode 100644
index 00000000000..f307117dc80
--- /dev/null
+++ b/src/cloudflare/types/flagship/apps/flag_list_params.py
@@ -0,0 +1,18 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["FlagListParams"]
+
+
+class FlagListParams(TypedDict, total=False):
+ account_id: Required[str]
+ """Cloudflare account ID."""
+
+ cursor: str
+ """Pagination cursor from a previous response."""
+
+ limit: str
+ """Max items to return (1–200)."""
diff --git a/src/cloudflare/types/flagship/apps/flag_list_response.py b/src/cloudflare/types/flagship/apps/flag_list_response.py
new file mode 100644
index 00000000000..4ccd80cb150
--- /dev/null
+++ b/src/cloudflare/types/flagship/apps/flag_list_response.py
@@ -0,0 +1,331 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict, List, Union, Optional
+from typing_extensions import Literal, TypeAlias
+
+from ...._models import BaseModel
+
+__all__ = [
+ "FlagListResponse",
+ "Rule",
+ "RuleCondition",
+ "RuleConditionUnionMember0",
+ "RuleConditionUnionMember1",
+ "RuleConditionUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1",
+ "RuleConditionUnionMember1ClauseUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "RuleRollout",
+]
+
+
+class RuleConditionUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(
+ BaseModel
+):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(
+ BaseModel
+):
+ clauses: List[Union[Optional[str], float, bool, Dict[str, object], List[object]]]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause
+ ]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+RuleConditionUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class RuleConditionUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[RuleConditionUnionMember1ClauseUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+RuleConditionUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember0, RuleConditionUnionMember1ClauseUnionMember1
+]
+
+
+class RuleConditionUnionMember1(BaseModel):
+ clauses: List[RuleConditionUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+RuleCondition: TypeAlias = Union[RuleConditionUnionMember0, RuleConditionUnionMember1]
+
+
+class RuleRollout(BaseModel):
+ percentage: float
+ """Percentage of matching traffic (0–100) served this variation.
+
+ For multi-way splits, use cumulative upper bounds across rules (e.g. 30, 70,
+ 100).
+ """
+
+ attribute: Optional[str] = None
+ """Context attribute used for sticky bucketing.
+
+ Defaults to `targetingKey`. If absent at evaluation time, bucketing is random
+ per request.
+ """
+
+
+class Rule(BaseModel):
+ conditions: List[RuleCondition]
+ """Conditions the context must satisfy for this rule to match.
+
+ An empty array matches all contexts.
+ """
+
+ priority: int
+ """Evaluation order; lower numbers are evaluated first.
+
+ Must be unique across the flag's rules.
+ """
+
+ serve_variation: str
+ """Variation served when this rule matches. Must be a key in `variations`."""
+
+ rollout: Optional[RuleRollout] = None
+
+
+class FlagListResponse(BaseModel):
+ default_variation: str
+ """Variation served when no rule matches or the flag is disabled.
+
+ Must be a key in `variations`.
+ """
+
+ enabled: bool
+ """When false, the flag bypasses all rules and always serves `default_variation`."""
+
+ key: str
+ """Unique identifier for the flag within an app.
+
+ Used in all evaluation and SDK calls.
+ """
+
+ rules: List[Rule]
+ """Targeting rules evaluated in ascending `priority`; the first matching rule wins.
+
+ An empty array means the flag always serves `default_variation`.
+ """
+
+ variations: Dict[str, Union[Optional[str], float, bool, Dict[str, object], List[object]]]
+ """Map of variation name to value.
+
+ All values must be the same type (boolean, string, number, or JSON
+ object/array). Each serialized value must be 10KB or smaller.
+ """
+
+ description: Optional[str] = None
+
+ type: Optional[Literal["boolean", "string", "number", "json"]] = None
+ """Value type of the flag's variations.
+
+ Inferred from the variation values on write, so it may be omitted in requests.
+ """
+
+ updated_at: Optional[str] = None
+
+ updated_by: Optional[str] = None
diff --git a/src/cloudflare/types/flagship/apps/flag_update_params.py b/src/cloudflare/types/flagship/apps/flag_update_params.py
new file mode 100644
index 00000000000..542774c48b4
--- /dev/null
+++ b/src/cloudflare/types/flagship/apps/flag_update_params.py
@@ -0,0 +1,353 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Dict, Union, Iterable, Optional
+from typing_extensions import Literal, Required, TypeAlias, TypedDict
+
+from ...._types import SequenceNotStr
+
+__all__ = [
+ "FlagUpdateParams",
+ "Rule",
+ "RuleCondition",
+ "RuleConditionUnionMember0",
+ "RuleConditionUnionMember1",
+ "RuleConditionUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1",
+ "RuleConditionUnionMember1ClauseUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "RuleRollout",
+]
+
+
+class FlagUpdateParams(TypedDict, total=False):
+ account_id: Required[str]
+ """Cloudflare account ID."""
+
+ app_id: Required[str]
+ """App identifier."""
+
+ default_variation: Required[str]
+ """Variation served when no rule matches or the flag is disabled.
+
+ Must be a key in `variations`.
+ """
+
+ enabled: Required[bool]
+ """When false, the flag bypasses all rules and always serves `default_variation`."""
+
+ key: Required[str]
+ """Unique identifier for the flag within an app.
+
+ Used in all evaluation and SDK calls.
+ """
+
+ rules: Required[Iterable[Rule]]
+ """Targeting rules evaluated in ascending `priority`; the first matching rule wins.
+
+ An empty array means the flag always serves `default_variation`.
+ """
+
+ variations: Required[Dict[str, Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]]]
+ """Map of variation name to value.
+
+ All values must be the same type (boolean, string, number, or JSON
+ object/array). Each serialized value must be 10KB or smaller.
+ """
+
+ description: Optional[str]
+
+ type: Literal["boolean", "string", "number", "json"]
+ """Value type of the flag's variations.
+
+ Inferred from the variation values on write, so it may be omitted in requests.
+ """
+
+
+class RuleConditionUnionMember0(TypedDict, total=False):
+ attribute: Required[str]
+
+ operator: Required[
+ Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+ ]
+
+ value: Required[object]
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember0(TypedDict, total=False):
+ attribute: Required[str]
+
+ operator: Required[
+ Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+ ]
+
+ value: Required[object]
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0(TypedDict, total=False):
+ attribute: Required[str]
+
+ operator: Required[
+ Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+ ]
+
+ value: Required[object]
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(TypedDict, total=False):
+ attribute: Required[str]
+
+ operator: Required[
+ Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+ ]
+
+ value: Required[object]
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(
+ TypedDict, total=False
+):
+ attribute: Required[str]
+
+ operator: Required[
+ Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+ ]
+
+ value: Required[object]
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(
+ TypedDict, total=False
+):
+ attribute: Required[str]
+
+ operator: Required[
+ Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+ ]
+
+ value: Required[object]
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(
+ TypedDict, total=False
+):
+ clauses: Required[SequenceNotStr[Union[Optional[str], float, bool, Dict[str, object], Iterable[object]]]]
+
+ logical_operator: Required[Literal["AND", "OR"]]
+
+
+RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(
+ TypedDict, total=False
+):
+ clauses: Required[
+ Iterable[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause
+ ]
+ ]
+
+ logical_operator: Required[Literal["AND", "OR"]]
+
+
+RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(TypedDict, total=False):
+ clauses: Required[Iterable[RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause]]
+
+ logical_operator: Required[Literal["AND", "OR"]]
+
+
+RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1(TypedDict, total=False):
+ clauses: Required[Iterable[RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause]]
+
+ logical_operator: Required[Literal["AND", "OR"]]
+
+
+RuleConditionUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class RuleConditionUnionMember1ClauseUnionMember1(TypedDict, total=False):
+ clauses: Required[Iterable[RuleConditionUnionMember1ClauseUnionMember1Clause]]
+
+ logical_operator: Required[Literal["AND", "OR"]]
+
+
+RuleConditionUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember0, RuleConditionUnionMember1ClauseUnionMember1
+]
+
+
+class RuleConditionUnionMember1(TypedDict, total=False):
+ clauses: Required[Iterable[RuleConditionUnionMember1Clause]]
+
+ logical_operator: Required[Literal["AND", "OR"]]
+
+
+RuleCondition: TypeAlias = Union[RuleConditionUnionMember0, RuleConditionUnionMember1]
+
+
+class RuleRollout(TypedDict, total=False):
+ percentage: Required[float]
+ """Percentage of matching traffic (0–100) served this variation.
+
+ For multi-way splits, use cumulative upper bounds across rules (e.g. 30, 70,
+ 100).
+ """
+
+ attribute: str
+ """Context attribute used for sticky bucketing.
+
+ Defaults to `targetingKey`. If absent at evaluation time, bucketing is random
+ per request.
+ """
+
+
+class Rule(TypedDict, total=False):
+ conditions: Required[Iterable[RuleCondition]]
+ """Conditions the context must satisfy for this rule to match.
+
+ An empty array matches all contexts.
+ """
+
+ priority: Required[int]
+ """Evaluation order; lower numbers are evaluated first.
+
+ Must be unique across the flag's rules.
+ """
+
+ serve_variation: Required[str]
+ """Variation served when this rule matches. Must be a key in `variations`."""
+
+ rollout: RuleRollout
diff --git a/src/cloudflare/types/flagship/apps/flag_update_response.py b/src/cloudflare/types/flagship/apps/flag_update_response.py
new file mode 100644
index 00000000000..38a85df3414
--- /dev/null
+++ b/src/cloudflare/types/flagship/apps/flag_update_response.py
@@ -0,0 +1,331 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict, List, Union, Optional
+from typing_extensions import Literal, TypeAlias
+
+from ...._models import BaseModel
+
+__all__ = [
+ "FlagUpdateResponse",
+ "Rule",
+ "RuleCondition",
+ "RuleConditionUnionMember0",
+ "RuleConditionUnionMember1",
+ "RuleConditionUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1",
+ "RuleConditionUnionMember1ClauseUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "RuleRollout",
+]
+
+
+class RuleConditionUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(
+ BaseModel
+):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(
+ BaseModel
+):
+ clauses: List[Union[Optional[str], float, bool, Dict[str, object], List[object]]]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause
+ ]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+RuleConditionUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ RuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class RuleConditionUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[RuleConditionUnionMember1ClauseUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+RuleConditionUnionMember1Clause: TypeAlias = Union[
+ RuleConditionUnionMember1ClauseUnionMember0, RuleConditionUnionMember1ClauseUnionMember1
+]
+
+
+class RuleConditionUnionMember1(BaseModel):
+ clauses: List[RuleConditionUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+RuleCondition: TypeAlias = Union[RuleConditionUnionMember0, RuleConditionUnionMember1]
+
+
+class RuleRollout(BaseModel):
+ percentage: float
+ """Percentage of matching traffic (0–100) served this variation.
+
+ For multi-way splits, use cumulative upper bounds across rules (e.g. 30, 70,
+ 100).
+ """
+
+ attribute: Optional[str] = None
+ """Context attribute used for sticky bucketing.
+
+ Defaults to `targetingKey`. If absent at evaluation time, bucketing is random
+ per request.
+ """
+
+
+class Rule(BaseModel):
+ conditions: List[RuleCondition]
+ """Conditions the context must satisfy for this rule to match.
+
+ An empty array matches all contexts.
+ """
+
+ priority: int
+ """Evaluation order; lower numbers are evaluated first.
+
+ Must be unique across the flag's rules.
+ """
+
+ serve_variation: str
+ """Variation served when this rule matches. Must be a key in `variations`."""
+
+ rollout: Optional[RuleRollout] = None
+
+
+class FlagUpdateResponse(BaseModel):
+ default_variation: str
+ """Variation served when no rule matches or the flag is disabled.
+
+ Must be a key in `variations`.
+ """
+
+ enabled: bool
+ """When false, the flag bypasses all rules and always serves `default_variation`."""
+
+ key: str
+ """Unique identifier for the flag within an app.
+
+ Used in all evaluation and SDK calls.
+ """
+
+ rules: List[Rule]
+ """Targeting rules evaluated in ascending `priority`; the first matching rule wins.
+
+ An empty array means the flag always serves `default_variation`.
+ """
+
+ variations: Dict[str, Union[Optional[str], float, bool, Dict[str, object], List[object]]]
+ """Map of variation name to value.
+
+ All values must be the same type (boolean, string, number, or JSON
+ object/array). Each serialized value must be 10KB or smaller.
+ """
+
+ description: Optional[str] = None
+
+ type: Optional[Literal["boolean", "string", "number", "json"]] = None
+ """Value type of the flag's variations.
+
+ Inferred from the variation values on write, so it may be omitted in requests.
+ """
+
+ updated_at: Optional[str] = None
+
+ updated_by: Optional[str] = None
diff --git a/src/cloudflare/types/flagship/apps/flags/__init__.py b/src/cloudflare/types/flagship/apps/flags/__init__.py
new file mode 100644
index 00000000000..e702f44c894
--- /dev/null
+++ b/src/cloudflare/types/flagship/apps/flags/__init__.py
@@ -0,0 +1,6 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .changelog_list_params import ChangelogListParams as ChangelogListParams
+from .changelog_list_response import ChangelogListResponse as ChangelogListResponse
diff --git a/src/cloudflare/types/flagship/apps/flags/changelog_list_params.py b/src/cloudflare/types/flagship/apps/flags/changelog_list_params.py
new file mode 100644
index 00000000000..8cb00b1ad1e
--- /dev/null
+++ b/src/cloudflare/types/flagship/apps/flags/changelog_list_params.py
@@ -0,0 +1,21 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["ChangelogListParams"]
+
+
+class ChangelogListParams(TypedDict, total=False):
+ account_id: Required[str]
+ """Cloudflare account ID."""
+
+ app_id: Required[str]
+ """App identifier."""
+
+ cursor: str
+ """Pagination cursor from a previous response."""
+
+ limit: str
+ """Max items to return (1–200)."""
diff --git a/src/cloudflare/types/flagship/apps/flags/changelog_list_response.py b/src/cloudflare/types/flagship/apps/flags/changelog_list_response.py
new file mode 100644
index 00000000000..479007b2d51
--- /dev/null
+++ b/src/cloudflare/types/flagship/apps/flags/changelog_list_response.py
@@ -0,0 +1,1046 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict, List, Union, Optional
+from typing_extensions import Literal, TypeAlias
+
+from pydantic import Field as FieldInfo
+
+from ....._models import BaseModel
+
+__all__ = [
+ "ChangelogListResponse",
+ "UnionMember0",
+ "UnionMember0After",
+ "UnionMember0AfterRule",
+ "UnionMember0AfterRuleCondition",
+ "UnionMember0AfterRuleConditionUnionMember0",
+ "UnionMember0AfterRuleConditionUnionMember1",
+ "UnionMember0AfterRuleConditionUnionMember1Clause",
+ "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember0",
+ "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1",
+ "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1Clause",
+ "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "UnionMember0AfterRuleRollout",
+ "UnionMember1",
+ "UnionMember1After",
+ "UnionMember1AfterRule",
+ "UnionMember1AfterRuleCondition",
+ "UnionMember1AfterRuleConditionUnionMember0",
+ "UnionMember1AfterRuleConditionUnionMember1",
+ "UnionMember1AfterRuleConditionUnionMember1Clause",
+ "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember0",
+ "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1",
+ "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1Clause",
+ "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "UnionMember1AfterRuleRollout",
+ "UnionMember2",
+ "UnionMember2After",
+ "UnionMember2AfterRule",
+ "UnionMember2AfterRuleCondition",
+ "UnionMember2AfterRuleConditionUnionMember0",
+ "UnionMember2AfterRuleConditionUnionMember1",
+ "UnionMember2AfterRuleConditionUnionMember1Clause",
+ "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember0",
+ "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1",
+ "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1Clause",
+ "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause",
+ "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0",
+ "UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1",
+ "UnionMember2AfterRuleRollout",
+ "UnionMember2Diff",
+]
+
+
+class UnionMember0AfterRuleConditionUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(
+ BaseModel
+):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(
+ BaseModel
+):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(
+ BaseModel
+):
+ clauses: List[Union[Optional[str], float, bool, Dict[str, object], List[object]]]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(
+ BaseModel
+):
+ clauses: List[
+ UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause
+ ]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[
+ UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause
+ ]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+UnionMember0AfterRuleConditionUnionMember1Clause: TypeAlias = Union[
+ UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember0,
+ UnionMember0AfterRuleConditionUnionMember1ClauseUnionMember1,
+]
+
+
+class UnionMember0AfterRuleConditionUnionMember1(BaseModel):
+ clauses: List[UnionMember0AfterRuleConditionUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+UnionMember0AfterRuleCondition: TypeAlias = Union[
+ UnionMember0AfterRuleConditionUnionMember0, UnionMember0AfterRuleConditionUnionMember1
+]
+
+
+class UnionMember0AfterRuleRollout(BaseModel):
+ percentage: float
+ """Percentage of matching traffic (0–100) served this variation.
+
+ For multi-way splits, use cumulative upper bounds across rules (e.g. 30, 70,
+ 100).
+ """
+
+ attribute: Optional[str] = None
+ """Context attribute used for sticky bucketing.
+
+ Defaults to `targetingKey`. If absent at evaluation time, bucketing is random
+ per request.
+ """
+
+
+class UnionMember0AfterRule(BaseModel):
+ conditions: List[UnionMember0AfterRuleCondition]
+ """Conditions the context must satisfy for this rule to match.
+
+ An empty array matches all contexts.
+ """
+
+ priority: int
+ """Evaluation order; lower numbers are evaluated first.
+
+ Must be unique across the flag's rules.
+ """
+
+ serve_variation: str
+ """Variation served when this rule matches. Must be a key in `variations`."""
+
+ rollout: Optional[UnionMember0AfterRuleRollout] = None
+
+
+class UnionMember0After(BaseModel):
+ default_variation: str
+ """Variation served when no rule matches or the flag is disabled.
+
+ Must be a key in `variations`.
+ """
+
+ enabled: bool
+ """When false, the flag bypasses all rules and always serves `default_variation`."""
+
+ key: str
+ """Unique identifier for the flag within an app.
+
+ Used in all evaluation and SDK calls.
+ """
+
+ rules: List[UnionMember0AfterRule]
+ """Targeting rules evaluated in ascending `priority`; the first matching rule wins.
+
+ An empty array means the flag always serves `default_variation`.
+ """
+
+ variations: Dict[str, Union[Optional[str], float, bool, Dict[str, object], List[object]]]
+ """Map of variation name to value.
+
+ All values must be the same type (boolean, string, number, or JSON
+ object/array). Each serialized value must be 10KB or smaller.
+ """
+
+ description: Optional[str] = None
+
+ type: Optional[Literal["boolean", "string", "number", "json"]] = None
+ """Value type of the flag's variations.
+
+ Inferred from the variation values on write, so it may be omitted in requests.
+ """
+
+ updated_at: Optional[str] = None
+
+ updated_by: Optional[str] = None
+
+
+class UnionMember0(BaseModel):
+ after: UnionMember0After
+
+ event: Literal["create"]
+
+ flag_key: str
+
+
+class UnionMember1AfterRuleConditionUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(
+ BaseModel
+):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(
+ BaseModel
+):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(
+ BaseModel
+):
+ clauses: List[Union[Optional[str], float, bool, Dict[str, object], List[object]]]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(
+ BaseModel
+):
+ clauses: List[
+ UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause
+ ]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[
+ UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause
+ ]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+UnionMember1AfterRuleConditionUnionMember1Clause: TypeAlias = Union[
+ UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember0,
+ UnionMember1AfterRuleConditionUnionMember1ClauseUnionMember1,
+]
+
+
+class UnionMember1AfterRuleConditionUnionMember1(BaseModel):
+ clauses: List[UnionMember1AfterRuleConditionUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+UnionMember1AfterRuleCondition: TypeAlias = Union[
+ UnionMember1AfterRuleConditionUnionMember0, UnionMember1AfterRuleConditionUnionMember1
+]
+
+
+class UnionMember1AfterRuleRollout(BaseModel):
+ percentage: float
+ """Percentage of matching traffic (0–100) served this variation.
+
+ For multi-way splits, use cumulative upper bounds across rules (e.g. 30, 70,
+ 100).
+ """
+
+ attribute: Optional[str] = None
+ """Context attribute used for sticky bucketing.
+
+ Defaults to `targetingKey`. If absent at evaluation time, bucketing is random
+ per request.
+ """
+
+
+class UnionMember1AfterRule(BaseModel):
+ conditions: List[UnionMember1AfterRuleCondition]
+ """Conditions the context must satisfy for this rule to match.
+
+ An empty array matches all contexts.
+ """
+
+ priority: int
+ """Evaluation order; lower numbers are evaluated first.
+
+ Must be unique across the flag's rules.
+ """
+
+ serve_variation: str
+ """Variation served when this rule matches. Must be a key in `variations`."""
+
+ rollout: Optional[UnionMember1AfterRuleRollout] = None
+
+
+class UnionMember1After(BaseModel):
+ default_variation: str
+ """Variation served when no rule matches or the flag is disabled.
+
+ Must be a key in `variations`.
+ """
+
+ enabled: bool
+ """When false, the flag bypasses all rules and always serves `default_variation`."""
+
+ key: str
+ """Unique identifier for the flag within an app.
+
+ Used in all evaluation and SDK calls.
+ """
+
+ rules: List[UnionMember1AfterRule]
+ """Targeting rules evaluated in ascending `priority`; the first matching rule wins.
+
+ An empty array means the flag always serves `default_variation`.
+ """
+
+ variations: Dict[str, Union[Optional[str], float, bool, Dict[str, object], List[object]]]
+ """Map of variation name to value.
+
+ All values must be the same type (boolean, string, number, or JSON
+ object/array). Each serialized value must be 10KB or smaller.
+ """
+
+ description: Optional[str] = None
+
+ type: Optional[Literal["boolean", "string", "number", "json"]] = None
+ """Value type of the flag's variations.
+
+ Inferred from the variation values on write, so it may be omitted in requests.
+ """
+
+ updated_at: Optional[str] = None
+
+ updated_by: Optional[str] = None
+
+
+class UnionMember1(BaseModel):
+ after: UnionMember1After
+
+ event: Literal["delete"]
+
+ flag_key: str
+
+
+class UnionMember2AfterRuleConditionUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(BaseModel):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(
+ BaseModel
+):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0(
+ BaseModel
+):
+ attribute: str
+
+ operator: Literal[
+ "equals",
+ "not_equals",
+ "greater_than",
+ "less_than",
+ "greater_than_or_equals",
+ "less_than_or_equals",
+ "contains",
+ "starts_with",
+ "ends_with",
+ "in",
+ "not_in",
+ ]
+
+ value: object
+ """Value to compare against the context attribute.
+
+ Must be an array for `in` and `not_in`; numeric and ISO-8601 datetime strings
+ are accepted by the ordering operators.
+ """
+
+
+class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(
+ BaseModel
+):
+ clauses: List[Union[Optional[str], float, bool, Dict[str, object], List[object]]]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(
+ BaseModel
+):
+ clauses: List[
+ UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause
+ ]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[
+ UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1Clause
+ ]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1Clause: TypeAlias = Union[
+ UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember0,
+ UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1ClauseUnionMember1,
+]
+
+
+class UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1(BaseModel):
+ clauses: List[UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+UnionMember2AfterRuleConditionUnionMember1Clause: TypeAlias = Union[
+ UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember0,
+ UnionMember2AfterRuleConditionUnionMember1ClauseUnionMember1,
+]
+
+
+class UnionMember2AfterRuleConditionUnionMember1(BaseModel):
+ clauses: List[UnionMember2AfterRuleConditionUnionMember1Clause]
+
+ logical_operator: Literal["AND", "OR"]
+
+
+UnionMember2AfterRuleCondition: TypeAlias = Union[
+ UnionMember2AfterRuleConditionUnionMember0, UnionMember2AfterRuleConditionUnionMember1
+]
+
+
+class UnionMember2AfterRuleRollout(BaseModel):
+ percentage: float
+ """Percentage of matching traffic (0–100) served this variation.
+
+ For multi-way splits, use cumulative upper bounds across rules (e.g. 30, 70,
+ 100).
+ """
+
+ attribute: Optional[str] = None
+ """Context attribute used for sticky bucketing.
+
+ Defaults to `targetingKey`. If absent at evaluation time, bucketing is random
+ per request.
+ """
+
+
+class UnionMember2AfterRule(BaseModel):
+ conditions: List[UnionMember2AfterRuleCondition]
+ """Conditions the context must satisfy for this rule to match.
+
+ An empty array matches all contexts.
+ """
+
+ priority: int
+ """Evaluation order; lower numbers are evaluated first.
+
+ Must be unique across the flag's rules.
+ """
+
+ serve_variation: str
+ """Variation served when this rule matches. Must be a key in `variations`."""
+
+ rollout: Optional[UnionMember2AfterRuleRollout] = None
+
+
+class UnionMember2After(BaseModel):
+ default_variation: str
+ """Variation served when no rule matches or the flag is disabled.
+
+ Must be a key in `variations`.
+ """
+
+ enabled: bool
+ """When false, the flag bypasses all rules and always serves `default_variation`."""
+
+ key: str
+ """Unique identifier for the flag within an app.
+
+ Used in all evaluation and SDK calls.
+ """
+
+ rules: List[UnionMember2AfterRule]
+ """Targeting rules evaluated in ascending `priority`; the first matching rule wins.
+
+ An empty array means the flag always serves `default_variation`.
+ """
+
+ variations: Dict[str, Union[Optional[str], float, bool, Dict[str, object], List[object]]]
+ """Map of variation name to value.
+
+ All values must be the same type (boolean, string, number, or JSON
+ object/array). Each serialized value must be 10KB or smaller.
+ """
+
+ description: Optional[str] = None
+
+ type: Optional[Literal["boolean", "string", "number", "json"]] = None
+ """Value type of the flag's variations.
+
+ Inferred from the variation values on write, so it may be omitted in requests.
+ """
+
+ updated_at: Optional[str] = None
+
+ updated_by: Optional[str] = None
+
+
+class UnionMember2Diff(BaseModel):
+ from_: Union[Optional[str], float, bool, Dict[str, object], List[object], None] = FieldInfo(
+ alias="from", default=None
+ )
+
+ to: Union[Optional[str], float, bool, Dict[str, object], List[object], None] = None
+
+
+class UnionMember2(BaseModel):
+ after: UnionMember2After
+
+ diff: Dict[str, UnionMember2Diff]
+
+ event: Literal["update"]
+
+ flag_key: str
+
+
+ChangelogListResponse: TypeAlias = Union[UnionMember0, UnionMember1, UnionMember2]
diff --git a/src/cloudflare/types/iam/__init__.py b/src/cloudflare/types/iam/__init__.py
index f211f2b77fb..138b8ae9ab3 100644
--- a/src/cloudflare/types/iam/__init__.py
+++ b/src/cloudflare/types/iam/__init__.py
@@ -15,6 +15,7 @@
from .user_group_list_response import UserGroupListResponse as UserGroupListResponse
from .user_group_update_params import UserGroupUpdateParams as UserGroupUpdateParams
from .oauth_client_get_response import OAuthClientGetResponse as OAuthClientGetResponse
+from .oauth_scope_list_response import OAuthScopeListResponse as OAuthScopeListResponse
from .oauth_client_create_params import OAuthClientCreateParams as OAuthClientCreateParams
from .oauth_client_list_response import OAuthClientListResponse as OAuthClientListResponse
from .oauth_client_update_params import OAuthClientUpdateParams as OAuthClientUpdateParams
diff --git a/src/cloudflare/types/iam/oauth_scopes/oauth_scope_list_response.py b/src/cloudflare/types/iam/oauth_scope_list_response.py
similarity index 95%
rename from src/cloudflare/types/iam/oauth_scopes/oauth_scope_list_response.py
rename to src/cloudflare/types/iam/oauth_scope_list_response.py
index e350ac52990..0248c0e41b7 100644
--- a/src/cloudflare/types/iam/oauth_scopes/oauth_scope_list_response.py
+++ b/src/cloudflare/types/iam/oauth_scope_list_response.py
@@ -2,7 +2,7 @@
from typing import List, Optional
-from ...._models import BaseModel
+from ..._models import BaseModel
__all__ = ["OAuthScopeListResponse"]
diff --git a/src/cloudflare/types/logpush/job_create_params.py b/src/cloudflare/types/logpush/job_create_params.py
index 61d6089a4d6..1f846042d34 100644
--- a/src/cloudflare/types/logpush/job_create_params.py
+++ b/src/cloudflare/types/logpush/job_create_params.py
@@ -57,6 +57,7 @@ class JobCreateParams(TypedDict, total=False):
"turnstile_events",
"warp_config_changes",
"warp_toggle_changes",
+ "websocket_analytics",
"workers_trace_events",
"zaraz_events",
"zero_trust_network_sessions",
diff --git a/src/cloudflare/types/logpush/logpush_job.py b/src/cloudflare/types/logpush/logpush_job.py
index fbe866558cc..91ca60b616c 100644
--- a/src/cloudflare/types/logpush/logpush_job.py
+++ b/src/cloudflare/types/logpush/logpush_job.py
@@ -47,6 +47,7 @@ class LogpushJob(BaseModel):
"turnstile_events",
"warp_config_changes",
"warp_toggle_changes",
+ "websocket_analytics",
"workers_trace_events",
"zaraz_events",
"zero_trust_network_sessions",
diff --git a/src/cloudflare/types/managed_transforms/managed_transform_edit_params.py b/src/cloudflare/types/managed_transforms/managed_transform_edit_params.py
index 572146cec03..d3aa4f2a1db 100644
--- a/src/cloudflare/types/managed_transforms/managed_transform_edit_params.py
+++ b/src/cloudflare/types/managed_transforms/managed_transform_edit_params.py
@@ -12,10 +12,10 @@ class ManagedTransformEditParams(TypedDict, total=False):
zone_id: Required[str]
"""The unique ID of the zone."""
- managed_request_headers: Required[Iterable[ManagedRequestHeader]]
+ managed_request_headers: Iterable[ManagedRequestHeader]
"""The list of Managed Request Transforms."""
- managed_response_headers: Required[Iterable[ManagedResponseHeader]]
+ managed_response_headers: Iterable[ManagedResponseHeader]
"""The list of Managed Response Transforms."""
diff --git a/src/cloudflare/types/organizations/organization.py b/src/cloudflare/types/organizations/organization.py
index 3070de32b8b..31c6b699b5f 100644
--- a/src/cloudflare/types/organizations/organization.py
+++ b/src/cloudflare/types/organizations/organization.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, Optional
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from pydantic import Field as FieldInfo
@@ -29,6 +29,15 @@ class Meta(BaseModel):
flags: Optional[MetaFlags] = None
"""Enable features for Organizations."""
+ hierarchy_tags: Optional[List[str]] = None
+ """
+ Ordered chain of organization tags from the root organization down to (and
+ including) this organization itself. Root organizations return a single-element
+ array containing their own tag; sub-organizations return
+ `[rootTag, ...intermediateTags, parentTag, selfTag]`. Useful for constructing
+ authorization scopes that need to cover every ancestor in the hierarchy.
+ """
+
managed_by: Optional[str] = None
if TYPE_CHECKING:
diff --git a/src/cloudflare/types/iam/oauth_scopes/__init__.py b/src/cloudflare/types/origin_tls_compliance_modes/__init__.py
similarity index 57%
rename from src/cloudflare/types/iam/oauth_scopes/__init__.py
rename to src/cloudflare/types/origin_tls_compliance_modes/__init__.py
index cb701505318..f8ee8b14b1c 100644
--- a/src/cloudflare/types/iam/oauth_scopes/__init__.py
+++ b/src/cloudflare/types/origin_tls_compliance_modes/__init__.py
@@ -1,5 +1,3 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from __future__ import annotations
-
-from .oauth_scope_list_response import OAuthScopeListResponse as OAuthScopeListResponse
diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_create_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_create_response.py
index 61c6e6f7223..92b486b5f0d 100644
--- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_create_response.py
+++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_create_response.py
@@ -99,6 +99,9 @@ class Server(BaseModel):
on_behalf: Optional[bool] = None
+ secure_web_gateway: Optional[bool] = None
+ """Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway"""
+
status: Optional[str] = None
updated_prompts: Optional[List[ServerUpdatedPrompt]] = None
diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_list_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_list_response.py
index 3008b57f175..6de62558668 100644
--- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_list_response.py
+++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_list_response.py
@@ -99,6 +99,9 @@ class Server(BaseModel):
on_behalf: Optional[bool] = None
+ secure_web_gateway: Optional[bool] = None
+ """Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway"""
+
status: Optional[str] = None
updated_prompts: Optional[List[ServerUpdatedPrompt]] = None
diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_read_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_read_response.py
index 07ed7ca9071..4df2e8eb20e 100644
--- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_read_response.py
+++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_read_response.py
@@ -99,6 +99,9 @@ class Server(BaseModel):
on_behalf: Optional[bool] = None
+ secure_web_gateway: Optional[bool] = None
+ """Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway"""
+
status: Optional[str] = None
updated_prompts: Optional[List[ServerUpdatedPrompt]] = None
diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_update_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_update_response.py
index a29b140f119..1f53e112b32 100644
--- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_update_response.py
+++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_update_response.py
@@ -99,6 +99,9 @@ class Server(BaseModel):
on_behalf: Optional[bool] = None
+ secure_web_gateway: Optional[bool] = None
+ """Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway"""
+
status: Optional[str] = None
updated_prompts: Optional[List[ServerUpdatedPrompt]] = None
diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_create_params.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_create_params.py
index 598d4762a3f..4ccd3c71a3d 100644
--- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_create_params.py
+++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_create_params.py
@@ -33,6 +33,9 @@ class ServerCreateParams(TypedDict, total=False):
behavior is gated by the gateway worker's per-env rollout mode KV key.
"""
+ secure_web_gateway: bool
+ """Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway"""
+
updated_prompts: Iterable[UpdatedPrompt]
updated_tools: Iterable[UpdatedTool]
diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_create_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_create_response.py
index 815b4463833..db01ca275b5 100644
--- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_create_response.py
+++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_create_response.py
@@ -87,6 +87,9 @@ class ServerCreateResponse(BaseModel):
modified_by: Optional[str] = None
+ secure_web_gateway: Optional[bool] = None
+ """Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway"""
+
status: Optional[str] = None
updated_prompts: Optional[List[UpdatedPrompt]] = None
diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_delete_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_delete_response.py
index 458ed1089ac..ac459345c3e 100644
--- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_delete_response.py
+++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_delete_response.py
@@ -87,6 +87,9 @@ class ServerDeleteResponse(BaseModel):
modified_by: Optional[str] = None
+ secure_web_gateway: Optional[bool] = None
+ """Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway"""
+
status: Optional[str] = None
updated_prompts: Optional[List[UpdatedPrompt]] = None
diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_list_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_list_response.py
index 7e12dd45fb8..d782f777b55 100644
--- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_list_response.py
+++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_list_response.py
@@ -87,6 +87,9 @@ class ServerListResponse(BaseModel):
modified_by: Optional[str] = None
+ secure_web_gateway: Optional[bool] = None
+ """Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway"""
+
status: Optional[str] = None
updated_prompts: Optional[List[UpdatedPrompt]] = None
diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_read_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_read_response.py
index 259bcd23a18..a12d32a5bc9 100644
--- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_read_response.py
+++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_read_response.py
@@ -87,6 +87,9 @@ class ServerReadResponse(BaseModel):
modified_by: Optional[str] = None
+ secure_web_gateway: Optional[bool] = None
+ """Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway"""
+
status: Optional[str] = None
updated_prompts: Optional[List[UpdatedPrompt]] = None
diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_update_params.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_update_params.py
index 394c9e5a3f4..f05072d243d 100644
--- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_update_params.py
+++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_update_params.py
@@ -26,6 +26,9 @@ class ServerUpdateParams(TypedDict, total=False):
name: str
+ secure_web_gateway: bool
+ """Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway"""
+
updated_prompts: Iterable[UpdatedPrompt]
updated_tools: Iterable[UpdatedTool]
diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_update_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_update_response.py
index af37f6b9644..6ab98c14808 100644
--- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_update_response.py
+++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_update_response.py
@@ -87,6 +87,9 @@ class ServerUpdateResponse(BaseModel):
modified_by: Optional[str] = None
+ secure_web_gateway: Optional[bool] = None
+ """Route outbound traffic to this MCP server through Zero Trust Secure Web Gateway"""
+
status: Optional[str] = None
updated_prompts: Optional[List[UpdatedPrompt]] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/__init__.py b/src/cloudflare/types/zero_trust/dlp/__init__.py
index 20490e402f1..928fddeeca4 100644
--- a/src/cloudflare/types/zero_trust/dlp/__init__.py
+++ b/src/cloudflare/types/zero_trust/dlp/__init__.py
@@ -23,11 +23,29 @@
from .entry_update_response import EntryUpdateResponse as EntryUpdateResponse
from .setting_update_params import SettingUpdateParams as SettingUpdateParams
from .context_awareness_param import ContextAwarenessParam as ContextAwarenessParam
+from .data_class_get_response import DataClassGetResponse as DataClassGetResponse
from .pattern_validate_params import PatternValidateParams as PatternValidateParams
+from .data_class_create_params import DataClassCreateParams as DataClassCreateParams
+from .data_class_list_response import DataClassListResponse as DataClassListResponse
+from .data_class_update_params import DataClassUpdateParams as DataClassUpdateParams
from .payload_log_get_response import PayloadLogGetResponse as PayloadLogGetResponse
from .skip_configuration_param import SkipConfigurationParam as SkipConfigurationParam
from .pattern_validate_response import PatternValidateResponse as PatternValidateResponse
from .payload_log_update_params import PayloadLogUpdateParams as PayloadLogUpdateParams
+from .data_class_create_response import DataClassCreateResponse as DataClassCreateResponse
+from .data_class_update_response import DataClassUpdateResponse as DataClassUpdateResponse
from .payload_log_update_response import PayloadLogUpdateResponse as PayloadLogUpdateResponse
+from .data_tag_category_get_response import DataTagCategoryGetResponse as DataTagCategoryGetResponse
+from .sensitivity_group_get_response import SensitivityGroupGetResponse as SensitivityGroupGetResponse
+from .data_tag_category_create_params import DataTagCategoryCreateParams as DataTagCategoryCreateParams
+from .data_tag_category_list_response import DataTagCategoryListResponse as DataTagCategoryListResponse
+from .data_tag_category_update_params import DataTagCategoryUpdateParams as DataTagCategoryUpdateParams
+from .sensitivity_group_create_params import SensitivityGroupCreateParams as SensitivityGroupCreateParams
+from .sensitivity_group_list_response import SensitivityGroupListResponse as SensitivityGroupListResponse
+from .sensitivity_group_update_params import SensitivityGroupUpdateParams as SensitivityGroupUpdateParams
from .custom_prompt_topic_create_params import CustomPromptTopicCreateParams as CustomPromptTopicCreateParams
from .custom_prompt_topic_update_params import CustomPromptTopicUpdateParams as CustomPromptTopicUpdateParams
+from .data_tag_category_create_response import DataTagCategoryCreateResponse as DataTagCategoryCreateResponse
+from .data_tag_category_update_response import DataTagCategoryUpdateResponse as DataTagCategoryUpdateResponse
+from .sensitivity_group_create_response import SensitivityGroupCreateResponse as SensitivityGroupCreateResponse
+from .sensitivity_group_update_response import SensitivityGroupUpdateResponse as SensitivityGroupUpdateResponse
diff --git a/src/cloudflare/types/zero_trust/dlp/data_class_create_params.py b/src/cloudflare/types/zero_trust/dlp/data_class_create_params.py
new file mode 100644
index 00000000000..ddba38e9c54
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/data_class_create_params.py
@@ -0,0 +1,34 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable, Optional
+from typing_extensions import Required, TypedDict
+
+from ...._types import SequenceNotStr
+
+__all__ = ["DataClassCreateParams", "SensitivityLevel"]
+
+
+class DataClassCreateParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ data_tags: Required[SequenceNotStr[str]]
+
+ expression: Required[str]
+
+ name: Required[str]
+
+ sensitivity_levels: Required[Iterable[SensitivityLevel]]
+
+ description: Optional[str]
+
+
+class SensitivityLevel(TypedDict, total=False):
+ """
+ A reference pairing a sensitivity group with a specific level within that group.
+ """
+
+ group_id: Required[str]
+
+ level_id: Required[str]
diff --git a/src/cloudflare/types/zero_trust/dlp/data_class_create_response.py b/src/cloudflare/types/zero_trust/dlp/data_class_create_response.py
new file mode 100644
index 00000000000..861416287c0
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/data_class_create_response.py
@@ -0,0 +1,36 @@
+# 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__ = ["DataClassCreateResponse", "SensitivityLevel"]
+
+
+class SensitivityLevel(BaseModel):
+ """
+ A reference pairing a sensitivity group with a specific level within that group.
+ """
+
+ group_id: str
+
+ level_id: str
+
+
+class DataClassCreateResponse(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ data_tags: List[str]
+
+ expression: str
+
+ name: str
+
+ sensitivity_levels: List[SensitivityLevel]
+
+ updated_at: datetime
+
+ description: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/data_class_get_response.py b/src/cloudflare/types/zero_trust/dlp/data_class_get_response.py
new file mode 100644
index 00000000000..3fcada50a3b
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/data_class_get_response.py
@@ -0,0 +1,36 @@
+# 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__ = ["DataClassGetResponse", "SensitivityLevel"]
+
+
+class SensitivityLevel(BaseModel):
+ """
+ A reference pairing a sensitivity group with a specific level within that group.
+ """
+
+ group_id: str
+
+ level_id: str
+
+
+class DataClassGetResponse(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ data_tags: List[str]
+
+ expression: str
+
+ name: str
+
+ sensitivity_levels: List[SensitivityLevel]
+
+ updated_at: datetime
+
+ description: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/data_class_list_response.py b/src/cloudflare/types/zero_trust/dlp/data_class_list_response.py
new file mode 100644
index 00000000000..547b2146945
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/data_class_list_response.py
@@ -0,0 +1,36 @@
+# 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__ = ["DataClassListResponse", "SensitivityLevel"]
+
+
+class SensitivityLevel(BaseModel):
+ """
+ A reference pairing a sensitivity group with a specific level within that group.
+ """
+
+ group_id: str
+
+ level_id: str
+
+
+class DataClassListResponse(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ data_tags: List[str]
+
+ expression: str
+
+ name: str
+
+ sensitivity_levels: List[SensitivityLevel]
+
+ updated_at: datetime
+
+ description: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/data_class_update_params.py b/src/cloudflare/types/zero_trust/dlp/data_class_update_params.py
new file mode 100644
index 00000000000..ae07339849a
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/data_class_update_params.py
@@ -0,0 +1,34 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable, Optional
+from typing_extensions import Required, TypedDict
+
+from ...._types import SequenceNotStr
+
+__all__ = ["DataClassUpdateParams", "SensitivityLevel"]
+
+
+class DataClassUpdateParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ data_tags: Optional[SequenceNotStr[str]]
+
+ description: Optional[str]
+
+ expression: Optional[str]
+
+ name: Optional[str]
+
+ sensitivity_levels: Optional[Iterable[SensitivityLevel]]
+
+
+class SensitivityLevel(TypedDict, total=False):
+ """
+ A reference pairing a sensitivity group with a specific level within that group.
+ """
+
+ group_id: Required[str]
+
+ level_id: Required[str]
diff --git a/src/cloudflare/types/zero_trust/dlp/data_class_update_response.py b/src/cloudflare/types/zero_trust/dlp/data_class_update_response.py
new file mode 100644
index 00000000000..fda1ad4df23
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/data_class_update_response.py
@@ -0,0 +1,36 @@
+# 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__ = ["DataClassUpdateResponse", "SensitivityLevel"]
+
+
+class SensitivityLevel(BaseModel):
+ """
+ A reference pairing a sensitivity group with a specific level within that group.
+ """
+
+ group_id: str
+
+ level_id: str
+
+
+class DataClassUpdateResponse(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ data_tags: List[str]
+
+ expression: str
+
+ name: str
+
+ sensitivity_levels: List[SensitivityLevel]
+
+ updated_at: datetime
+
+ description: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/data_tag_categories/__init__.py b/src/cloudflare/types/zero_trust/dlp/data_tag_categories/__init__.py
new file mode 100644
index 00000000000..250d6e48788
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/data_tag_categories/__init__.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .data_tag_get_response import DataTagGetResponse as DataTagGetResponse
+from .data_tag_create_params import DataTagCreateParams as DataTagCreateParams
+from .data_tag_list_response import DataTagListResponse as DataTagListResponse
+from .data_tag_update_params import DataTagUpdateParams as DataTagUpdateParams
+from .data_tag_create_response import DataTagCreateResponse as DataTagCreateResponse
+from .data_tag_update_response import DataTagUpdateResponse as DataTagUpdateResponse
diff --git a/src/cloudflare/types/zero_trust/dlp/data_tag_categories/data_tag_create_params.py b/src/cloudflare/types/zero_trust/dlp/data_tag_categories/data_tag_create_params.py
new file mode 100644
index 00000000000..ee2e13f787f
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/data_tag_categories/data_tag_create_params.py
@@ -0,0 +1,16 @@
+# 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__ = ["DataTagCreateParams"]
+
+
+class DataTagCreateParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ name: Required[str]
+
+ description: Optional[str]
diff --git a/src/cloudflare/types/zero_trust/dlp/data_tag_categories/data_tag_create_response.py b/src/cloudflare/types/zero_trust/dlp/data_tag_categories/data_tag_create_response.py
new file mode 100644
index 00000000000..38607cb3e19
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/data_tag_categories/data_tag_create_response.py
@@ -0,0 +1,20 @@
+# 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__ = ["DataTagCreateResponse"]
+
+
+class DataTagCreateResponse(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ name: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/data_tag_categories/data_tag_get_response.py b/src/cloudflare/types/zero_trust/dlp/data_tag_categories/data_tag_get_response.py
new file mode 100644
index 00000000000..d422b5f0a69
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/data_tag_categories/data_tag_get_response.py
@@ -0,0 +1,20 @@
+# 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__ = ["DataTagGetResponse"]
+
+
+class DataTagGetResponse(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ name: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/data_tag_categories/data_tag_list_response.py b/src/cloudflare/types/zero_trust/dlp/data_tag_categories/data_tag_list_response.py
new file mode 100644
index 00000000000..a6ca0f99d54
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/data_tag_categories/data_tag_list_response.py
@@ -0,0 +1,20 @@
+# 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__ = ["DataTagListResponse"]
+
+
+class DataTagListResponse(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ name: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/data_tag_categories/data_tag_update_params.py b/src/cloudflare/types/zero_trust/dlp/data_tag_categories/data_tag_update_params.py
new file mode 100644
index 00000000000..265a1fd8d7f
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/data_tag_categories/data_tag_update_params.py
@@ -0,0 +1,18 @@
+# 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__ = ["DataTagUpdateParams"]
+
+
+class DataTagUpdateParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ category_id: Required[str]
+
+ description: Optional[str]
+
+ name: Optional[str]
diff --git a/src/cloudflare/types/zero_trust/dlp/data_tag_categories/data_tag_update_response.py b/src/cloudflare/types/zero_trust/dlp/data_tag_categories/data_tag_update_response.py
new file mode 100644
index 00000000000..8d33f1ab065
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/data_tag_categories/data_tag_update_response.py
@@ -0,0 +1,20 @@
+# 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__ = ["DataTagUpdateResponse"]
+
+
+class DataTagUpdateResponse(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ name: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/data_tag_category_create_params.py b/src/cloudflare/types/zero_trust/dlp/data_tag_category_create_params.py
new file mode 100644
index 00000000000..28425cf2cec
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/data_tag_category_create_params.py
@@ -0,0 +1,27 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable, Optional
+from typing_extensions import Required, TypedDict
+
+__all__ = ["DataTagCategoryCreateParams", "Tag"]
+
+
+class DataTagCategoryCreateParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ name: Required[str]
+
+ description: Optional[str]
+
+ tags: Iterable[Tag]
+ """Tags to create with the category. Mutually exclusive with `template_id`."""
+
+ template_id: Optional[str]
+
+
+class Tag(TypedDict, total=False):
+ name: Required[str]
+
+ description: Optional[str]
diff --git a/src/cloudflare/types/zero_trust/dlp/data_tag_category_create_response.py b/src/cloudflare/types/zero_trust/dlp/data_tag_category_create_response.py
new file mode 100644
index 00000000000..3736e0c2b78
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/data_tag_category_create_response.py
@@ -0,0 +1,36 @@
+# 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__ = ["DataTagCategoryCreateResponse", "Tag"]
+
+
+class Tag(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ name: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
+
+
+class DataTagCategoryCreateResponse(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ name: str
+
+ tags: List[Tag]
+
+ updated_at: datetime
+
+ description: Optional[str] = None
+
+ template_id: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/data_tag_category_get_response.py b/src/cloudflare/types/zero_trust/dlp/data_tag_category_get_response.py
new file mode 100644
index 00000000000..1cb071ea233
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/data_tag_category_get_response.py
@@ -0,0 +1,36 @@
+# 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__ = ["DataTagCategoryGetResponse", "Tag"]
+
+
+class Tag(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ name: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
+
+
+class DataTagCategoryGetResponse(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ name: str
+
+ tags: List[Tag]
+
+ updated_at: datetime
+
+ description: Optional[str] = None
+
+ template_id: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/data_tag_category_list_response.py b/src/cloudflare/types/zero_trust/dlp/data_tag_category_list_response.py
new file mode 100644
index 00000000000..26e4e100097
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/data_tag_category_list_response.py
@@ -0,0 +1,36 @@
+# 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__ = ["DataTagCategoryListResponse", "Tag"]
+
+
+class Tag(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ name: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
+
+
+class DataTagCategoryListResponse(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ name: str
+
+ tags: List[Tag]
+
+ updated_at: datetime
+
+ description: Optional[str] = None
+
+ template_id: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/data_tag_category_update_params.py b/src/cloudflare/types/zero_trust/dlp/data_tag_category_update_params.py
new file mode 100644
index 00000000000..8bcaa5ea292
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/data_tag_category_update_params.py
@@ -0,0 +1,36 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable, Optional
+from typing_extensions import Required, TypedDict
+
+__all__ = ["DataTagCategoryUpdateParams", "Tag"]
+
+
+class DataTagCategoryUpdateParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ description: Optional[str]
+
+ name: Optional[str]
+
+ tags: Optional[Iterable[Tag]]
+ """The desired final state of tags.
+
+ - `None` (omitted): no tag changes.
+ - `Some([])`: delete all tags.
+ - `Some([...])`: desired final set + order.
+ """
+
+
+class Tag(TypedDict, total=False):
+ id: Optional[str]
+ """If `None` (omitted), a new tag will be created.
+
+ Otherwise, an existing tag will be updated.
+ """
+
+ description: Optional[str]
+
+ name: Optional[str]
diff --git a/src/cloudflare/types/zero_trust/dlp/data_tag_category_update_response.py b/src/cloudflare/types/zero_trust/dlp/data_tag_category_update_response.py
new file mode 100644
index 00000000000..b9da353aa2e
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/data_tag_category_update_response.py
@@ -0,0 +1,36 @@
+# 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__ = ["DataTagCategoryUpdateResponse", "Tag"]
+
+
+class Tag(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ name: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
+
+
+class DataTagCategoryUpdateResponse(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ name: str
+
+ tags: List[Tag]
+
+ updated_at: datetime
+
+ description: Optional[str] = None
+
+ template_id: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/sensitivity_group_create_params.py b/src/cloudflare/types/zero_trust/dlp/sensitivity_group_create_params.py
new file mode 100644
index 00000000000..e1e320a095c
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/sensitivity_group_create_params.py
@@ -0,0 +1,27 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable, Optional
+from typing_extensions import Required, TypedDict
+
+__all__ = ["SensitivityGroupCreateParams", "Level"]
+
+
+class SensitivityGroupCreateParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ name: Required[str]
+
+ description: Optional[str]
+
+ levels: Iterable[Level]
+ """Levels to create with the group. Mutually exclusive with `template_id`."""
+
+ template_id: Optional[str]
+
+
+class Level(TypedDict, total=False):
+ name: Required[str]
+
+ description: Optional[str]
diff --git a/src/cloudflare/types/zero_trust/dlp/sensitivity_group_create_response.py b/src/cloudflare/types/zero_trust/dlp/sensitivity_group_create_response.py
new file mode 100644
index 00000000000..cd7487586a4
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/sensitivity_group_create_response.py
@@ -0,0 +1,36 @@
+# 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__ = ["SensitivityGroupCreateResponse", "Level"]
+
+
+class Level(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ name: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
+
+
+class SensitivityGroupCreateResponse(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ levels: List[Level]
+
+ name: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
+
+ template_id: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/sensitivity_group_get_response.py b/src/cloudflare/types/zero_trust/dlp/sensitivity_group_get_response.py
new file mode 100644
index 00000000000..89baa7b8f2f
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/sensitivity_group_get_response.py
@@ -0,0 +1,36 @@
+# 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__ = ["SensitivityGroupGetResponse", "Level"]
+
+
+class Level(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ name: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
+
+
+class SensitivityGroupGetResponse(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ levels: List[Level]
+
+ name: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
+
+ template_id: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/sensitivity_group_list_response.py b/src/cloudflare/types/zero_trust/dlp/sensitivity_group_list_response.py
new file mode 100644
index 00000000000..1e2e36a6c90
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/sensitivity_group_list_response.py
@@ -0,0 +1,36 @@
+# 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__ = ["SensitivityGroupListResponse", "Level"]
+
+
+class Level(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ name: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
+
+
+class SensitivityGroupListResponse(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ levels: List[Level]
+
+ name: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
+
+ template_id: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/sensitivity_group_update_params.py b/src/cloudflare/types/zero_trust/dlp/sensitivity_group_update_params.py
new file mode 100644
index 00000000000..c72029b458e
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/sensitivity_group_update_params.py
@@ -0,0 +1,36 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable, Optional
+from typing_extensions import Required, TypedDict
+
+__all__ = ["SensitivityGroupUpdateParams", "Level"]
+
+
+class SensitivityGroupUpdateParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ description: Optional[str]
+
+ levels: Optional[Iterable[Level]]
+ """The desired final state of levels.
+
+ - `None` (omitted): no level changes.
+ - `Some([])`: delete all levels.
+ - `Some([...])`: desired final set + order.
+ """
+
+ name: Optional[str]
+
+
+class Level(TypedDict, total=False):
+ id: Optional[str]
+ """If `None` (omitted), a new level will be created.
+
+ Otherwise, an existing level will be updated.
+ """
+
+ description: Optional[str]
+
+ name: Optional[str]
diff --git a/src/cloudflare/types/zero_trust/dlp/sensitivity_group_update_response.py b/src/cloudflare/types/zero_trust/dlp/sensitivity_group_update_response.py
new file mode 100644
index 00000000000..7a7d0fb33cc
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/sensitivity_group_update_response.py
@@ -0,0 +1,36 @@
+# 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__ = ["SensitivityGroupUpdateResponse", "Level"]
+
+
+class Level(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ name: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
+
+
+class SensitivityGroupUpdateResponse(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ levels: List[Level]
+
+ name: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
+
+ template_id: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/__init__.py b/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/__init__.py
new file mode 100644
index 00000000000..e0d0926fb6e
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/__init__.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .level_get_response import LevelGetResponse as LevelGetResponse
+from .level_create_params import LevelCreateParams as LevelCreateParams
+from .level_list_response import LevelListResponse as LevelListResponse
+from .level_update_params import LevelUpdateParams as LevelUpdateParams
+from .level_create_response import LevelCreateResponse as LevelCreateResponse
+from .level_update_response import LevelUpdateResponse as LevelUpdateResponse
diff --git a/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/level_create_params.py b/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/level_create_params.py
new file mode 100644
index 00000000000..3454a729837
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/level_create_params.py
@@ -0,0 +1,16 @@
+# 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__ = ["LevelCreateParams"]
+
+
+class LevelCreateParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ name: Required[str]
+
+ description: Optional[str]
diff --git a/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/level_create_response.py b/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/level_create_response.py
new file mode 100644
index 00000000000..674b79564da
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/level_create_response.py
@@ -0,0 +1,20 @@
+# 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__ = ["LevelCreateResponse"]
+
+
+class LevelCreateResponse(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ name: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/level_get_response.py b/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/level_get_response.py
new file mode 100644
index 00000000000..04817fc9cc3
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/level_get_response.py
@@ -0,0 +1,20 @@
+# 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__ = ["LevelGetResponse"]
+
+
+class LevelGetResponse(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ name: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/level_list_response.py b/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/level_list_response.py
new file mode 100644
index 00000000000..d3bedeab733
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/level_list_response.py
@@ -0,0 +1,20 @@
+# 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__ = ["LevelListResponse"]
+
+
+class LevelListResponse(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ name: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/level_update_params.py b/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/level_update_params.py
new file mode 100644
index 00000000000..cf4acd076dc
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/level_update_params.py
@@ -0,0 +1,18 @@
+# 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__ = ["LevelUpdateParams"]
+
+
+class LevelUpdateParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ sensitivity_group_id: Required[str]
+
+ description: Optional[str]
+
+ name: Optional[str]
diff --git a/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/level_update_response.py b/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/level_update_response.py
new file mode 100644
index 00000000000..b80aef9e8df
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/level_update_response.py
@@ -0,0 +1,20 @@
+# 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__ = ["LevelUpdateResponse"]
+
+
+class LevelUpdateResponse(BaseModel):
+ id: str
+
+ created_at: datetime
+
+ name: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/levels/__init__.py b/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/levels/__init__.py
new file mode 100644
index 00000000000..b32bf1b4263
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/levels/__init__.py
@@ -0,0 +1,7 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .order_get_response import OrderGetResponse as OrderGetResponse
+from .order_update_params import OrderUpdateParams as OrderUpdateParams
+from .order_update_response import OrderUpdateResponse as OrderUpdateResponse
diff --git a/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/levels/order_get_response.py b/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/levels/order_get_response.py
new file mode 100644
index 00000000000..0b662514671
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/levels/order_get_response.py
@@ -0,0 +1,16 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List
+
+from ......_models import BaseModel
+
+__all__ = ["OrderGetResponse"]
+
+
+class OrderGetResponse(BaseModel):
+ """
+ The ordered list of level IDs for a sensitivity group.
+ Used to get and set the ordering of levels independently of level attributes.
+ """
+
+ level_ids: List[str]
diff --git a/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/levels/order_update_params.py b/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/levels/order_update_params.py
new file mode 100644
index 00000000000..a37cfbe6cdf
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/levels/order_update_params.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+from ......_types import SequenceNotStr
+
+__all__ = ["OrderUpdateParams"]
+
+
+class OrderUpdateParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ level_ids: Required[SequenceNotStr[str]]
diff --git a/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/levels/order_update_response.py b/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/levels/order_update_response.py
new file mode 100644
index 00000000000..b795d973c05
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/sensitivity_groups/levels/order_update_response.py
@@ -0,0 +1,16 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List
+
+from ......_models import BaseModel
+
+__all__ = ["OrderUpdateResponse"]
+
+
+class OrderUpdateResponse(BaseModel):
+ """
+ The ordered list of level IDs for a sensitivity group.
+ Used to get and set the ordering of levels independently of level attributes.
+ """
+
+ level_ids: List[str]
diff --git a/src/cloudflare/types/zero_trust/tunnels/warp_connector/__init__.py b/src/cloudflare/types/zero_trust/tunnels/warp_connector/__init__.py
index dd281be36a2..2015eae116e 100644
--- a/src/cloudflare/types/zero_trust/tunnels/warp_connector/__init__.py
+++ b/src/cloudflare/types/zero_trust/tunnels/warp_connector/__init__.py
@@ -6,3 +6,6 @@
from .connector_get_response import ConnectorGetResponse as ConnectorGetResponse
from .failover_update_params import FailoverUpdateParams as FailoverUpdateParams
from .connection_get_response import ConnectionGetResponse as ConnectionGetResponse
+from .configuration_get_response import ConfigurationGetResponse as ConfigurationGetResponse
+from .configuration_update_params import ConfigurationUpdateParams as ConfigurationUpdateParams
+from .configuration_update_response import ConfigurationUpdateResponse as ConfigurationUpdateResponse
diff --git a/src/cloudflare/types/zero_trust/tunnels/warp_connector/configuration_get_response.py b/src/cloudflare/types/zero_trust/tunnels/warp_connector/configuration_get_response.py
new file mode 100644
index 00000000000..ec7a21f96fc
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/tunnels/warp_connector/configuration_get_response.py
@@ -0,0 +1,71 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Union, Optional
+from datetime import datetime
+from typing_extensions import Literal, TypeAlias
+
+from ....._models import BaseModel
+
+__all__ = [
+ "ConfigurationGetResponse",
+ "Config",
+ "ConfigTunnelMeshAwsConfig",
+ "ConfigTunnelMeshLocalConfig",
+ "ConfigTunnelMeshLocalConfigVip",
+ "ConfigTunnelMeshLocalConfigVipsPrevious",
+]
+
+
+class ConfigTunnelMeshAwsConfig(BaseModel):
+ fnr_id: str
+ """
+ Floating Network Resource ID — the secondary ENI that is moved between nodes on
+ failover.
+ """
+
+
+class ConfigTunnelMeshLocalConfigVip(BaseModel):
+ address: str
+ """Virtual IP address (IPv4 or IPv6)."""
+
+
+class ConfigTunnelMeshLocalConfigVipsPrevious(BaseModel):
+ address: str
+ """Virtual IP address (IPv4 or IPv6)."""
+
+
+class ConfigTunnelMeshLocalConfig(BaseModel):
+ vips: List[ConfigTunnelMeshLocalConfigVip]
+ """VIPs to assign on the CloudflareWARP interface."""
+
+ vips_previous: Optional[List[ConfigTunnelMeshLocalConfigVipsPrevious]] = None
+ """VIPs to clean up on demotion or version drift."""
+
+
+Config: TypeAlias = Union[ConfigTunnelMeshAwsConfig, ConfigTunnelMeshLocalConfig, None]
+
+
+class ConfigurationGetResponse(BaseModel):
+ configuration_version: int
+ """Monotonically increasing configuration version, incremented on each PUT."""
+
+ created_at: datetime
+ """Timestamp of when the resource was created."""
+
+ ha_mode: Literal["none", "disabled", "aws", "local"]
+ """High-availability mode for the WARP Connector tunnel.
+
+ `none` means HA is enabled but no provider is configured yet (newly created
+ tunnels default to this). `disabled` means HA is explicitly turned off. `aws`
+ uses AWS ENI move for failover. `local` uses virtual IPs (VIPs) on the local
+ interface.
+ """
+
+ tunnel_id: str
+ """UUID of the tunnel."""
+
+ config: Optional[Config] = None
+ """Provider-specific configuration. Present for `aws` and `local` modes."""
+
+ updated_at: Optional[datetime] = None
+ """Timestamp of the last update. Null if never updated."""
diff --git a/src/cloudflare/types/zero_trust/tunnels/warp_connector/configuration_update_params.py b/src/cloudflare/types/zero_trust/tunnels/warp_connector/configuration_update_params.py
new file mode 100644
index 00000000000..ae57389e24a
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/tunnels/warp_connector/configuration_update_params.py
@@ -0,0 +1,66 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union, Iterable, Optional
+from typing_extensions import Literal, Required, TypeAlias, TypedDict
+
+__all__ = [
+ "ConfigurationUpdateParams",
+ "Config",
+ "ConfigTunnelMeshAwsConfig",
+ "ConfigTunnelMeshLocalConfig",
+ "ConfigTunnelMeshLocalConfigVip",
+ "ConfigTunnelMeshLocalConfigVipsPrevious",
+]
+
+
+class ConfigurationUpdateParams(TypedDict, total=False):
+ account_id: Required[str]
+ """Identifier."""
+
+ ha_mode: Required[Literal["none", "disabled", "aws", "local"]]
+ """High-availability mode for the WARP Connector tunnel.
+
+ `none` means HA is enabled but no provider is configured yet (newly created
+ tunnels default to this). `disabled` means HA is explicitly turned off. `aws`
+ uses AWS ENI move for failover. `local` uses virtual IPs (VIPs) on the local
+ interface.
+ """
+
+ config: Optional[Config]
+ """Provider-specific configuration.
+
+ Required shape depends on ha_mode. For `aws`, must contain `fnr_id`. For
+ `local`, must contain `vips`. For `none` and `disabled`, must be empty or
+ omitted.
+ """
+
+
+class ConfigTunnelMeshAwsConfig(TypedDict, total=False):
+ fnr_id: Required[str]
+ """
+ Floating Network Resource ID — the secondary ENI that is moved between nodes on
+ failover.
+ """
+
+
+class ConfigTunnelMeshLocalConfigVip(TypedDict, total=False):
+ address: Required[str]
+ """Virtual IP address (IPv4 or IPv6)."""
+
+
+class ConfigTunnelMeshLocalConfigVipsPrevious(TypedDict, total=False):
+ address: Required[str]
+ """Virtual IP address (IPv4 or IPv6)."""
+
+
+class ConfigTunnelMeshLocalConfig(TypedDict, total=False):
+ vips: Required[Iterable[ConfigTunnelMeshLocalConfigVip]]
+ """VIPs to assign on the CloudflareWARP interface."""
+
+ vips_previous: Iterable[ConfigTunnelMeshLocalConfigVipsPrevious]
+ """VIPs to clean up on demotion or version drift."""
+
+
+Config: TypeAlias = Union[ConfigTunnelMeshAwsConfig, ConfigTunnelMeshLocalConfig, object]
diff --git a/src/cloudflare/types/zero_trust/tunnels/warp_connector/configuration_update_response.py b/src/cloudflare/types/zero_trust/tunnels/warp_connector/configuration_update_response.py
new file mode 100644
index 00000000000..899c188b845
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/tunnels/warp_connector/configuration_update_response.py
@@ -0,0 +1,71 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Union, Optional
+from datetime import datetime
+from typing_extensions import Literal, TypeAlias
+
+from ....._models import BaseModel
+
+__all__ = [
+ "ConfigurationUpdateResponse",
+ "Config",
+ "ConfigTunnelMeshAwsConfig",
+ "ConfigTunnelMeshLocalConfig",
+ "ConfigTunnelMeshLocalConfigVip",
+ "ConfigTunnelMeshLocalConfigVipsPrevious",
+]
+
+
+class ConfigTunnelMeshAwsConfig(BaseModel):
+ fnr_id: str
+ """
+ Floating Network Resource ID — the secondary ENI that is moved between nodes on
+ failover.
+ """
+
+
+class ConfigTunnelMeshLocalConfigVip(BaseModel):
+ address: str
+ """Virtual IP address (IPv4 or IPv6)."""
+
+
+class ConfigTunnelMeshLocalConfigVipsPrevious(BaseModel):
+ address: str
+ """Virtual IP address (IPv4 or IPv6)."""
+
+
+class ConfigTunnelMeshLocalConfig(BaseModel):
+ vips: List[ConfigTunnelMeshLocalConfigVip]
+ """VIPs to assign on the CloudflareWARP interface."""
+
+ vips_previous: Optional[List[ConfigTunnelMeshLocalConfigVipsPrevious]] = None
+ """VIPs to clean up on demotion or version drift."""
+
+
+Config: TypeAlias = Union[ConfigTunnelMeshAwsConfig, ConfigTunnelMeshLocalConfig, None]
+
+
+class ConfigurationUpdateResponse(BaseModel):
+ configuration_version: int
+ """Monotonically increasing configuration version, incremented on each PUT."""
+
+ created_at: datetime
+ """Timestamp of when the resource was created."""
+
+ ha_mode: Literal["none", "disabled", "aws", "local"]
+ """High-availability mode for the WARP Connector tunnel.
+
+ `none` means HA is enabled but no provider is configured yet (newly created
+ tunnels default to this). `disabled` means HA is explicitly turned off. `aws`
+ uses AWS ENI move for failover. `local` uses virtual IPs (VIPs) on the local
+ interface.
+ """
+
+ tunnel_id: str
+ """UUID of the tunnel."""
+
+ config: Optional[Config] = None
+ """Provider-specific configuration. Present for `aws` and `local` modes."""
+
+ updated_at: Optional[datetime] = None
+ """Timestamp of the last update. Null if never updated."""
diff --git a/tests/api_resources/ai/test_models.py b/tests/api_resources/ai/test_models.py
index 0837a03d5d6..2b79ffed055 100644
--- a/tests/api_resources/ai/test_models.py
+++ b/tests/api_resources/ai/test_models.py
@@ -31,6 +31,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None:
author="author",
format="openrouter",
hide_experimental=True,
+ include_deprecated=True,
page=0,
per_page=0,
search="search",
@@ -90,6 +91,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare)
author="author",
format="openrouter",
hide_experimental=True,
+ include_deprecated=True,
page=0,
per_page=0,
search="search",
diff --git a/tests/api_resources/ai_gateway/test_provider_configs.py b/tests/api_resources/ai_gateway/test_provider_configs.py
index c1add46928c..8dcaeb6e552 100644
--- a/tests/api_resources/ai_gateway/test_provider_configs.py
+++ b/tests/api_resources/ai_gateway/test_provider_configs.py
@@ -29,8 +29,6 @@ def test_method_create(self, client: Cloudflare) -> None:
alias="alias",
default_config=True,
provider_slug="provider_slug",
- secret="secret",
- secret_id="secret_id",
)
assert_matches_type(ProviderConfigCreateResponse, provider_config, path=["response"])
@@ -42,10 +40,10 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None:
alias="alias",
default_config=True,
provider_slug="provider_slug",
- secret="secret",
- secret_id="secret_id",
rate_limit=0,
rate_limit_period=0,
+ secret="secret",
+ secret_id="secret_id",
)
assert_matches_type(ProviderConfigCreateResponse, provider_config, path=["response"])
@@ -57,8 +55,6 @@ def test_raw_response_create(self, client: Cloudflare) -> None:
alias="alias",
default_config=True,
provider_slug="provider_slug",
- secret="secret",
- secret_id="secret_id",
)
assert response.is_closed is True
@@ -74,8 +70,6 @@ def test_streaming_response_create(self, client: Cloudflare) -> None:
alias="alias",
default_config=True,
provider_slug="provider_slug",
- secret="secret",
- secret_id="secret_id",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -94,8 +88,6 @@ def test_path_params_create(self, client: Cloudflare) -> None:
alias="alias",
default_config=True,
provider_slug="provider_slug",
- secret="secret",
- secret_id="secret_id",
)
with pytest.raises(ValueError, match=r"Expected a non-empty value for `gateway_id` but received ''"):
@@ -105,8 +97,6 @@ def test_path_params_create(self, client: Cloudflare) -> None:
alias="alias",
default_config=True,
provider_slug="provider_slug",
- secret="secret",
- secret_id="secret_id",
)
@parametrize
@@ -183,8 +173,6 @@ async def test_method_create(self, async_client: AsyncCloudflare) -> None:
alias="alias",
default_config=True,
provider_slug="provider_slug",
- secret="secret",
- secret_id="secret_id",
)
assert_matches_type(ProviderConfigCreateResponse, provider_config, path=["response"])
@@ -196,10 +184,10 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare
alias="alias",
default_config=True,
provider_slug="provider_slug",
- secret="secret",
- secret_id="secret_id",
rate_limit=0,
rate_limit_period=0,
+ secret="secret",
+ secret_id="secret_id",
)
assert_matches_type(ProviderConfigCreateResponse, provider_config, path=["response"])
@@ -211,8 +199,6 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None:
alias="alias",
default_config=True,
provider_slug="provider_slug",
- secret="secret",
- secret_id="secret_id",
)
assert response.is_closed is True
@@ -228,8 +214,6 @@ async def test_streaming_response_create(self, async_client: AsyncCloudflare) ->
alias="alias",
default_config=True,
provider_slug="provider_slug",
- secret="secret",
- secret_id="secret_id",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -248,8 +232,6 @@ async def test_path_params_create(self, async_client: AsyncCloudflare) -> None:
alias="alias",
default_config=True,
provider_slug="provider_slug",
- secret="secret",
- secret_id="secret_id",
)
with pytest.raises(ValueError, match=r"Expected a non-empty value for `gateway_id` but received ''"):
@@ -259,8 +241,6 @@ async def test_path_params_create(self, async_client: AsyncCloudflare) -> None:
alias="alias",
default_config=True,
provider_slug="provider_slug",
- secret="secret",
- secret_id="secret_id",
)
@parametrize
diff --git a/tests/api_resources/d1/test_database.py b/tests/api_resources/d1/test_database.py
index 32993faaf5b..352eeb0ee0d 100644
--- a/tests/api_resources/d1/test_database.py
+++ b/tests/api_resources/d1/test_database.py
@@ -360,6 +360,15 @@ def test_method_get(self, client: Cloudflare) -> None:
)
assert_matches_type(D1, database, path=["response"])
+ @parametrize
+ def test_method_get_with_all_params(self, client: Cloudflare) -> None:
+ database = client.d1.database.get(
+ database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ fields=["uuid"],
+ )
+ assert_matches_type(D1, database, path=["response"])
+
@parametrize
def test_raw_response_get(self, client: Cloudflare) -> None:
response = client.d1.database.with_raw_response.get(
@@ -1152,6 +1161,15 @@ async def test_method_get(self, async_client: AsyncCloudflare) -> None:
)
assert_matches_type(D1, database, path=["response"])
+ @parametrize
+ async def test_method_get_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ database = await async_client.d1.database.get(
+ database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ fields=["uuid"],
+ )
+ assert_matches_type(D1, database, path=["response"])
+
@parametrize
async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
response = await async_client.d1.database.with_raw_response.get(
diff --git a/tests/api_resources/flagship/__init__.py b/tests/api_resources/flagship/__init__.py
new file mode 100644
index 00000000000..fd8019a9a1a
--- /dev/null
+++ b/tests/api_resources/flagship/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/flagship/apps/__init__.py b/tests/api_resources/flagship/apps/__init__.py
new file mode 100644
index 00000000000..fd8019a9a1a
--- /dev/null
+++ b/tests/api_resources/flagship/apps/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/flagship/apps/flags/__init__.py b/tests/api_resources/flagship/apps/flags/__init__.py
new file mode 100644
index 00000000000..fd8019a9a1a
--- /dev/null
+++ b/tests/api_resources/flagship/apps/flags/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/flagship/apps/flags/test_changelog.py b/tests/api_resources/flagship/apps/flags/test_changelog.py
new file mode 100644
index 00000000000..ce57b10ee64
--- /dev/null
+++ b/tests/api_resources/flagship/apps/flags/test_changelog.py
@@ -0,0 +1,167 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare.pagination import SyncCursorPaginationAfter, AsyncCursorPaginationAfter
+from cloudflare.types.flagship.apps.flags import ChangelogListResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestChangelog:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_list(self, client: Cloudflare) -> None:
+ changelog = client.flagship.apps.flags.changelog.list(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ )
+ assert_matches_type(SyncCursorPaginationAfter[ChangelogListResponse], changelog, path=["response"])
+
+ @parametrize
+ def test_method_list_with_all_params(self, client: Cloudflare) -> None:
+ changelog = client.flagship.apps.flags.changelog.list(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ cursor="cursor",
+ limit="limit",
+ )
+ assert_matches_type(SyncCursorPaginationAfter[ChangelogListResponse], changelog, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Cloudflare) -> None:
+ response = client.flagship.apps.flags.changelog.with_raw_response.list(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ changelog = response.parse()
+ assert_matches_type(SyncCursorPaginationAfter[ChangelogListResponse], changelog, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Cloudflare) -> None:
+ with client.flagship.apps.flags.changelog.with_streaming_response.list(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ changelog = response.parse()
+ assert_matches_type(SyncCursorPaginationAfter[ChangelogListResponse], changelog, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_list(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.flagship.apps.flags.changelog.with_raw_response.list(
+ flag_key="flag_key",
+ account_id="",
+ app_id="app_id",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"):
+ client.flagship.apps.flags.changelog.with_raw_response.list(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `flag_key` but received ''"):
+ client.flagship.apps.flags.changelog.with_raw_response.list(
+ flag_key="",
+ account_id="account_id",
+ app_id="app_id",
+ )
+
+
+class TestAsyncChangelog:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncCloudflare) -> None:
+ changelog = await async_client.flagship.apps.flags.changelog.list(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ )
+ assert_matches_type(AsyncCursorPaginationAfter[ChangelogListResponse], changelog, path=["response"])
+
+ @parametrize
+ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ changelog = await async_client.flagship.apps.flags.changelog.list(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ cursor="cursor",
+ limit="limit",
+ )
+ assert_matches_type(AsyncCursorPaginationAfter[ChangelogListResponse], changelog, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.flagship.apps.flags.changelog.with_raw_response.list(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ changelog = await response.parse()
+ assert_matches_type(AsyncCursorPaginationAfter[ChangelogListResponse], changelog, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.flagship.apps.flags.changelog.with_streaming_response.list(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ changelog = await response.parse()
+ assert_matches_type(AsyncCursorPaginationAfter[ChangelogListResponse], changelog, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.flagship.apps.flags.changelog.with_raw_response.list(
+ flag_key="flag_key",
+ account_id="",
+ app_id="app_id",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"):
+ await async_client.flagship.apps.flags.changelog.with_raw_response.list(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `flag_key` but received ''"):
+ await async_client.flagship.apps.flags.changelog.with_raw_response.list(
+ flag_key="",
+ account_id="account_id",
+ app_id="app_id",
+ )
diff --git a/tests/api_resources/flagship/apps/test_evaluate.py b/tests/api_resources/flagship/apps/test_evaluate.py
new file mode 100644
index 00000000000..0d0d825c928
--- /dev/null
+++ b/tests/api_resources/flagship/apps/test_evaluate.py
@@ -0,0 +1,150 @@
+# 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.flagship.apps import EvaluateGetResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestEvaluate:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_get(self, client: Cloudflare) -> None:
+ evaluate = client.flagship.apps.evaluate.get(
+ app_id="app_id",
+ account_id="account_id",
+ flag_key="flagKey",
+ )
+ assert_matches_type(EvaluateGetResponse, evaluate, path=["response"])
+
+ @parametrize
+ def test_method_get_with_all_params(self, client: Cloudflare) -> None:
+ evaluate = client.flagship.apps.evaluate.get(
+ app_id="app_id",
+ account_id="account_id",
+ flag_key="flagKey",
+ targeting_key="targetingKey",
+ )
+ assert_matches_type(EvaluateGetResponse, evaluate, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Cloudflare) -> None:
+ response = client.flagship.apps.evaluate.with_raw_response.get(
+ app_id="app_id",
+ account_id="account_id",
+ flag_key="flagKey",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ evaluate = response.parse()
+ assert_matches_type(EvaluateGetResponse, evaluate, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Cloudflare) -> None:
+ with client.flagship.apps.evaluate.with_streaming_response.get(
+ app_id="app_id",
+ account_id="account_id",
+ flag_key="flagKey",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ evaluate = response.parse()
+ assert_matches_type(EvaluateGetResponse, evaluate, 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.flagship.apps.evaluate.with_raw_response.get(
+ app_id="app_id",
+ account_id="",
+ flag_key="flagKey",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"):
+ client.flagship.apps.evaluate.with_raw_response.get(
+ app_id="",
+ account_id="account_id",
+ flag_key="flagKey",
+ )
+
+
+class TestAsyncEvaluate:
+ 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:
+ evaluate = await async_client.flagship.apps.evaluate.get(
+ app_id="app_id",
+ account_id="account_id",
+ flag_key="flagKey",
+ )
+ assert_matches_type(EvaluateGetResponse, evaluate, path=["response"])
+
+ @parametrize
+ async def test_method_get_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ evaluate = await async_client.flagship.apps.evaluate.get(
+ app_id="app_id",
+ account_id="account_id",
+ flag_key="flagKey",
+ targeting_key="targetingKey",
+ )
+ assert_matches_type(EvaluateGetResponse, evaluate, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.flagship.apps.evaluate.with_raw_response.get(
+ app_id="app_id",
+ account_id="account_id",
+ flag_key="flagKey",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ evaluate = await response.parse()
+ assert_matches_type(EvaluateGetResponse, evaluate, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.flagship.apps.evaluate.with_streaming_response.get(
+ app_id="app_id",
+ account_id="account_id",
+ flag_key="flagKey",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ evaluate = await response.parse()
+ assert_matches_type(EvaluateGetResponse, evaluate, 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.flagship.apps.evaluate.with_raw_response.get(
+ app_id="app_id",
+ account_id="",
+ flag_key="flagKey",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"):
+ await async_client.flagship.apps.evaluate.with_raw_response.get(
+ app_id="",
+ account_id="account_id",
+ flag_key="flagKey",
+ )
diff --git a/tests/api_resources/flagship/apps/test_flags.py b/tests/api_resources/flagship/apps/test_flags.py
new file mode 100644
index 00000000000..9dc75645713
--- /dev/null
+++ b/tests/api_resources/flagship/apps/test_flags.py
@@ -0,0 +1,1103 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare.pagination import SyncCursorPaginationAfter, AsyncCursorPaginationAfter
+from cloudflare.types.flagship.apps import (
+ FlagGetResponse,
+ FlagListResponse,
+ FlagCreateResponse,
+ FlagDeleteResponse,
+ FlagUpdateResponse,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestFlags:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: Cloudflare) -> None:
+ flag = client.flagship.apps.flags.create(
+ app_id="app_id",
+ account_id="account_id",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ }
+ ],
+ variations={"foo": "string"},
+ )
+ assert_matches_type(FlagCreateResponse, flag, path=["response"])
+
+ @parametrize
+ def test_method_create_with_all_params(self, client: Cloudflare) -> None:
+ flag = client.flagship.apps.flags.create(
+ app_id="app_id",
+ account_id="account_id",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ "rollout": {
+ "percentage": 0,
+ "attribute": "x",
+ },
+ }
+ ],
+ variations={"foo": "string"},
+ description="description",
+ type="boolean",
+ )
+ assert_matches_type(FlagCreateResponse, flag, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Cloudflare) -> None:
+ response = client.flagship.apps.flags.with_raw_response.create(
+ app_id="app_id",
+ account_id="account_id",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ }
+ ],
+ variations={"foo": "string"},
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ flag = response.parse()
+ assert_matches_type(FlagCreateResponse, flag, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: Cloudflare) -> None:
+ with client.flagship.apps.flags.with_streaming_response.create(
+ app_id="app_id",
+ account_id="account_id",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ }
+ ],
+ variations={"foo": "string"},
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ flag = response.parse()
+ assert_matches_type(FlagCreateResponse, flag, 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.flagship.apps.flags.with_raw_response.create(
+ app_id="app_id",
+ account_id="",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ }
+ ],
+ variations={"foo": "string"},
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"):
+ client.flagship.apps.flags.with_raw_response.create(
+ app_id="",
+ account_id="account_id",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ }
+ ],
+ variations={"foo": "string"},
+ )
+
+ @parametrize
+ def test_method_update(self, client: Cloudflare) -> None:
+ flag = client.flagship.apps.flags.update(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ }
+ ],
+ variations={"foo": "string"},
+ )
+ assert_matches_type(FlagUpdateResponse, flag, path=["response"])
+
+ @parametrize
+ def test_method_update_with_all_params(self, client: Cloudflare) -> None:
+ flag = client.flagship.apps.flags.update(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ "rollout": {
+ "percentage": 0,
+ "attribute": "x",
+ },
+ }
+ ],
+ variations={"foo": "string"},
+ description="description",
+ type="boolean",
+ )
+ assert_matches_type(FlagUpdateResponse, flag, path=["response"])
+
+ @parametrize
+ def test_raw_response_update(self, client: Cloudflare) -> None:
+ response = client.flagship.apps.flags.with_raw_response.update(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ }
+ ],
+ variations={"foo": "string"},
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ flag = response.parse()
+ assert_matches_type(FlagUpdateResponse, flag, path=["response"])
+
+ @parametrize
+ def test_streaming_response_update(self, client: Cloudflare) -> None:
+ with client.flagship.apps.flags.with_streaming_response.update(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ }
+ ],
+ variations={"foo": "string"},
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ flag = response.parse()
+ assert_matches_type(FlagUpdateResponse, flag, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @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 ''"):
+ client.flagship.apps.flags.with_raw_response.update(
+ flag_key="flag_key",
+ account_id="",
+ app_id="app_id",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ }
+ ],
+ variations={"foo": "string"},
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"):
+ client.flagship.apps.flags.with_raw_response.update(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ }
+ ],
+ variations={"foo": "string"},
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `flag_key` but received ''"):
+ client.flagship.apps.flags.with_raw_response.update(
+ flag_key="",
+ account_id="account_id",
+ app_id="app_id",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ }
+ ],
+ variations={"foo": "string"},
+ )
+
+ @parametrize
+ def test_method_list(self, client: Cloudflare) -> None:
+ flag = client.flagship.apps.flags.list(
+ app_id="app_id",
+ account_id="account_id",
+ )
+ assert_matches_type(SyncCursorPaginationAfter[FlagListResponse], flag, path=["response"])
+
+ @parametrize
+ def test_method_list_with_all_params(self, client: Cloudflare) -> None:
+ flag = client.flagship.apps.flags.list(
+ app_id="app_id",
+ account_id="account_id",
+ cursor="cursor",
+ limit="limit",
+ )
+ assert_matches_type(SyncCursorPaginationAfter[FlagListResponse], flag, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Cloudflare) -> None:
+ response = client.flagship.apps.flags.with_raw_response.list(
+ app_id="app_id",
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ flag = response.parse()
+ assert_matches_type(SyncCursorPaginationAfter[FlagListResponse], flag, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Cloudflare) -> None:
+ with client.flagship.apps.flags.with_streaming_response.list(
+ app_id="app_id",
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ flag = response.parse()
+ assert_matches_type(SyncCursorPaginationAfter[FlagListResponse], flag, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_list(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.flagship.apps.flags.with_raw_response.list(
+ app_id="app_id",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"):
+ client.flagship.apps.flags.with_raw_response.list(
+ app_id="",
+ account_id="account_id",
+ )
+
+ @parametrize
+ def test_method_delete(self, client: Cloudflare) -> None:
+ flag = client.flagship.apps.flags.delete(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ )
+ assert_matches_type(FlagDeleteResponse, flag, path=["response"])
+
+ @parametrize
+ def test_raw_response_delete(self, client: Cloudflare) -> None:
+ response = client.flagship.apps.flags.with_raw_response.delete(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ flag = response.parse()
+ assert_matches_type(FlagDeleteResponse, flag, path=["response"])
+
+ @parametrize
+ def test_streaming_response_delete(self, client: Cloudflare) -> None:
+ with client.flagship.apps.flags.with_streaming_response.delete(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ flag = response.parse()
+ assert_matches_type(FlagDeleteResponse, flag, 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.flagship.apps.flags.with_raw_response.delete(
+ flag_key="flag_key",
+ account_id="",
+ app_id="app_id",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"):
+ client.flagship.apps.flags.with_raw_response.delete(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `flag_key` but received ''"):
+ client.flagship.apps.flags.with_raw_response.delete(
+ flag_key="",
+ account_id="account_id",
+ app_id="app_id",
+ )
+
+ @parametrize
+ def test_method_get(self, client: Cloudflare) -> None:
+ flag = client.flagship.apps.flags.get(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ )
+ assert_matches_type(FlagGetResponse, flag, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Cloudflare) -> None:
+ response = client.flagship.apps.flags.with_raw_response.get(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ flag = response.parse()
+ assert_matches_type(FlagGetResponse, flag, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Cloudflare) -> None:
+ with client.flagship.apps.flags.with_streaming_response.get(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ flag = response.parse()
+ assert_matches_type(FlagGetResponse, flag, 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.flagship.apps.flags.with_raw_response.get(
+ flag_key="flag_key",
+ account_id="",
+ app_id="app_id",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"):
+ client.flagship.apps.flags.with_raw_response.get(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `flag_key` but received ''"):
+ client.flagship.apps.flags.with_raw_response.get(
+ flag_key="",
+ account_id="account_id",
+ app_id="app_id",
+ )
+
+
+class TestAsyncFlags:
+ 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:
+ flag = await async_client.flagship.apps.flags.create(
+ app_id="app_id",
+ account_id="account_id",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ }
+ ],
+ variations={"foo": "string"},
+ )
+ assert_matches_type(FlagCreateResponse, flag, path=["response"])
+
+ @parametrize
+ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ flag = await async_client.flagship.apps.flags.create(
+ app_id="app_id",
+ account_id="account_id",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ "rollout": {
+ "percentage": 0,
+ "attribute": "x",
+ },
+ }
+ ],
+ variations={"foo": "string"},
+ description="description",
+ type="boolean",
+ )
+ assert_matches_type(FlagCreateResponse, flag, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.flagship.apps.flags.with_raw_response.create(
+ app_id="app_id",
+ account_id="account_id",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ }
+ ],
+ variations={"foo": "string"},
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ flag = await response.parse()
+ assert_matches_type(FlagCreateResponse, flag, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.flagship.apps.flags.with_streaming_response.create(
+ app_id="app_id",
+ account_id="account_id",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ }
+ ],
+ variations={"foo": "string"},
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ flag = await response.parse()
+ assert_matches_type(FlagCreateResponse, flag, 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.flagship.apps.flags.with_raw_response.create(
+ app_id="app_id",
+ account_id="",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ }
+ ],
+ variations={"foo": "string"},
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"):
+ await async_client.flagship.apps.flags.with_raw_response.create(
+ app_id="",
+ account_id="account_id",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ }
+ ],
+ variations={"foo": "string"},
+ )
+
+ @parametrize
+ async def test_method_update(self, async_client: AsyncCloudflare) -> None:
+ flag = await async_client.flagship.apps.flags.update(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ }
+ ],
+ variations={"foo": "string"},
+ )
+ assert_matches_type(FlagUpdateResponse, flag, path=["response"])
+
+ @parametrize
+ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ flag = await async_client.flagship.apps.flags.update(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ "rollout": {
+ "percentage": 0,
+ "attribute": "x",
+ },
+ }
+ ],
+ variations={"foo": "string"},
+ description="description",
+ type="boolean",
+ )
+ assert_matches_type(FlagUpdateResponse, flag, path=["response"])
+
+ @parametrize
+ async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.flagship.apps.flags.with_raw_response.update(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ }
+ ],
+ variations={"foo": "string"},
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ flag = await response.parse()
+ assert_matches_type(FlagUpdateResponse, flag, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.flagship.apps.flags.with_streaming_response.update(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ }
+ ],
+ variations={"foo": "string"},
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ flag = await response.parse()
+ assert_matches_type(FlagUpdateResponse, flag, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @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 ''"):
+ await async_client.flagship.apps.flags.with_raw_response.update(
+ flag_key="flag_key",
+ account_id="",
+ app_id="app_id",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ }
+ ],
+ variations={"foo": "string"},
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"):
+ await async_client.flagship.apps.flags.with_raw_response.update(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ }
+ ],
+ variations={"foo": "string"},
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `flag_key` but received ''"):
+ await async_client.flagship.apps.flags.with_raw_response.update(
+ flag_key="",
+ account_id="account_id",
+ app_id="app_id",
+ default_variation="x",
+ enabled=True,
+ key="x",
+ rules=[
+ {
+ "conditions": [
+ {
+ "attribute": "x",
+ "operator": "equals",
+ "value": {},
+ }
+ ],
+ "priority": 1,
+ "serve_variation": "x",
+ }
+ ],
+ variations={"foo": "string"},
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncCloudflare) -> None:
+ flag = await async_client.flagship.apps.flags.list(
+ app_id="app_id",
+ account_id="account_id",
+ )
+ assert_matches_type(AsyncCursorPaginationAfter[FlagListResponse], flag, path=["response"])
+
+ @parametrize
+ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ flag = await async_client.flagship.apps.flags.list(
+ app_id="app_id",
+ account_id="account_id",
+ cursor="cursor",
+ limit="limit",
+ )
+ assert_matches_type(AsyncCursorPaginationAfter[FlagListResponse], flag, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.flagship.apps.flags.with_raw_response.list(
+ app_id="app_id",
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ flag = await response.parse()
+ assert_matches_type(AsyncCursorPaginationAfter[FlagListResponse], flag, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.flagship.apps.flags.with_streaming_response.list(
+ app_id="app_id",
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ flag = await response.parse()
+ assert_matches_type(AsyncCursorPaginationAfter[FlagListResponse], flag, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.flagship.apps.flags.with_raw_response.list(
+ app_id="app_id",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"):
+ await async_client.flagship.apps.flags.with_raw_response.list(
+ app_id="",
+ account_id="account_id",
+ )
+
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncCloudflare) -> None:
+ flag = await async_client.flagship.apps.flags.delete(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ )
+ assert_matches_type(FlagDeleteResponse, flag, path=["response"])
+
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.flagship.apps.flags.with_raw_response.delete(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ flag = await response.parse()
+ assert_matches_type(FlagDeleteResponse, flag, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.flagship.apps.flags.with_streaming_response.delete(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ flag = await response.parse()
+ assert_matches_type(FlagDeleteResponse, flag, 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.flagship.apps.flags.with_raw_response.delete(
+ flag_key="flag_key",
+ account_id="",
+ app_id="app_id",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"):
+ await async_client.flagship.apps.flags.with_raw_response.delete(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `flag_key` but received ''"):
+ await async_client.flagship.apps.flags.with_raw_response.delete(
+ flag_key="",
+ account_id="account_id",
+ app_id="app_id",
+ )
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncCloudflare) -> None:
+ flag = await async_client.flagship.apps.flags.get(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ )
+ assert_matches_type(FlagGetResponse, flag, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.flagship.apps.flags.with_raw_response.get(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ flag = await response.parse()
+ assert_matches_type(FlagGetResponse, flag, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.flagship.apps.flags.with_streaming_response.get(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="app_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ flag = await response.parse()
+ assert_matches_type(FlagGetResponse, flag, 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.flagship.apps.flags.with_raw_response.get(
+ flag_key="flag_key",
+ account_id="",
+ app_id="app_id",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"):
+ await async_client.flagship.apps.flags.with_raw_response.get(
+ flag_key="flag_key",
+ account_id="account_id",
+ app_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `flag_key` but received ''"):
+ await async_client.flagship.apps.flags.with_raw_response.get(
+ flag_key="",
+ account_id="account_id",
+ app_id="app_id",
+ )
diff --git a/tests/api_resources/flagship/test_apps.py b/tests/api_resources/flagship/test_apps.py
new file mode 100644
index 00000000000..5d8f4e58caa
--- /dev/null
+++ b/tests/api_resources/flagship/test_apps.py
@@ -0,0 +1,497 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare.pagination import SyncSinglePage, AsyncSinglePage
+from cloudflare.types.flagship import (
+ AppGetResponse,
+ AppListResponse,
+ AppCreateResponse,
+ AppDeleteResponse,
+ AppUpdateResponse,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestApps:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: Cloudflare) -> None:
+ app = client.flagship.apps.create(
+ account_id="account_id",
+ name="x",
+ )
+ assert_matches_type(AppCreateResponse, app, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Cloudflare) -> None:
+ response = client.flagship.apps.with_raw_response.create(
+ account_id="account_id",
+ name="x",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ app = response.parse()
+ assert_matches_type(AppCreateResponse, app, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: Cloudflare) -> None:
+ with client.flagship.apps.with_streaming_response.create(
+ account_id="account_id",
+ name="x",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ app = response.parse()
+ assert_matches_type(AppCreateResponse, app, 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.flagship.apps.with_raw_response.create(
+ account_id="",
+ name="x",
+ )
+
+ @parametrize
+ def test_method_update(self, client: Cloudflare) -> None:
+ app = client.flagship.apps.update(
+ app_id="app_id",
+ account_id="account_id",
+ )
+ assert_matches_type(AppUpdateResponse, app, path=["response"])
+
+ @parametrize
+ def test_method_update_with_all_params(self, client: Cloudflare) -> None:
+ app = client.flagship.apps.update(
+ app_id="app_id",
+ account_id="account_id",
+ name="x",
+ )
+ assert_matches_type(AppUpdateResponse, app, path=["response"])
+
+ @parametrize
+ def test_raw_response_update(self, client: Cloudflare) -> None:
+ response = client.flagship.apps.with_raw_response.update(
+ app_id="app_id",
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ app = response.parse()
+ assert_matches_type(AppUpdateResponse, app, path=["response"])
+
+ @parametrize
+ def test_streaming_response_update(self, client: Cloudflare) -> None:
+ with client.flagship.apps.with_streaming_response.update(
+ app_id="app_id",
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ app = response.parse()
+ assert_matches_type(AppUpdateResponse, app, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @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 ''"):
+ client.flagship.apps.with_raw_response.update(
+ app_id="app_id",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"):
+ client.flagship.apps.with_raw_response.update(
+ app_id="",
+ account_id="account_id",
+ )
+
+ @parametrize
+ def test_method_list(self, client: Cloudflare) -> None:
+ app = client.flagship.apps.list(
+ account_id="account_id",
+ )
+ assert_matches_type(SyncSinglePage[AppListResponse], app, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Cloudflare) -> None:
+ response = client.flagship.apps.with_raw_response.list(
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ app = response.parse()
+ assert_matches_type(SyncSinglePage[AppListResponse], app, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Cloudflare) -> None:
+ with client.flagship.apps.with_streaming_response.list(
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ app = response.parse()
+ assert_matches_type(SyncSinglePage[AppListResponse], app, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_list(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.flagship.apps.with_raw_response.list(
+ account_id="",
+ )
+
+ @parametrize
+ def test_method_delete(self, client: Cloudflare) -> None:
+ app = client.flagship.apps.delete(
+ app_id="app_id",
+ account_id="account_id",
+ )
+ assert_matches_type(AppDeleteResponse, app, path=["response"])
+
+ @parametrize
+ def test_raw_response_delete(self, client: Cloudflare) -> None:
+ response = client.flagship.apps.with_raw_response.delete(
+ app_id="app_id",
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ app = response.parse()
+ assert_matches_type(AppDeleteResponse, app, path=["response"])
+
+ @parametrize
+ def test_streaming_response_delete(self, client: Cloudflare) -> None:
+ with client.flagship.apps.with_streaming_response.delete(
+ app_id="app_id",
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ app = response.parse()
+ assert_matches_type(AppDeleteResponse, app, 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.flagship.apps.with_raw_response.delete(
+ app_id="app_id",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"):
+ client.flagship.apps.with_raw_response.delete(
+ app_id="",
+ account_id="account_id",
+ )
+
+ @parametrize
+ def test_method_get(self, client: Cloudflare) -> None:
+ app = client.flagship.apps.get(
+ app_id="app_id",
+ account_id="account_id",
+ )
+ assert_matches_type(AppGetResponse, app, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Cloudflare) -> None:
+ response = client.flagship.apps.with_raw_response.get(
+ app_id="app_id",
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ app = response.parse()
+ assert_matches_type(AppGetResponse, app, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Cloudflare) -> None:
+ with client.flagship.apps.with_streaming_response.get(
+ app_id="app_id",
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ app = response.parse()
+ assert_matches_type(AppGetResponse, app, 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.flagship.apps.with_raw_response.get(
+ app_id="app_id",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"):
+ client.flagship.apps.with_raw_response.get(
+ app_id="",
+ account_id="account_id",
+ )
+
+
+class TestAsyncApps:
+ 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:
+ app = await async_client.flagship.apps.create(
+ account_id="account_id",
+ name="x",
+ )
+ assert_matches_type(AppCreateResponse, app, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.flagship.apps.with_raw_response.create(
+ account_id="account_id",
+ name="x",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ app = await response.parse()
+ assert_matches_type(AppCreateResponse, app, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.flagship.apps.with_streaming_response.create(
+ account_id="account_id",
+ name="x",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ app = await response.parse()
+ assert_matches_type(AppCreateResponse, app, 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.flagship.apps.with_raw_response.create(
+ account_id="",
+ name="x",
+ )
+
+ @parametrize
+ async def test_method_update(self, async_client: AsyncCloudflare) -> None:
+ app = await async_client.flagship.apps.update(
+ app_id="app_id",
+ account_id="account_id",
+ )
+ assert_matches_type(AppUpdateResponse, app, path=["response"])
+
+ @parametrize
+ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ app = await async_client.flagship.apps.update(
+ app_id="app_id",
+ account_id="account_id",
+ name="x",
+ )
+ assert_matches_type(AppUpdateResponse, app, path=["response"])
+
+ @parametrize
+ async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.flagship.apps.with_raw_response.update(
+ app_id="app_id",
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ app = await response.parse()
+ assert_matches_type(AppUpdateResponse, app, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.flagship.apps.with_streaming_response.update(
+ app_id="app_id",
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ app = await response.parse()
+ assert_matches_type(AppUpdateResponse, app, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @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 ''"):
+ await async_client.flagship.apps.with_raw_response.update(
+ app_id="app_id",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"):
+ await async_client.flagship.apps.with_raw_response.update(
+ app_id="",
+ account_id="account_id",
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncCloudflare) -> None:
+ app = await async_client.flagship.apps.list(
+ account_id="account_id",
+ )
+ assert_matches_type(AsyncSinglePage[AppListResponse], app, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.flagship.apps.with_raw_response.list(
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ app = await response.parse()
+ assert_matches_type(AsyncSinglePage[AppListResponse], app, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.flagship.apps.with_streaming_response.list(
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ app = await response.parse()
+ assert_matches_type(AsyncSinglePage[AppListResponse], app, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.flagship.apps.with_raw_response.list(
+ account_id="",
+ )
+
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncCloudflare) -> None:
+ app = await async_client.flagship.apps.delete(
+ app_id="app_id",
+ account_id="account_id",
+ )
+ assert_matches_type(AppDeleteResponse, app, path=["response"])
+
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.flagship.apps.with_raw_response.delete(
+ app_id="app_id",
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ app = await response.parse()
+ assert_matches_type(AppDeleteResponse, app, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.flagship.apps.with_streaming_response.delete(
+ app_id="app_id",
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ app = await response.parse()
+ assert_matches_type(AppDeleteResponse, app, 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.flagship.apps.with_raw_response.delete(
+ app_id="app_id",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"):
+ await async_client.flagship.apps.with_raw_response.delete(
+ app_id="",
+ account_id="account_id",
+ )
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncCloudflare) -> None:
+ app = await async_client.flagship.apps.get(
+ app_id="app_id",
+ account_id="account_id",
+ )
+ assert_matches_type(AppGetResponse, app, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.flagship.apps.with_raw_response.get(
+ app_id="app_id",
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ app = await response.parse()
+ assert_matches_type(AppGetResponse, app, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.flagship.apps.with_streaming_response.get(
+ app_id="app_id",
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ app = await response.parse()
+ assert_matches_type(AppGetResponse, app, 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.flagship.apps.with_raw_response.get(
+ app_id="app_id",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `app_id` but received ''"):
+ await async_client.flagship.apps.with_raw_response.get(
+ app_id="",
+ account_id="account_id",
+ )
diff --git a/tests/api_resources/iam/test_oauth_scopes.py b/tests/api_resources/iam/test_oauth_scopes.py
index e08cafecc36..662ec81864c 100644
--- a/tests/api_resources/iam/test_oauth_scopes.py
+++ b/tests/api_resources/iam/test_oauth_scopes.py
@@ -9,8 +9,8 @@
from cloudflare import Cloudflare, AsyncCloudflare
from tests.utils import assert_matches_type
+from cloudflare.types.iam import OAuthScopeListResponse
from cloudflare.pagination import SyncSinglePage, AsyncSinglePage
-from cloudflare.types.iam.oauth_scopes import OAuthScopeListResponse
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
diff --git a/tests/api_resources/origin_tls_compliance_modes/__init__.py b/tests/api_resources/origin_tls_compliance_modes/__init__.py
new file mode 100644
index 00000000000..fd8019a9a1a
--- /dev/null
+++ b/tests/api_resources/origin_tls_compliance_modes/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/test_email_sending.py b/tests/api_resources/test_email_sending.py
index 16c993039fb..c7e683354d7 100644
--- a/tests/api_resources/test_email_sending.py
+++ b/tests/api_resources/test_email_sending.py
@@ -26,7 +26,6 @@ def test_method_send(self, client: Cloudflare) -> None:
account_id="account_id",
from_="sender@example.com",
subject="Monthly Report",
- to=["recipient@example.com"],
)
assert_matches_type(EmailSendingSendResponse, email_sending, path=["response"])
@@ -36,7 +35,6 @@ def test_method_send_with_all_params(self, client: Cloudflare) -> None:
account_id="account_id",
from_="sender@example.com",
subject="Monthly Report",
- to=["recipient@example.com"],
attachments=[
{
"content": "JVBERi0xLjQK...",
@@ -51,6 +49,7 @@ def test_method_send_with_all_params(self, client: Cloudflare) -> None:
html="
Please find your report attached.
", reply_to="user@example.com", text="Hello\n\nPlease find your report attached.", + to=["recipient@example.com"], ) assert_matches_type(EmailSendingSendResponse, email_sending, path=["response"]) @@ -60,7 +59,6 @@ def test_raw_response_send(self, client: Cloudflare) -> None: account_id="account_id", from_="sender@example.com", subject="Monthly Report", - to=["recipient@example.com"], ) assert response.is_closed is True @@ -74,7 +72,6 @@ def test_streaming_response_send(self, client: Cloudflare) -> None: account_id="account_id", from_="sender@example.com", subject="Monthly Report", - to=["recipient@example.com"], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -91,7 +88,6 @@ def test_path_params_send(self, client: Cloudflare) -> None: account_id="", from_="sender@example.com", subject="Monthly Report", - to=["recipient@example.com"], ) @parametrize @@ -156,7 +152,6 @@ async def test_method_send(self, async_client: AsyncCloudflare) -> None: account_id="account_id", from_="sender@example.com", subject="Monthly Report", - to=["recipient@example.com"], ) assert_matches_type(EmailSendingSendResponse, email_sending, path=["response"]) @@ -166,7 +161,6 @@ async def test_method_send_with_all_params(self, async_client: AsyncCloudflare) account_id="account_id", from_="sender@example.com", subject="Monthly Report", - to=["recipient@example.com"], attachments=[ { "content": "JVBERi0xLjQK...", @@ -181,6 +175,7 @@ async def test_method_send_with_all_params(self, async_client: AsyncCloudflare) html="Please find your report attached.
", reply_to="user@example.com", text="Hello\n\nPlease find your report attached.", + to=["recipient@example.com"], ) assert_matches_type(EmailSendingSendResponse, email_sending, path=["response"]) @@ -190,7 +185,6 @@ async def test_raw_response_send(self, async_client: AsyncCloudflare) -> None: account_id="account_id", from_="sender@example.com", subject="Monthly Report", - to=["recipient@example.com"], ) assert response.is_closed is True @@ -204,7 +198,6 @@ async def test_streaming_response_send(self, async_client: AsyncCloudflare) -> N account_id="account_id", from_="sender@example.com", subject="Monthly Report", - to=["recipient@example.com"], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -221,7 +214,6 @@ async def test_path_params_send(self, async_client: AsyncCloudflare) -> None: account_id="", from_="sender@example.com", subject="Monthly Report", - to=["recipient@example.com"], ) @parametrize diff --git a/tests/api_resources/test_managed_transforms.py b/tests/api_resources/test_managed_transforms.py index d2e91bfbb4f..846fa1ad28a 100644 --- a/tests/api_resources/test_managed_transforms.py +++ b/tests/api_resources/test_managed_transforms.py @@ -107,6 +107,14 @@ def test_path_params_delete(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate unauthorized HTTP response") @parametrize def test_method_edit(self, client: Cloudflare) -> None: + managed_transform = client.managed_transforms.edit( + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + assert_matches_type(ManagedTransformEditResponse, managed_transform, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate unauthorized HTTP response") + @parametrize + def test_method_edit_with_all_params(self, client: Cloudflare) -> None: managed_transform = client.managed_transforms.edit( zone_id="9f1839b6152d298aca64c4e906b6d074", managed_request_headers=[ @@ -129,18 +137,6 @@ def test_method_edit(self, client: Cloudflare) -> None: def test_raw_response_edit(self, client: Cloudflare) -> None: response = client.managed_transforms.with_raw_response.edit( zone_id="9f1839b6152d298aca64c4e906b6d074", - managed_request_headers=[ - { - "id": "add_bot_protection_headers", - "enabled": True, - } - ], - managed_response_headers=[ - { - "id": "add_security_headers", - "enabled": True, - } - ], ) assert response.is_closed is True @@ -153,18 +149,6 @@ def test_raw_response_edit(self, client: Cloudflare) -> None: def test_streaming_response_edit(self, client: Cloudflare) -> None: with client.managed_transforms.with_streaming_response.edit( zone_id="9f1839b6152d298aca64c4e906b6d074", - managed_request_headers=[ - { - "id": "add_bot_protection_headers", - "enabled": True, - } - ], - managed_response_headers=[ - { - "id": "add_security_headers", - "enabled": True, - } - ], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -180,18 +164,6 @@ def test_path_params_edit(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): client.managed_transforms.with_raw_response.edit( zone_id="", - managed_request_headers=[ - { - "id": "add_bot_protection_headers", - "enabled": True, - } - ], - managed_response_headers=[ - { - "id": "add_security_headers", - "enabled": True, - } - ], ) @@ -287,6 +259,14 @@ async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None: @pytest.mark.skip(reason="TODO: investigate unauthorized HTTP response") @parametrize async def test_method_edit(self, async_client: AsyncCloudflare) -> None: + managed_transform = await async_client.managed_transforms.edit( + zone_id="9f1839b6152d298aca64c4e906b6d074", + ) + assert_matches_type(ManagedTransformEditResponse, managed_transform, path=["response"]) + + @pytest.mark.skip(reason="TODO: investigate unauthorized HTTP response") + @parametrize + async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) -> None: managed_transform = await async_client.managed_transforms.edit( zone_id="9f1839b6152d298aca64c4e906b6d074", managed_request_headers=[ @@ -309,18 +289,6 @@ async def test_method_edit(self, async_client: AsyncCloudflare) -> None: async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None: response = await async_client.managed_transforms.with_raw_response.edit( zone_id="9f1839b6152d298aca64c4e906b6d074", - managed_request_headers=[ - { - "id": "add_bot_protection_headers", - "enabled": True, - } - ], - managed_response_headers=[ - { - "id": "add_security_headers", - "enabled": True, - } - ], ) assert response.is_closed is True @@ -333,18 +301,6 @@ async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None: async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> None: async with async_client.managed_transforms.with_streaming_response.edit( zone_id="9f1839b6152d298aca64c4e906b6d074", - managed_request_headers=[ - { - "id": "add_bot_protection_headers", - "enabled": True, - } - ], - managed_response_headers=[ - { - "id": "add_security_headers", - "enabled": True, - } - ], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -360,16 +316,4 @@ async def test_path_params_edit(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): await async_client.managed_transforms.with_raw_response.edit( zone_id="", - managed_request_headers=[ - { - "id": "add_bot_protection_headers", - "enabled": True, - } - ], - managed_response_headers=[ - { - "id": "add_security_headers", - "enabled": True, - } - ], ) diff --git a/tests/api_resources/workers/observability/test_queries.py b/tests/api_resources/workers/observability/test_queries.py index 0b35362c9c1..6e212a5bfc2 100644 --- a/tests/api_resources/workers/observability/test_queries.py +++ b/tests/api_resources/workers/observability/test_queries.py @@ -53,7 +53,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: "filters": [ { "filter_combination": "and", - "filters": [{}], + "filters": [], "kind": "group", } ], @@ -214,7 +214,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare "filters": [ { "filter_combination": "and", - "filters": [{}], + "filters": [], "kind": "group", } ], diff --git a/tests/api_resources/workers/observability/test_shared_queries.py b/tests/api_resources/workers/observability/test_shared_queries.py index 33cf3151f60..baa7a7326e0 100644 --- a/tests/api_resources/workers/observability/test_shared_queries.py +++ b/tests/api_resources/workers/observability/test_shared_queries.py @@ -67,7 +67,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: "filters": [ { "filter_combination": "and", - "filters": [{}], + "filters": [], "kind": "group", } ], @@ -258,7 +258,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare "filters": [ { "filter_combination": "and", - "filters": [{}], + "filters": [], "kind": "group", } ], diff --git a/tests/api_resources/workers/observability/test_telemetry.py b/tests/api_resources/workers/observability/test_telemetry.py index 98e585f23da..3be3cfc8411 100644 --- a/tests/api_resources/workers/observability/test_telemetry.py +++ b/tests/api_resources/workers/observability/test_telemetry.py @@ -43,7 +43,7 @@ def test_method_keys_with_all_params(self, client: Cloudflare) -> None: "filters": [ { "filter_combination": "and", - "filters": [{}], + "filters": [], "kind": "group", } ], @@ -120,7 +120,7 @@ def test_method_live_tail_with_all_params(self, client: Cloudflare) -> None: "filters": [ { "filter_combination": "and", - "filters": [{}], + "filters": [], "kind": "group", } ], @@ -265,7 +265,7 @@ def test_method_query_with_all_params(self, client: Cloudflare) -> None: "filters": [ { "filter_combination": "and", - "filters": [{}], + "filters": [], "kind": "group", } ], @@ -382,7 +382,7 @@ def test_method_values_with_all_params(self, client: Cloudflare) -> None: "filters": [ { "filter_combination": "and", - "filters": [{}], + "filters": [], "kind": "group", } ], @@ -479,7 +479,7 @@ async def test_method_keys_with_all_params(self, async_client: AsyncCloudflare) "filters": [ { "filter_combination": "and", - "filters": [{}], + "filters": [], "kind": "group", } ], @@ -556,7 +556,7 @@ async def test_method_live_tail_with_all_params(self, async_client: AsyncCloudfl "filters": [ { "filter_combination": "and", - "filters": [{}], + "filters": [], "kind": "group", } ], @@ -701,7 +701,7 @@ async def test_method_query_with_all_params(self, async_client: AsyncCloudflare) "filters": [ { "filter_combination": "and", - "filters": [{}], + "filters": [], "kind": "group", } ], @@ -818,7 +818,7 @@ async def test_method_values_with_all_params(self, async_client: AsyncCloudflare "filters": [ { "filter_combination": "and", - "filters": [{}], + "filters": [], "kind": "group", } ], diff --git a/tests/api_resources/zero_trust/access/ai_controls/mcp/test_servers.py b/tests/api_resources/zero_trust/access/ai_controls/mcp/test_servers.py index 33145a04d0d..402a5724124 100644 --- a/tests/api_resources/zero_trust/access/ai_controls/mcp/test_servers.py +++ b/tests/api_resources/zero_trust/access/ai_controls/mcp/test_servers.py @@ -47,6 +47,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: auth_credentials="auth_credentials", description="This is one remote mcp server", is_shared_oauth_callback_enabled=True, + secure_web_gateway=False, updated_prompts=[ { "name": "name", @@ -126,6 +127,7 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: description="This is one remote mcp server", is_shared_oauth_callback_enabled=True, name="My MCP Server", + secure_web_gateway=False, updated_prompts=[ { "name": "name", @@ -405,6 +407,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare auth_credentials="auth_credentials", description="This is one remote mcp server", is_shared_oauth_callback_enabled=True, + secure_web_gateway=False, updated_prompts=[ { "name": "name", @@ -484,6 +487,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare description="This is one remote mcp server", is_shared_oauth_callback_enabled=True, name="My MCP Server", + secure_web_gateway=False, updated_prompts=[ { "name": "name", diff --git a/tests/api_resources/zero_trust/dlp/data_tag_categories/__init__.py b/tests/api_resources/zero_trust/dlp/data_tag_categories/__init__.py new file mode 100644 index 00000000000..fd8019a9a1a --- /dev/null +++ b/tests/api_resources/zero_trust/dlp/data_tag_categories/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/zero_trust/dlp/data_tag_categories/test_data_tags.py b/tests/api_resources/zero_trust/dlp/data_tag_categories/test_data_tags.py new file mode 100644 index 00000000000..bbd693f16eb --- /dev/null +++ b/tests/api_resources/zero_trust/dlp/data_tag_categories/test_data_tags.py @@ -0,0 +1,634 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +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 +from cloudflare.types.zero_trust.dlp.data_tag_categories import ( + DataTagGetResponse, + DataTagListResponse, + DataTagCreateResponse, + DataTagUpdateResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestDataTags: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + data_tag = client.zero_trust.dlp.data_tag_categories.data_tags.create( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + name="name", + ) + assert_matches_type(Optional[DataTagCreateResponse], data_tag, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + data_tag = client.zero_trust.dlp.data_tag_categories.data_tags.create( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + name="name", + description="description", + ) + assert_matches_type(Optional[DataTagCreateResponse], data_tag, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.create( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + name="name", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_tag = response.parse() + assert_matches_type(Optional[DataTagCreateResponse], data_tag, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.data_tag_categories.data_tags.with_streaming_response.create( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + name="name", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_tag = response.parse() + assert_matches_type(Optional[DataTagCreateResponse], data_tag, 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.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.create( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + name="name", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `category_id` but received ''"): + client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.create( + category_id="", + account_id="account_id", + name="name", + ) + + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + data_tag = client.zero_trust.dlp.data_tag_categories.data_tags.update( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(Optional[DataTagUpdateResponse], data_tag, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: Cloudflare) -> None: + data_tag = client.zero_trust.dlp.data_tag_categories.data_tags.update( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + description="description", + name="name", + ) + assert_matches_type(Optional[DataTagUpdateResponse], data_tag, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.update( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_tag = response.parse() + assert_matches_type(Optional[DataTagUpdateResponse], data_tag, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.data_tag_categories.data_tags.with_streaming_response.update( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_tag = response.parse() + assert_matches_type(Optional[DataTagUpdateResponse], data_tag, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @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 ''"): + client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.update( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `category_id` but received ''"): + client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.update( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `tag_id` but received ''"): + client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.update( + tag_id="", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + data_tag = client.zero_trust.dlp.data_tag_categories.data_tags.list( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(SyncSinglePage[DataTagListResponse], data_tag, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.list( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_tag = response.parse() + assert_matches_type(SyncSinglePage[DataTagListResponse], data_tag, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.data_tag_categories.data_tags.with_streaming_response.list( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_tag = response.parse() + assert_matches_type(SyncSinglePage[DataTagListResponse], data_tag, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.list( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `category_id` but received ''"): + client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.list( + category_id="", + account_id="account_id", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + data_tag = client.zero_trust.dlp.data_tag_categories.data_tags.delete( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(object, data_tag, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.delete( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_tag = response.parse() + assert_matches_type(object, data_tag, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.data_tag_categories.data_tags.with_streaming_response.delete( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_tag = response.parse() + assert_matches_type(object, data_tag, 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.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.delete( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `category_id` but received ''"): + client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.delete( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `tag_id` but received ''"): + client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.delete( + tag_id="", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + data_tag = client.zero_trust.dlp.data_tag_categories.data_tags.get( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(Optional[DataTagGetResponse], data_tag, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.get( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_tag = response.parse() + assert_matches_type(Optional[DataTagGetResponse], data_tag, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.data_tag_categories.data_tags.with_streaming_response.get( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_tag = response.parse() + assert_matches_type(Optional[DataTagGetResponse], data_tag, 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.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.get( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `category_id` but received ''"): + client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.get( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `tag_id` but received ''"): + client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.get( + tag_id="", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + +class TestAsyncDataTags: + 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: + data_tag = await async_client.zero_trust.dlp.data_tag_categories.data_tags.create( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + name="name", + ) + assert_matches_type(Optional[DataTagCreateResponse], data_tag, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + data_tag = await async_client.zero_trust.dlp.data_tag_categories.data_tags.create( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + name="name", + description="description", + ) + assert_matches_type(Optional[DataTagCreateResponse], data_tag, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.create( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + name="name", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_tag = await response.parse() + assert_matches_type(Optional[DataTagCreateResponse], data_tag, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.data_tag_categories.data_tags.with_streaming_response.create( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + name="name", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_tag = await response.parse() + assert_matches_type(Optional[DataTagCreateResponse], data_tag, 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.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.create( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + name="name", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `category_id` but received ''"): + await async_client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.create( + category_id="", + account_id="account_id", + name="name", + ) + + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + data_tag = await async_client.zero_trust.dlp.data_tag_categories.data_tags.update( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(Optional[DataTagUpdateResponse], data_tag, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: + data_tag = await async_client.zero_trust.dlp.data_tag_categories.data_tags.update( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + description="description", + name="name", + ) + assert_matches_type(Optional[DataTagUpdateResponse], data_tag, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.update( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_tag = await response.parse() + assert_matches_type(Optional[DataTagUpdateResponse], data_tag, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.data_tag_categories.data_tags.with_streaming_response.update( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_tag = await response.parse() + assert_matches_type(Optional[DataTagUpdateResponse], data_tag, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @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 ''"): + await async_client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.update( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `category_id` but received ''"): + await async_client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.update( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `tag_id` but received ''"): + await async_client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.update( + tag_id="", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + data_tag = await async_client.zero_trust.dlp.data_tag_categories.data_tags.list( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(AsyncSinglePage[DataTagListResponse], data_tag, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.list( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_tag = await response.parse() + assert_matches_type(AsyncSinglePage[DataTagListResponse], data_tag, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.data_tag_categories.data_tags.with_streaming_response.list( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_tag = await response.parse() + assert_matches_type(AsyncSinglePage[DataTagListResponse], data_tag, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.list( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `category_id` but received ''"): + await async_client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.list( + category_id="", + account_id="account_id", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + data_tag = await async_client.zero_trust.dlp.data_tag_categories.data_tags.delete( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(object, data_tag, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.delete( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_tag = await response.parse() + assert_matches_type(object, data_tag, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.data_tag_categories.data_tags.with_streaming_response.delete( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_tag = await response.parse() + assert_matches_type(object, data_tag, 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.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.delete( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `category_id` but received ''"): + await async_client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.delete( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `tag_id` but received ''"): + await async_client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.delete( + tag_id="", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + data_tag = await async_client.zero_trust.dlp.data_tag_categories.data_tags.get( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(Optional[DataTagGetResponse], data_tag, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.get( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_tag = await response.parse() + assert_matches_type(Optional[DataTagGetResponse], data_tag, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.data_tag_categories.data_tags.with_streaming_response.get( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_tag = await response.parse() + assert_matches_type(Optional[DataTagGetResponse], data_tag, 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.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.get( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `category_id` but received ''"): + await async_client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.get( + tag_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + category_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `tag_id` but received ''"): + await async_client.zero_trust.dlp.data_tag_categories.data_tags.with_raw_response.get( + tag_id="", + account_id="account_id", + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) diff --git a/tests/api_resources/zero_trust/dlp/sensitivity_groups/__init__.py b/tests/api_resources/zero_trust/dlp/sensitivity_groups/__init__.py new file mode 100644 index 00000000000..fd8019a9a1a --- /dev/null +++ b/tests/api_resources/zero_trust/dlp/sensitivity_groups/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/zero_trust/dlp/sensitivity_groups/levels/__init__.py b/tests/api_resources/zero_trust/dlp/sensitivity_groups/levels/__init__.py new file mode 100644 index 00000000000..fd8019a9a1a --- /dev/null +++ b/tests/api_resources/zero_trust/dlp/sensitivity_groups/levels/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/zero_trust/dlp/sensitivity_groups/levels/test_order.py b/tests/api_resources/zero_trust/dlp/sensitivity_groups/levels/test_order.py new file mode 100644 index 00000000000..03d3585b4f1 --- /dev/null +++ b/tests/api_resources/zero_trust/dlp/sensitivity_groups/levels/test_order.py @@ -0,0 +1,229 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, Optional, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.types.zero_trust.dlp.sensitivity_groups.levels import ( + OrderGetResponse, + OrderUpdateResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestOrder: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + order = client.zero_trust.dlp.sensitivity_groups.levels.order.update( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + level_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) + assert_matches_type(Optional[OrderUpdateResponse], order, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.sensitivity_groups.levels.order.with_raw_response.update( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + level_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + order = response.parse() + assert_matches_type(Optional[OrderUpdateResponse], order, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.sensitivity_groups.levels.order.with_streaming_response.update( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + level_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + order = response.parse() + assert_matches_type(Optional[OrderUpdateResponse], order, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @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 ''"): + client.zero_trust.dlp.sensitivity_groups.levels.order.with_raw_response.update( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + level_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_group_id` but received ''"): + client.zero_trust.dlp.sensitivity_groups.levels.order.with_raw_response.update( + sensitivity_group_id="", + account_id="account_id", + level_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + order = client.zero_trust.dlp.sensitivity_groups.levels.order.get( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(Optional[OrderGetResponse], order, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.sensitivity_groups.levels.order.with_raw_response.get( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + order = response.parse() + assert_matches_type(Optional[OrderGetResponse], order, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.sensitivity_groups.levels.order.with_streaming_response.get( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + order = response.parse() + assert_matches_type(Optional[OrderGetResponse], order, 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.zero_trust.dlp.sensitivity_groups.levels.order.with_raw_response.get( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_group_id` but received ''"): + client.zero_trust.dlp.sensitivity_groups.levels.order.with_raw_response.get( + sensitivity_group_id="", + account_id="account_id", + ) + + +class TestAsyncOrder: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + order = await async_client.zero_trust.dlp.sensitivity_groups.levels.order.update( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + level_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) + assert_matches_type(Optional[OrderUpdateResponse], order, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.sensitivity_groups.levels.order.with_raw_response.update( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + level_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + order = await response.parse() + assert_matches_type(Optional[OrderUpdateResponse], order, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.sensitivity_groups.levels.order.with_streaming_response.update( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + level_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + order = await response.parse() + assert_matches_type(Optional[OrderUpdateResponse], order, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @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 ''"): + await async_client.zero_trust.dlp.sensitivity_groups.levels.order.with_raw_response.update( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + level_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_group_id` but received ''"): + await async_client.zero_trust.dlp.sensitivity_groups.levels.order.with_raw_response.update( + sensitivity_group_id="", + account_id="account_id", + level_ids=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + order = await async_client.zero_trust.dlp.sensitivity_groups.levels.order.get( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(Optional[OrderGetResponse], order, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.sensitivity_groups.levels.order.with_raw_response.get( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + order = await response.parse() + assert_matches_type(Optional[OrderGetResponse], order, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.sensitivity_groups.levels.order.with_streaming_response.get( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + order = await response.parse() + assert_matches_type(Optional[OrderGetResponse], order, 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.zero_trust.dlp.sensitivity_groups.levels.order.with_raw_response.get( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_group_id` but received ''"): + await async_client.zero_trust.dlp.sensitivity_groups.levels.order.with_raw_response.get( + sensitivity_group_id="", + account_id="account_id", + ) diff --git a/tests/api_resources/zero_trust/dlp/sensitivity_groups/test_levels.py b/tests/api_resources/zero_trust/dlp/sensitivity_groups/test_levels.py new file mode 100644 index 00000000000..9a78bc5440f --- /dev/null +++ b/tests/api_resources/zero_trust/dlp/sensitivity_groups/test_levels.py @@ -0,0 +1,634 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +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 +from cloudflare.types.zero_trust.dlp.sensitivity_groups import ( + LevelGetResponse, + LevelListResponse, + LevelCreateResponse, + LevelUpdateResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestLevels: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + level = client.zero_trust.dlp.sensitivity_groups.levels.create( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + name="name", + ) + assert_matches_type(Optional[LevelCreateResponse], level, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + level = client.zero_trust.dlp.sensitivity_groups.levels.create( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + name="name", + description="description", + ) + assert_matches_type(Optional[LevelCreateResponse], level, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.create( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + name="name", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + level = response.parse() + assert_matches_type(Optional[LevelCreateResponse], level, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.sensitivity_groups.levels.with_streaming_response.create( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + name="name", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + level = response.parse() + assert_matches_type(Optional[LevelCreateResponse], level, 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.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.create( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + name="name", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_group_id` but received ''"): + client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.create( + sensitivity_group_id="", + account_id="account_id", + name="name", + ) + + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + level = client.zero_trust.dlp.sensitivity_groups.levels.update( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(Optional[LevelUpdateResponse], level, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: Cloudflare) -> None: + level = client.zero_trust.dlp.sensitivity_groups.levels.update( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + description="description", + name="name", + ) + assert_matches_type(Optional[LevelUpdateResponse], level, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.update( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + level = response.parse() + assert_matches_type(Optional[LevelUpdateResponse], level, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.sensitivity_groups.levels.with_streaming_response.update( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + level = response.parse() + assert_matches_type(Optional[LevelUpdateResponse], level, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @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 ''"): + client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.update( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_group_id` but received ''"): + client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.update( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_level_id` but received ''"): + client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.update( + sensitivity_level_id="", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + level = client.zero_trust.dlp.sensitivity_groups.levels.list( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(SyncSinglePage[LevelListResponse], level, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.list( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + level = response.parse() + assert_matches_type(SyncSinglePage[LevelListResponse], level, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.sensitivity_groups.levels.with_streaming_response.list( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + level = response.parse() + assert_matches_type(SyncSinglePage[LevelListResponse], level, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.list( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_group_id` but received ''"): + client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.list( + sensitivity_group_id="", + account_id="account_id", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + level = client.zero_trust.dlp.sensitivity_groups.levels.delete( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(object, level, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.delete( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + level = response.parse() + assert_matches_type(object, level, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.sensitivity_groups.levels.with_streaming_response.delete( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + level = response.parse() + assert_matches_type(object, level, 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.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.delete( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_group_id` but received ''"): + client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.delete( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_level_id` but received ''"): + client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.delete( + sensitivity_level_id="", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + level = client.zero_trust.dlp.sensitivity_groups.levels.get( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(Optional[LevelGetResponse], level, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.get( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + level = response.parse() + assert_matches_type(Optional[LevelGetResponse], level, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.sensitivity_groups.levels.with_streaming_response.get( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + level = response.parse() + assert_matches_type(Optional[LevelGetResponse], level, 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.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.get( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_group_id` but received ''"): + client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.get( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_level_id` but received ''"): + client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.get( + sensitivity_level_id="", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + +class TestAsyncLevels: + 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: + level = await async_client.zero_trust.dlp.sensitivity_groups.levels.create( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + name="name", + ) + assert_matches_type(Optional[LevelCreateResponse], level, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + level = await async_client.zero_trust.dlp.sensitivity_groups.levels.create( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + name="name", + description="description", + ) + assert_matches_type(Optional[LevelCreateResponse], level, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.create( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + name="name", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + level = await response.parse() + assert_matches_type(Optional[LevelCreateResponse], level, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.sensitivity_groups.levels.with_streaming_response.create( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + name="name", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + level = await response.parse() + assert_matches_type(Optional[LevelCreateResponse], level, 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.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.create( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + name="name", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_group_id` but received ''"): + await async_client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.create( + sensitivity_group_id="", + account_id="account_id", + name="name", + ) + + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + level = await async_client.zero_trust.dlp.sensitivity_groups.levels.update( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(Optional[LevelUpdateResponse], level, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: + level = await async_client.zero_trust.dlp.sensitivity_groups.levels.update( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + description="description", + name="name", + ) + assert_matches_type(Optional[LevelUpdateResponse], level, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.update( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + level = await response.parse() + assert_matches_type(Optional[LevelUpdateResponse], level, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.sensitivity_groups.levels.with_streaming_response.update( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + level = await response.parse() + assert_matches_type(Optional[LevelUpdateResponse], level, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @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 ''"): + await async_client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.update( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_group_id` but received ''"): + await async_client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.update( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_level_id` but received ''"): + await async_client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.update( + sensitivity_level_id="", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + level = await async_client.zero_trust.dlp.sensitivity_groups.levels.list( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(AsyncSinglePage[LevelListResponse], level, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.list( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + level = await response.parse() + assert_matches_type(AsyncSinglePage[LevelListResponse], level, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.sensitivity_groups.levels.with_streaming_response.list( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + level = await response.parse() + assert_matches_type(AsyncSinglePage[LevelListResponse], level, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.list( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_group_id` but received ''"): + await async_client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.list( + sensitivity_group_id="", + account_id="account_id", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + level = await async_client.zero_trust.dlp.sensitivity_groups.levels.delete( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(object, level, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.delete( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + level = await response.parse() + assert_matches_type(object, level, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.sensitivity_groups.levels.with_streaming_response.delete( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + level = await response.parse() + assert_matches_type(object, level, 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.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.delete( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_group_id` but received ''"): + await async_client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.delete( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_level_id` but received ''"): + await async_client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.delete( + sensitivity_level_id="", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + level = await async_client.zero_trust.dlp.sensitivity_groups.levels.get( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(Optional[LevelGetResponse], level, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.get( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + level = await response.parse() + assert_matches_type(Optional[LevelGetResponse], level, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.sensitivity_groups.levels.with_streaming_response.get( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + level = await response.parse() + assert_matches_type(Optional[LevelGetResponse], level, 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.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.get( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_group_id` but received ''"): + await async_client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.get( + sensitivity_level_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + sensitivity_group_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_level_id` but received ''"): + await async_client.zero_trust.dlp.sensitivity_groups.levels.with_raw_response.get( + sensitivity_level_id="", + account_id="account_id", + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) diff --git a/tests/api_resources/zero_trust/dlp/test_data_classes.py b/tests/api_resources/zero_trust/dlp/test_data_classes.py new file mode 100644 index 00000000000..3091bd57d42 --- /dev/null +++ b/tests/api_resources/zero_trust/dlp/test_data_classes.py @@ -0,0 +1,612 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +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 +from cloudflare.types.zero_trust.dlp import ( + DataClassGetResponse, + DataClassListResponse, + DataClassCreateResponse, + DataClassUpdateResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestDataClasses: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + data_class = client.zero_trust.dlp.data_classes.create( + account_id="account_id", + data_tags=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + expression="expression", + name="name", + sensitivity_levels=[ + { + "group_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "level_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + } + ], + ) + assert_matches_type(Optional[DataClassCreateResponse], data_class, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + data_class = client.zero_trust.dlp.data_classes.create( + account_id="account_id", + data_tags=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + expression="expression", + name="name", + sensitivity_levels=[ + { + "group_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "level_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + } + ], + description="description", + ) + assert_matches_type(Optional[DataClassCreateResponse], data_class, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.data_classes.with_raw_response.create( + account_id="account_id", + data_tags=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + expression="expression", + name="name", + sensitivity_levels=[ + { + "group_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "level_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + } + ], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_class = response.parse() + assert_matches_type(Optional[DataClassCreateResponse], data_class, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.data_classes.with_streaming_response.create( + account_id="account_id", + data_tags=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + expression="expression", + name="name", + sensitivity_levels=[ + { + "group_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "level_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + } + ], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_class = response.parse() + assert_matches_type(Optional[DataClassCreateResponse], data_class, 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.zero_trust.dlp.data_classes.with_raw_response.create( + account_id="", + data_tags=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + expression="expression", + name="name", + sensitivity_levels=[ + { + "group_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "level_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + } + ], + ) + + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + data_class = client.zero_trust.dlp.data_classes.update( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(Optional[DataClassUpdateResponse], data_class, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: Cloudflare) -> None: + data_class = client.zero_trust.dlp.data_classes.update( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + data_tags=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + description="description", + expression="expression", + name="name", + sensitivity_levels=[ + { + "group_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "level_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + } + ], + ) + assert_matches_type(Optional[DataClassUpdateResponse], data_class, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.data_classes.with_raw_response.update( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_class = response.parse() + assert_matches_type(Optional[DataClassUpdateResponse], data_class, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.data_classes.with_streaming_response.update( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_class = response.parse() + assert_matches_type(Optional[DataClassUpdateResponse], data_class, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @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 ''"): + client.zero_trust.dlp.data_classes.with_raw_response.update( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `data_class_id` but received ''"): + client.zero_trust.dlp.data_classes.with_raw_response.update( + data_class_id="", + account_id="account_id", + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + data_class = client.zero_trust.dlp.data_classes.list( + account_id="account_id", + ) + assert_matches_type(SyncSinglePage[DataClassListResponse], data_class, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.data_classes.with_raw_response.list( + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_class = response.parse() + assert_matches_type(SyncSinglePage[DataClassListResponse], data_class, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.data_classes.with_streaming_response.list( + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_class = response.parse() + assert_matches_type(SyncSinglePage[DataClassListResponse], data_class, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.dlp.data_classes.with_raw_response.list( + account_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + data_class = client.zero_trust.dlp.data_classes.delete( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(object, data_class, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.data_classes.with_raw_response.delete( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_class = response.parse() + assert_matches_type(object, data_class, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.data_classes.with_streaming_response.delete( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_class = response.parse() + assert_matches_type(object, data_class, 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.zero_trust.dlp.data_classes.with_raw_response.delete( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `data_class_id` but received ''"): + client.zero_trust.dlp.data_classes.with_raw_response.delete( + data_class_id="", + account_id="account_id", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + data_class = client.zero_trust.dlp.data_classes.get( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(Optional[DataClassGetResponse], data_class, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.data_classes.with_raw_response.get( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_class = response.parse() + assert_matches_type(Optional[DataClassGetResponse], data_class, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.data_classes.with_streaming_response.get( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_class = response.parse() + assert_matches_type(Optional[DataClassGetResponse], data_class, 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.zero_trust.dlp.data_classes.with_raw_response.get( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `data_class_id` but received ''"): + client.zero_trust.dlp.data_classes.with_raw_response.get( + data_class_id="", + account_id="account_id", + ) + + +class TestAsyncDataClasses: + 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: + data_class = await async_client.zero_trust.dlp.data_classes.create( + account_id="account_id", + data_tags=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + expression="expression", + name="name", + sensitivity_levels=[ + { + "group_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "level_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + } + ], + ) + assert_matches_type(Optional[DataClassCreateResponse], data_class, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + data_class = await async_client.zero_trust.dlp.data_classes.create( + account_id="account_id", + data_tags=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + expression="expression", + name="name", + sensitivity_levels=[ + { + "group_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "level_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + } + ], + description="description", + ) + assert_matches_type(Optional[DataClassCreateResponse], data_class, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.data_classes.with_raw_response.create( + account_id="account_id", + data_tags=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + expression="expression", + name="name", + sensitivity_levels=[ + { + "group_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "level_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + } + ], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_class = await response.parse() + assert_matches_type(Optional[DataClassCreateResponse], data_class, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.data_classes.with_streaming_response.create( + account_id="account_id", + data_tags=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + expression="expression", + name="name", + sensitivity_levels=[ + { + "group_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "level_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + } + ], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_class = await response.parse() + assert_matches_type(Optional[DataClassCreateResponse], data_class, 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.zero_trust.dlp.data_classes.with_raw_response.create( + account_id="", + data_tags=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + expression="expression", + name="name", + sensitivity_levels=[ + { + "group_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "level_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + } + ], + ) + + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + data_class = await async_client.zero_trust.dlp.data_classes.update( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(Optional[DataClassUpdateResponse], data_class, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: + data_class = await async_client.zero_trust.dlp.data_classes.update( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + data_tags=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + description="description", + expression="expression", + name="name", + sensitivity_levels=[ + { + "group_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "level_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + } + ], + ) + assert_matches_type(Optional[DataClassUpdateResponse], data_class, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.data_classes.with_raw_response.update( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_class = await response.parse() + assert_matches_type(Optional[DataClassUpdateResponse], data_class, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.data_classes.with_streaming_response.update( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_class = await response.parse() + assert_matches_type(Optional[DataClassUpdateResponse], data_class, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @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 ''"): + await async_client.zero_trust.dlp.data_classes.with_raw_response.update( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `data_class_id` but received ''"): + await async_client.zero_trust.dlp.data_classes.with_raw_response.update( + data_class_id="", + account_id="account_id", + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + data_class = await async_client.zero_trust.dlp.data_classes.list( + account_id="account_id", + ) + assert_matches_type(AsyncSinglePage[DataClassListResponse], data_class, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.data_classes.with_raw_response.list( + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_class = await response.parse() + assert_matches_type(AsyncSinglePage[DataClassListResponse], data_class, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.data_classes.with_streaming_response.list( + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_class = await response.parse() + assert_matches_type(AsyncSinglePage[DataClassListResponse], data_class, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.dlp.data_classes.with_raw_response.list( + account_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + data_class = await async_client.zero_trust.dlp.data_classes.delete( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(object, data_class, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.data_classes.with_raw_response.delete( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_class = await response.parse() + assert_matches_type(object, data_class, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.data_classes.with_streaming_response.delete( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_class = await response.parse() + assert_matches_type(object, data_class, 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.zero_trust.dlp.data_classes.with_raw_response.delete( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `data_class_id` but received ''"): + await async_client.zero_trust.dlp.data_classes.with_raw_response.delete( + data_class_id="", + account_id="account_id", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + data_class = await async_client.zero_trust.dlp.data_classes.get( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(Optional[DataClassGetResponse], data_class, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.data_classes.with_raw_response.get( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_class = await response.parse() + assert_matches_type(Optional[DataClassGetResponse], data_class, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.data_classes.with_streaming_response.get( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_class = await response.parse() + assert_matches_type(Optional[DataClassGetResponse], data_class, 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.zero_trust.dlp.data_classes.with_raw_response.get( + data_class_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `data_class_id` but received ''"): + await async_client.zero_trust.dlp.data_classes.with_raw_response.get( + data_class_id="", + account_id="account_id", + ) diff --git a/tests/api_resources/zero_trust/dlp/test_data_tag_categories.py b/tests/api_resources/zero_trust/dlp/test_data_tag_categories.py new file mode 100644 index 00000000000..6492a860a79 --- /dev/null +++ b/tests/api_resources/zero_trust/dlp/test_data_tag_categories.py @@ -0,0 +1,544 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +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 +from cloudflare.types.zero_trust.dlp import ( + DataTagCategoryGetResponse, + DataTagCategoryListResponse, + DataTagCategoryCreateResponse, + DataTagCategoryUpdateResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestDataTagCategories: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + data_tag_category = client.zero_trust.dlp.data_tag_categories.create( + account_id="account_id", + name="name", + ) + assert_matches_type(Optional[DataTagCategoryCreateResponse], data_tag_category, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + data_tag_category = client.zero_trust.dlp.data_tag_categories.create( + account_id="account_id", + name="name", + description="description", + tags=[ + { + "name": "name", + "description": "description", + } + ], + template_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(Optional[DataTagCategoryCreateResponse], data_tag_category, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.data_tag_categories.with_raw_response.create( + account_id="account_id", + name="name", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_tag_category = response.parse() + assert_matches_type(Optional[DataTagCategoryCreateResponse], data_tag_category, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.data_tag_categories.with_streaming_response.create( + account_id="account_id", + name="name", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_tag_category = response.parse() + assert_matches_type(Optional[DataTagCategoryCreateResponse], data_tag_category, 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.zero_trust.dlp.data_tag_categories.with_raw_response.create( + account_id="", + name="name", + ) + + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + data_tag_category = client.zero_trust.dlp.data_tag_categories.update( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(Optional[DataTagCategoryUpdateResponse], data_tag_category, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: Cloudflare) -> None: + data_tag_category = client.zero_trust.dlp.data_tag_categories.update( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + description="description", + name="name", + tags=[ + { + "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "description": "description", + "name": "name", + } + ], + ) + assert_matches_type(Optional[DataTagCategoryUpdateResponse], data_tag_category, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.data_tag_categories.with_raw_response.update( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_tag_category = response.parse() + assert_matches_type(Optional[DataTagCategoryUpdateResponse], data_tag_category, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.data_tag_categories.with_streaming_response.update( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_tag_category = response.parse() + assert_matches_type(Optional[DataTagCategoryUpdateResponse], data_tag_category, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @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 ''"): + client.zero_trust.dlp.data_tag_categories.with_raw_response.update( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `category_id` but received ''"): + client.zero_trust.dlp.data_tag_categories.with_raw_response.update( + category_id="", + account_id="account_id", + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + data_tag_category = client.zero_trust.dlp.data_tag_categories.list( + account_id="account_id", + ) + assert_matches_type(SyncSinglePage[DataTagCategoryListResponse], data_tag_category, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.data_tag_categories.with_raw_response.list( + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_tag_category = response.parse() + assert_matches_type(SyncSinglePage[DataTagCategoryListResponse], data_tag_category, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.data_tag_categories.with_streaming_response.list( + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_tag_category = response.parse() + assert_matches_type(SyncSinglePage[DataTagCategoryListResponse], data_tag_category, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.dlp.data_tag_categories.with_raw_response.list( + account_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + data_tag_category = client.zero_trust.dlp.data_tag_categories.delete( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(object, data_tag_category, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.data_tag_categories.with_raw_response.delete( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_tag_category = response.parse() + assert_matches_type(object, data_tag_category, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.data_tag_categories.with_streaming_response.delete( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_tag_category = response.parse() + assert_matches_type(object, data_tag_category, 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.zero_trust.dlp.data_tag_categories.with_raw_response.delete( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `category_id` but received ''"): + client.zero_trust.dlp.data_tag_categories.with_raw_response.delete( + category_id="", + account_id="account_id", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + data_tag_category = client.zero_trust.dlp.data_tag_categories.get( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(Optional[DataTagCategoryGetResponse], data_tag_category, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.data_tag_categories.with_raw_response.get( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_tag_category = response.parse() + assert_matches_type(Optional[DataTagCategoryGetResponse], data_tag_category, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.data_tag_categories.with_streaming_response.get( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_tag_category = response.parse() + assert_matches_type(Optional[DataTagCategoryGetResponse], data_tag_category, 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.zero_trust.dlp.data_tag_categories.with_raw_response.get( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `category_id` but received ''"): + client.zero_trust.dlp.data_tag_categories.with_raw_response.get( + category_id="", + account_id="account_id", + ) + + +class TestAsyncDataTagCategories: + 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: + data_tag_category = await async_client.zero_trust.dlp.data_tag_categories.create( + account_id="account_id", + name="name", + ) + assert_matches_type(Optional[DataTagCategoryCreateResponse], data_tag_category, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + data_tag_category = await async_client.zero_trust.dlp.data_tag_categories.create( + account_id="account_id", + name="name", + description="description", + tags=[ + { + "name": "name", + "description": "description", + } + ], + template_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(Optional[DataTagCategoryCreateResponse], data_tag_category, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.data_tag_categories.with_raw_response.create( + account_id="account_id", + name="name", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_tag_category = await response.parse() + assert_matches_type(Optional[DataTagCategoryCreateResponse], data_tag_category, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.data_tag_categories.with_streaming_response.create( + account_id="account_id", + name="name", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_tag_category = await response.parse() + assert_matches_type(Optional[DataTagCategoryCreateResponse], data_tag_category, 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.zero_trust.dlp.data_tag_categories.with_raw_response.create( + account_id="", + name="name", + ) + + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + data_tag_category = await async_client.zero_trust.dlp.data_tag_categories.update( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(Optional[DataTagCategoryUpdateResponse], data_tag_category, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: + data_tag_category = await async_client.zero_trust.dlp.data_tag_categories.update( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + description="description", + name="name", + tags=[ + { + "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "description": "description", + "name": "name", + } + ], + ) + assert_matches_type(Optional[DataTagCategoryUpdateResponse], data_tag_category, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.data_tag_categories.with_raw_response.update( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_tag_category = await response.parse() + assert_matches_type(Optional[DataTagCategoryUpdateResponse], data_tag_category, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.data_tag_categories.with_streaming_response.update( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_tag_category = await response.parse() + assert_matches_type(Optional[DataTagCategoryUpdateResponse], data_tag_category, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @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 ''"): + await async_client.zero_trust.dlp.data_tag_categories.with_raw_response.update( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `category_id` but received ''"): + await async_client.zero_trust.dlp.data_tag_categories.with_raw_response.update( + category_id="", + account_id="account_id", + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + data_tag_category = await async_client.zero_trust.dlp.data_tag_categories.list( + account_id="account_id", + ) + assert_matches_type(AsyncSinglePage[DataTagCategoryListResponse], data_tag_category, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.data_tag_categories.with_raw_response.list( + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_tag_category = await response.parse() + assert_matches_type(AsyncSinglePage[DataTagCategoryListResponse], data_tag_category, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.data_tag_categories.with_streaming_response.list( + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_tag_category = await response.parse() + assert_matches_type(AsyncSinglePage[DataTagCategoryListResponse], data_tag_category, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.dlp.data_tag_categories.with_raw_response.list( + account_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + data_tag_category = await async_client.zero_trust.dlp.data_tag_categories.delete( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(object, data_tag_category, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.data_tag_categories.with_raw_response.delete( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_tag_category = await response.parse() + assert_matches_type(object, data_tag_category, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.data_tag_categories.with_streaming_response.delete( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_tag_category = await response.parse() + assert_matches_type(object, data_tag_category, 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.zero_trust.dlp.data_tag_categories.with_raw_response.delete( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `category_id` but received ''"): + await async_client.zero_trust.dlp.data_tag_categories.with_raw_response.delete( + category_id="", + account_id="account_id", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + data_tag_category = await async_client.zero_trust.dlp.data_tag_categories.get( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(Optional[DataTagCategoryGetResponse], data_tag_category, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.data_tag_categories.with_raw_response.get( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + data_tag_category = await response.parse() + assert_matches_type(Optional[DataTagCategoryGetResponse], data_tag_category, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.data_tag_categories.with_streaming_response.get( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + data_tag_category = await response.parse() + assert_matches_type(Optional[DataTagCategoryGetResponse], data_tag_category, 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.zero_trust.dlp.data_tag_categories.with_raw_response.get( + category_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `category_id` but received ''"): + await async_client.zero_trust.dlp.data_tag_categories.with_raw_response.get( + category_id="", + account_id="account_id", + ) diff --git a/tests/api_resources/zero_trust/dlp/test_sensitivity_groups.py b/tests/api_resources/zero_trust/dlp/test_sensitivity_groups.py new file mode 100644 index 00000000000..ad2e3e56f83 --- /dev/null +++ b/tests/api_resources/zero_trust/dlp/test_sensitivity_groups.py @@ -0,0 +1,544 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +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 +from cloudflare.types.zero_trust.dlp import ( + SensitivityGroupGetResponse, + SensitivityGroupListResponse, + SensitivityGroupCreateResponse, + SensitivityGroupUpdateResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestSensitivityGroups: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + sensitivity_group = client.zero_trust.dlp.sensitivity_groups.create( + account_id="account_id", + name="name", + ) + assert_matches_type(Optional[SensitivityGroupCreateResponse], sensitivity_group, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + sensitivity_group = client.zero_trust.dlp.sensitivity_groups.create( + account_id="account_id", + name="name", + description="description", + levels=[ + { + "name": "name", + "description": "description", + } + ], + template_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(Optional[SensitivityGroupCreateResponse], sensitivity_group, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.sensitivity_groups.with_raw_response.create( + account_id="account_id", + name="name", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + sensitivity_group = response.parse() + assert_matches_type(Optional[SensitivityGroupCreateResponse], sensitivity_group, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.sensitivity_groups.with_streaming_response.create( + account_id="account_id", + name="name", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + sensitivity_group = response.parse() + assert_matches_type(Optional[SensitivityGroupCreateResponse], sensitivity_group, 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.zero_trust.dlp.sensitivity_groups.with_raw_response.create( + account_id="", + name="name", + ) + + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + sensitivity_group = client.zero_trust.dlp.sensitivity_groups.update( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(Optional[SensitivityGroupUpdateResponse], sensitivity_group, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: Cloudflare) -> None: + sensitivity_group = client.zero_trust.dlp.sensitivity_groups.update( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + description="description", + levels=[ + { + "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "description": "description", + "name": "name", + } + ], + name="name", + ) + assert_matches_type(Optional[SensitivityGroupUpdateResponse], sensitivity_group, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.sensitivity_groups.with_raw_response.update( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + sensitivity_group = response.parse() + assert_matches_type(Optional[SensitivityGroupUpdateResponse], sensitivity_group, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.sensitivity_groups.with_streaming_response.update( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + sensitivity_group = response.parse() + assert_matches_type(Optional[SensitivityGroupUpdateResponse], sensitivity_group, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @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 ''"): + client.zero_trust.dlp.sensitivity_groups.with_raw_response.update( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_group_id` but received ''"): + client.zero_trust.dlp.sensitivity_groups.with_raw_response.update( + sensitivity_group_id="", + account_id="account_id", + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + sensitivity_group = client.zero_trust.dlp.sensitivity_groups.list( + account_id="account_id", + ) + assert_matches_type(SyncSinglePage[SensitivityGroupListResponse], sensitivity_group, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.sensitivity_groups.with_raw_response.list( + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + sensitivity_group = response.parse() + assert_matches_type(SyncSinglePage[SensitivityGroupListResponse], sensitivity_group, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.sensitivity_groups.with_streaming_response.list( + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + sensitivity_group = response.parse() + assert_matches_type(SyncSinglePage[SensitivityGroupListResponse], sensitivity_group, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_list(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.zero_trust.dlp.sensitivity_groups.with_raw_response.list( + account_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + sensitivity_group = client.zero_trust.dlp.sensitivity_groups.delete( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(object, sensitivity_group, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.sensitivity_groups.with_raw_response.delete( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + sensitivity_group = response.parse() + assert_matches_type(object, sensitivity_group, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.sensitivity_groups.with_streaming_response.delete( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + sensitivity_group = response.parse() + assert_matches_type(object, sensitivity_group, 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.zero_trust.dlp.sensitivity_groups.with_raw_response.delete( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_group_id` but received ''"): + client.zero_trust.dlp.sensitivity_groups.with_raw_response.delete( + sensitivity_group_id="", + account_id="account_id", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + sensitivity_group = client.zero_trust.dlp.sensitivity_groups.get( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(Optional[SensitivityGroupGetResponse], sensitivity_group, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.dlp.sensitivity_groups.with_raw_response.get( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + sensitivity_group = response.parse() + assert_matches_type(Optional[SensitivityGroupGetResponse], sensitivity_group, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.dlp.sensitivity_groups.with_streaming_response.get( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + sensitivity_group = response.parse() + assert_matches_type(Optional[SensitivityGroupGetResponse], sensitivity_group, 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.zero_trust.dlp.sensitivity_groups.with_raw_response.get( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_group_id` but received ''"): + client.zero_trust.dlp.sensitivity_groups.with_raw_response.get( + sensitivity_group_id="", + account_id="account_id", + ) + + +class TestAsyncSensitivityGroups: + 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: + sensitivity_group = await async_client.zero_trust.dlp.sensitivity_groups.create( + account_id="account_id", + name="name", + ) + assert_matches_type(Optional[SensitivityGroupCreateResponse], sensitivity_group, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + sensitivity_group = await async_client.zero_trust.dlp.sensitivity_groups.create( + account_id="account_id", + name="name", + description="description", + levels=[ + { + "name": "name", + "description": "description", + } + ], + template_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(Optional[SensitivityGroupCreateResponse], sensitivity_group, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.sensitivity_groups.with_raw_response.create( + account_id="account_id", + name="name", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + sensitivity_group = await response.parse() + assert_matches_type(Optional[SensitivityGroupCreateResponse], sensitivity_group, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.sensitivity_groups.with_streaming_response.create( + account_id="account_id", + name="name", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + sensitivity_group = await response.parse() + assert_matches_type(Optional[SensitivityGroupCreateResponse], sensitivity_group, 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.zero_trust.dlp.sensitivity_groups.with_raw_response.create( + account_id="", + name="name", + ) + + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + sensitivity_group = await async_client.zero_trust.dlp.sensitivity_groups.update( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(Optional[SensitivityGroupUpdateResponse], sensitivity_group, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: + sensitivity_group = await async_client.zero_trust.dlp.sensitivity_groups.update( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + description="description", + levels=[ + { + "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "description": "description", + "name": "name", + } + ], + name="name", + ) + assert_matches_type(Optional[SensitivityGroupUpdateResponse], sensitivity_group, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.sensitivity_groups.with_raw_response.update( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + sensitivity_group = await response.parse() + assert_matches_type(Optional[SensitivityGroupUpdateResponse], sensitivity_group, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.sensitivity_groups.with_streaming_response.update( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + sensitivity_group = await response.parse() + assert_matches_type(Optional[SensitivityGroupUpdateResponse], sensitivity_group, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @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 ''"): + await async_client.zero_trust.dlp.sensitivity_groups.with_raw_response.update( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_group_id` but received ''"): + await async_client.zero_trust.dlp.sensitivity_groups.with_raw_response.update( + sensitivity_group_id="", + account_id="account_id", + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + sensitivity_group = await async_client.zero_trust.dlp.sensitivity_groups.list( + account_id="account_id", + ) + assert_matches_type(AsyncSinglePage[SensitivityGroupListResponse], sensitivity_group, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.sensitivity_groups.with_raw_response.list( + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + sensitivity_group = await response.parse() + assert_matches_type(AsyncSinglePage[SensitivityGroupListResponse], sensitivity_group, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.sensitivity_groups.with_streaming_response.list( + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + sensitivity_group = await response.parse() + assert_matches_type(AsyncSinglePage[SensitivityGroupListResponse], sensitivity_group, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.zero_trust.dlp.sensitivity_groups.with_raw_response.list( + account_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + sensitivity_group = await async_client.zero_trust.dlp.sensitivity_groups.delete( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(object, sensitivity_group, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.sensitivity_groups.with_raw_response.delete( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + sensitivity_group = await response.parse() + assert_matches_type(object, sensitivity_group, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.sensitivity_groups.with_streaming_response.delete( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + sensitivity_group = await response.parse() + assert_matches_type(object, sensitivity_group, 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.zero_trust.dlp.sensitivity_groups.with_raw_response.delete( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_group_id` but received ''"): + await async_client.zero_trust.dlp.sensitivity_groups.with_raw_response.delete( + sensitivity_group_id="", + account_id="account_id", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + sensitivity_group = await async_client.zero_trust.dlp.sensitivity_groups.get( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + assert_matches_type(Optional[SensitivityGroupGetResponse], sensitivity_group, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.dlp.sensitivity_groups.with_raw_response.get( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + sensitivity_group = await response.parse() + assert_matches_type(Optional[SensitivityGroupGetResponse], sensitivity_group, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.dlp.sensitivity_groups.with_streaming_response.get( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="account_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + sensitivity_group = await response.parse() + assert_matches_type(Optional[SensitivityGroupGetResponse], sensitivity_group, 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.zero_trust.dlp.sensitivity_groups.with_raw_response.get( + sensitivity_group_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `sensitivity_group_id` but received ''"): + await async_client.zero_trust.dlp.sensitivity_groups.with_raw_response.get( + sensitivity_group_id="", + account_id="account_id", + ) diff --git a/tests/api_resources/zero_trust/tunnels/warp_connector/test_configurations.py b/tests/api_resources/zero_trust/tunnels/warp_connector/test_configurations.py new file mode 100644 index 00000000000..fe093aebee2 --- /dev/null +++ b/tests/api_resources/zero_trust/tunnels/warp_connector/test_configurations.py @@ -0,0 +1,249 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, Optional, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.types.zero_trust.tunnels.warp_connector import ( + ConfigurationGetResponse, + ConfigurationUpdateResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestConfigurations: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + configuration = client.zero_trust.tunnels.warp_connector.configurations.update( + tunnel_id="f70ff985-a4ef-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ha_mode="aws", + ) + assert_matches_type(Optional[ConfigurationUpdateResponse], configuration, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: Cloudflare) -> None: + configuration = client.zero_trust.tunnels.warp_connector.configurations.update( + tunnel_id="f70ff985-a4ef-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ha_mode="aws", + config={"fnr_id": "eni-0123456789abcdef0"}, + ) + assert_matches_type(Optional[ConfigurationUpdateResponse], configuration, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.zero_trust.tunnels.warp_connector.configurations.with_raw_response.update( + tunnel_id="f70ff985-a4ef-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ha_mode="aws", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + configuration = response.parse() + assert_matches_type(Optional[ConfigurationUpdateResponse], configuration, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.zero_trust.tunnels.warp_connector.configurations.with_streaming_response.update( + tunnel_id="f70ff985-a4ef-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ha_mode="aws", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + configuration = response.parse() + assert_matches_type(Optional[ConfigurationUpdateResponse], configuration, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @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 ''"): + client.zero_trust.tunnels.warp_connector.configurations.with_raw_response.update( + tunnel_id="f70ff985-a4ef-4643-bbbc-4a0ed4fc8415", + account_id="", + ha_mode="aws", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `tunnel_id` but received ''"): + client.zero_trust.tunnels.warp_connector.configurations.with_raw_response.update( + tunnel_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ha_mode="aws", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + configuration = client.zero_trust.tunnels.warp_connector.configurations.get( + tunnel_id="f70ff985-a4ef-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[ConfigurationGetResponse], configuration, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.zero_trust.tunnels.warp_connector.configurations.with_raw_response.get( + tunnel_id="f70ff985-a4ef-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + configuration = response.parse() + assert_matches_type(Optional[ConfigurationGetResponse], configuration, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.zero_trust.tunnels.warp_connector.configurations.with_streaming_response.get( + tunnel_id="f70ff985-a4ef-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + configuration = response.parse() + assert_matches_type(Optional[ConfigurationGetResponse], configuration, 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.zero_trust.tunnels.warp_connector.configurations.with_raw_response.get( + tunnel_id="f70ff985-a4ef-4643-bbbc-4a0ed4fc8415", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `tunnel_id` but received ''"): + client.zero_trust.tunnels.warp_connector.configurations.with_raw_response.get( + tunnel_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + +class TestAsyncConfigurations: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + configuration = await async_client.zero_trust.tunnels.warp_connector.configurations.update( + tunnel_id="f70ff985-a4ef-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ha_mode="aws", + ) + assert_matches_type(Optional[ConfigurationUpdateResponse], configuration, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: + configuration = await async_client.zero_trust.tunnels.warp_connector.configurations.update( + tunnel_id="f70ff985-a4ef-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ha_mode="aws", + config={"fnr_id": "eni-0123456789abcdef0"}, + ) + assert_matches_type(Optional[ConfigurationUpdateResponse], configuration, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.tunnels.warp_connector.configurations.with_raw_response.update( + tunnel_id="f70ff985-a4ef-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ha_mode="aws", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + configuration = await response.parse() + assert_matches_type(Optional[ConfigurationUpdateResponse], configuration, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.tunnels.warp_connector.configurations.with_streaming_response.update( + tunnel_id="f70ff985-a4ef-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ha_mode="aws", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + configuration = await response.parse() + assert_matches_type(Optional[ConfigurationUpdateResponse], configuration, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @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 ''"): + await async_client.zero_trust.tunnels.warp_connector.configurations.with_raw_response.update( + tunnel_id="f70ff985-a4ef-4643-bbbc-4a0ed4fc8415", + account_id="", + ha_mode="aws", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `tunnel_id` but received ''"): + await async_client.zero_trust.tunnels.warp_connector.configurations.with_raw_response.update( + tunnel_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ha_mode="aws", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + configuration = await async_client.zero_trust.tunnels.warp_connector.configurations.get( + tunnel_id="f70ff985-a4ef-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[ConfigurationGetResponse], configuration, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.zero_trust.tunnels.warp_connector.configurations.with_raw_response.get( + tunnel_id="f70ff985-a4ef-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + configuration = await response.parse() + assert_matches_type(Optional[ConfigurationGetResponse], configuration, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.zero_trust.tunnels.warp_connector.configurations.with_streaming_response.get( + tunnel_id="f70ff985-a4ef-4643-bbbc-4a0ed4fc8415", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + configuration = await response.parse() + assert_matches_type(Optional[ConfigurationGetResponse], configuration, 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.zero_trust.tunnels.warp_connector.configurations.with_raw_response.get( + tunnel_id="f70ff985-a4ef-4643-bbbc-4a0ed4fc8415", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `tunnel_id` but received ''"): + await async_client.zero_trust.tunnels.warp_connector.configurations.with_raw_response.get( + tunnel_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) From 72eb20551c18d2cae3dfbef960a12ff22b4a7de7 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 12 Jun 2026 11:42:57 +0000 Subject: [PATCH 02/23] chore(api): update composite API spec --- .stats.yml | 4 +- .../devtools/browser/browser.py | 4 +- .../custom_hostnames/custom_hostnames.py | 6 +- .../resources/zero_trust/devices/dex_tests.py | 40 +++- .../zero_trust/devices/fleet_status.py | 20 +- .../resources/zero_trust/dex/colos.py | 12 +- .../zero_trust/dex/commands/commands.py | 44 ++-- .../zero_trust/dex/commands/devices.py | 16 +- .../zero_trust/dex/commands/downloads.py | 4 + .../zero_trust/dex/commands/quota.py | 4 + .../resources/zero_trust/dex/devices/isps.py | 20 +- .../zero_trust/dex/fleet_status/devices.py | 56 +++-- .../dex/fleet_status/fleet_status.py | 40 ++-- .../zero_trust/dex/http_tests/http_tests.py | 12 +- .../zero_trust/dex/http_tests/percentiles.py | 12 +- .../resources/zero_trust/dex/rules.py | 60 +++-- .../resources/zero_trust/dex/tests/tests.py | 16 +- .../zero_trust/dex/tests/unique_devices.py | 8 +- .../traceroute_test_results/network_path.py | 4 + .../zero_trust/dex/traceroute_tests.py | 48 ++-- .../zero_trust/dex/warp_change_events.py | 24 +- .../custom_hostname_list_params.py | 24 +- .../devices/dex_test_create_params.py | 7 +- .../devices/dex_test_create_response.py | 6 +- .../devices/dex_test_delete_response.py | 6 +- .../devices/dex_test_get_response.py | 6 +- .../devices/dex_test_list_params.py | 9 +- .../devices/dex_test_list_response.py | 6 +- .../devices/dex_test_update_params.py | 7 +- .../devices/dex_test_update_response.py | 6 +- .../devices/fleet_status_get_params.py | 7 +- .../devices/fleet_status_get_response.py | 208 ++++++++++++++++-- .../types/zero_trust/dex/colo_list_params.py | 5 +- .../zero_trust/dex/command_create_params.py | 1 + .../zero_trust/dex/command_list_params.py | 17 +- .../dex/commands/device_list_params.py | 7 +- .../dex/commands/device_list_response.py | 7 +- .../dex/commands/quota_get_response.py | 6 +- .../zero_trust/dex/devices/isp_list_params.py | 9 +- .../types/zero_trust/dex/devices/isps.py | 12 +- .../dex/fleet_status/device_list_params.py | 31 ++- .../dex/fleet_status/device_list_response.py | 208 ++++++++++++++++-- .../dex/fleet_status_live_params.py | 3 +- .../dex/fleet_status_over_time_params.py | 17 +- .../dex/fleet_status_over_time_response.py | 2 - .../types/zero_trust/dex/http_details.py | 22 +- .../zero_trust/dex/http_test_get_params.py | 5 +- .../dex/http_tests/percentile_get_params.py | 5 +- .../dex/http_tests/test_stat_over_time.py | 6 +- .../zero_trust/dex/rule_create_params.py | 1 + .../types/zero_trust/dex/rule_list_params.py | 11 +- .../zero_trust/dex/rule_update_params.py | 1 + .../types/zero_trust/dex/test_list_params.py | 5 +- .../types/zero_trust/dex/tests/tests.py | 4 +- .../dex/tests/unique_device_list_params.py | 3 +- .../types/zero_trust/dex/traceroute.py | 32 +-- .../dex/traceroute_test_get_params.py | 5 +- .../traceroute_test_network_path_params.py | 7 +- .../dex/traceroute_test_percentiles_params.py | 5 +- .../network_path_get_response.py | 17 +- .../dex/warp_change_event_get_params.py | 11 +- .../dex/warp_change_event_get_response.py | 43 ++-- .../zero_trust/digital_experience_monitor.py | 2 +- .../types/zero_trust/network_path_response.py | 3 +- .../types/zero_trust/percentiles.py | 8 +- tests/api_resources/test_custom_hostnames.py | 12 +- .../zero_trust/devices/test_dex_tests.py | 4 +- .../zero_trust/dex/commands/test_devices.py | 20 +- .../zero_trust/dex/devices/test_isps.py | 24 +- .../dex/fleet_status/test_devices.py | 40 ++-- .../dex/http_tests/test_percentiles.py | 8 +- .../zero_trust/dex/test_commands.py | 20 +- .../zero_trust/dex/test_fleet_status.py | 40 ++-- .../zero_trust/dex/test_http_tests.py | 8 +- .../zero_trust/dex/test_rules.py | 20 +- .../zero_trust/dex/test_tests.py | 16 +- .../zero_trust/dex/test_warp_change_events.py | 20 +- .../dex/tests/test_unique_devices.py | 4 +- 78 files changed, 1033 insertions(+), 470 deletions(-) diff --git a/.stats.yml b/.stats.yml index c8a83c41f1b..b15b9003bdf 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 2376 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-f63166c7c5fb3e729ec074f8dc759d35278ec33e71d77f31b2ccbfd9bf139b64.yml -openapi_spec_hash: 8f069d1e288250bf1dcb466b696cd11c +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-514c439211d08727278b25d13388b711bf1e431382b55eeb10079db550d01fa3.yml +openapi_spec_hash: c5f909ea82142fc11cd786fb212209fa config_hash: ec0647c69ef9d049d1e12e9ddb0673ee diff --git a/src/cloudflare/resources/browser_rendering/devtools/browser/browser.py b/src/cloudflare/resources/browser_rendering/devtools/browser/browser.py index 64451ef8143..c5ba1cae03d 100644 --- a/src/cloudflare/resources/browser_rendering/devtools/browser/browser.py +++ b/src/cloudflare/resources/browser_rendering/devtools/browser/browser.py @@ -84,7 +84,7 @@ def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BrowserCreateResponse: """ - Get a browser session ID. + Acquire a new browser DevTools session Args: account_id: Account ID. @@ -420,7 +420,7 @@ async def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BrowserCreateResponse: """ - Get a browser session ID. + Acquire a new browser DevTools session Args: account_id: Account ID. diff --git a/src/cloudflare/resources/custom_hostnames/custom_hostnames.py b/src/cloudflare/resources/custom_hostnames/custom_hostnames.py index ab912b5ab63..ec04158e48b 100644 --- a/src/cloudflare/resources/custom_hostnames/custom_hostnames.py +++ b/src/cloudflare/resources/custom_hostnames/custom_hostnames.py @@ -216,7 +216,8 @@ def list( id: Hostname ID to match against. This ID was generated and returned during the initial custom_hostname creation. This parameter cannot be used with the - 'hostname' parameter. + 'hostname', 'hostname.exact', 'hostname.contain', or 'hostname.startsWith' + parameters. certificate_authority: Filter by the certificate authority that issued the SSL certificate. @@ -620,7 +621,8 @@ def list( id: Hostname ID to match against. This ID was generated and returned during the initial custom_hostname creation. This parameter cannot be used with the - 'hostname' parameter. + 'hostname', 'hostname.exact', 'hostname.contain', or 'hostname.startsWith' + parameters. certificate_authority: Filter by the certificate authority that issued the SSL certificate. diff --git a/src/cloudflare/resources/zero_trust/devices/dex_tests.py b/src/cloudflare/resources/zero_trust/devices/dex_tests.py index 3514a023e2c..6a61e41c8be 100644 --- a/src/cloudflare/resources/zero_trust/devices/dex_tests.py +++ b/src/cloudflare/resources/zero_trust/devices/dex_tests.py @@ -72,6 +72,8 @@ def create( Create a DEX test. Args: + account_id: Unique identifier linked to an account. + data: The configuration object which contains the details for the WARP client to conduct the test. @@ -142,6 +144,8 @@ def update( Update a DEX test. Args: + account_id: Unique identifier linked to an account. + dex_test_id: API Resource UUID tag. data: The configuration object which contains the details for the WARP client to @@ -213,16 +217,18 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncV4PagePaginationArray[DEXTestListResponse]: """ - Fetch all DEX tests + Fetch all DEX tests. Args: - kind: Filter by test type + account_id: Unique identifier linked to an account. + + kind: Filter by test type. - page: Page number of paginated results + page: Page number of paginated results. - per_page: Number of items per page + per_page: Number of results per page. - test_name: Filter by test name + test_name: Filter by test name. extra_headers: Send extra headers @@ -273,6 +279,8 @@ def delete( account. Args: + account_id: Unique identifier linked to an account. + dex_test_id: API Resource UUID tag. extra_headers: Send extra headers @@ -319,6 +327,8 @@ def get( Fetch a single DEX test. Args: + account_id: Unique identifier linked to an account. + dex_test_id: The unique identifier for the test. extra_headers: Send extra headers @@ -392,6 +402,8 @@ async def create( Create a DEX test. Args: + account_id: Unique identifier linked to an account. + data: The configuration object which contains the details for the WARP client to conduct the test. @@ -462,6 +474,8 @@ async def update( Update a DEX test. Args: + account_id: Unique identifier linked to an account. + dex_test_id: API Resource UUID tag. data: The configuration object which contains the details for the WARP client to @@ -533,16 +547,18 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[DEXTestListResponse, AsyncV4PagePaginationArray[DEXTestListResponse]]: """ - Fetch all DEX tests + Fetch all DEX tests. Args: - kind: Filter by test type + account_id: Unique identifier linked to an account. + + kind: Filter by test type. - page: Page number of paginated results + page: Page number of paginated results. - per_page: Number of items per page + per_page: Number of results per page. - test_name: Filter by test name + test_name: Filter by test name. extra_headers: Send extra headers @@ -593,6 +609,8 @@ async def delete( account. Args: + account_id: Unique identifier linked to an account. + dex_test_id: API Resource UUID tag. extra_headers: Send extra headers @@ -639,6 +657,8 @@ async def get( Fetch a single DEX test. Args: + account_id: Unique identifier linked to an account. + dex_test_id: The unique identifier for the test. extra_headers: Send extra headers diff --git a/src/cloudflare/resources/zero_trust/devices/fleet_status.py b/src/cloudflare/resources/zero_trust/devices/fleet_status.py index dccbc892b71..bd73e30ba4b 100644 --- a/src/cloudflare/resources/zero_trust/devices/fleet_status.py +++ b/src/cloudflare/resources/zero_trust/devices/fleet_status.py @@ -61,13 +61,15 @@ def get( table Args: - device_id: Device-specific ID, given as UUID v4 + account_id: Unique identifier linked to an account. - since_minutes: Number of minutes before current time + device_id: Unique identifier for the physical device (UUID). - colo: List of data centers to filter results + since_minutes: Number of minutes before current time. - time_now: Number of minutes before current time + colo: List of data centers to filter results. + + time_now: Current time in ISO format. extra_headers: Send extra headers @@ -145,13 +147,15 @@ async def get( table Args: - device_id: Device-specific ID, given as UUID v4 + account_id: Unique identifier linked to an account. + + device_id: Unique identifier for the physical device (UUID). - since_minutes: Number of minutes before current time + since_minutes: Number of minutes before current time. - colo: List of data centers to filter results + colo: List of data centers to filter results. - time_now: Number of minutes before current time + time_now: Current time in ISO format. extra_headers: Send extra headers diff --git a/src/cloudflare/resources/zero_trust/dex/colos.py b/src/cloudflare/resources/zero_trust/dex/colos.py index ba8caaff060..0dd99abbc94 100644 --- a/src/cloudflare/resources/zero_trust/dex/colos.py +++ b/src/cloudflare/resources/zero_trust/dex/colos.py @@ -64,9 +64,11 @@ def list( are also returned and sorted alphabetically. Args: - from_: Start time for connection period in ISO (RFC3339 - ISO 8601) format + account_id: Unique identifier linked to an account. - to: End time for connection period in ISO (RFC3339 - ISO 8601) format + from_: Start time for connection period in ISO (RFC3339 - ISO 8601) format. + + to: End time for connection period in ISO (RFC3339 - ISO 8601) format. sort_by: Type of usage that colos should be sorted by. If unspecified, returns all Cloudflare colos sorted alphabetically. @@ -142,9 +144,11 @@ def list( are also returned and sorted alphabetically. Args: - from_: Start time for connection period in ISO (RFC3339 - ISO 8601) format + account_id: Unique identifier linked to an account. + + from_: Start time for connection period in ISO (RFC3339 - ISO 8601) format. - to: End time for connection period in ISO (RFC3339 - ISO 8601) format + to: End time for connection period in ISO (RFC3339 - ISO 8601) format. sort_by: Type of usage that colos should be sorted by. If unspecified, returns all Cloudflare colos sorted alphabetically. diff --git a/src/cloudflare/resources/zero_trust/dex/commands/commands.py b/src/cloudflare/resources/zero_trust/dex/commands/commands.py index a03bf6bb3f8..abd7af455c2 100644 --- a/src/cloudflare/resources/zero_trust/dex/commands/commands.py +++ b/src/cloudflare/resources/zero_trust/dex/commands/commands.py @@ -97,9 +97,11 @@ def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[CommandCreateResponse]: """ - Initiate commands for up to 10 devices per account + Initiate commands for up to 10 devices per account. Args: + account_id: Unique identifier linked to an account. + commands: List of device-level commands to execute extra_headers: Send extra headers @@ -149,21 +151,23 @@ def list( account, optionally filtered by time range, device, or other parameters Args: - page: Page number for pagination + account_id: Unique identifier linked to an account. + + page: Page number of paginated results. - per_page: Number of results per page + per_page: Number of results per page. - command_type: Optionally filter executed commands by command type + command_type: Optionally filter executed commands by command type. - device_id: Unique identifier for a device + device_id: Unique identifier for a device. - from_: Start time for the query in ISO (RFC3339 - ISO 8601) format + from_: Start time for the query in ISO (RFC3339 - ISO 8601) format. - status: Optionally filter executed commands by status + status: Optionally filter executed commands by status. - to: End time for the query in ISO (RFC3339 - ISO 8601) format + to: End time for the query in ISO (RFC3339 - ISO 8601) format. - user_email: Email tied to the device + user_email: Email tied to the device. extra_headers: Send extra headers @@ -246,9 +250,11 @@ async def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[CommandCreateResponse]: """ - Initiate commands for up to 10 devices per account + Initiate commands for up to 10 devices per account. Args: + account_id: Unique identifier linked to an account. + commands: List of device-level commands to execute extra_headers: Send extra headers @@ -298,21 +304,23 @@ def list( account, optionally filtered by time range, device, or other parameters Args: - page: Page number for pagination + account_id: Unique identifier linked to an account. + + page: Page number of paginated results. - per_page: Number of results per page + per_page: Number of results per page. - command_type: Optionally filter executed commands by command type + command_type: Optionally filter executed commands by command type. - device_id: Unique identifier for a device + device_id: Unique identifier for a device. - from_: Start time for the query in ISO (RFC3339 - ISO 8601) format + from_: Start time for the query in ISO (RFC3339 - ISO 8601) format. - status: Optionally filter executed commands by status + status: Optionally filter executed commands by status. - to: End time for the query in ISO (RFC3339 - ISO 8601) format + to: End time for the query in ISO (RFC3339 - ISO 8601) format. - user_email: Email tied to the device + user_email: Email tied to the device. extra_headers: Send extra headers diff --git a/src/cloudflare/resources/zero_trust/dex/commands/devices.py b/src/cloudflare/resources/zero_trust/dex/commands/devices.py index 02323f2d7d8..5eb43055acd 100644 --- a/src/cloudflare/resources/zero_trust/dex/commands/devices.py +++ b/src/cloudflare/resources/zero_trust/dex/commands/devices.py @@ -63,11 +63,13 @@ def list( connected in the last 1 hour. Args: - page: Page number of paginated results + account_id: Unique identifier linked to an account. - per_page: Number of items per page + page: Page number of paginated results. - search: Filter devices by name or email + per_page: Number of results per page. + + search: Filter devices by name or email. extra_headers: Send extra headers @@ -139,11 +141,13 @@ def list( connected in the last 1 hour. Args: - page: Page number of paginated results + account_id: Unique identifier linked to an account. + + page: Page number of paginated results. - per_page: Number of items per page + per_page: Number of results per page. - search: Filter devices by name or email + search: Filter devices by name or email. extra_headers: Send extra headers diff --git a/src/cloudflare/resources/zero_trust/dex/commands/downloads.py b/src/cloudflare/resources/zero_trust/dex/commands/downloads.py index e3df1ee0218..4d918e74fb4 100644 --- a/src/cloudflare/resources/zero_trust/dex/commands/downloads.py +++ b/src/cloudflare/resources/zero_trust/dex/commands/downloads.py @@ -61,6 +61,8 @@ def get( Bulk downloads are not supported Args: + account_id: Unique identifier linked to an account. + command_id: Unique identifier for a command extra_headers: Send extra headers @@ -130,6 +132,8 @@ async def get( Bulk downloads are not supported Args: + account_id: Unique identifier linked to an account. + command_id: Unique identifier for a command extra_headers: Send extra headers diff --git a/src/cloudflare/resources/zero_trust/dex/commands/quota.py b/src/cloudflare/resources/zero_trust/dex/commands/quota.py index e89e5853a67..810dc9de631 100644 --- a/src/cloudflare/resources/zero_trust/dex/commands/quota.py +++ b/src/cloudflare/resources/zero_trust/dex/commands/quota.py @@ -59,6 +59,8 @@ def get( specific account, including the time when the quota will reset Args: + account_id: Unique identifier linked to an account. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -118,6 +120,8 @@ async def get( specific account, including the time when the quota will reset Args: + account_id: Unique identifier linked to an account. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request diff --git a/src/cloudflare/resources/zero_trust/dex/devices/isps.py b/src/cloudflare/resources/zero_trust/dex/devices/isps.py index 4e3675de167..72668dc9c2d 100644 --- a/src/cloudflare/resources/zero_trust/dex/devices/isps.py +++ b/src/cloudflare/resources/zero_trust/dex/devices/isps.py @@ -69,21 +69,23 @@ def list( List ISP information observed for a specific device during traceroute tests. Args: + account_id: Unique identifier linked to an account. + device_id: API Resource UUID tag. per_page: Number of items per page cursor: Cursor for cursor-based pagination. Mutually exclusive with page. - from_: Start time for the query in ISO 8601 format + from_: Start time for the query in ISO 8601 format. page: Page number of paginated results. Mutually exclusive with cursor. - sort_by: The field to sort results by + sort_by: The field to sort results by. - sort_order: The order to sort results + sort_order: The order to sort results. - to: End time for the query in ISO 8601 format + to: End time for the query in ISO 8601 format. extra_headers: Send extra headers @@ -167,21 +169,23 @@ def list( List ISP information observed for a specific device during traceroute tests. Args: + account_id: Unique identifier linked to an account. + device_id: API Resource UUID tag. per_page: Number of items per page cursor: Cursor for cursor-based pagination. Mutually exclusive with page. - from_: Start time for the query in ISO 8601 format + from_: Start time for the query in ISO 8601 format. page: Page number of paginated results. Mutually exclusive with cursor. - sort_by: The field to sort results by + sort_by: The field to sort results by. - sort_order: The order to sort results + sort_order: The order to sort results. - to: End time for the query in ISO 8601 format + to: End time for the query in ISO 8601 format. extra_headers: Send extra headers diff --git a/src/cloudflare/resources/zero_trust/dex/fleet_status/devices.py b/src/cloudflare/resources/zero_trust/dex/fleet_status/devices.py index 2921bea6d2b..001d0b6e11d 100644 --- a/src/cloudflare/resources/zero_trust/dex/fleet_status/devices.py +++ b/src/cloudflare/resources/zero_trust/dex/fleet_status/devices.py @@ -68,26 +68,30 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncV4PagePaginationArray[DeviceListResponse]: """ - List details for devices using WARP + List details for devices using WARP. Args: - from_: Time range beginning in ISO format + account_id: Unique identifier linked to an account. - page: Page number + from_: Start of the time range to query. Timestamp can be provided in ISO 8601 datetime + format or milliseconds since epoch. - per_page: Number of results per page + page: Page number of paginated results. - to: Time range end in ISO format + per_page: Number of results per page. - colo: Cloudflare colo + to: End of the time range to query. Timestamp can be provided in ISO 8601 datetime + format or milliseconds since epoch. - device_id: Device-specific ID, given as UUID v4 + colo: Cloudflare colo airport code. - mode: The mode under which the WARP client is run + device_id: Device-specific ID, given as UUID. - platform: Operating system + mode: The mode under which the WARP client is run. - sort_by: Dimension to sort results by + platform: Operating system. + + sort_by: Dimension to sort results by. source: Source: @@ -98,9 +102,9 @@ def list( instead for longer time ranges. - `raw` - device details, up to 7 days prior - status: Network status + status: Network status. - version: WARP client version + version: WARP client version. extra_headers: Send extra headers @@ -186,26 +190,30 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[DeviceListResponse, AsyncV4PagePaginationArray[DeviceListResponse]]: """ - List details for devices using WARP + List details for devices using WARP. Args: - from_: Time range beginning in ISO format + account_id: Unique identifier linked to an account. + + from_: Start of the time range to query. Timestamp can be provided in ISO 8601 datetime + format or milliseconds since epoch. - page: Page number + page: Page number of paginated results. - per_page: Number of results per page + per_page: Number of results per page. - to: Time range end in ISO format + to: End of the time range to query. Timestamp can be provided in ISO 8601 datetime + format or milliseconds since epoch. - colo: Cloudflare colo + colo: Cloudflare colo airport code. - device_id: Device-specific ID, given as UUID v4 + device_id: Device-specific ID, given as UUID. - mode: The mode under which the WARP client is run + mode: The mode under which the WARP client is run. - platform: Operating system + platform: Operating system. - sort_by: Dimension to sort results by + sort_by: Dimension to sort results by. source: Source: @@ -216,9 +224,9 @@ def list( instead for longer time ranges. - `raw` - device details, up to 7 days prior - status: Network status + status: Network status. - version: WARP client version + version: WARP client version. extra_headers: Send extra headers diff --git a/src/cloudflare/resources/zero_trust/dex/fleet_status/fleet_status.py b/src/cloudflare/resources/zero_trust/dex/fleet_status/fleet_status.py index 9ccee6a129b..fef7537e35d 100644 --- a/src/cloudflare/resources/zero_trust/dex/fleet_status/fleet_status.py +++ b/src/cloudflare/resources/zero_trust/dex/fleet_status/fleet_status.py @@ -70,10 +70,12 @@ def live( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[FleetStatusLiveResponse]: """ - List details for live (up to 60 minutes) devices using WARP + List details for live (up to 60 minutes) devices using WARP. Args: - since_minutes: Number of minutes before current time + account_id: Unique identifier linked to an account. + + since_minutes: Number of minutes before current time. extra_headers: Send extra headers @@ -114,16 +116,20 @@ def over_time( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[FleetStatusOverTimeResponse]: """ - List details for devices using WARP, up to 7 days + List details for devices using WARP, up to 7 days. Args: - from_: Time range beginning in ISO format + account_id: Unique identifier linked to an account. + + from_: Start of the time range to query. Timestamp can be provided in ISO 8601 datetime + format or milliseconds since epoch. - to: Time range end in ISO format + to: End of the time range to query. Timestamp can be provided in ISO 8601 datetime + format or milliseconds since epoch. - colo: Cloudflare colo + colo: Cloudflare colo airport code. - device_id: Device-specific ID, given as UUID v4 + device_id: Device-specific ID, given as UUID. extra_headers: Send extra headers @@ -194,10 +200,12 @@ async def live( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[FleetStatusLiveResponse]: """ - List details for live (up to 60 minutes) devices using WARP + List details for live (up to 60 minutes) devices using WARP. Args: - since_minutes: Number of minutes before current time + account_id: Unique identifier linked to an account. + + since_minutes: Number of minutes before current time. extra_headers: Send extra headers @@ -240,16 +248,20 @@ async def over_time( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[FleetStatusOverTimeResponse]: """ - List details for devices using WARP, up to 7 days + List details for devices using WARP, up to 7 days. Args: - from_: Time range beginning in ISO format + account_id: Unique identifier linked to an account. + + from_: Start of the time range to query. Timestamp can be provided in ISO 8601 datetime + format or milliseconds since epoch. - to: Time range end in ISO format + to: End of the time range to query. Timestamp can be provided in ISO 8601 datetime + format or milliseconds since epoch. - colo: Cloudflare colo + colo: Cloudflare colo airport code. - device_id: Device-specific ID, given as UUID v4 + device_id: Device-specific ID, given as UUID. extra_headers: Send extra headers diff --git a/src/cloudflare/resources/zero_trust/dex/http_tests/http_tests.py b/src/cloudflare/resources/zero_trust/dex/http_tests/http_tests.py index 1a93e810b25..c998ce3b22c 100644 --- a/src/cloudflare/resources/zero_trust/dex/http_tests/http_tests.py +++ b/src/cloudflare/resources/zero_trust/dex/http_tests/http_tests.py @@ -79,13 +79,15 @@ def get( time period between 1 hour and 7 days. Args: + account_id: Unique identifier linked to an account. + test_id: API Resource UUID tag. - from_: Start time for aggregate metrics in ISO ms + from_: Start time for aggregate metrics in ISO ms. interval: Time interval for aggregate time slots. - to: End time for aggregate metrics in ISO ms + to: End time for aggregate metrics in ISO ms. colo: Optionally filter result stats to a Cloudflare colo. Cannot be used in combination with deviceId param. @@ -174,13 +176,15 @@ async def get( time period between 1 hour and 7 days. Args: + account_id: Unique identifier linked to an account. + test_id: API Resource UUID tag. - from_: Start time for aggregate metrics in ISO ms + from_: Start time for aggregate metrics in ISO ms. interval: Time interval for aggregate time slots. - to: End time for aggregate metrics in ISO ms + to: End time for aggregate metrics in ISO ms. colo: Optionally filter result stats to a Cloudflare colo. Cannot be used in combination with deviceId param. diff --git a/src/cloudflare/resources/zero_trust/dex/http_tests/percentiles.py b/src/cloudflare/resources/zero_trust/dex/http_tests/percentiles.py index db4efac7297..7bb993648b3 100644 --- a/src/cloudflare/resources/zero_trust/dex/http_tests/percentiles.py +++ b/src/cloudflare/resources/zero_trust/dex/http_tests/percentiles.py @@ -65,11 +65,13 @@ def get( days. Args: + account_id: Unique identifier linked to an account. + test_id: API Resource UUID tag. - from_: Start time for the query in ISO (RFC3339 - ISO 8601) format + from_: Start time for the query in ISO (RFC3339 - ISO 8601) format. - to: End time for the query in ISO (RFC3339 - ISO 8601) format + to: End time for the query in ISO (RFC3339 - ISO 8601) format. colo: Optionally filter result stats to a Cloudflare colo. Cannot be used in combination with deviceId param. @@ -154,11 +156,13 @@ async def get( days. Args: + account_id: Unique identifier linked to an account. + test_id: API Resource UUID tag. - from_: Start time for the query in ISO (RFC3339 - ISO 8601) format + from_: Start time for the query in ISO (RFC3339 - ISO 8601) format. - to: End time for the query in ISO (RFC3339 - ISO 8601) format + to: End time for the query in ISO (RFC3339 - ISO 8601) format. colo: Optionally filter result stats to a Cloudflare colo. Cannot be used in combination with deviceId param. diff --git a/src/cloudflare/resources/zero_trust/dex/rules.py b/src/cloudflare/resources/zero_trust/dex/rules.py index db3b4ce4358..31a43aa6e4a 100644 --- a/src/cloudflare/resources/zero_trust/dex/rules.py +++ b/src/cloudflare/resources/zero_trust/dex/rules.py @@ -65,9 +65,11 @@ def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[RuleCreateResponse]: """ - Create a DEX Rule + Create a DEX Rule. Args: + account_id: Unique identifier linked to an account. + match: The wirefilter expression to match. name: The name of the Rule. @@ -118,9 +120,11 @@ def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[RuleUpdateResponse]: """ - Update a DEX Rule + Update a DEX Rule. Args: + account_id: Unique identifier linked to an account. + rule_id: API Resource UUID tag. match: The wirefilter expression to match. @@ -176,18 +180,20 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncV4PagePagination[Optional[RuleListResponse]]: """ - List DEX Rules + List DEX Rules. Args: - page: Page number of paginated results + account_id: Unique identifier linked to an account. + + page: Page number of paginated results. - per_page: Number of items per page + per_page: Number of results per page. - name: Filter results by rule name + name: Filter results by rule name. - sort_by: Which property to sort results by + sort_by: Which property to sort results by. - sort_order: Sort direction for sort_by property + sort_order: Sort direction for sort_by property. extra_headers: Send extra headers @@ -234,9 +240,11 @@ def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[RuleDeleteResponse]: """ - Delete a DEX Rule + Delete a DEX Rule. Args: + account_id: Unique identifier linked to an account. + rule_id: API Resource UUID tag. extra_headers: Send extra headers @@ -276,9 +284,11 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[RuleGetResponse]: """ - Get details for a DEX Rule + Get details for a DEX Rule. Args: + account_id: Unique identifier linked to an account. + rule_id: API Resource UUID tag. extra_headers: Send extra headers @@ -341,9 +351,11 @@ async def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[RuleCreateResponse]: """ - Create a DEX Rule + Create a DEX Rule. Args: + account_id: Unique identifier linked to an account. + match: The wirefilter expression to match. name: The name of the Rule. @@ -394,9 +406,11 @@ async def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[RuleUpdateResponse]: """ - Update a DEX Rule + Update a DEX Rule. Args: + account_id: Unique identifier linked to an account. + rule_id: API Resource UUID tag. match: The wirefilter expression to match. @@ -452,18 +466,20 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[Optional[RuleListResponse], AsyncV4PagePagination[Optional[RuleListResponse]]]: """ - List DEX Rules + List DEX Rules. Args: - page: Page number of paginated results + account_id: Unique identifier linked to an account. + + page: Page number of paginated results. - per_page: Number of items per page + per_page: Number of results per page. - name: Filter results by rule name + name: Filter results by rule name. - sort_by: Which property to sort results by + sort_by: Which property to sort results by. - sort_order: Sort direction for sort_by property + sort_order: Sort direction for sort_by property. extra_headers: Send extra headers @@ -510,9 +526,11 @@ async def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[RuleDeleteResponse]: """ - Delete a DEX Rule + Delete a DEX Rule. Args: + account_id: Unique identifier linked to an account. + rule_id: API Resource UUID tag. extra_headers: Send extra headers @@ -552,9 +570,11 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[RuleGetResponse]: """ - Get details for a DEX Rule + Get details for a DEX Rule. Args: + account_id: Unique identifier linked to an account. + rule_id: API Resource UUID tag. extra_headers: Send extra headers diff --git a/src/cloudflare/resources/zero_trust/dex/tests/tests.py b/src/cloudflare/resources/zero_trust/dex/tests/tests.py index f2130d84b48..2fb91a3935c 100644 --- a/src/cloudflare/resources/zero_trust/dex/tests/tests.py +++ b/src/cloudflare/resources/zero_trust/dex/tests/tests.py @@ -78,16 +78,18 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SyncV4PagePagination[Optional[Tests]]: """ - List DEX tests with overview metrics + List DEX tests with overview metrics. Args: + account_id: Unique identifier linked to an account. + colo: Optionally filter result stats to a Cloudflare colo. Cannot be used in combination with deviceId param. device_id: Optionally filter result stats to a specific device(s). Cannot be used in combination with colo param. - kind: Filter by test type + kind: Filter by test type. page: Page number of paginated results @@ -96,7 +98,7 @@ def list( registration_id: Optionally filter results to a specific device registration. Must be used in combination with a single deviceId. - test_name: Optionally filter results by test name + test_name: Optionally filter results by test name. extra_headers: Send extra headers @@ -176,16 +178,18 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AsyncPaginator[Optional[Tests], AsyncV4PagePagination[Optional[Tests]]]: """ - List DEX tests with overview metrics + List DEX tests with overview metrics. Args: + account_id: Unique identifier linked to an account. + colo: Optionally filter result stats to a Cloudflare colo. Cannot be used in combination with deviceId param. device_id: Optionally filter result stats to a specific device(s). Cannot be used in combination with colo param. - kind: Filter by test type + kind: Filter by test type. page: Page number of paginated results @@ -194,7 +198,7 @@ def list( registration_id: Optionally filter results to a specific device registration. Must be used in combination with a single deviceId. - test_name: Optionally filter results by test name + test_name: Optionally filter results by test name. extra_headers: Send extra headers diff --git a/src/cloudflare/resources/zero_trust/dex/tests/unique_devices.py b/src/cloudflare/resources/zero_trust/dex/tests/unique_devices.py index 06ee76805e8..1614a54aaea 100644 --- a/src/cloudflare/resources/zero_trust/dex/tests/unique_devices.py +++ b/src/cloudflare/resources/zero_trust/dex/tests/unique_devices.py @@ -62,10 +62,12 @@ def list( tests in the past 7 days. Args: + account_id: Unique identifier linked to an account. + device_id: Optionally filter result stats to a specific device(s). Cannot be used in combination with colo param. - test_name: Optionally filter results by test name + test_name: Optionally filter results by test name. extra_headers: Send extra headers @@ -135,10 +137,12 @@ async def list( tests in the past 7 days. Args: + account_id: Unique identifier linked to an account. + device_id: Optionally filter result stats to a specific device(s). Cannot be used in combination with colo param. - test_name: Optionally filter results by test name + test_name: Optionally filter results by test name. extra_headers: Send extra headers diff --git a/src/cloudflare/resources/zero_trust/dex/traceroute_test_results/network_path.py b/src/cloudflare/resources/zero_trust/dex/traceroute_test_results/network_path.py index b061a59f743..2c3a9e0fa3e 100644 --- a/src/cloudflare/resources/zero_trust/dex/traceroute_test_results/network_path.py +++ b/src/cloudflare/resources/zero_trust/dex/traceroute_test_results/network_path.py @@ -60,6 +60,8 @@ def get( run Args: + account_id: Unique identifier linked to an account. + test_result_id: API Resource UUID tag. extra_headers: Send extra headers @@ -128,6 +130,8 @@ async def get( run Args: + account_id: Unique identifier linked to an account. + test_result_id: API Resource UUID tag. extra_headers: Send extra headers diff --git a/src/cloudflare/resources/zero_trust/dex/traceroute_tests.py b/src/cloudflare/resources/zero_trust/dex/traceroute_tests.py index 7216f0f51db..9284e6bfc40 100644 --- a/src/cloudflare/resources/zero_trust/dex/traceroute_tests.py +++ b/src/cloudflare/resources/zero_trust/dex/traceroute_tests.py @@ -69,17 +69,19 @@ def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[Traceroute]: """ - Get test details and aggregate performance metrics for an traceroute test for a + Get test details and aggregate performance metrics for a traceroute test for a given time period between 1 hour and 7 days. Args: + account_id: Unique identifier linked to an account. + test_id: API Resource UUID tag. - from_: Start time for aggregate metrics in ISO ms + from_: Start time for aggregate metrics in ISO ms. interval: Time interval for aggregate time slots. - to: End time for aggregate metrics in ISO ms + to: End time for aggregate metrics in ISO ms. colo: Optionally filter result stats to a Cloudflare colo. Cannot be used in combination with deviceId param. @@ -140,18 +142,20 @@ def network_path( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[NetworkPathResponse]: """ - Get a breakdown of metrics by hop for individual traceroute test runs + Get a breakdown of metrics by hop for individual traceroute test runs. Args: + account_id: Unique identifier linked to an account. + test_id: API Resource UUID tag. - device_id: Device to filter tracroute result runs to + device_id: Device to filter traceroute result runs to. - from_: Start time for aggregate metrics in ISO ms + from_: Start time for aggregate metrics in ISO ms. interval: Time interval for aggregate time slots. - to: End time for aggregate metrics in ISO ms + to: End time for aggregate metrics in ISO ms. extra_headers: Send extra headers @@ -211,11 +215,13 @@ def percentiles( 7 days. Args: + account_id: Unique identifier linked to an account. + test_id: API Resource UUID tag. - from_: Start time for the query in ISO (RFC3339 - ISO 8601) format + from_: Start time for the query in ISO (RFC3339 - ISO 8601) format. - to: End time for the query in ISO (RFC3339 - ISO 8601) format + to: End time for the query in ISO (RFC3339 - ISO 8601) format. colo: Optionally filter result stats to a Cloudflare colo. Cannot be used in combination with deviceId param. @@ -301,17 +307,19 @@ async def get( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[Traceroute]: """ - Get test details and aggregate performance metrics for an traceroute test for a + Get test details and aggregate performance metrics for a traceroute test for a given time period between 1 hour and 7 days. Args: + account_id: Unique identifier linked to an account. + test_id: API Resource UUID tag. - from_: Start time for aggregate metrics in ISO ms + from_: Start time for aggregate metrics in ISO ms. interval: Time interval for aggregate time slots. - to: End time for aggregate metrics in ISO ms + to: End time for aggregate metrics in ISO ms. colo: Optionally filter result stats to a Cloudflare colo. Cannot be used in combination with deviceId param. @@ -372,18 +380,20 @@ async def network_path( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Optional[NetworkPathResponse]: """ - Get a breakdown of metrics by hop for individual traceroute test runs + Get a breakdown of metrics by hop for individual traceroute test runs. Args: + account_id: Unique identifier linked to an account. + test_id: API Resource UUID tag. - device_id: Device to filter tracroute result runs to + device_id: Device to filter traceroute result runs to. - from_: Start time for aggregate metrics in ISO ms + from_: Start time for aggregate metrics in ISO ms. interval: Time interval for aggregate time slots. - to: End time for aggregate metrics in ISO ms + to: End time for aggregate metrics in ISO ms. extra_headers: Send extra headers @@ -443,11 +453,13 @@ async def percentiles( 7 days. Args: + account_id: Unique identifier linked to an account. + test_id: API Resource UUID tag. - from_: Start time for the query in ISO (RFC3339 - ISO 8601) format + from_: Start time for the query in ISO (RFC3339 - ISO 8601) format. - to: End time for the query in ISO (RFC3339 - ISO 8601) format + to: End time for the query in ISO (RFC3339 - ISO 8601) format. colo: Optionally filter result stats to a Cloudflare colo. Cannot be used in combination with deviceId param. diff --git a/src/cloudflare/resources/zero_trust/dex/warp_change_events.py b/src/cloudflare/resources/zero_trust/dex/warp_change_events.py index d4ad3033aba..5a1cafa2363 100644 --- a/src/cloudflare/resources/zero_trust/dex/warp_change_events.py +++ b/src/cloudflare/resources/zero_trust/dex/warp_change_events.py @@ -69,13 +69,15 @@ def get( List WARP configuration and enablement toggle change events by device. Args: - from_: Start time for the query in ISO (RFC3339 - ISO 8601) format + account_id: Unique identifier linked to an account. - page: Page number of paginated results + from_: Start time for the query in ISO (RFC3339 - ISO 8601) format. - per_page: Number of items per page + page: Page number of paginated results. - to: End time for the query in ISO (RFC3339 - ISO 8601) format + per_page: Number of results per page. + + to: End time for the query in ISO (RFC3339 - ISO 8601) format. account_name: Filter events by account name. @@ -86,7 +88,7 @@ def get( toggle: Filter events by type toggle value. Applicable to type='toggle' events only. - type: Filter events by type 'config' or 'toggle' + type: Filter events by type 'config' or 'toggle'. extra_headers: Send extra headers @@ -169,13 +171,15 @@ async def get( List WARP configuration and enablement toggle change events by device. Args: - from_: Start time for the query in ISO (RFC3339 - ISO 8601) format + account_id: Unique identifier linked to an account. + + from_: Start time for the query in ISO (RFC3339 - ISO 8601) format. - page: Page number of paginated results + page: Page number of paginated results. - per_page: Number of items per page + per_page: Number of results per page. - to: End time for the query in ISO (RFC3339 - ISO 8601) format + to: End time for the query in ISO (RFC3339 - ISO 8601) format. account_name: Filter events by account name. @@ -186,7 +190,7 @@ async def get( toggle: Filter events by type toggle value. Applicable to type='toggle' events only. - type: Filter events by type 'config' or 'toggle' + type: Filter events by type 'config' or 'toggle'. extra_headers: Send extra headers diff --git a/src/cloudflare/types/custom_hostnames/custom_hostname_list_params.py b/src/cloudflare/types/custom_hostnames/custom_hostname_list_params.py index d6dbca994e7..69871d4f264 100644 --- a/src/cloudflare/types/custom_hostnames/custom_hostname_list_params.py +++ b/src/cloudflare/types/custom_hostnames/custom_hostname_list_params.py @@ -2,7 +2,9 @@ from __future__ import annotations -from typing_extensions import Literal, Required, TypedDict +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ..._utils import PropertyInfo __all__ = ["CustomHostnameListParams", "Hostname"] @@ -15,7 +17,8 @@ class CustomHostnameListParams(TypedDict, total=False): """Hostname ID to match against. This ID was generated and returned during the initial custom_hostname creation. - This parameter cannot be used with the 'hostname' parameter. + This parameter cannot be used with the 'hostname', 'hostname.exact', + 'hostname.contain', or 'hostname.startsWith' parameters. """ certificate_authority: Literal["google", "lets_encrypt", "ssl_com"] @@ -94,5 +97,20 @@ class Hostname(TypedDict, total=False): contain: str """Filters hostnames by a substring match on the hostname value. - This parameter cannot be used with the 'id' parameter. + This parameter cannot be used with the 'id', 'hostname', 'hostname.exact', or + 'hostname.startsWith' parameters. + """ + + exact: str + """Fully qualified domain name to match against. + + This parameter cannot be used with the 'id', 'hostname', 'hostname.contain', or + 'hostname.startsWith' parameters. + """ + + starts_with: Annotated[str, PropertyInfo(alias="startsWith")] + """Filters hostnames by a prefix match on the hostname value. + + This parameter cannot be used with the 'id', 'hostname', 'hostname.exact', or + 'hostname.contain' parameters. """ diff --git a/src/cloudflare/types/zero_trust/devices/dex_test_create_params.py b/src/cloudflare/types/zero_trust/devices/dex_test_create_params.py index 8cb648370a6..3eab2118b65 100644 --- a/src/cloudflare/types/zero_trust/devices/dex_test_create_params.py +++ b/src/cloudflare/types/zero_trust/devices/dex_test_create_params.py @@ -10,6 +10,7 @@ class DEXTestCreateParams(TypedDict, total=False): account_id: Required[str] + """Unique identifier linked to an account.""" data: Required[Data] """ @@ -52,10 +53,10 @@ class Data(TypedDict, total=False): class TargetPolicy(TypedDict, total=False): id: Required[str] - """API Resource UUID tag.""" + """The id of the DEX rule.""" default: bool - """Whether the DEX rule is the account default""" + """Whether the DEX rule is the account default.""" name: str - """The name of the DEX rule""" + """The name of the DEX rule.""" diff --git a/src/cloudflare/types/zero_trust/devices/dex_test_create_response.py b/src/cloudflare/types/zero_trust/devices/dex_test_create_response.py index e7b25b42ece..8288174bbfb 100644 --- a/src/cloudflare/types/zero_trust/devices/dex_test_create_response.py +++ b/src/cloudflare/types/zero_trust/devices/dex_test_create_response.py @@ -25,13 +25,13 @@ class Data(BaseModel): class TargetPolicy(BaseModel): id: str - """API Resource UUID tag.""" + """The id of the DEX rule.""" default: Optional[bool] = None - """Whether the DEX rule is the account default""" + """Whether the DEX rule is the account default.""" name: Optional[str] = None - """The name of the DEX rule""" + """The name of the DEX rule.""" class DEXTestCreateResponse(BaseModel): diff --git a/src/cloudflare/types/zero_trust/devices/dex_test_delete_response.py b/src/cloudflare/types/zero_trust/devices/dex_test_delete_response.py index 8c32a6e7c6a..a715d05338b 100644 --- a/src/cloudflare/types/zero_trust/devices/dex_test_delete_response.py +++ b/src/cloudflare/types/zero_trust/devices/dex_test_delete_response.py @@ -25,13 +25,13 @@ class DEXTestData(BaseModel): class DEXTestTargetPolicy(BaseModel): id: str - """API Resource UUID tag.""" + """The id of the DEX rule.""" default: Optional[bool] = None - """Whether the DEX rule is the account default""" + """Whether the DEX rule is the account default.""" name: Optional[str] = None - """The name of the DEX rule""" + """The name of the DEX rule.""" class DEXTest(BaseModel): diff --git a/src/cloudflare/types/zero_trust/devices/dex_test_get_response.py b/src/cloudflare/types/zero_trust/devices/dex_test_get_response.py index 32045cd3db6..b5e1a7cefae 100644 --- a/src/cloudflare/types/zero_trust/devices/dex_test_get_response.py +++ b/src/cloudflare/types/zero_trust/devices/dex_test_get_response.py @@ -25,13 +25,13 @@ class Data(BaseModel): class TargetPolicy(BaseModel): id: str - """API Resource UUID tag.""" + """The id of the DEX rule.""" default: Optional[bool] = None - """Whether the DEX rule is the account default""" + """Whether the DEX rule is the account default.""" name: Optional[str] = None - """The name of the DEX rule""" + """The name of the DEX rule.""" class DEXTestGetResponse(BaseModel): diff --git a/src/cloudflare/types/zero_trust/devices/dex_test_list_params.py b/src/cloudflare/types/zero_trust/devices/dex_test_list_params.py index 6a0abe911f6..eab6e5465f6 100644 --- a/src/cloudflare/types/zero_trust/devices/dex_test_list_params.py +++ b/src/cloudflare/types/zero_trust/devices/dex_test_list_params.py @@ -11,15 +11,16 @@ class DEXTestListParams(TypedDict, total=False): account_id: Required[str] + """Unique identifier linked to an account.""" kind: Literal["http", "traceroute"] - """Filter by test type""" + """Filter by test type.""" page: float - """Page number of paginated results""" + """Page number of paginated results.""" per_page: float - """Number of items per page""" + """Number of results per page.""" test_name: Annotated[str, PropertyInfo(alias="testName")] - """Filter by test name""" + """Filter by test name.""" diff --git a/src/cloudflare/types/zero_trust/devices/dex_test_list_response.py b/src/cloudflare/types/zero_trust/devices/dex_test_list_response.py index a212ec3bf95..7366df2b871 100644 --- a/src/cloudflare/types/zero_trust/devices/dex_test_list_response.py +++ b/src/cloudflare/types/zero_trust/devices/dex_test_list_response.py @@ -25,13 +25,13 @@ class Data(BaseModel): class TargetPolicy(BaseModel): id: str - """API Resource UUID tag.""" + """The id of the DEX rule.""" default: Optional[bool] = None - """Whether the DEX rule is the account default""" + """Whether the DEX rule is the account default.""" name: Optional[str] = None - """The name of the DEX rule""" + """The name of the DEX rule.""" class DEXTestListResponse(BaseModel): diff --git a/src/cloudflare/types/zero_trust/devices/dex_test_update_params.py b/src/cloudflare/types/zero_trust/devices/dex_test_update_params.py index 9f4c11b91f7..540fda7a666 100644 --- a/src/cloudflare/types/zero_trust/devices/dex_test_update_params.py +++ b/src/cloudflare/types/zero_trust/devices/dex_test_update_params.py @@ -10,6 +10,7 @@ class DEXTestUpdateParams(TypedDict, total=False): account_id: Required[str] + """Unique identifier linked to an account.""" data: Required[Data] """ @@ -52,10 +53,10 @@ class Data(TypedDict, total=False): class TargetPolicy(TypedDict, total=False): id: Required[str] - """API Resource UUID tag.""" + """The id of the DEX rule.""" default: bool - """Whether the DEX rule is the account default""" + """Whether the DEX rule is the account default.""" name: str - """The name of the DEX rule""" + """The name of the DEX rule.""" diff --git a/src/cloudflare/types/zero_trust/devices/dex_test_update_response.py b/src/cloudflare/types/zero_trust/devices/dex_test_update_response.py index 2234d118c68..c7eab532884 100644 --- a/src/cloudflare/types/zero_trust/devices/dex_test_update_response.py +++ b/src/cloudflare/types/zero_trust/devices/dex_test_update_response.py @@ -25,13 +25,13 @@ class Data(BaseModel): class TargetPolicy(BaseModel): id: str - """API Resource UUID tag.""" + """The id of the DEX rule.""" default: Optional[bool] = None - """Whether the DEX rule is the account default""" + """Whether the DEX rule is the account default.""" name: Optional[str] = None - """The name of the DEX rule""" + """The name of the DEX rule.""" class DEXTestUpdateResponse(BaseModel): diff --git a/src/cloudflare/types/zero_trust/devices/fleet_status_get_params.py b/src/cloudflare/types/zero_trust/devices/fleet_status_get_params.py index 09a81b98c51..feb403d8347 100644 --- a/src/cloudflare/types/zero_trust/devices/fleet_status_get_params.py +++ b/src/cloudflare/types/zero_trust/devices/fleet_status_get_params.py @@ -9,12 +9,13 @@ class FleetStatusGetParams(TypedDict, total=False): account_id: Required[str] + """Unique identifier linked to an account.""" since_minutes: Required[float] - """Number of minutes before current time""" + """Number of minutes before current time.""" colo: str - """List of data centers to filter results""" + """List of data centers to filter results.""" time_now: str - """Number of minutes before current time""" + """Current time in ISO format.""" diff --git a/src/cloudflare/types/zero_trust/devices/fleet_status_get_response.py b/src/cloudflare/types/zero_trust/devices/fleet_status_get_response.py index f5744ade2a7..036128b430e 100644 --- a/src/cloudflare/types/zero_trust/devices/fleet_status_get_response.py +++ b/src/cloudflare/types/zero_trust/devices/fleet_status_get_response.py @@ -22,13 +22,28 @@ "ISPIPV6", "ISPIPV6Location", "RamUsedPctByApp", + "RTT", + "RTTMinRTTUs", + "RTTRTTUs", + "RTTRTTVarUs", + "TunnelStats", + "TunnelStatsBytesLost", + "TunnelStatsBytesReceived", + "TunnelStatsBytesRetransmitted", + "TunnelStatsBytesSent", + "TunnelStatsPacketsLost", + "TunnelStatsPacketsReceived", + "TunnelStatsPacketsRetransmitted", + "TunnelStatsPacketsSent", ] class CPUPctByApp(BaseModel): cpu_pct: Optional[float] = None + """CPU usage percentage, on a scale of 0 to 100.""" name: Optional[str] = None + """Application name.""" class DeviceIPV4Location(BaseModel): @@ -50,9 +65,12 @@ class DeviceIPV4(BaseModel): location: Optional[DeviceIPV4Location] = None + name: Optional[str] = None + netmask: Optional[str] = None - version: Optional[str] = None + version: Optional[int] = None + """IP version (`1` for IPv4, `2` for IPv6, `0` if unknown).""" class DeviceIPV6Location(BaseModel): @@ -74,9 +92,12 @@ class DeviceIPV6(BaseModel): location: Optional[DeviceIPV6Location] = None + name: Optional[str] = None + netmask: Optional[str] = None - version: Optional[str] = None + version: Optional[int] = None + """IP version (`1` for IPv4, `2` for IPv6, `0` if unknown).""" class GatewayIPV4Location(BaseModel): @@ -98,9 +119,12 @@ class GatewayIPV4(BaseModel): location: Optional[GatewayIPV4Location] = None + name: Optional[str] = None + netmask: Optional[str] = None - version: Optional[str] = None + version: Optional[int] = None + """IP version (`1` for IPv4, `2` for IPv6, `0` if unknown).""" class GatewayIPV6Location(BaseModel): @@ -122,9 +146,12 @@ class GatewayIPV6(BaseModel): location: Optional[GatewayIPV6Location] = None + name: Optional[str] = None + netmask: Optional[str] = None - version: Optional[str] = None + version: Optional[int] = None + """IP version (`1` for IPv4, `2` for IPv6, `0` if unknown).""" class ISPIPV4Location(BaseModel): @@ -146,9 +173,12 @@ class ISPIPV4(BaseModel): location: Optional[ISPIPV4Location] = None + name: Optional[str] = None + netmask: Optional[str] = None - version: Optional[str] = None + version: Optional[int] = None + """IP version (`1` for IPv4, `2` for IPv6, `0` if unknown).""" class ISPIPV6Location(BaseModel): @@ -170,38 +200,176 @@ class ISPIPV6(BaseModel): location: Optional[ISPIPV6Location] = None + name: Optional[str] = None + netmask: Optional[str] = None - version: Optional[str] = None + version: Optional[int] = None + """IP version (`1` for IPv4, `2` for IPv6, `0` if unknown).""" class RamUsedPctByApp(BaseModel): name: Optional[str] = None + """Application name.""" ram_used_pct: Optional[float] = None + """RAM usage percentage, on a scale of 0 to 100.""" + + +class RTTMinRTTUs(BaseModel): + """Minimum round-trip time in microseconds.""" + + downstream: Optional[int] = None + + upstream: Optional[int] = None + + +class RTTRTTUs(BaseModel): + """Round-trip time in microseconds.""" + + downstream: Optional[int] = None + + upstream: Optional[int] = None + + +class RTTRTTVarUs(BaseModel): + """Round-trip time variance in microseconds.""" + + downstream: Optional[int] = None + + upstream: Optional[int] = None + + +class RTT(BaseModel): + """Round-trip time statistics for the WARP tunnel.""" + + min_rtt_us: Optional[RTTMinRTTUs] = FieldInfo(alias="minRttUs", default=None) + """Minimum round-trip time in microseconds.""" + + rtt_us: Optional[RTTRTTUs] = FieldInfo(alias="rttUs", default=None) + """Round-trip time in microseconds.""" + + rtt_var_us: Optional[RTTRTTVarUs] = FieldInfo(alias="rttVarUs", default=None) + """Round-trip time variance in microseconds.""" + + +class TunnelStatsBytesLost(BaseModel): + """Number of bytes lost, split by direction.""" + + downstream: Optional[int] = None + + upstream: Optional[int] = None + + +class TunnelStatsBytesReceived(BaseModel): + """Number of bytes received, split by direction.""" + + downstream: Optional[int] = None + + upstream: Optional[int] = None + + +class TunnelStatsBytesRetransmitted(BaseModel): + """Number of bytes retransmitted, split by direction.""" + + downstream: Optional[int] = None + + upstream: Optional[int] = None + + +class TunnelStatsBytesSent(BaseModel): + """Number of bytes sent, split by direction.""" + + downstream: Optional[int] = None + + upstream: Optional[int] = None + + +class TunnelStatsPacketsLost(BaseModel): + """Number of packets lost, split by direction.""" + + downstream: Optional[int] = None + + upstream: Optional[int] = None + + +class TunnelStatsPacketsReceived(BaseModel): + """Number of packets received, split by direction.""" + + downstream: Optional[int] = None + + upstream: Optional[int] = None + + +class TunnelStatsPacketsRetransmitted(BaseModel): + """Number of packets retransmitted, split by direction.""" + + downstream: Optional[int] = None + + upstream: Optional[int] = None + + +class TunnelStatsPacketsSent(BaseModel): + """Number of packets sent, split by direction.""" + + downstream: Optional[int] = None + + upstream: Optional[int] = None + + +class TunnelStats(BaseModel): + """WARP tunnel packet and byte counters.""" + + bytes_lost: Optional[TunnelStatsBytesLost] = FieldInfo(alias="bytesLost", default=None) + """Number of bytes lost, split by direction.""" + + bytes_received: Optional[TunnelStatsBytesReceived] = FieldInfo(alias="bytesReceived", default=None) + """Number of bytes received, split by direction.""" + + bytes_retransmitted: Optional[TunnelStatsBytesRetransmitted] = FieldInfo(alias="bytesRetransmitted", default=None) + """Number of bytes retransmitted, split by direction.""" + + bytes_sent: Optional[TunnelStatsBytesSent] = FieldInfo(alias="bytesSent", default=None) + """Number of bytes sent, split by direction.""" + + packets_lost: Optional[TunnelStatsPacketsLost] = FieldInfo(alias="packetsLost", default=None) + """Number of packets lost, split by direction.""" + + packets_received: Optional[TunnelStatsPacketsReceived] = FieldInfo(alias="packetsReceived", default=None) + """Number of packets received, split by direction.""" + + packets_retransmitted: Optional[TunnelStatsPacketsRetransmitted] = FieldInfo( + alias="packetsRetransmitted", default=None + ) + """Number of packets retransmitted, split by direction.""" + + packets_sent: Optional[TunnelStatsPacketsSent] = FieldInfo(alias="packetsSent", default=None) + """Number of packets sent, split by direction.""" + + stats_window_ms: Optional[int] = FieldInfo(alias="statsWindowMs", default=None) + """The measurement window duration in milliseconds.""" class FleetStatusGetResponse(BaseModel): colo: str - """Cloudflare colo""" + """Cloudflare colo airport code.""" device_id: str = FieldInfo(alias="deviceId") """Device identifier (UUID v4)""" mode: str - """The mode under which the WARP client is run""" + """The mode under which the WARP client is run.""" platform: str - """Operating system""" + """Operating system.""" status: str - """Network status""" + """Network status.""" timestamp: str - """Timestamp in ISO format""" version: str - """WARP client version""" + """WARP client version.""" always_on: Optional[bool] = FieldInfo(alias="alwaysOn", default=None) @@ -215,17 +383,17 @@ class FleetStatusGetResponse(BaseModel): cpu_pct: Optional[float] = FieldInfo(alias="cpuPct", default=None) - cpu_pct_by_app: Optional[List[List[CPUPctByApp]]] = FieldInfo(alias="cpuPctByApp", default=None) + cpu_pct_by_app: Optional[List[CPUPctByApp]] = FieldInfo(alias="cpuPctByApp", default=None) device_ipv4: Optional[DeviceIPV4] = FieldInfo(alias="deviceIpv4", default=None) device_ipv6: Optional[DeviceIPV6] = FieldInfo(alias="deviceIpv6", default=None) device_name: Optional[str] = FieldInfo(alias="deviceName", default=None) - """Device identifier (human readable)""" + """Device identifier (human readable).""" device_registration: Optional[str] = FieldInfo(alias="deviceRegistration", default=None) - """Deprecated: use registrationId. Device registration identifier (UUID v4).""" + """Deprecated: use registrationId. Device registration identifier (UUID).""" disk_read_bps: Optional[int] = FieldInfo(alias="diskReadBps", default=None) @@ -264,7 +432,7 @@ class FleetStatusGetResponse(BaseModel): ram_used_pct: Optional[float] = FieldInfo(alias="ramUsedPct", default=None) - ram_used_pct_by_app: Optional[List[List[RamUsedPctByApp]]] = FieldInfo(alias="ramUsedPctByApp", default=None) + ram_used_pct_by_app: Optional[List[RamUsedPctByApp]] = FieldInfo(alias="ramUsedPctByApp", default=None) registration_id: Optional[str] = FieldInfo(alias="registrationId", default=None) """Device registration identifier (UUID v4). @@ -273,6 +441,14 @@ class FleetStatusGetResponse(BaseModel): device. """ + rtt: Optional[RTT] = None + """Round-trip time statistics for the WARP tunnel.""" + switch_locked: Optional[bool] = FieldInfo(alias="switchLocked", default=None) + tunnel_stats: Optional[TunnelStats] = FieldInfo(alias="tunnelStats", default=None) + """WARP tunnel packet and byte counters.""" + + tunnel_type: Optional[str] = FieldInfo(alias="tunnelType", default=None) + wifi_strength_dbm: Optional[int] = FieldInfo(alias="wifiStrengthDbm", default=None) diff --git a/src/cloudflare/types/zero_trust/dex/colo_list_params.py b/src/cloudflare/types/zero_trust/dex/colo_list_params.py index c208fcae20f..965670e91b0 100644 --- a/src/cloudflare/types/zero_trust/dex/colo_list_params.py +++ b/src/cloudflare/types/zero_trust/dex/colo_list_params.py @@ -11,12 +11,13 @@ class ColoListParams(TypedDict, total=False): account_id: Required[str] + """Unique identifier linked to an account.""" from_: Required[Annotated[str, PropertyInfo(alias="from")]] - """Start time for connection period in ISO (RFC3339 - ISO 8601) format""" + """Start time for connection period in ISO (RFC3339 - ISO 8601) format.""" to: Required[str] - """End time for connection period in ISO (RFC3339 - ISO 8601) format""" + """End time for connection period in ISO (RFC3339 - ISO 8601) format.""" sort_by: Annotated[Literal["fleet-status-usage", "application-tests-usage"], PropertyInfo(alias="sortBy")] """Type of usage that colos should be sorted by. diff --git a/src/cloudflare/types/zero_trust/dex/command_create_params.py b/src/cloudflare/types/zero_trust/dex/command_create_params.py index a9e81017ece..654a87e5857 100644 --- a/src/cloudflare/types/zero_trust/dex/command_create_params.py +++ b/src/cloudflare/types/zero_trust/dex/command_create_params.py @@ -19,6 +19,7 @@ class CommandCreateParams(TypedDict, total=False): account_id: Required[str] + """Unique identifier linked to an account.""" commands: Required[Iterable[Command]] """List of device-level commands to execute""" diff --git a/src/cloudflare/types/zero_trust/dex/command_list_params.py b/src/cloudflare/types/zero_trust/dex/command_list_params.py index e9bf59a863c..8474defe143 100644 --- a/src/cloudflare/types/zero_trust/dex/command_list_params.py +++ b/src/cloudflare/types/zero_trust/dex/command_list_params.py @@ -13,27 +13,28 @@ class CommandListParams(TypedDict, total=False): account_id: Required[str] + """Unique identifier linked to an account.""" page: Required[float] - """Page number for pagination""" + """Page number of paginated results.""" per_page: Required[float] - """Number of results per page""" + """Number of results per page.""" command_type: Literal["pcap", "speed-test", "warp-diag"] - """Optionally filter executed commands by command type""" + """Optionally filter executed commands by command type.""" device_id: str - """Unique identifier for a device""" + """Unique identifier for a device.""" from_: Annotated[Union[str, datetime], PropertyInfo(alias="from", format="iso8601")] - """Start time for the query in ISO (RFC3339 - ISO 8601) format""" + """Start time for the query in ISO (RFC3339 - ISO 8601) format.""" status: Literal["PENDING_EXEC", "PENDING_UPLOAD", "SUCCESS", "FAILED"] - """Optionally filter executed commands by status""" + """Optionally filter executed commands by status.""" to: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] - """End time for the query in ISO (RFC3339 - ISO 8601) format""" + """End time for the query in ISO (RFC3339 - ISO 8601) format.""" user_email: str - """Email tied to the device""" + """Email tied to the device.""" diff --git a/src/cloudflare/types/zero_trust/dex/commands/device_list_params.py b/src/cloudflare/types/zero_trust/dex/commands/device_list_params.py index 126d1a8cb20..a9c27eeb48d 100644 --- a/src/cloudflare/types/zero_trust/dex/commands/device_list_params.py +++ b/src/cloudflare/types/zero_trust/dex/commands/device_list_params.py @@ -9,12 +9,13 @@ class DeviceListParams(TypedDict, total=False): account_id: Required[str] + """Unique identifier linked to an account.""" page: Required[float] - """Page number of paginated results""" + """Page number of paginated results.""" per_page: Required[float] - """Number of items per page""" + """Number of results per page.""" search: str - """Filter devices by name or email""" + """Filter devices by name or email.""" diff --git a/src/cloudflare/types/zero_trust/dex/commands/device_list_response.py b/src/cloudflare/types/zero_trust/dex/commands/device_list_response.py index 26000944013..a118f6e2657 100644 --- a/src/cloudflare/types/zero_trust/dex/commands/device_list_response.py +++ b/src/cloudflare/types/zero_trust/dex/commands/device_list_response.py @@ -26,7 +26,7 @@ class Device(BaseModel): """User contact email address""" platform: Optional[str] = None - """Operating system""" + """Operating system.""" registration_id: Optional[str] = FieldInfo(alias="registrationId", default=None) """Device registration identifier (UUID v4). @@ -36,13 +36,12 @@ class Device(BaseModel): """ status: Optional[str] = None - """Network status""" + """Network status.""" timestamp: Optional[str] = None - """Timestamp in ISO format""" version: Optional[str] = None - """WARP client version""" + """WARP client version.""" class DeviceListResponse(BaseModel): diff --git a/src/cloudflare/types/zero_trust/dex/commands/quota_get_response.py b/src/cloudflare/types/zero_trust/dex/commands/quota_get_response.py index df1cc7d0596..1d4faf4ad38 100644 --- a/src/cloudflare/types/zero_trust/dex/commands/quota_get_response.py +++ b/src/cloudflare/types/zero_trust/dex/commands/quota_get_response.py @@ -9,10 +9,10 @@ class QuotaGetResponse(BaseModel): quota: float - """The remaining number of commands that can be initiated for an account""" + """The total number of commands that can be initiated for an account.""" quota_usage: float - """The number of commands that have been initiated for an account""" + """The number of commands that have been initiated for an account.""" reset_time: datetime - """The time when the quota resets""" + """The time when the quota resets.""" diff --git a/src/cloudflare/types/zero_trust/dex/devices/isp_list_params.py b/src/cloudflare/types/zero_trust/dex/devices/isp_list_params.py index 127afcc2b87..5eaf77e2808 100644 --- a/src/cloudflare/types/zero_trust/dex/devices/isp_list_params.py +++ b/src/cloudflare/types/zero_trust/dex/devices/isp_list_params.py @@ -13,6 +13,7 @@ class ISPListParams(TypedDict, total=False): account_id: Required[str] + """Unique identifier linked to an account.""" per_page: Required[int] """Number of items per page""" @@ -21,16 +22,16 @@ class ISPListParams(TypedDict, total=False): """Cursor for cursor-based pagination. Mutually exclusive with page.""" from_: Annotated[Union[str, datetime], PropertyInfo(alias="from", format="iso8601")] - """Start time for the query in ISO 8601 format""" + """Start time for the query in ISO 8601 format.""" page: int """Page number of paginated results. Mutually exclusive with cursor.""" sort_by: Literal["time_start"] - """The field to sort results by""" + """The field to sort results by.""" sort_order: Literal["ASC", "DESC"] - """The order to sort results""" + """The order to sort results.""" to: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] - """End time for the query in ISO 8601 format""" + """End time for the query in ISO 8601 format.""" diff --git a/src/cloudflare/types/zero_trust/dex/devices/isps.py b/src/cloudflare/types/zero_trust/dex/devices/isps.py index 86840403985..13a6fefa893 100644 --- a/src/cloudflare/types/zero_trust/dex/devices/isps.py +++ b/src/cloudflare/types/zero_trust/dex/devices/isps.py @@ -37,10 +37,10 @@ class ISPIP(BaseModel): """IP address. Returned as `"REDACTED"` without PII permission.""" asn: Optional[int] = None - """Autonomous System Number""" + """Autonomous System Number.""" aso: Optional[str] = None - """Autonomous System Organization name""" + """Autonomous System Organization name.""" location: Optional[ISPIPLocation] = None """Geographic location information. @@ -59,18 +59,18 @@ class ISPIP(BaseModel): """Network mask. Returned as `"REDACTED"` without PII permission.""" version: Optional[int] = None - """IP version (`1` for IPv4, `2` for IPv6, `0` if unknown)""" + """IP version (`1` for IPv4, `2` for IPv6, `0` if unknown).""" class ISP(BaseModel): test_id: str - """The test that generated this result""" + """The test that generated this result.""" test_result_id: str - """The specific test result""" + """The specific test result.""" time_start: datetime - """Timestamp of when the ISP was observed""" + """Timestamp of when the ISP was observed.""" ip: Optional[ISPIP] = None """IP address information for the ISP hop. diff --git a/src/cloudflare/types/zero_trust/dex/fleet_status/device_list_params.py b/src/cloudflare/types/zero_trust/dex/fleet_status/device_list_params.py index 2e4d8182f1b..21a58da80d0 100644 --- a/src/cloudflare/types/zero_trust/dex/fleet_status/device_list_params.py +++ b/src/cloudflare/types/zero_trust/dex/fleet_status/device_list_params.py @@ -11,33 +11,42 @@ class DeviceListParams(TypedDict, total=False): account_id: Required[str] + """Unique identifier linked to an account.""" from_: Required[Annotated[str, PropertyInfo(alias="from")]] - """Time range beginning in ISO format""" + """Start of the time range to query. + + Timestamp can be provided in ISO 8601 datetime format or milliseconds since + epoch. + """ page: Required[float] - """Page number""" + """Page number of paginated results.""" per_page: Required[float] - """Number of results per page""" + """Number of results per page.""" to: Required[str] - """Time range end in ISO format""" + """End of the time range to query. + + Timestamp can be provided in ISO 8601 datetime format or milliseconds since + epoch. + """ colo: str - """Cloudflare colo""" + """Cloudflare colo airport code.""" device_id: str - """Device-specific ID, given as UUID v4""" + """Device-specific ID, given as UUID.""" mode: str - """The mode under which the WARP client is run""" + """The mode under which the WARP client is run.""" platform: str - """Operating system""" + """Operating system.""" sort_by: Literal["colo", "device_id", "mode", "platform", "status", "timestamp", "version"] - """Dimension to sort results by""" + """Dimension to sort results by.""" source: Literal["last_seen", "hourly", "raw"] """Source: @@ -50,7 +59,7 @@ class DeviceListParams(TypedDict, total=False): """ status: str - """Network status""" + """Network status.""" version: str - """WARP client version""" + """WARP client version.""" diff --git a/src/cloudflare/types/zero_trust/dex/fleet_status/device_list_response.py b/src/cloudflare/types/zero_trust/dex/fleet_status/device_list_response.py index c2b6197b3fc..fffa39b83eb 100644 --- a/src/cloudflare/types/zero_trust/dex/fleet_status/device_list_response.py +++ b/src/cloudflare/types/zero_trust/dex/fleet_status/device_list_response.py @@ -22,13 +22,28 @@ "ISPIPV6", "ISPIPV6Location", "RamUsedPctByApp", + "RTT", + "RTTMinRTTUs", + "RTTRTTUs", + "RTTRTTVarUs", + "TunnelStats", + "TunnelStatsBytesLost", + "TunnelStatsBytesReceived", + "TunnelStatsBytesRetransmitted", + "TunnelStatsBytesSent", + "TunnelStatsPacketsLost", + "TunnelStatsPacketsReceived", + "TunnelStatsPacketsRetransmitted", + "TunnelStatsPacketsSent", ] class CPUPctByApp(BaseModel): cpu_pct: Optional[float] = None + """CPU usage percentage, on a scale of 0 to 100.""" name: Optional[str] = None + """Application name.""" class DeviceIPV4Location(BaseModel): @@ -50,9 +65,12 @@ class DeviceIPV4(BaseModel): location: Optional[DeviceIPV4Location] = None + name: Optional[str] = None + netmask: Optional[str] = None - version: Optional[str] = None + version: Optional[int] = None + """IP version (`1` for IPv4, `2` for IPv6, `0` if unknown).""" class DeviceIPV6Location(BaseModel): @@ -74,9 +92,12 @@ class DeviceIPV6(BaseModel): location: Optional[DeviceIPV6Location] = None + name: Optional[str] = None + netmask: Optional[str] = None - version: Optional[str] = None + version: Optional[int] = None + """IP version (`1` for IPv4, `2` for IPv6, `0` if unknown).""" class GatewayIPV4Location(BaseModel): @@ -98,9 +119,12 @@ class GatewayIPV4(BaseModel): location: Optional[GatewayIPV4Location] = None + name: Optional[str] = None + netmask: Optional[str] = None - version: Optional[str] = None + version: Optional[int] = None + """IP version (`1` for IPv4, `2` for IPv6, `0` if unknown).""" class GatewayIPV6Location(BaseModel): @@ -122,9 +146,12 @@ class GatewayIPV6(BaseModel): location: Optional[GatewayIPV6Location] = None + name: Optional[str] = None + netmask: Optional[str] = None - version: Optional[str] = None + version: Optional[int] = None + """IP version (`1` for IPv4, `2` for IPv6, `0` if unknown).""" class ISPIPV4Location(BaseModel): @@ -146,9 +173,12 @@ class ISPIPV4(BaseModel): location: Optional[ISPIPV4Location] = None + name: Optional[str] = None + netmask: Optional[str] = None - version: Optional[str] = None + version: Optional[int] = None + """IP version (`1` for IPv4, `2` for IPv6, `0` if unknown).""" class ISPIPV6Location(BaseModel): @@ -170,38 +200,176 @@ class ISPIPV6(BaseModel): location: Optional[ISPIPV6Location] = None + name: Optional[str] = None + netmask: Optional[str] = None - version: Optional[str] = None + version: Optional[int] = None + """IP version (`1` for IPv4, `2` for IPv6, `0` if unknown).""" class RamUsedPctByApp(BaseModel): name: Optional[str] = None + """Application name.""" ram_used_pct: Optional[float] = None + """RAM usage percentage, on a scale of 0 to 100.""" + + +class RTTMinRTTUs(BaseModel): + """Minimum round-trip time in microseconds.""" + + downstream: Optional[int] = None + + upstream: Optional[int] = None + + +class RTTRTTUs(BaseModel): + """Round-trip time in microseconds.""" + + downstream: Optional[int] = None + + upstream: Optional[int] = None + + +class RTTRTTVarUs(BaseModel): + """Round-trip time variance in microseconds.""" + + downstream: Optional[int] = None + + upstream: Optional[int] = None + + +class RTT(BaseModel): + """Round-trip time statistics for the WARP tunnel.""" + + min_rtt_us: Optional[RTTMinRTTUs] = FieldInfo(alias="minRttUs", default=None) + """Minimum round-trip time in microseconds.""" + + rtt_us: Optional[RTTRTTUs] = FieldInfo(alias="rttUs", default=None) + """Round-trip time in microseconds.""" + + rtt_var_us: Optional[RTTRTTVarUs] = FieldInfo(alias="rttVarUs", default=None) + """Round-trip time variance in microseconds.""" + + +class TunnelStatsBytesLost(BaseModel): + """Number of bytes lost, split by direction.""" + + downstream: Optional[int] = None + + upstream: Optional[int] = None + + +class TunnelStatsBytesReceived(BaseModel): + """Number of bytes received, split by direction.""" + + downstream: Optional[int] = None + + upstream: Optional[int] = None + + +class TunnelStatsBytesRetransmitted(BaseModel): + """Number of bytes retransmitted, split by direction.""" + + downstream: Optional[int] = None + + upstream: Optional[int] = None + + +class TunnelStatsBytesSent(BaseModel): + """Number of bytes sent, split by direction.""" + + downstream: Optional[int] = None + + upstream: Optional[int] = None + + +class TunnelStatsPacketsLost(BaseModel): + """Number of packets lost, split by direction.""" + + downstream: Optional[int] = None + + upstream: Optional[int] = None + + +class TunnelStatsPacketsReceived(BaseModel): + """Number of packets received, split by direction.""" + + downstream: Optional[int] = None + + upstream: Optional[int] = None + + +class TunnelStatsPacketsRetransmitted(BaseModel): + """Number of packets retransmitted, split by direction.""" + + downstream: Optional[int] = None + + upstream: Optional[int] = None + + +class TunnelStatsPacketsSent(BaseModel): + """Number of packets sent, split by direction.""" + + downstream: Optional[int] = None + + upstream: Optional[int] = None + + +class TunnelStats(BaseModel): + """WARP tunnel packet and byte counters.""" + + bytes_lost: Optional[TunnelStatsBytesLost] = FieldInfo(alias="bytesLost", default=None) + """Number of bytes lost, split by direction.""" + + bytes_received: Optional[TunnelStatsBytesReceived] = FieldInfo(alias="bytesReceived", default=None) + """Number of bytes received, split by direction.""" + + bytes_retransmitted: Optional[TunnelStatsBytesRetransmitted] = FieldInfo(alias="bytesRetransmitted", default=None) + """Number of bytes retransmitted, split by direction.""" + + bytes_sent: Optional[TunnelStatsBytesSent] = FieldInfo(alias="bytesSent", default=None) + """Number of bytes sent, split by direction.""" + + packets_lost: Optional[TunnelStatsPacketsLost] = FieldInfo(alias="packetsLost", default=None) + """Number of packets lost, split by direction.""" + + packets_received: Optional[TunnelStatsPacketsReceived] = FieldInfo(alias="packetsReceived", default=None) + """Number of packets received, split by direction.""" + + packets_retransmitted: Optional[TunnelStatsPacketsRetransmitted] = FieldInfo( + alias="packetsRetransmitted", default=None + ) + """Number of packets retransmitted, split by direction.""" + + packets_sent: Optional[TunnelStatsPacketsSent] = FieldInfo(alias="packetsSent", default=None) + """Number of packets sent, split by direction.""" + + stats_window_ms: Optional[int] = FieldInfo(alias="statsWindowMs", default=None) + """The measurement window duration in milliseconds.""" class DeviceListResponse(BaseModel): colo: str - """Cloudflare colo""" + """Cloudflare colo airport code.""" device_id: str = FieldInfo(alias="deviceId") """Device identifier (UUID v4)""" mode: str - """The mode under which the WARP client is run""" + """The mode under which the WARP client is run.""" platform: str - """Operating system""" + """Operating system.""" status: str - """Network status""" + """Network status.""" timestamp: str - """Timestamp in ISO format""" version: str - """WARP client version""" + """WARP client version.""" always_on: Optional[bool] = FieldInfo(alias="alwaysOn", default=None) @@ -215,17 +383,17 @@ class DeviceListResponse(BaseModel): cpu_pct: Optional[float] = FieldInfo(alias="cpuPct", default=None) - cpu_pct_by_app: Optional[List[List[CPUPctByApp]]] = FieldInfo(alias="cpuPctByApp", default=None) + cpu_pct_by_app: Optional[List[CPUPctByApp]] = FieldInfo(alias="cpuPctByApp", default=None) device_ipv4: Optional[DeviceIPV4] = FieldInfo(alias="deviceIpv4", default=None) device_ipv6: Optional[DeviceIPV6] = FieldInfo(alias="deviceIpv6", default=None) device_name: Optional[str] = FieldInfo(alias="deviceName", default=None) - """Device identifier (human readable)""" + """Device identifier (human readable).""" device_registration: Optional[str] = FieldInfo(alias="deviceRegistration", default=None) - """Deprecated: use registrationId. Device registration identifier (UUID v4).""" + """Deprecated: use registrationId. Device registration identifier (UUID).""" disk_read_bps: Optional[int] = FieldInfo(alias="diskReadBps", default=None) @@ -264,7 +432,7 @@ class DeviceListResponse(BaseModel): ram_used_pct: Optional[float] = FieldInfo(alias="ramUsedPct", default=None) - ram_used_pct_by_app: Optional[List[List[RamUsedPctByApp]]] = FieldInfo(alias="ramUsedPctByApp", default=None) + ram_used_pct_by_app: Optional[List[RamUsedPctByApp]] = FieldInfo(alias="ramUsedPctByApp", default=None) registration_id: Optional[str] = FieldInfo(alias="registrationId", default=None) """Device registration identifier (UUID v4). @@ -273,6 +441,14 @@ class DeviceListResponse(BaseModel): device. """ + rtt: Optional[RTT] = None + """Round-trip time statistics for the WARP tunnel.""" + switch_locked: Optional[bool] = FieldInfo(alias="switchLocked", default=None) + tunnel_stats: Optional[TunnelStats] = FieldInfo(alias="tunnelStats", default=None) + """WARP tunnel packet and byte counters.""" + + tunnel_type: Optional[str] = FieldInfo(alias="tunnelType", default=None) + wifi_strength_dbm: Optional[int] = FieldInfo(alias="wifiStrengthDbm", default=None) diff --git a/src/cloudflare/types/zero_trust/dex/fleet_status_live_params.py b/src/cloudflare/types/zero_trust/dex/fleet_status_live_params.py index 3f30049cf2d..c3e4f744357 100644 --- a/src/cloudflare/types/zero_trust/dex/fleet_status_live_params.py +++ b/src/cloudflare/types/zero_trust/dex/fleet_status_live_params.py @@ -9,6 +9,7 @@ class FleetStatusLiveParams(TypedDict, total=False): account_id: Required[str] + """Unique identifier linked to an account.""" since_minutes: Required[float] - """Number of minutes before current time""" + """Number of minutes before current time.""" diff --git a/src/cloudflare/types/zero_trust/dex/fleet_status_over_time_params.py b/src/cloudflare/types/zero_trust/dex/fleet_status_over_time_params.py index 662cf4e307c..3369f4065e9 100644 --- a/src/cloudflare/types/zero_trust/dex/fleet_status_over_time_params.py +++ b/src/cloudflare/types/zero_trust/dex/fleet_status_over_time_params.py @@ -11,15 +11,24 @@ class FleetStatusOverTimeParams(TypedDict, total=False): account_id: Required[str] + """Unique identifier linked to an account.""" from_: Required[Annotated[str, PropertyInfo(alias="from")]] - """Time range beginning in ISO format""" + """Start of the time range to query. + + Timestamp can be provided in ISO 8601 datetime format or milliseconds since + epoch. + """ to: Required[str] - """Time range end in ISO format""" + """End of the time range to query. + + Timestamp can be provided in ISO 8601 datetime format or milliseconds since + epoch. + """ colo: str - """Cloudflare colo""" + """Cloudflare colo airport code.""" device_id: str - """Device-specific ID, given as UUID v4""" + """Device-specific ID, given as UUID.""" diff --git a/src/cloudflare/types/zero_trust/dex/fleet_status_over_time_response.py b/src/cloudflare/types/zero_trust/dex/fleet_status_over_time_response.py index c7508a81750..cc6ade24a5b 100644 --- a/src/cloudflare/types/zero_trust/dex/fleet_status_over_time_response.py +++ b/src/cloudflare/types/zero_trust/dex/fleet_status_over_time_response.py @@ -11,7 +11,6 @@ class DeviceStatsByMode(BaseModel): timestamp: Optional[str] = None - """Timestamp in ISO format""" unique_devices_total: Optional[float] = FieldInfo(alias="uniqueDevicesTotal", default=None) """Number of unique devices""" @@ -21,7 +20,6 @@ class DeviceStatsByMode(BaseModel): class DeviceStatsByStatus(BaseModel): timestamp: Optional[str] = None - """Timestamp in ISO format""" unique_devices_total: Optional[float] = FieldInfo(alias="uniqueDevicesTotal", default=None) """Number of unique devices""" diff --git a/src/cloudflare/types/zero_trust/dex/http_details.py b/src/cloudflare/types/zero_trust/dex/http_details.py index ab4c28b811b..60315f1089d 100644 --- a/src/cloudflare/types/zero_trust/dex/http_details.py +++ b/src/cloudflare/types/zero_trust/dex/http_details.py @@ -32,13 +32,13 @@ class HTTPStatsAvailabilityPct(BaseModel): slots: List[HTTPStatsAvailabilityPctSlot] avg: Optional[float] = None - """average observed in the time period""" + """average observed in the time period.""" max: Optional[float] = None - """highest observed in the time period""" + """highest observed in the time period.""" min: Optional[float] = None - """lowest observed in the time period""" + """lowest observed in the time period.""" class HTTPStatsHTTPStatusCode(BaseModel): @@ -65,7 +65,7 @@ class HTTPStats(BaseModel): server_response_time_ms: TestStatOverTime = FieldInfo(alias="serverResponseTimeMs") unique_devices_total: int = FieldInfo(alias="uniqueDevicesTotal") - """Count of unique devices that have run this test in the given time period""" + """Count of unique devices that have run this test in the given time period.""" class HTTPStatsByColoAvailabilityPctSlot(BaseModel): @@ -78,13 +78,13 @@ class HTTPStatsByColoAvailabilityPct(BaseModel): slots: List[HTTPStatsByColoAvailabilityPctSlot] avg: Optional[float] = None - """average observed in the time period""" + """average observed in the time period.""" max: Optional[float] = None - """highest observed in the time period""" + """highest observed in the time period.""" min: Optional[float] = None - """lowest observed in the time period""" + """lowest observed in the time period.""" class HTTPStatsByColoHTTPStatusCode(BaseModel): @@ -113,12 +113,12 @@ class HTTPStatsByColo(BaseModel): server_response_time_ms: TestStatOverTime = FieldInfo(alias="serverResponseTimeMs") unique_devices_total: int = FieldInfo(alias="uniqueDevicesTotal") - """Count of unique devices that have run this test in the given time period""" + """Count of unique devices that have run this test in the given time period.""" class HTTPDetails(BaseModel): host: Optional[str] = None - """The url of the HTTP synthetic application test""" + """The url of the HTTP synthetic application test.""" http_stats: Optional[HTTPStats] = FieldInfo(alias="httpStats", default=None) @@ -130,10 +130,10 @@ class HTTPDetails(BaseModel): kind: Optional[Literal["http"]] = None method: Optional[str] = None - """The HTTP method to use when running the test""" + """The HTTP method to use when running the test.""" name: Optional[str] = None - """The name of the HTTP synthetic application test""" + """The name of the HTTP synthetic application test.""" target_policies: Optional[List[DigitalExperienceMonitor]] = None diff --git a/src/cloudflare/types/zero_trust/dex/http_test_get_params.py b/src/cloudflare/types/zero_trust/dex/http_test_get_params.py index 0ebbb588734..c4485b0a6f6 100644 --- a/src/cloudflare/types/zero_trust/dex/http_test_get_params.py +++ b/src/cloudflare/types/zero_trust/dex/http_test_get_params.py @@ -12,15 +12,16 @@ class HTTPTestGetParams(TypedDict, total=False): account_id: Required[str] + """Unique identifier linked to an account.""" from_: Required[Annotated[str, PropertyInfo(alias="from")]] - """Start time for aggregate metrics in ISO ms""" + """Start time for aggregate metrics in ISO ms.""" interval: Required[Literal["minute", "hour"]] """Time interval for aggregate time slots.""" to: Required[str] - """End time for aggregate metrics in ISO ms""" + """End time for aggregate metrics in ISO ms.""" colo: str """Optionally filter result stats to a Cloudflare colo. diff --git a/src/cloudflare/types/zero_trust/dex/http_tests/percentile_get_params.py b/src/cloudflare/types/zero_trust/dex/http_tests/percentile_get_params.py index 393e611ad5e..f9befd27242 100644 --- a/src/cloudflare/types/zero_trust/dex/http_tests/percentile_get_params.py +++ b/src/cloudflare/types/zero_trust/dex/http_tests/percentile_get_params.py @@ -12,12 +12,13 @@ class PercentileGetParams(TypedDict, total=False): account_id: Required[str] + """Unique identifier linked to an account.""" from_: Required[Annotated[str, PropertyInfo(alias="from")]] - """Start time for the query in ISO (RFC3339 - ISO 8601) format""" + """Start time for the query in ISO (RFC3339 - ISO 8601) format.""" to: Required[str] - """End time for the query in ISO (RFC3339 - ISO 8601) format""" + """End time for the query in ISO (RFC3339 - ISO 8601) format.""" colo: str """Optionally filter result stats to a Cloudflare colo. diff --git a/src/cloudflare/types/zero_trust/dex/http_tests/test_stat_over_time.py b/src/cloudflare/types/zero_trust/dex/http_tests/test_stat_over_time.py index 6fd470656f2..8b4768190a0 100644 --- a/src/cloudflare/types/zero_trust/dex/http_tests/test_stat_over_time.py +++ b/src/cloudflare/types/zero_trust/dex/http_tests/test_stat_over_time.py @@ -18,10 +18,10 @@ class TestStatOverTime(BaseModel): slots: List[Slot] avg: Optional[int] = None - """average observed in the time period""" + """average observed in the time period.""" max: Optional[int] = None - """highest observed in the time period""" + """highest observed in the time period.""" min: Optional[int] = None - """lowest observed in the time period""" + """lowest observed in the time period.""" diff --git a/src/cloudflare/types/zero_trust/dex/rule_create_params.py b/src/cloudflare/types/zero_trust/dex/rule_create_params.py index db10c6a7be7..44b0a037a25 100644 --- a/src/cloudflare/types/zero_trust/dex/rule_create_params.py +++ b/src/cloudflare/types/zero_trust/dex/rule_create_params.py @@ -9,6 +9,7 @@ class RuleCreateParams(TypedDict, total=False): account_id: Required[str] + """Unique identifier linked to an account.""" match: Required[str] """The wirefilter expression to match.""" diff --git a/src/cloudflare/types/zero_trust/dex/rule_list_params.py b/src/cloudflare/types/zero_trust/dex/rule_list_params.py index f7a59482cd0..ea562b5b730 100644 --- a/src/cloudflare/types/zero_trust/dex/rule_list_params.py +++ b/src/cloudflare/types/zero_trust/dex/rule_list_params.py @@ -9,18 +9,19 @@ class RuleListParams(TypedDict, total=False): account_id: Required[str] + """Unique identifier linked to an account.""" page: Required[float] - """Page number of paginated results""" + """Page number of paginated results.""" per_page: Required[float] - """Number of items per page""" + """Number of results per page.""" name: str - """Filter results by rule name""" + """Filter results by rule name.""" sort_by: Literal["name", "created_at", "updated_at"] - """Which property to sort results by""" + """Which property to sort results by.""" sort_order: Literal["ASC", "DESC"] - """Sort direction for sort_by property""" + """Sort direction for sort_by property.""" diff --git a/src/cloudflare/types/zero_trust/dex/rule_update_params.py b/src/cloudflare/types/zero_trust/dex/rule_update_params.py index 4bafbd979b1..e629a897747 100644 --- a/src/cloudflare/types/zero_trust/dex/rule_update_params.py +++ b/src/cloudflare/types/zero_trust/dex/rule_update_params.py @@ -9,6 +9,7 @@ class RuleUpdateParams(TypedDict, total=False): account_id: Required[str] + """Unique identifier linked to an account.""" description: str diff --git a/src/cloudflare/types/zero_trust/dex/test_list_params.py b/src/cloudflare/types/zero_trust/dex/test_list_params.py index eeadc12677d..4b3e250dfa3 100644 --- a/src/cloudflare/types/zero_trust/dex/test_list_params.py +++ b/src/cloudflare/types/zero_trust/dex/test_list_params.py @@ -12,6 +12,7 @@ class TestListParams(TypedDict, total=False): account_id: Required[str] + """Unique identifier linked to an account.""" colo: str """Optionally filter result stats to a Cloudflare colo. @@ -26,7 +27,7 @@ class TestListParams(TypedDict, total=False): """ kind: Literal["http", "traceroute"] - """Filter by test type""" + """Filter by test type.""" page: float """Page number of paginated results""" @@ -41,4 +42,4 @@ class TestListParams(TypedDict, total=False): """ test_name: Annotated[str, PropertyInfo(alias="testName")] - """Optionally filter results by test name""" + """Optionally filter results by test name.""" diff --git a/src/cloudflare/types/zero_trust/dex/tests/tests.py b/src/cloudflare/types/zero_trust/dex/tests/tests.py index 6e2a9b09e49..a46f07a8968 100644 --- a/src/cloudflare/types/zero_trust/dex/tests/tests.py +++ b/src/cloudflare/types/zero_trust/dex/tests/tests.py @@ -41,10 +41,10 @@ class OverviewMetrics(BaseModel): """number of tests.""" avg_http_availability_pct: Optional[float] = FieldInfo(alias="avgHttpAvailabilityPct", default=None) - """percentage availability for all HTTP test results in response""" + """percentage availability for all HTTP test results in response.""" avg_traceroute_availability_pct: Optional[float] = FieldInfo(alias="avgTracerouteAvailabilityPct", default=None) - """percentage availability for all traceroutes results in response""" + """percentage availability for all traceroutes results in response.""" class TestHTTPResultsResourceFetchTimeHistory(BaseModel): diff --git a/src/cloudflare/types/zero_trust/dex/tests/unique_device_list_params.py b/src/cloudflare/types/zero_trust/dex/tests/unique_device_list_params.py index 6aae8692406..42c122437c5 100644 --- a/src/cloudflare/types/zero_trust/dex/tests/unique_device_list_params.py +++ b/src/cloudflare/types/zero_trust/dex/tests/unique_device_list_params.py @@ -12,6 +12,7 @@ class UniqueDeviceListParams(TypedDict, total=False): account_id: Required[str] + """Unique identifier linked to an account.""" device_id: Annotated[SequenceNotStr[str], PropertyInfo(alias="deviceId")] """Optionally filter result stats to a specific device(s). @@ -20,4 +21,4 @@ class UniqueDeviceListParams(TypedDict, total=False): """ test_name: Annotated[str, PropertyInfo(alias="testName")] - """Optionally filter results by test name""" + """Optionally filter results by test name.""" diff --git a/src/cloudflare/types/zero_trust/dex/traceroute.py b/src/cloudflare/types/zero_trust/dex/traceroute.py index 536fd47bc6f..188a0a1362b 100644 --- a/src/cloudflare/types/zero_trust/dex/traceroute.py +++ b/src/cloudflare/types/zero_trust/dex/traceroute.py @@ -34,13 +34,13 @@ class TracerouteStatsAvailabilityPct(BaseModel): slots: List[TracerouteStatsAvailabilityPctSlot] avg: Optional[float] = None - """average observed in the time period""" + """average observed in the time period.""" max: Optional[float] = None - """highest observed in the time period""" + """highest observed in the time period.""" min: Optional[float] = None - """lowest observed in the time period""" + """lowest observed in the time period.""" class TracerouteStatsPacketLossPctSlot(BaseModel): @@ -53,13 +53,13 @@ class TracerouteStatsPacketLossPct(BaseModel): slots: List[TracerouteStatsPacketLossPctSlot] avg: Optional[float] = None - """average observed in the time period""" + """average observed in the time period.""" max: Optional[float] = None - """highest observed in the time period""" + """highest observed in the time period.""" min: Optional[float] = None - """lowest observed in the time period""" + """lowest observed in the time period.""" class TracerouteStats(BaseModel): @@ -72,7 +72,7 @@ class TracerouteStats(BaseModel): round_trip_time_ms: TestStatOverTime = FieldInfo(alias="roundTripTimeMs") unique_devices_total: int = FieldInfo(alias="uniqueDevicesTotal") - """Count of unique devices that have run this test in the given time period""" + """Count of unique devices that have run this test in the given time period.""" class TracerouteStatsByColoAvailabilityPctSlot(BaseModel): @@ -85,13 +85,13 @@ class TracerouteStatsByColoAvailabilityPct(BaseModel): slots: List[TracerouteStatsByColoAvailabilityPctSlot] avg: Optional[float] = None - """average observed in the time period""" + """average observed in the time period.""" max: Optional[float] = None - """highest observed in the time period""" + """highest observed in the time period.""" min: Optional[float] = None - """lowest observed in the time period""" + """lowest observed in the time period.""" class TracerouteStatsByColoPacketLossPctSlot(BaseModel): @@ -104,13 +104,13 @@ class TracerouteStatsByColoPacketLossPct(BaseModel): slots: List[TracerouteStatsByColoPacketLossPctSlot] avg: Optional[float] = None - """average observed in the time period""" + """average observed in the time period.""" max: Optional[float] = None - """highest observed in the time period""" + """highest observed in the time period.""" min: Optional[float] = None - """lowest observed in the time period""" + """lowest observed in the time period.""" class TracerouteStatsByColo(BaseModel): @@ -125,12 +125,12 @@ class TracerouteStatsByColo(BaseModel): round_trip_time_ms: TestStatOverTime = FieldInfo(alias="roundTripTimeMs") unique_devices_total: int = FieldInfo(alias="uniqueDevicesTotal") - """Count of unique devices that have run this test in the given time period""" + """Count of unique devices that have run this test in the given time period.""" class Traceroute(BaseModel): host: str - """The host of the Traceroute synthetic application test""" + """The host of the Traceroute synthetic application test.""" interval: str """The interval at which the Traceroute synthetic application test is set to run.""" @@ -138,7 +138,7 @@ class Traceroute(BaseModel): kind: Literal["traceroute"] name: str - """The name of the Traceroute synthetic application test""" + """The name of the Traceroute synthetic application test.""" target_policies: Optional[List[DigitalExperienceMonitor]] = None diff --git a/src/cloudflare/types/zero_trust/dex/traceroute_test_get_params.py b/src/cloudflare/types/zero_trust/dex/traceroute_test_get_params.py index 912f057de27..65073130877 100644 --- a/src/cloudflare/types/zero_trust/dex/traceroute_test_get_params.py +++ b/src/cloudflare/types/zero_trust/dex/traceroute_test_get_params.py @@ -12,15 +12,16 @@ class TracerouteTestGetParams(TypedDict, total=False): account_id: Required[str] + """Unique identifier linked to an account.""" from_: Required[Annotated[str, PropertyInfo(alias="from")]] - """Start time for aggregate metrics in ISO ms""" + """Start time for aggregate metrics in ISO ms.""" interval: Required[Literal["minute", "hour"]] """Time interval for aggregate time slots.""" to: Required[str] - """End time for aggregate metrics in ISO ms""" + """End time for aggregate metrics in ISO ms.""" colo: str """Optionally filter result stats to a Cloudflare colo. diff --git a/src/cloudflare/types/zero_trust/dex/traceroute_test_network_path_params.py b/src/cloudflare/types/zero_trust/dex/traceroute_test_network_path_params.py index b6ffc3f49e0..a86780d4e4b 100644 --- a/src/cloudflare/types/zero_trust/dex/traceroute_test_network_path_params.py +++ b/src/cloudflare/types/zero_trust/dex/traceroute_test_network_path_params.py @@ -11,15 +11,16 @@ class TracerouteTestNetworkPathParams(TypedDict, total=False): account_id: Required[str] + """Unique identifier linked to an account.""" device_id: Required[Annotated[str, PropertyInfo(alias="deviceId")]] - """Device to filter tracroute result runs to""" + """Device to filter traceroute result runs to.""" from_: Required[Annotated[str, PropertyInfo(alias="from")]] - """Start time for aggregate metrics in ISO ms""" + """Start time for aggregate metrics in ISO ms.""" interval: Required[Literal["minute", "hour"]] """Time interval for aggregate time slots.""" to: Required[str] - """End time for aggregate metrics in ISO ms""" + """End time for aggregate metrics in ISO ms.""" diff --git a/src/cloudflare/types/zero_trust/dex/traceroute_test_percentiles_params.py b/src/cloudflare/types/zero_trust/dex/traceroute_test_percentiles_params.py index 7c6a8511b34..ba6f9b3816b 100644 --- a/src/cloudflare/types/zero_trust/dex/traceroute_test_percentiles_params.py +++ b/src/cloudflare/types/zero_trust/dex/traceroute_test_percentiles_params.py @@ -12,12 +12,13 @@ class TracerouteTestPercentilesParams(TypedDict, total=False): account_id: Required[str] + """Unique identifier linked to an account.""" from_: Required[Annotated[str, PropertyInfo(alias="from")]] - """Start time for the query in ISO (RFC3339 - ISO 8601) format""" + """Start time for the query in ISO (RFC3339 - ISO 8601) format.""" to: Required[str] - """End time for the query in ISO (RFC3339 - ISO 8601) format""" + """End time for the query in ISO (RFC3339 - ISO 8601) format.""" colo: str """Optionally filter result stats to a Cloudflare colo. diff --git a/src/cloudflare/types/zero_trust/dex/traceroute_test_results/network_path_get_response.py b/src/cloudflare/types/zero_trust/dex/traceroute_test_results/network_path_get_response.py index 8b14533ea18..edc85670f61 100644 --- a/src/cloudflare/types/zero_trust/dex/traceroute_test_results/network_path_get_response.py +++ b/src/cloudflare/types/zero_trust/dex/traceroute_test_results/network_path_get_response.py @@ -40,16 +40,27 @@ class Hop(BaseModel): class NetworkPathGetResponse(BaseModel): hops: List[Hop] - """an array of the hops taken by the device to reach the end destination""" + """An array of the hops taken by the device to reach the end destination.""" result_id: str = FieldInfo(alias="resultId") """API Resource UUID tag.""" + colo: Optional[str] = None + """Cloudflare colo airport code.""" + device_name: Optional[str] = FieldInfo(alias="deviceName", default=None) - """name of the device associated with this network path response""" + """Name of the device associated with this network path response.""" + + execution_context: Optional[Literal["EXECUTION_CONTEXT_INVALID", "OUT_OF_TUNNEL", "IN_TUNNEL"]] = None + """Whether the test was run inside or outside of the WARP tunnel.""" test_id: Optional[str] = FieldInfo(alias="testId", default=None) """API Resource UUID tag.""" test_name: Optional[str] = FieldInfo(alias="testName", default=None) - """name of the tracroute test""" + """Name of the traceroute test.""" + + time_start: Optional[str] = None + """Timestamp indicating when the traceroute test execution began.""" + + tunnel_type: Optional[str] = None diff --git a/src/cloudflare/types/zero_trust/dex/warp_change_event_get_params.py b/src/cloudflare/types/zero_trust/dex/warp_change_event_get_params.py index 33c691637a0..b815ee4c036 100644 --- a/src/cloudflare/types/zero_trust/dex/warp_change_event_get_params.py +++ b/src/cloudflare/types/zero_trust/dex/warp_change_event_get_params.py @@ -11,18 +11,19 @@ class WARPChangeEventGetParams(TypedDict, total=False): account_id: Required[str] + """Unique identifier linked to an account.""" from_: Required[Annotated[str, PropertyInfo(alias="from")]] - """Start time for the query in ISO (RFC3339 - ISO 8601) format""" + """Start time for the query in ISO (RFC3339 - ISO 8601) format.""" page: Required[float] - """Page number of paginated results""" + """Page number of paginated results.""" per_page: Required[float] - """Number of items per page""" + """Number of results per page.""" to: Required[str] - """End time for the query in ISO (RFC3339 - ISO 8601) format""" + """End time for the query in ISO (RFC3339 - ISO 8601) format.""" account_name: str """Filter events by account name.""" @@ -40,4 +41,4 @@ class WARPChangeEventGetParams(TypedDict, total=False): """Filter events by type toggle value. Applicable to type='toggle' events only.""" type: Literal["config", "toggle"] - """Filter events by type 'config' or 'toggle'""" + """Filter events by type 'config' or 'toggle'.""" diff --git a/src/cloudflare/types/zero_trust/dex/warp_change_event_get_response.py b/src/cloudflare/types/zero_trust/dex/warp_change_event_get_response.py index 17e914600d5..c7f0d7acc0a 100644 --- a/src/cloudflare/types/zero_trust/dex/warp_change_event_get_response.py +++ b/src/cloudflare/types/zero_trust/dex/warp_change_event_get_response.py @@ -1,6 +1,7 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import List, Union, Optional +from datetime import datetime from typing_extensions import Literal, TypeAlias from pydantic import Field as FieldInfo @@ -25,47 +26,51 @@ class WARPChangeEventGetResponseItemDigitalExperienceMonitoringWARPToggleChangeE """The public account identifier.""" device_id: Optional[str] = None - """API Resource UUID tag.""" + """The device ID.""" device_registration: Optional[str] = None - """API Resource UUID tag.""" + """Deprecated: use registration_id. The device registration ID.""" hostname: Optional[str] = None - """The hostname of the machine the event is from""" + """The hostname of the machine the event is from.""" registration_id: Optional[str] = None - """API Resource UUID tag.""" + """The device registration ID.""" serial_number: Optional[str] = None - """The serial number of the machine the event is from""" + """The serial number of the machine the event is from.""" - timestamp: Optional[str] = None - """Timestamp in ISO format""" + timestamp: Optional[datetime] = None + """The event time.""" toggle: Optional[Literal["on", "off"]] = None """The state of the WARP toggle.""" user_email: Optional[str] = None - """Email tied to the device""" + """Email tied to the device.""" class WARPChangeEventGetResponseItemDigitalExperienceMonitoringWARPConfigChangeEventFrom(BaseModel): + """The details for the WARP configuration that was switched from.""" + account_name: Optional[str] = None """The account name.""" account_tag: Optional[str] = None - """API Resource UUID tag.""" + """The public account identifier.""" config_name: Optional[str] = None """The name of the WARP configuration.""" class WARPChangeEventGetResponseItemDigitalExperienceMonitoringWARPConfigChangeEventTo(BaseModel): + """The details for the WARP configuration that was switched to.""" + account_name: Optional[str] = None """The account name.""" account_tag: Optional[str] = None - """API Resource UUID tag.""" + """The public account identifier.""" config_name: Optional[str] = None """The name of the WARP configuration.""" @@ -73,31 +78,33 @@ class WARPChangeEventGetResponseItemDigitalExperienceMonitoringWARPConfigChangeE class WARPChangeEventGetResponseItemDigitalExperienceMonitoringWARPConfigChangeEvent(BaseModel): device_id: Optional[str] = None - """API Resource UUID tag.""" + """The device ID.""" device_registration: Optional[str] = None - """API Resource UUID tag.""" + """Deprecated: use registration_id. The device registration ID.""" from_: Optional[WARPChangeEventGetResponseItemDigitalExperienceMonitoringWARPConfigChangeEventFrom] = FieldInfo( alias="from", default=None ) + """The details for the WARP configuration that was switched from.""" hostname: Optional[str] = None - """The hostname of the machine the event is from""" + """The hostname of the machine the event is from.""" registration_id: Optional[str] = None - """API Resource UUID tag.""" + """The device registration ID.""" serial_number: Optional[str] = None - """The serial number of the machine the event is from""" + """The serial number of the machine the event is from.""" - timestamp: Optional[str] = None - """Timestamp in ISO format""" + timestamp: Optional[datetime] = None + """The event time.""" to: Optional[WARPChangeEventGetResponseItemDigitalExperienceMonitoringWARPConfigChangeEventTo] = None + """The details for the WARP configuration that was switched to.""" user_email: Optional[str] = None - """Email tied to the device""" + """Email tied to the device.""" WARPChangeEventGetResponseItem: TypeAlias = Union[ diff --git a/src/cloudflare/types/zero_trust/digital_experience_monitor.py b/src/cloudflare/types/zero_trust/digital_experience_monitor.py index 4f9105218ce..845c6eb8b6e 100644 --- a/src/cloudflare/types/zero_trust/digital_experience_monitor.py +++ b/src/cloudflare/types/zero_trust/digital_experience_monitor.py @@ -10,6 +10,6 @@ class DigitalExperienceMonitor(BaseModel): """API Resource UUID tag.""" default: bool - """Whether the policy is the default for the account""" + """Whether the policy is the default for the account.""" name: str diff --git a/src/cloudflare/types/zero_trust/network_path_response.py b/src/cloudflare/types/zero_trust/network_path_response.py index c0c4f672893..1c4aec6d59e 100644 --- a/src/cloudflare/types/zero_trust/network_path_response.py +++ b/src/cloudflare/types/zero_trust/network_path_response.py @@ -16,6 +16,7 @@ class NetworkPathResponse(BaseModel): """API Resource UUID tag.""" device_name: Optional[str] = FieldInfo(alias="deviceName", default=None) + """Name of the device that ran the test.""" interval: Optional[str] = None """The interval at which the Traceroute synthetic application test is set to run.""" @@ -27,4 +28,4 @@ class NetworkPathResponse(BaseModel): network_path: Optional[NetworkPath] = FieldInfo(alias="networkPath", default=None) url: Optional[str] = None - """The host of the Traceroute synthetic application test""" + """The host of the Traceroute synthetic application test.""" diff --git a/src/cloudflare/types/zero_trust/percentiles.py b/src/cloudflare/types/zero_trust/percentiles.py index fe27397ea19..df83106f81b 100644 --- a/src/cloudflare/types/zero_trust/percentiles.py +++ b/src/cloudflare/types/zero_trust/percentiles.py @@ -9,13 +9,13 @@ class Percentiles(BaseModel): p50: Optional[float] = None - """p50 observed in the time period""" + """p50 observed in the time period.""" p90: Optional[float] = None - """p90 observed in the time period""" + """p90 observed in the time period.""" p95: Optional[float] = None - """p95 observed in the time period""" + """p95 observed in the time period.""" p99: Optional[float] = None - """p99 observed in the time period""" + """p99 observed in the time period.""" diff --git a/tests/api_resources/test_custom_hostnames.py b/tests/api_resources/test_custom_hostnames.py index 1c5fc1a0c66..68f29d564a1 100644 --- a/tests/api_resources/test_custom_hostnames.py +++ b/tests/api_resources/test_custom_hostnames.py @@ -114,7 +114,11 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: certificate_authority="google", custom_origin_server="origin2.example.com", direction="desc", - hostname={"contain": "example.com"}, + hostname={ + "contain": "example.com", + "exact": "app.example.com", + "starts_with": "app", + }, hostname_status="provisioned", order="ssl", page=1, @@ -433,7 +437,11 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) certificate_authority="google", custom_origin_server="origin2.example.com", direction="desc", - hostname={"contain": "example.com"}, + hostname={ + "contain": "example.com", + "exact": "app.example.com", + "starts_with": "app", + }, hostname_status="provisioned", order="ssl", page=1, diff --git a/tests/api_resources/zero_trust/devices/test_dex_tests.py b/tests/api_resources/zero_trust/devices/test_dex_tests.py index e6b7bad3063..f75e72da56f 100644 --- a/tests/api_resources/zero_trust/devices/test_dex_tests.py +++ b/tests/api_resources/zero_trust/devices/test_dex_tests.py @@ -235,7 +235,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: account_id="01a7362d577a6c3019a474fd6f485823", kind="http", page=1, - per_page=1, + per_page=10, test_name="testName", ) assert_matches_type(SyncV4PagePaginationArray[DEXTestListResponse], dex_test, path=["response"]) @@ -584,7 +584,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) account_id="01a7362d577a6c3019a474fd6f485823", kind="http", page=1, - per_page=1, + per_page=10, test_name="testName", ) assert_matches_type(AsyncV4PagePaginationArray[DEXTestListResponse], dex_test, path=["response"]) diff --git a/tests/api_resources/zero_trust/dex/commands/test_devices.py b/tests/api_resources/zero_trust/dex/commands/test_devices.py index d364b9938d9..726fe0233a8 100644 --- a/tests/api_resources/zero_trust/dex/commands/test_devices.py +++ b/tests/api_resources/zero_trust/dex/commands/test_devices.py @@ -23,7 +23,7 @@ def test_method_list(self, client: Cloudflare) -> None: device = client.zero_trust.dex.commands.devices.list( account_id="01a7362d577a6c3019a474fd6f485823", page=1, - per_page=1, + per_page=10, ) assert_matches_type(SyncV4PagePagination[Optional[DeviceListResponse]], device, path=["response"]) @@ -32,7 +32,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: device = client.zero_trust.dex.commands.devices.list( account_id="01a7362d577a6c3019a474fd6f485823", page=1, - per_page=1, + per_page=10, search="search", ) assert_matches_type(SyncV4PagePagination[Optional[DeviceListResponse]], device, path=["response"]) @@ -42,7 +42,7 @@ def test_raw_response_list(self, client: Cloudflare) -> None: response = client.zero_trust.dex.commands.devices.with_raw_response.list( account_id="01a7362d577a6c3019a474fd6f485823", page=1, - per_page=1, + per_page=10, ) assert response.is_closed is True @@ -55,7 +55,7 @@ def test_streaming_response_list(self, client: Cloudflare) -> None: with client.zero_trust.dex.commands.devices.with_streaming_response.list( account_id="01a7362d577a6c3019a474fd6f485823", page=1, - per_page=1, + per_page=10, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -71,7 +71,7 @@ def test_path_params_list(self, client: Cloudflare) -> None: client.zero_trust.dex.commands.devices.with_raw_response.list( account_id="", page=1, - per_page=1, + per_page=10, ) @@ -85,7 +85,7 @@ async def test_method_list(self, async_client: AsyncCloudflare) -> None: device = await async_client.zero_trust.dex.commands.devices.list( account_id="01a7362d577a6c3019a474fd6f485823", page=1, - per_page=1, + per_page=10, ) assert_matches_type(AsyncV4PagePagination[Optional[DeviceListResponse]], device, path=["response"]) @@ -94,7 +94,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) device = await async_client.zero_trust.dex.commands.devices.list( account_id="01a7362d577a6c3019a474fd6f485823", page=1, - per_page=1, + per_page=10, search="search", ) assert_matches_type(AsyncV4PagePagination[Optional[DeviceListResponse]], device, path=["response"]) @@ -104,7 +104,7 @@ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.dex.commands.devices.with_raw_response.list( account_id="01a7362d577a6c3019a474fd6f485823", page=1, - per_page=1, + per_page=10, ) assert response.is_closed is True @@ -117,7 +117,7 @@ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> N async with async_client.zero_trust.dex.commands.devices.with_streaming_response.list( account_id="01a7362d577a6c3019a474fd6f485823", page=1, - per_page=1, + per_page=10, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -133,5 +133,5 @@ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: await async_client.zero_trust.dex.commands.devices.with_raw_response.list( account_id="", page=1, - per_page=1, + per_page=10, ) diff --git a/tests/api_resources/zero_trust/dex/devices/test_isps.py b/tests/api_resources/zero_trust/dex/devices/test_isps.py index 85455da30ec..dc569975da8 100644 --- a/tests/api_resources/zero_trust/dex/devices/test_isps.py +++ b/tests/api_resources/zero_trust/dex/devices/test_isps.py @@ -24,7 +24,7 @@ def test_method_list(self, client: Cloudflare) -> None: isp = client.zero_trust.dex.devices.isps.list( device_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="01a7362d577a6c3019a474fd6f485823", - per_page=1, + per_page=10, ) assert_matches_type(SyncV4PagePagination[Optional[ISPs]], isp, path=["response"]) @@ -33,7 +33,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: isp = client.zero_trust.dex.devices.isps.list( device_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="01a7362d577a6c3019a474fd6f485823", - per_page=1, + per_page=10, cursor="cursor", from_=parse_datetime("2019-12-27T18:11:19.117Z"), page=1, @@ -48,7 +48,7 @@ def test_raw_response_list(self, client: Cloudflare) -> None: response = client.zero_trust.dex.devices.isps.with_raw_response.list( device_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="01a7362d577a6c3019a474fd6f485823", - per_page=1, + per_page=10, ) assert response.is_closed is True @@ -61,7 +61,7 @@ def test_streaming_response_list(self, client: Cloudflare) -> None: with client.zero_trust.dex.devices.isps.with_streaming_response.list( device_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="01a7362d577a6c3019a474fd6f485823", - per_page=1, + per_page=10, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -77,14 +77,14 @@ def test_path_params_list(self, client: Cloudflare) -> None: client.zero_trust.dex.devices.isps.with_raw_response.list( device_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", - per_page=1, + per_page=10, ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `device_id` but received ''"): client.zero_trust.dex.devices.isps.with_raw_response.list( device_id="", account_id="01a7362d577a6c3019a474fd6f485823", - per_page=1, + per_page=10, ) @@ -98,7 +98,7 @@ async def test_method_list(self, async_client: AsyncCloudflare) -> None: isp = await async_client.zero_trust.dex.devices.isps.list( device_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="01a7362d577a6c3019a474fd6f485823", - per_page=1, + per_page=10, ) assert_matches_type(AsyncV4PagePagination[Optional[ISPs]], isp, path=["response"]) @@ -107,7 +107,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) isp = await async_client.zero_trust.dex.devices.isps.list( device_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="01a7362d577a6c3019a474fd6f485823", - per_page=1, + per_page=10, cursor="cursor", from_=parse_datetime("2019-12-27T18:11:19.117Z"), page=1, @@ -122,7 +122,7 @@ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.dex.devices.isps.with_raw_response.list( device_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="01a7362d577a6c3019a474fd6f485823", - per_page=1, + per_page=10, ) assert response.is_closed is True @@ -135,7 +135,7 @@ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> N async with async_client.zero_trust.dex.devices.isps.with_streaming_response.list( device_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="01a7362d577a6c3019a474fd6f485823", - per_page=1, + per_page=10, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -151,12 +151,12 @@ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: await async_client.zero_trust.dex.devices.isps.with_raw_response.list( device_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415", account_id="", - per_page=1, + per_page=10, ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `device_id` but received ''"): await async_client.zero_trust.dex.devices.isps.with_raw_response.list( device_id="", account_id="01a7362d577a6c3019a474fd6f485823", - per_page=1, + per_page=10, ) diff --git a/tests/api_resources/zero_trust/dex/fleet_status/test_devices.py b/tests/api_resources/zero_trust/dex/fleet_status/test_devices.py index c77565e0f06..6f73ef11cbd 100644 --- a/tests/api_resources/zero_trust/dex/fleet_status/test_devices.py +++ b/tests/api_resources/zero_trust/dex/fleet_status/test_devices.py @@ -23,10 +23,10 @@ class TestDevices: def test_method_list(self, client: Cloudflare) -> None: device = client.zero_trust.dex.fleet_status.devices.list( account_id="01a7362d577a6c3019a474fd6f485823", - from_="2023-10-11T00:00:00Z", + from_="2023-10-11 00:00:00+00", page=1, per_page=10, - to="2023-10-11T00:00:00Z", + to="2023-10-11 00:00:00+00", ) assert_matches_type(SyncV4PagePaginationArray[DeviceListResponse], device, path=["response"]) @@ -35,10 +35,10 @@ def test_method_list(self, client: Cloudflare) -> None: def test_method_list_with_all_params(self, client: Cloudflare) -> None: device = client.zero_trust.dex.fleet_status.devices.list( account_id="01a7362d577a6c3019a474fd6f485823", - from_="2023-10-11T00:00:00Z", + from_="2023-10-11 00:00:00+00", page=1, per_page=10, - to="2023-10-11T00:00:00Z", + to="2023-10-11 00:00:00+00", colo="SJC", device_id="cb49c27f-7f97-49c5-b6f3-f7c01ead0fd7", mode="proxy", @@ -55,10 +55,10 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: def test_raw_response_list(self, client: Cloudflare) -> None: response = client.zero_trust.dex.fleet_status.devices.with_raw_response.list( account_id="01a7362d577a6c3019a474fd6f485823", - from_="2023-10-11T00:00:00Z", + from_="2023-10-11 00:00:00+00", page=1, per_page=10, - to="2023-10-11T00:00:00Z", + to="2023-10-11 00:00:00+00", ) assert response.is_closed is True @@ -71,10 +71,10 @@ def test_raw_response_list(self, client: Cloudflare) -> None: def test_streaming_response_list(self, client: Cloudflare) -> None: with client.zero_trust.dex.fleet_status.devices.with_streaming_response.list( account_id="01a7362d577a6c3019a474fd6f485823", - from_="2023-10-11T00:00:00Z", + from_="2023-10-11 00:00:00+00", page=1, per_page=10, - to="2023-10-11T00:00:00Z", + to="2023-10-11 00:00:00+00", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -90,10 +90,10 @@ def test_path_params_list(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.zero_trust.dex.fleet_status.devices.with_raw_response.list( account_id="", - from_="2023-10-11T00:00:00Z", + from_="2023-10-11 00:00:00+00", page=1, per_page=10, - to="2023-10-11T00:00:00Z", + to="2023-10-11 00:00:00+00", ) @@ -107,10 +107,10 @@ class TestAsyncDevices: async def test_method_list(self, async_client: AsyncCloudflare) -> None: device = await async_client.zero_trust.dex.fleet_status.devices.list( account_id="01a7362d577a6c3019a474fd6f485823", - from_="2023-10-11T00:00:00Z", + from_="2023-10-11 00:00:00+00", page=1, per_page=10, - to="2023-10-11T00:00:00Z", + to="2023-10-11 00:00:00+00", ) assert_matches_type(AsyncV4PagePaginationArray[DeviceListResponse], device, path=["response"]) @@ -119,10 +119,10 @@ async def test_method_list(self, async_client: AsyncCloudflare) -> None: async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: device = await async_client.zero_trust.dex.fleet_status.devices.list( account_id="01a7362d577a6c3019a474fd6f485823", - from_="2023-10-11T00:00:00Z", + from_="2023-10-11 00:00:00+00", page=1, per_page=10, - to="2023-10-11T00:00:00Z", + to="2023-10-11 00:00:00+00", colo="SJC", device_id="cb49c27f-7f97-49c5-b6f3-f7c01ead0fd7", mode="proxy", @@ -139,10 +139,10 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.dex.fleet_status.devices.with_raw_response.list( account_id="01a7362d577a6c3019a474fd6f485823", - from_="2023-10-11T00:00:00Z", + from_="2023-10-11 00:00:00+00", page=1, per_page=10, - to="2023-10-11T00:00:00Z", + to="2023-10-11 00:00:00+00", ) assert response.is_closed is True @@ -155,10 +155,10 @@ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.dex.fleet_status.devices.with_streaming_response.list( account_id="01a7362d577a6c3019a474fd6f485823", - from_="2023-10-11T00:00:00Z", + from_="2023-10-11 00:00:00+00", page=1, per_page=10, - to="2023-10-11T00:00:00Z", + to="2023-10-11 00:00:00+00", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -174,8 +174,8 @@ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.zero_trust.dex.fleet_status.devices.with_raw_response.list( account_id="", - from_="2023-10-11T00:00:00Z", + from_="2023-10-11 00:00:00+00", page=1, per_page=10, - to="2023-10-11T00:00:00Z", + to="2023-10-11 00:00:00+00", ) diff --git a/tests/api_resources/zero_trust/dex/http_tests/test_percentiles.py b/tests/api_resources/zero_trust/dex/http_tests/test_percentiles.py index 6a6125e8a30..e796a927e59 100644 --- a/tests/api_resources/zero_trust/dex/http_tests/test_percentiles.py +++ b/tests/api_resources/zero_trust/dex/http_tests/test_percentiles.py @@ -34,8 +34,8 @@ def test_method_get_with_all_params(self, client: Cloudflare) -> None: account_id="01a7362d577a6c3019a474fd6f485823", from_="2023-09-20T17:00:00Z", to="2023-09-20T17:00:00Z", - colo="colo", - device_id=["string"], + colo="SJC", + device_id=["cb49c27f-7f97-49c5-b6f3-f7c01ead0fd7"], ) assert_matches_type(Optional[HTTPDetailsPercentiles], percentile, path=["response"]) @@ -110,8 +110,8 @@ async def test_method_get_with_all_params(self, async_client: AsyncCloudflare) - account_id="01a7362d577a6c3019a474fd6f485823", from_="2023-09-20T17:00:00Z", to="2023-09-20T17:00:00Z", - colo="colo", - device_id=["string"], + colo="SJC", + device_id=["cb49c27f-7f97-49c5-b6f3-f7c01ead0fd7"], ) assert_matches_type(Optional[HTTPDetailsPercentiles], percentile, path=["response"]) diff --git a/tests/api_resources/zero_trust/dex/test_commands.py b/tests/api_resources/zero_trust/dex/test_commands.py index 51cbf912d94..c399cdcfe85 100644 --- a/tests/api_resources/zero_trust/dex/test_commands.py +++ b/tests/api_resources/zero_trust/dex/test_commands.py @@ -93,7 +93,7 @@ def test_method_list(self, client: Cloudflare) -> None: command = client.zero_trust.dex.commands.list( account_id="01a7362d577a6c3019a474fd6f485823", page=1, - per_page=50, + per_page=10, ) assert_matches_type(SyncV4PagePagination[Optional[CommandListResponse]], command, path=["response"]) @@ -102,7 +102,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: command = client.zero_trust.dex.commands.list( account_id="01a7362d577a6c3019a474fd6f485823", page=1, - per_page=50, + per_page=10, command_type="pcap", device_id="device_id", from_=parse_datetime("2023-08-20T20:45:00Z"), @@ -117,7 +117,7 @@ def test_raw_response_list(self, client: Cloudflare) -> None: response = client.zero_trust.dex.commands.with_raw_response.list( account_id="01a7362d577a6c3019a474fd6f485823", page=1, - per_page=50, + per_page=10, ) assert response.is_closed is True @@ -130,7 +130,7 @@ def test_streaming_response_list(self, client: Cloudflare) -> None: with client.zero_trust.dex.commands.with_streaming_response.list( account_id="01a7362d577a6c3019a474fd6f485823", page=1, - per_page=50, + per_page=10, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -146,7 +146,7 @@ def test_path_params_list(self, client: Cloudflare) -> None: client.zero_trust.dex.commands.with_raw_response.list( account_id="", page=1, - per_page=50, + per_page=10, ) @@ -226,7 +226,7 @@ async def test_method_list(self, async_client: AsyncCloudflare) -> None: command = await async_client.zero_trust.dex.commands.list( account_id="01a7362d577a6c3019a474fd6f485823", page=1, - per_page=50, + per_page=10, ) assert_matches_type(AsyncV4PagePagination[Optional[CommandListResponse]], command, path=["response"]) @@ -235,7 +235,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) command = await async_client.zero_trust.dex.commands.list( account_id="01a7362d577a6c3019a474fd6f485823", page=1, - per_page=50, + per_page=10, command_type="pcap", device_id="device_id", from_=parse_datetime("2023-08-20T20:45:00Z"), @@ -250,7 +250,7 @@ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.dex.commands.with_raw_response.list( account_id="01a7362d577a6c3019a474fd6f485823", page=1, - per_page=50, + per_page=10, ) assert response.is_closed is True @@ -263,7 +263,7 @@ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> N async with async_client.zero_trust.dex.commands.with_streaming_response.list( account_id="01a7362d577a6c3019a474fd6f485823", page=1, - per_page=50, + per_page=10, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -279,5 +279,5 @@ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: await async_client.zero_trust.dex.commands.with_raw_response.list( account_id="", page=1, - per_page=50, + per_page=10, ) diff --git a/tests/api_resources/zero_trust/dex/test_fleet_status.py b/tests/api_resources/zero_trust/dex/test_fleet_status.py index 490d37cd105..c5ee7c6d0ff 100644 --- a/tests/api_resources/zero_trust/dex/test_fleet_status.py +++ b/tests/api_resources/zero_trust/dex/test_fleet_status.py @@ -66,8 +66,8 @@ def test_path_params_live(self, client: Cloudflare) -> None: def test_method_over_time(self, client: Cloudflare) -> None: fleet_status = client.zero_trust.dex.fleet_status.over_time( account_id="01a7362d577a6c3019a474fd6f485823", - from_="2023-10-11T00:00:00Z", - to="2023-10-11T00:00:00Z", + from_="2023-10-11 00:00:00+00", + to="2023-10-11 00:00:00+00", ) assert_matches_type(Optional[FleetStatusOverTimeResponse], fleet_status, path=["response"]) @@ -75,8 +75,8 @@ def test_method_over_time(self, client: Cloudflare) -> None: def test_method_over_time_with_all_params(self, client: Cloudflare) -> None: fleet_status = client.zero_trust.dex.fleet_status.over_time( account_id="01a7362d577a6c3019a474fd6f485823", - from_="2023-10-11T00:00:00Z", - to="2023-10-11T00:00:00Z", + from_="2023-10-11 00:00:00+00", + to="2023-10-11 00:00:00+00", colo="SJC", device_id="cb49c27f-7f97-49c5-b6f3-f7c01ead0fd7", ) @@ -86,8 +86,8 @@ def test_method_over_time_with_all_params(self, client: Cloudflare) -> None: def test_raw_response_over_time(self, client: Cloudflare) -> None: response = client.zero_trust.dex.fleet_status.with_raw_response.over_time( account_id="01a7362d577a6c3019a474fd6f485823", - from_="2023-10-11T00:00:00Z", - to="2023-10-11T00:00:00Z", + from_="2023-10-11 00:00:00+00", + to="2023-10-11 00:00:00+00", ) assert response.is_closed is True @@ -99,8 +99,8 @@ def test_raw_response_over_time(self, client: Cloudflare) -> None: def test_streaming_response_over_time(self, client: Cloudflare) -> None: with client.zero_trust.dex.fleet_status.with_streaming_response.over_time( account_id="01a7362d577a6c3019a474fd6f485823", - from_="2023-10-11T00:00:00Z", - to="2023-10-11T00:00:00Z", + from_="2023-10-11 00:00:00+00", + to="2023-10-11 00:00:00+00", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -115,8 +115,8 @@ def test_path_params_over_time(self, client: Cloudflare) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): client.zero_trust.dex.fleet_status.with_raw_response.over_time( account_id="", - from_="2023-10-11T00:00:00Z", - to="2023-10-11T00:00:00Z", + from_="2023-10-11 00:00:00+00", + to="2023-10-11 00:00:00+00", ) @@ -171,8 +171,8 @@ async def test_path_params_live(self, async_client: AsyncCloudflare) -> None: async def test_method_over_time(self, async_client: AsyncCloudflare) -> None: fleet_status = await async_client.zero_trust.dex.fleet_status.over_time( account_id="01a7362d577a6c3019a474fd6f485823", - from_="2023-10-11T00:00:00Z", - to="2023-10-11T00:00:00Z", + from_="2023-10-11 00:00:00+00", + to="2023-10-11 00:00:00+00", ) assert_matches_type(Optional[FleetStatusOverTimeResponse], fleet_status, path=["response"]) @@ -180,8 +180,8 @@ async def test_method_over_time(self, async_client: AsyncCloudflare) -> None: async def test_method_over_time_with_all_params(self, async_client: AsyncCloudflare) -> None: fleet_status = await async_client.zero_trust.dex.fleet_status.over_time( account_id="01a7362d577a6c3019a474fd6f485823", - from_="2023-10-11T00:00:00Z", - to="2023-10-11T00:00:00Z", + from_="2023-10-11 00:00:00+00", + to="2023-10-11 00:00:00+00", colo="SJC", device_id="cb49c27f-7f97-49c5-b6f3-f7c01ead0fd7", ) @@ -191,8 +191,8 @@ async def test_method_over_time_with_all_params(self, async_client: AsyncCloudfl async def test_raw_response_over_time(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.dex.fleet_status.with_raw_response.over_time( account_id="01a7362d577a6c3019a474fd6f485823", - from_="2023-10-11T00:00:00Z", - to="2023-10-11T00:00:00Z", + from_="2023-10-11 00:00:00+00", + to="2023-10-11 00:00:00+00", ) assert response.is_closed is True @@ -204,8 +204,8 @@ async def test_raw_response_over_time(self, async_client: AsyncCloudflare) -> No async def test_streaming_response_over_time(self, async_client: AsyncCloudflare) -> None: async with async_client.zero_trust.dex.fleet_status.with_streaming_response.over_time( account_id="01a7362d577a6c3019a474fd6f485823", - from_="2023-10-11T00:00:00Z", - to="2023-10-11T00:00:00Z", + from_="2023-10-11 00:00:00+00", + to="2023-10-11 00:00:00+00", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -220,6 +220,6 @@ async def test_path_params_over_time(self, async_client: AsyncCloudflare) -> Non with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): await async_client.zero_trust.dex.fleet_status.with_raw_response.over_time( account_id="", - from_="2023-10-11T00:00:00Z", - to="2023-10-11T00:00:00Z", + from_="2023-10-11 00:00:00+00", + to="2023-10-11 00:00:00+00", ) diff --git a/tests/api_resources/zero_trust/dex/test_http_tests.py b/tests/api_resources/zero_trust/dex/test_http_tests.py index 47ab64b6035..45da5261a93 100644 --- a/tests/api_resources/zero_trust/dex/test_http_tests.py +++ b/tests/api_resources/zero_trust/dex/test_http_tests.py @@ -36,8 +36,8 @@ def test_method_get_with_all_params(self, client: Cloudflare) -> None: from_="1689520412000", interval="minute", to="1689606812000", - colo="colo", - device_id=["string"], + colo="SJC", + device_id=["cb49c27f-7f97-49c5-b6f3-f7c01ead0fd7"], ) assert_matches_type(Optional[HTTPDetails], http_test, path=["response"]) @@ -118,8 +118,8 @@ async def test_method_get_with_all_params(self, async_client: AsyncCloudflare) - from_="1689520412000", interval="minute", to="1689606812000", - colo="colo", - device_id=["string"], + colo="SJC", + device_id=["cb49c27f-7f97-49c5-b6f3-f7c01ead0fd7"], ) assert_matches_type(Optional[HTTPDetails], http_test, path=["response"]) diff --git a/tests/api_resources/zero_trust/dex/test_rules.py b/tests/api_resources/zero_trust/dex/test_rules.py index c4f5cd1242d..eba9fca950c 100644 --- a/tests/api_resources/zero_trust/dex/test_rules.py +++ b/tests/api_resources/zero_trust/dex/test_rules.py @@ -144,7 +144,7 @@ def test_method_list(self, client: Cloudflare) -> None: rule = client.zero_trust.dex.rules.list( account_id="01a7362d577a6c3019a474fd6f485823", page=1, - per_page=1, + per_page=10, ) assert_matches_type(SyncV4PagePagination[Optional[RuleListResponse]], rule, path=["response"]) @@ -153,7 +153,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None: rule = client.zero_trust.dex.rules.list( account_id="01a7362d577a6c3019a474fd6f485823", page=1, - per_page=1, + per_page=10, name="name", sort_by="name", sort_order="ASC", @@ -165,7 +165,7 @@ def test_raw_response_list(self, client: Cloudflare) -> None: response = client.zero_trust.dex.rules.with_raw_response.list( account_id="01a7362d577a6c3019a474fd6f485823", page=1, - per_page=1, + per_page=10, ) assert response.is_closed is True @@ -178,7 +178,7 @@ def test_streaming_response_list(self, client: Cloudflare) -> None: with client.zero_trust.dex.rules.with_streaming_response.list( account_id="01a7362d577a6c3019a474fd6f485823", page=1, - per_page=1, + per_page=10, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -194,7 +194,7 @@ def test_path_params_list(self, client: Cloudflare) -> None: client.zero_trust.dex.rules.with_raw_response.list( account_id="", page=1, - per_page=1, + per_page=10, ) @parametrize @@ -419,7 +419,7 @@ async def test_method_list(self, async_client: AsyncCloudflare) -> None: rule = await async_client.zero_trust.dex.rules.list( account_id="01a7362d577a6c3019a474fd6f485823", page=1, - per_page=1, + per_page=10, ) assert_matches_type(AsyncV4PagePagination[Optional[RuleListResponse]], rule, path=["response"]) @@ -428,7 +428,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) rule = await async_client.zero_trust.dex.rules.list( account_id="01a7362d577a6c3019a474fd6f485823", page=1, - per_page=1, + per_page=10, name="name", sort_by="name", sort_order="ASC", @@ -440,7 +440,7 @@ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: response = await async_client.zero_trust.dex.rules.with_raw_response.list( account_id="01a7362d577a6c3019a474fd6f485823", page=1, - per_page=1, + per_page=10, ) assert response.is_closed is True @@ -453,7 +453,7 @@ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> N async with async_client.zero_trust.dex.rules.with_streaming_response.list( account_id="01a7362d577a6c3019a474fd6f485823", page=1, - per_page=1, + per_page=10, ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -469,7 +469,7 @@ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: await async_client.zero_trust.dex.rules.with_raw_response.list( account_id="", page=1, - per_page=1, + per_page=10, ) @parametrize diff --git a/tests/api_resources/zero_trust/dex/test_tests.py b/tests/api_resources/zero_trust/dex/test_tests.py index dbfa65d5631..1ae14b44078 100644 --- a/tests/api_resources/zero_trust/dex/test_tests.py +++ b/tests/api_resources/zero_trust/dex/test_tests.py @@ -29,12 +29,12 @@ def test_method_list(self, client: Cloudflare) -> None: def test_method_list_with_all_params(self, client: Cloudflare) -> None: test = client.zero_trust.dex.tests.list( account_id="01a7362d577a6c3019a474fd6f485823", - colo="colo", - device_id=["string"], + colo="SJC", + device_id=["cb49c27f-7f97-49c5-b6f3-f7c01ead0fd7"], kind="http", page=1, - per_page=1, - registration_id="registration_id", + per_page=10, + registration_id="a1b2c3d4-e5f6-7890-abcd-ef1234567890", test_name="testName", ) assert_matches_type(SyncV4PagePagination[Optional[Tests]], test, path=["response"]) @@ -87,12 +87,12 @@ async def test_method_list(self, async_client: AsyncCloudflare) -> None: async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: test = await async_client.zero_trust.dex.tests.list( account_id="01a7362d577a6c3019a474fd6f485823", - colo="colo", - device_id=["string"], + colo="SJC", + device_id=["cb49c27f-7f97-49c5-b6f3-f7c01ead0fd7"], kind="http", page=1, - per_page=1, - registration_id="registration_id", + per_page=10, + registration_id="a1b2c3d4-e5f6-7890-abcd-ef1234567890", test_name="testName", ) assert_matches_type(AsyncV4PagePagination[Optional[Tests]], test, path=["response"]) diff --git a/tests/api_resources/zero_trust/dex/test_warp_change_events.py b/tests/api_resources/zero_trust/dex/test_warp_change_events.py index fa9309617f8..0bc2cf95446 100644 --- a/tests/api_resources/zero_trust/dex/test_warp_change_events.py +++ b/tests/api_resources/zero_trust/dex/test_warp_change_events.py @@ -23,7 +23,7 @@ def test_method_get(self, client: Cloudflare) -> None: account_id="01a7362d577a6c3019a474fd6f485823", from_="2023-09-20T17:00:00Z", page=1, - per_page=1, + per_page=10, to="2023-09-20T17:00:00Z", ) assert_matches_type(Optional[WARPChangeEventGetResponse], warp_change_event, path=["response"]) @@ -34,7 +34,7 @@ def test_method_get_with_all_params(self, client: Cloudflare) -> None: account_id="01a7362d577a6c3019a474fd6f485823", from_="2023-09-20T17:00:00Z", page=1, - per_page=1, + per_page=10, to="2023-09-20T17:00:00Z", account_name="Myorg", config_name="MASQUE", @@ -50,7 +50,7 @@ def test_raw_response_get(self, client: Cloudflare) -> None: account_id="01a7362d577a6c3019a474fd6f485823", from_="2023-09-20T17:00:00Z", page=1, - per_page=1, + per_page=10, to="2023-09-20T17:00:00Z", ) @@ -65,7 +65,7 @@ def test_streaming_response_get(self, client: Cloudflare) -> None: account_id="01a7362d577a6c3019a474fd6f485823", from_="2023-09-20T17:00:00Z", page=1, - per_page=1, + per_page=10, to="2023-09-20T17:00:00Z", ) as response: assert not response.is_closed @@ -83,7 +83,7 @@ def test_path_params_get(self, client: Cloudflare) -> None: account_id="", from_="2023-09-20T17:00:00Z", page=1, - per_page=1, + per_page=10, to="2023-09-20T17:00:00Z", ) @@ -99,7 +99,7 @@ async def test_method_get(self, async_client: AsyncCloudflare) -> None: account_id="01a7362d577a6c3019a474fd6f485823", from_="2023-09-20T17:00:00Z", page=1, - per_page=1, + per_page=10, to="2023-09-20T17:00:00Z", ) assert_matches_type(Optional[WARPChangeEventGetResponse], warp_change_event, path=["response"]) @@ -110,7 +110,7 @@ async def test_method_get_with_all_params(self, async_client: AsyncCloudflare) - account_id="01a7362d577a6c3019a474fd6f485823", from_="2023-09-20T17:00:00Z", page=1, - per_page=1, + per_page=10, to="2023-09-20T17:00:00Z", account_name="Myorg", config_name="MASQUE", @@ -126,7 +126,7 @@ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: account_id="01a7362d577a6c3019a474fd6f485823", from_="2023-09-20T17:00:00Z", page=1, - per_page=1, + per_page=10, to="2023-09-20T17:00:00Z", ) @@ -141,7 +141,7 @@ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> No account_id="01a7362d577a6c3019a474fd6f485823", from_="2023-09-20T17:00:00Z", page=1, - per_page=1, + per_page=10, to="2023-09-20T17:00:00Z", ) as response: assert not response.is_closed @@ -159,6 +159,6 @@ async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: account_id="", from_="2023-09-20T17:00:00Z", page=1, - per_page=1, + per_page=10, to="2023-09-20T17:00:00Z", ) diff --git a/tests/api_resources/zero_trust/dex/tests/test_unique_devices.py b/tests/api_resources/zero_trust/dex/tests/test_unique_devices.py index 6a91c7b68c4..e9247f6842c 100644 --- a/tests/api_resources/zero_trust/dex/tests/test_unique_devices.py +++ b/tests/api_resources/zero_trust/dex/tests/test_unique_devices.py @@ -28,7 +28,7 @@ def test_method_list(self, client: Cloudflare) -> None: def test_method_list_with_all_params(self, client: Cloudflare) -> None: unique_device = client.zero_trust.dex.tests.unique_devices.list( account_id="01a7362d577a6c3019a474fd6f485823", - device_id=["string"], + device_id=["cb49c27f-7f97-49c5-b6f3-f7c01ead0fd7"], test_name="testName", ) assert_matches_type(Optional[UniqueDevices], unique_device, path=["response"]) @@ -81,7 +81,7 @@ async def test_method_list(self, async_client: AsyncCloudflare) -> None: async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: unique_device = await async_client.zero_trust.dex.tests.unique_devices.list( account_id="01a7362d577a6c3019a474fd6f485823", - device_id=["string"], + device_id=["cb49c27f-7f97-49c5-b6f3-f7c01ead0fd7"], test_name="testName", ) assert_matches_type(Optional[UniqueDevices], unique_device, path=["response"]) From 45260b91f48ed30eb69f1ecd184f245b03a59146 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 12 Jun 2026 11:48:27 +0000 Subject: [PATCH 03/23] chore(api): update composite API spec --- .stats.yml | 4 +-- .../resources/workflows/instances/events.py | 8 +++++ .../workflows/instances/instances.py | 16 ++++++++++ .../resources/workflows/instances/status.py | 32 +++++++++++++++++++ .../instances/event_create_params.py | 6 ++++ 5 files changed, 64 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index b15b9003bdf..82bdde321a7 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 2376 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-514c439211d08727278b25d13388b711bf1e431382b55eeb10079db550d01fa3.yml -openapi_spec_hash: c5f909ea82142fc11cd786fb212209fa +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-cec3848a0457a00a9b2587156f76ec6853dec07782076c38deed2640effe0db6.yml +openapi_spec_hash: 7bfe2cfc93064c81db893a09bc1ba5c9 config_hash: ec0647c69ef9d049d1e12e9ddb0673ee diff --git a/src/cloudflare/resources/workflows/instances/events.py b/src/cloudflare/resources/workflows/instances/events.py index 8e90369159d..c68d0efd3f8 100644 --- a/src/cloudflare/resources/workflows/instances/events.py +++ b/src/cloudflare/resources/workflows/instances/events.py @@ -62,6 +62,10 @@ def create( Sends an event to a running workflow instance to trigger state transitions. Args: + instance_id: Instance identifier. User-created instances match `^[a-zA-Z0-9_][a-zA-Z0-9-_]*$` + (max 100 characters); cron-triggered instances can use a longer, + system-generated id derived from the cron expression. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -137,6 +141,10 @@ async def create( Sends an event to a running workflow instance to trigger state transitions. Args: + instance_id: Instance identifier. User-created instances match `^[a-zA-Z0-9_][a-zA-Z0-9-_]*$` + (max 100 characters); cron-triggered instances can use a longer, + system-generated id derived from the cron expression. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request diff --git a/src/cloudflare/resources/workflows/instances/instances.py b/src/cloudflare/resources/workflows/instances/instances.py index fe90af5e81b..b8d36d81e31 100644 --- a/src/cloudflare/resources/workflows/instances/instances.py +++ b/src/cloudflare/resources/workflows/instances/instances.py @@ -283,6 +283,10 @@ def get( Retrieves logs and execution status for a specific workflow instance. Args: + instance_id: Instance identifier. User-created instances match `^[a-zA-Z0-9_][a-zA-Z0-9-_]*$` + (max 100 characters); cron-triggered instances can use a longer, + system-generated id derived from the cron expression. + order: Step ordering: "asc" (default, oldest first) or "desc" (newest first). simple: When true, omits step details and returns only metadata with step_count. @@ -352,6 +356,10 @@ def step( currently retrying after a prior attempt failed. Args: + instance_id: Instance identifier. User-created instances match `^[a-zA-Z0-9_][a-zA-Z0-9-_]*$` + (max 100 characters); cron-triggered instances can use a longer, + system-generated id derived from the cron expression. + name: Exact step name from the instance logs response, including the generated counter suffix. @@ -630,6 +638,10 @@ async def get( Retrieves logs and execution status for a specific workflow instance. Args: + instance_id: Instance identifier. User-created instances match `^[a-zA-Z0-9_][a-zA-Z0-9-_]*$` + (max 100 characters); cron-triggered instances can use a longer, + system-generated id derived from the cron expression. + order: Step ordering: "asc" (default, oldest first) or "desc" (newest first). simple: When true, omits step details and returns only metadata with step_count. @@ -699,6 +711,10 @@ async def step( currently retrying after a prior attempt failed. Args: + instance_id: Instance identifier. User-created instances match `^[a-zA-Z0-9_][a-zA-Z0-9-_]*$` + (max 100 characters); cron-triggered instances can use a longer, + system-generated id derived from the cron expression. + name: Exact step name from the instance logs response, including the generated counter suffix. diff --git a/src/cloudflare/resources/workflows/instances/status.py b/src/cloudflare/resources/workflows/instances/status.py index f9e68106691..d486242d2d9 100644 --- a/src/cloudflare/resources/workflows/instances/status.py +++ b/src/cloudflare/resources/workflows/instances/status.py @@ -65,6 +65,10 @@ def edit( terminate). Args: + instance_id: Instance identifier. User-created instances match `^[a-zA-Z0-9_][a-zA-Z0-9-_]*$` + (max 100 characters); cron-triggered instances can use a longer, + system-generated id derived from the cron expression. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -95,6 +99,10 @@ def edit( terminate). Args: + instance_id: Instance identifier. User-created instances match `^[a-zA-Z0-9_][a-zA-Z0-9-_]*$` + (max 100 characters); cron-triggered instances can use a longer, + system-generated id derived from the cron expression. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -126,6 +134,10 @@ def edit( terminate). Args: + instance_id: Instance identifier. User-created instances match `^[a-zA-Z0-9_][a-zA-Z0-9-_]*$` + (max 100 characters); cron-triggered instances can use a longer, + system-generated id derived from the cron expression. + rollback: Run rollback before terminating. extra_headers: Send extra headers @@ -159,6 +171,10 @@ def edit( terminate). Args: + instance_id: Instance identifier. User-created instances match `^[a-zA-Z0-9_][a-zA-Z0-9-_]*$` + (max 100 characters); cron-triggered instances can use a longer, + system-generated id derived from the cron expression. + from_: Step to restart from. extra_headers: Send extra headers @@ -260,6 +276,10 @@ async def edit( terminate). Args: + instance_id: Instance identifier. User-created instances match `^[a-zA-Z0-9_][a-zA-Z0-9-_]*$` + (max 100 characters); cron-triggered instances can use a longer, + system-generated id derived from the cron expression. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -290,6 +310,10 @@ async def edit( terminate). Args: + instance_id: Instance identifier. User-created instances match `^[a-zA-Z0-9_][a-zA-Z0-9-_]*$` + (max 100 characters); cron-triggered instances can use a longer, + system-generated id derived from the cron expression. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -321,6 +345,10 @@ async def edit( terminate). Args: + instance_id: Instance identifier. User-created instances match `^[a-zA-Z0-9_][a-zA-Z0-9-_]*$` + (max 100 characters); cron-triggered instances can use a longer, + system-generated id derived from the cron expression. + rollback: Run rollback before terminating. extra_headers: Send extra headers @@ -354,6 +382,10 @@ async def edit( terminate). Args: + instance_id: Instance identifier. User-created instances match `^[a-zA-Z0-9_][a-zA-Z0-9-_]*$` + (max 100 characters); cron-triggered instances can use a longer, + system-generated id derived from the cron expression. + from_: Step to restart from. extra_headers: Send extra headers diff --git a/src/cloudflare/types/workflows/instances/event_create_params.py b/src/cloudflare/types/workflows/instances/event_create_params.py index 52118424ae5..f26e63b6d34 100644 --- a/src/cloudflare/types/workflows/instances/event_create_params.py +++ b/src/cloudflare/types/workflows/instances/event_create_params.py @@ -13,5 +13,11 @@ class EventCreateParams(TypedDict, total=False): workflow_name: Required[str] instance_id: Required[str] + """Instance identifier. + + User-created instances match `^[a-zA-Z0-9_][a-zA-Z0-9-_]*$` (max 100 + characters); cron-triggered instances can use a longer, system-generated id + derived from the cron expression. + """ body: object From 7677b4c9566495b627b2cd90c9220268f9c6c46d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 12 Jun 2026 14:35:06 +0000 Subject: [PATCH 04/23] feat: feat(tenants): add tenants resource SDK mapping [PT-2567] * feat(tenants): add tenants resource SDK mapping Production promotion of staging MR !931 (PT-2567). Adds the tenants top-level resource and the user.tenants subresource (GET /user/tenants) to enable SDK/docs coverage for tenant-api public routes documented under the No Private APIs initiative. JIRA: PT-2567 --- .stats.yml | 6 +- api.md | 2 + src/cloudflare/_client.py | 38 +++ src/cloudflare/resources/tenants/__init__.py | 75 +++++ .../resources/tenants/account_types.py | 167 ++++++++++ src/cloudflare/resources/tenants/accounts.py | 167 ++++++++++ src/cloudflare/resources/tenants/api.md | 59 ++++ .../resources/tenants/entitlements.py | 175 ++++++++++ .../resources/tenants/memberships.py | 167 ++++++++++ src/cloudflare/resources/tenants/tenants.py | 303 ++++++++++++++++++ src/cloudflare/resources/user/__init__.py | 14 + src/cloudflare/resources/user/api.md | 6 + src/cloudflare/resources/user/tenants.py | 138 ++++++++ src/cloudflare/resources/user/user.py | 32 ++ src/cloudflare/types/tenants/__init__.py | 9 + .../tenants/account_type_list_response.py | 7 + src/cloudflare/types/tenants/tenant.py | 66 ++++ .../types/tenants/tenant_account.py | 45 +++ .../types/tenants/tenant_entitlements.py | 100 ++++++ .../types/tenants/tenant_membership.py | 13 + tests/api_resources/tenants/__init__.py | 1 + .../tenants/test_account_types.py | 101 ++++++ tests/api_resources/tenants/test_accounts.py | 101 ++++++ .../tenants/test_entitlements.py | 100 ++++++ .../api_resources/tenants/test_memberships.py | 101 ++++++ tests/api_resources/test_tenants.py | 100 ++++++ tests/api_resources/user/test_tenants.py | 75 +++++ 27 files changed, 2165 insertions(+), 3 deletions(-) create mode 100644 src/cloudflare/resources/tenants/__init__.py create mode 100644 src/cloudflare/resources/tenants/account_types.py create mode 100644 src/cloudflare/resources/tenants/accounts.py create mode 100644 src/cloudflare/resources/tenants/api.md create mode 100644 src/cloudflare/resources/tenants/entitlements.py create mode 100644 src/cloudflare/resources/tenants/memberships.py create mode 100644 src/cloudflare/resources/tenants/tenants.py create mode 100644 src/cloudflare/resources/user/tenants.py create mode 100644 src/cloudflare/types/tenants/__init__.py create mode 100644 src/cloudflare/types/tenants/account_type_list_response.py create mode 100644 src/cloudflare/types/tenants/tenant.py create mode 100644 src/cloudflare/types/tenants/tenant_account.py create mode 100644 src/cloudflare/types/tenants/tenant_entitlements.py create mode 100644 src/cloudflare/types/tenants/tenant_membership.py create mode 100644 tests/api_resources/tenants/__init__.py create mode 100644 tests/api_resources/tenants/test_account_types.py create mode 100644 tests/api_resources/tenants/test_accounts.py create mode 100644 tests/api_resources/tenants/test_entitlements.py create mode 100644 tests/api_resources/tenants/test_memberships.py create mode 100644 tests/api_resources/test_tenants.py create mode 100644 tests/api_resources/user/test_tenants.py diff --git a/.stats.yml b/.stats.yml index 82bdde321a7..7a5ea3ca675 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 2376 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-cec3848a0457a00a9b2587156f76ec6853dec07782076c38deed2640effe0db6.yml +configured_endpoints: 2382 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-cee99874469854ece2870d6467b8e2b37b96f773e0f706b974fad60c518f34c4.yml openapi_spec_hash: 7bfe2cfc93064c81db893a09bc1ba5c9 -config_hash: ec0647c69ef9d049d1e12e9ddb0673ee +config_hash: ec5b9d51fe96b49ca07d180985847027 diff --git a/api.md b/api.md index 843cf80894a..b05e7b8d057 100644 --- a/api.md +++ b/api.md @@ -33,6 +33,8 @@ from cloudflare.types import ( # [Organizations](src/cloudflare/resources/organizations/api.md) +# [Tenants](src/cloudflare/resources/tenants/api.md) + # [OriginCACertificates](src/cloudflare/resources/origin_ca_certificates/api.md) # [IPs](src/cloudflare/resources/ips/api.md) diff --git a/src/cloudflare/_client.py b/src/cloudflare/_client.py index a336d47db52..5b1e77d948c 100644 --- a/src/cloudflare/_client.py +++ b/src/cloudflare/_client.py @@ -69,6 +69,7 @@ billing, filters, logpush, + tenants, workers, accounts, aisearch, @@ -183,6 +184,7 @@ from .resources.billing.billing import BillingResource, AsyncBillingResource from .resources.filters.filters import FiltersResource, AsyncFiltersResource from .resources.logpush.logpush import LogpushResource, AsyncLogpushResource + from .resources.tenants.tenants import TenantsResource, AsyncTenantsResource from .resources.workers.workers import WorkersResource, AsyncWorkersResource from .resources.accounts.accounts import AccountsResource, AsyncAccountsResource from .resources.aisearch.aisearch import AISearchResource, AsyncAISearchResource @@ -424,6 +426,12 @@ def organizations(self) -> OrganizationsResource: return OrganizationsResource(self) + @cached_property + def tenants(self) -> TenantsResource: + from .resources.tenants import TenantsResource + + return TenantsResource(self) + @cached_property def origin_ca_certificates(self) -> OriginCACertificatesResource: from .resources.origin_ca_certificates import OriginCACertificatesResource @@ -1364,6 +1372,12 @@ def organizations(self) -> AsyncOrganizationsResource: return AsyncOrganizationsResource(self) + @cached_property + def tenants(self) -> AsyncTenantsResource: + from .resources.tenants import AsyncTenantsResource + + return AsyncTenantsResource(self) + @cached_property def origin_ca_certificates(self) -> AsyncOriginCACertificatesResource: from .resources.origin_ca_certificates import AsyncOriginCACertificatesResource @@ -2224,6 +2238,12 @@ def organizations(self) -> organizations.OrganizationsResourceWithRawResponse: return OrganizationsResourceWithRawResponse(self._client.organizations) + @cached_property + def tenants(self) -> tenants.TenantsResourceWithRawResponse: + from .resources.tenants import TenantsResourceWithRawResponse + + return TenantsResourceWithRawResponse(self._client.tenants) + @cached_property def origin_ca_certificates(self) -> origin_ca_certificates.OriginCACertificatesResourceWithRawResponse: from .resources.origin_ca_certificates import OriginCACertificatesResourceWithRawResponse @@ -2911,6 +2931,12 @@ def organizations(self) -> organizations.AsyncOrganizationsResourceWithRawRespon return AsyncOrganizationsResourceWithRawResponse(self._client.organizations) + @cached_property + def tenants(self) -> tenants.AsyncTenantsResourceWithRawResponse: + from .resources.tenants import AsyncTenantsResourceWithRawResponse + + return AsyncTenantsResourceWithRawResponse(self._client.tenants) + @cached_property def origin_ca_certificates(self) -> origin_ca_certificates.AsyncOriginCACertificatesResourceWithRawResponse: from .resources.origin_ca_certificates import AsyncOriginCACertificatesResourceWithRawResponse @@ -3600,6 +3626,12 @@ def organizations(self) -> organizations.OrganizationsResourceWithStreamingRespo return OrganizationsResourceWithStreamingResponse(self._client.organizations) + @cached_property + def tenants(self) -> tenants.TenantsResourceWithStreamingResponse: + from .resources.tenants import TenantsResourceWithStreamingResponse + + return TenantsResourceWithStreamingResponse(self._client.tenants) + @cached_property def origin_ca_certificates(self) -> origin_ca_certificates.OriginCACertificatesResourceWithStreamingResponse: from .resources.origin_ca_certificates import OriginCACertificatesResourceWithStreamingResponse @@ -4289,6 +4321,12 @@ def organizations(self) -> organizations.AsyncOrganizationsResourceWithStreaming return AsyncOrganizationsResourceWithStreamingResponse(self._client.organizations) + @cached_property + def tenants(self) -> tenants.AsyncTenantsResourceWithStreamingResponse: + from .resources.tenants import AsyncTenantsResourceWithStreamingResponse + + return AsyncTenantsResourceWithStreamingResponse(self._client.tenants) + @cached_property def origin_ca_certificates(self) -> origin_ca_certificates.AsyncOriginCACertificatesResourceWithStreamingResponse: from .resources.origin_ca_certificates import AsyncOriginCACertificatesResourceWithStreamingResponse diff --git a/src/cloudflare/resources/tenants/__init__.py b/src/cloudflare/resources/tenants/__init__.py new file mode 100644 index 00000000000..74459d119a6 --- /dev/null +++ b/src/cloudflare/resources/tenants/__init__.py @@ -0,0 +1,75 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .tenants import ( + TenantsResource, + AsyncTenantsResource, + TenantsResourceWithRawResponse, + AsyncTenantsResourceWithRawResponse, + TenantsResourceWithStreamingResponse, + AsyncTenantsResourceWithStreamingResponse, +) +from .accounts import ( + AccountsResource, + AsyncAccountsResource, + AccountsResourceWithRawResponse, + AsyncAccountsResourceWithRawResponse, + AccountsResourceWithStreamingResponse, + AsyncAccountsResourceWithStreamingResponse, +) +from .memberships import ( + MembershipsResource, + AsyncMembershipsResource, + MembershipsResourceWithRawResponse, + AsyncMembershipsResourceWithRawResponse, + MembershipsResourceWithStreamingResponse, + AsyncMembershipsResourceWithStreamingResponse, +) +from .entitlements import ( + EntitlementsResource, + AsyncEntitlementsResource, + EntitlementsResourceWithRawResponse, + AsyncEntitlementsResourceWithRawResponse, + EntitlementsResourceWithStreamingResponse, + AsyncEntitlementsResourceWithStreamingResponse, +) +from .account_types import ( + AccountTypesResource, + AsyncAccountTypesResource, + AccountTypesResourceWithRawResponse, + AsyncAccountTypesResourceWithRawResponse, + AccountTypesResourceWithStreamingResponse, + AsyncAccountTypesResourceWithStreamingResponse, +) + +__all__ = [ + "AccountTypesResource", + "AsyncAccountTypesResource", + "AccountTypesResourceWithRawResponse", + "AsyncAccountTypesResourceWithRawResponse", + "AccountTypesResourceWithStreamingResponse", + "AsyncAccountTypesResourceWithStreamingResponse", + "AccountsResource", + "AsyncAccountsResource", + "AccountsResourceWithRawResponse", + "AsyncAccountsResourceWithRawResponse", + "AccountsResourceWithStreamingResponse", + "AsyncAccountsResourceWithStreamingResponse", + "EntitlementsResource", + "AsyncEntitlementsResource", + "EntitlementsResourceWithRawResponse", + "AsyncEntitlementsResourceWithRawResponse", + "EntitlementsResourceWithStreamingResponse", + "AsyncEntitlementsResourceWithStreamingResponse", + "MembershipsResource", + "AsyncMembershipsResource", + "MembershipsResourceWithRawResponse", + "AsyncMembershipsResourceWithRawResponse", + "MembershipsResourceWithStreamingResponse", + "AsyncMembershipsResourceWithStreamingResponse", + "TenantsResource", + "AsyncTenantsResource", + "TenantsResourceWithRawResponse", + "AsyncTenantsResourceWithRawResponse", + "TenantsResourceWithStreamingResponse", + "AsyncTenantsResourceWithStreamingResponse", +] diff --git a/src/cloudflare/resources/tenants/account_types.py b/src/cloudflare/resources/tenants/account_types.py new file mode 100644 index 00000000000..1a082cf4647 --- /dev/null +++ b/src/cloudflare/resources/tenants/account_types.py @@ -0,0 +1,167 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +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 ...pagination import SyncSinglePage, AsyncSinglePage +from ..._base_client import AsyncPaginator, make_request_options +from ...types.tenants.account_type_list_response import AccountTypeListResponse + +__all__ = ["AccountTypesResource", "AsyncAccountTypesResource"] + + +class AccountTypesResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> AccountTypesResourceWithRawResponse: + """ + 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 AccountTypesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AccountTypesResourceWithStreamingResponse: + """ + 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 AccountTypesResourceWithStreamingResponse(self) + + def list( + self, + tenant_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[AccountTypeListResponse]: + """ + List of account types available for the Tenant to provision accounts. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not tenant_id: + raise ValueError(f"Expected a non-empty value for `tenant_id` but received {tenant_id!r}") + return self._get_api_list( + path_template("/tenants/{tenant_id}/account_types", tenant_id=tenant_id), + page=SyncSinglePage[AccountTypeListResponse], + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + model=str, + ) + + +class AsyncAccountTypesResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncAccountTypesResourceWithRawResponse: + """ + 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 AsyncAccountTypesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncAccountTypesResourceWithStreamingResponse: + """ + 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 AsyncAccountTypesResourceWithStreamingResponse(self) + + def list( + self, + tenant_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[AccountTypeListResponse, AsyncSinglePage[AccountTypeListResponse]]: + """ + List of account types available for the Tenant to provision accounts. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not tenant_id: + raise ValueError(f"Expected a non-empty value for `tenant_id` but received {tenant_id!r}") + return self._get_api_list( + path_template("/tenants/{tenant_id}/account_types", tenant_id=tenant_id), + page=AsyncSinglePage[AccountTypeListResponse], + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + model=str, + ) + + +class AccountTypesResourceWithRawResponse: + def __init__(self, account_types: AccountTypesResource) -> None: + self._account_types = account_types + + self.list = to_raw_response_wrapper( + account_types.list, + ) + + +class AsyncAccountTypesResourceWithRawResponse: + def __init__(self, account_types: AsyncAccountTypesResource) -> None: + self._account_types = account_types + + self.list = async_to_raw_response_wrapper( + account_types.list, + ) + + +class AccountTypesResourceWithStreamingResponse: + def __init__(self, account_types: AccountTypesResource) -> None: + self._account_types = account_types + + self.list = to_streamed_response_wrapper( + account_types.list, + ) + + +class AsyncAccountTypesResourceWithStreamingResponse: + def __init__(self, account_types: AsyncAccountTypesResource) -> None: + self._account_types = account_types + + self.list = async_to_streamed_response_wrapper( + account_types.list, + ) diff --git a/src/cloudflare/resources/tenants/accounts.py b/src/cloudflare/resources/tenants/accounts.py new file mode 100644 index 00000000000..b6221d6d169 --- /dev/null +++ b/src/cloudflare/resources/tenants/accounts.py @@ -0,0 +1,167 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +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 ...pagination import SyncSinglePage, AsyncSinglePage +from ..._base_client import AsyncPaginator, make_request_options +from ...types.tenants.tenant_account import TenantAccount + +__all__ = ["AccountsResource", "AsyncAccountsResource"] + + +class AccountsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> AccountsResourceWithRawResponse: + """ + 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 AccountsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AccountsResourceWithStreamingResponse: + """ + 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 AccountsResourceWithStreamingResponse(self) + + def list( + self, + tenant_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[TenantAccount]: + """ + List of accounts for the Tenant. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not tenant_id: + raise ValueError(f"Expected a non-empty value for `tenant_id` but received {tenant_id!r}") + return self._get_api_list( + path_template("/tenants/{tenant_id}/accounts", tenant_id=tenant_id), + page=SyncSinglePage[TenantAccount], + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + model=TenantAccount, + ) + + +class AsyncAccountsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncAccountsResourceWithRawResponse: + """ + 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 AsyncAccountsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncAccountsResourceWithStreamingResponse: + """ + 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 AsyncAccountsResourceWithStreamingResponse(self) + + def list( + self, + tenant_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[TenantAccount, AsyncSinglePage[TenantAccount]]: + """ + List of accounts for the Tenant. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not tenant_id: + raise ValueError(f"Expected a non-empty value for `tenant_id` but received {tenant_id!r}") + return self._get_api_list( + path_template("/tenants/{tenant_id}/accounts", tenant_id=tenant_id), + page=AsyncSinglePage[TenantAccount], + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + model=TenantAccount, + ) + + +class AccountsResourceWithRawResponse: + def __init__(self, accounts: AccountsResource) -> None: + self._accounts = accounts + + self.list = to_raw_response_wrapper( + accounts.list, + ) + + +class AsyncAccountsResourceWithRawResponse: + def __init__(self, accounts: AsyncAccountsResource) -> None: + self._accounts = accounts + + self.list = async_to_raw_response_wrapper( + accounts.list, + ) + + +class AccountsResourceWithStreamingResponse: + def __init__(self, accounts: AccountsResource) -> None: + self._accounts = accounts + + self.list = to_streamed_response_wrapper( + accounts.list, + ) + + +class AsyncAccountsResourceWithStreamingResponse: + def __init__(self, accounts: AsyncAccountsResource) -> None: + self._accounts = accounts + + self.list = async_to_streamed_response_wrapper( + accounts.list, + ) diff --git a/src/cloudflare/resources/tenants/api.md b/src/cloudflare/resources/tenants/api.md new file mode 100644 index 00000000000..ffac91773b5 --- /dev/null +++ b/src/cloudflare/resources/tenants/api.md @@ -0,0 +1,59 @@ +# Tenants + +Types: + +```python +from cloudflare.types.tenants import Tenant +``` + +Methods: + +-client.tenants.get(tenant_id) -> Tenant
+
+## AccountTypes
+
+Types:
+
+```python
+from cloudflare.types.tenants import AccountTypeListResponse
+```
+
+Methods:
+
+- client.tenants.account_types.list(tenant_id) -> SyncSinglePage[AccountTypeListResponse]
+
+## Accounts
+
+Types:
+
+```python
+from cloudflare.types.tenants import TenantAccount
+```
+
+Methods:
+
+- client.tenants.accounts.list(tenant_id) -> SyncSinglePage[TenantAccount]
+
+## Entitlements
+
+Types:
+
+```python
+from cloudflare.types.tenants import TenantEntitlements
+```
+
+Methods:
+
+- client.tenants.entitlements.get(tenant_id) -> TenantEntitlements
+
+## Memberships
+
+Types:
+
+```python
+from cloudflare.types.tenants import TenantMembership
+```
+
+Methods:
+
+- client.tenants.memberships.list(tenant_id) -> SyncSinglePage[TenantMembership]
diff --git a/src/cloudflare/resources/tenants/entitlements.py b/src/cloudflare/resources/tenants/entitlements.py
new file mode 100644
index 00000000000..b51632c3b8f
--- /dev/null
+++ b/src/cloudflare/resources/tenants/entitlements.py
@@ -0,0 +1,175 @@
+# 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.tenants.tenant_entitlements import TenantEntitlements
+
+__all__ = ["EntitlementsResource", "AsyncEntitlementsResource"]
+
+
+class EntitlementsResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> EntitlementsResourceWithRawResponse:
+ """
+ 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 EntitlementsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> EntitlementsResourceWithStreamingResponse:
+ """
+ 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 EntitlementsResourceWithStreamingResponse(self)
+
+ def get(
+ self,
+ tenant_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,
+ ) -> TenantEntitlements:
+ """
+ List of innate entitlements available for the Tenant.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not tenant_id:
+ raise ValueError(f"Expected a non-empty value for `tenant_id` but received {tenant_id!r}")
+ return self._get(
+ path_template("/tenants/{tenant_id}/entitlements", tenant_id=tenant_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[TenantEntitlements]._unwrapper,
+ ),
+ cast_to=cast(Type[TenantEntitlements], ResultWrapper[TenantEntitlements]),
+ )
+
+
+class AsyncEntitlementsResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncEntitlementsResourceWithRawResponse:
+ """
+ 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 AsyncEntitlementsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncEntitlementsResourceWithStreamingResponse:
+ """
+ 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 AsyncEntitlementsResourceWithStreamingResponse(self)
+
+ async def get(
+ self,
+ tenant_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,
+ ) -> TenantEntitlements:
+ """
+ List of innate entitlements available for the Tenant.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not tenant_id:
+ raise ValueError(f"Expected a non-empty value for `tenant_id` but received {tenant_id!r}")
+ return await self._get(
+ path_template("/tenants/{tenant_id}/entitlements", tenant_id=tenant_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[TenantEntitlements]._unwrapper,
+ ),
+ cast_to=cast(Type[TenantEntitlements], ResultWrapper[TenantEntitlements]),
+ )
+
+
+class EntitlementsResourceWithRawResponse:
+ def __init__(self, entitlements: EntitlementsResource) -> None:
+ self._entitlements = entitlements
+
+ self.get = to_raw_response_wrapper(
+ entitlements.get,
+ )
+
+
+class AsyncEntitlementsResourceWithRawResponse:
+ def __init__(self, entitlements: AsyncEntitlementsResource) -> None:
+ self._entitlements = entitlements
+
+ self.get = async_to_raw_response_wrapper(
+ entitlements.get,
+ )
+
+
+class EntitlementsResourceWithStreamingResponse:
+ def __init__(self, entitlements: EntitlementsResource) -> None:
+ self._entitlements = entitlements
+
+ self.get = to_streamed_response_wrapper(
+ entitlements.get,
+ )
+
+
+class AsyncEntitlementsResourceWithStreamingResponse:
+ def __init__(self, entitlements: AsyncEntitlementsResource) -> None:
+ self._entitlements = entitlements
+
+ self.get = async_to_streamed_response_wrapper(
+ entitlements.get,
+ )
diff --git a/src/cloudflare/resources/tenants/memberships.py b/src/cloudflare/resources/tenants/memberships.py
new file mode 100644
index 00000000000..8c7f0ebea8a
--- /dev/null
+++ b/src/cloudflare/resources/tenants/memberships.py
@@ -0,0 +1,167 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+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 ...pagination import SyncSinglePage, AsyncSinglePage
+from ..._base_client import AsyncPaginator, make_request_options
+from ...types.tenants.tenant_membership import TenantMembership
+
+__all__ = ["MembershipsResource", "AsyncMembershipsResource"]
+
+
+class MembershipsResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> MembershipsResourceWithRawResponse:
+ """
+ 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 MembershipsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> MembershipsResourceWithStreamingResponse:
+ """
+ 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 MembershipsResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ tenant_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[TenantMembership]:
+ """
+ List of active members (Cloudflare users) for the Tenant.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not tenant_id:
+ raise ValueError(f"Expected a non-empty value for `tenant_id` but received {tenant_id!r}")
+ return self._get_api_list(
+ path_template("/tenants/{tenant_id}/memberships", tenant_id=tenant_id),
+ page=SyncSinglePage[TenantMembership],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=TenantMembership,
+ )
+
+
+class AsyncMembershipsResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncMembershipsResourceWithRawResponse:
+ """
+ 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 AsyncMembershipsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncMembershipsResourceWithStreamingResponse:
+ """
+ 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 AsyncMembershipsResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ tenant_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[TenantMembership, AsyncSinglePage[TenantMembership]]:
+ """
+ List of active members (Cloudflare users) for the Tenant.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not tenant_id:
+ raise ValueError(f"Expected a non-empty value for `tenant_id` but received {tenant_id!r}")
+ return self._get_api_list(
+ path_template("/tenants/{tenant_id}/memberships", tenant_id=tenant_id),
+ page=AsyncSinglePage[TenantMembership],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=TenantMembership,
+ )
+
+
+class MembershipsResourceWithRawResponse:
+ def __init__(self, memberships: MembershipsResource) -> None:
+ self._memberships = memberships
+
+ self.list = to_raw_response_wrapper(
+ memberships.list,
+ )
+
+
+class AsyncMembershipsResourceWithRawResponse:
+ def __init__(self, memberships: AsyncMembershipsResource) -> None:
+ self._memberships = memberships
+
+ self.list = async_to_raw_response_wrapper(
+ memberships.list,
+ )
+
+
+class MembershipsResourceWithStreamingResponse:
+ def __init__(self, memberships: MembershipsResource) -> None:
+ self._memberships = memberships
+
+ self.list = to_streamed_response_wrapper(
+ memberships.list,
+ )
+
+
+class AsyncMembershipsResourceWithStreamingResponse:
+ def __init__(self, memberships: AsyncMembershipsResource) -> None:
+ self._memberships = memberships
+
+ self.list = async_to_streamed_response_wrapper(
+ memberships.list,
+ )
diff --git a/src/cloudflare/resources/tenants/tenants.py b/src/cloudflare/resources/tenants/tenants.py
new file mode 100644
index 00000000000..60e19a8c84b
--- /dev/null
+++ b/src/cloudflare/resources/tenants/tenants.py
@@ -0,0 +1,303 @@
+# 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 .accounts import (
+ AccountsResource,
+ AsyncAccountsResource,
+ AccountsResourceWithRawResponse,
+ AsyncAccountsResourceWithRawResponse,
+ AccountsResourceWithStreamingResponse,
+ AsyncAccountsResourceWithStreamingResponse,
+)
+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 .memberships import (
+ MembershipsResource,
+ AsyncMembershipsResource,
+ MembershipsResourceWithRawResponse,
+ AsyncMembershipsResourceWithRawResponse,
+ MembershipsResourceWithStreamingResponse,
+ AsyncMembershipsResourceWithStreamingResponse,
+)
+from .entitlements import (
+ EntitlementsResource,
+ AsyncEntitlementsResource,
+ EntitlementsResourceWithRawResponse,
+ AsyncEntitlementsResourceWithRawResponse,
+ EntitlementsResourceWithStreamingResponse,
+ AsyncEntitlementsResourceWithStreamingResponse,
+)
+from .account_types import (
+ AccountTypesResource,
+ AsyncAccountTypesResource,
+ AccountTypesResourceWithRawResponse,
+ AsyncAccountTypesResourceWithRawResponse,
+ AccountTypesResourceWithStreamingResponse,
+ AsyncAccountTypesResourceWithStreamingResponse,
+)
+from ..._base_client import make_request_options
+from ...types.tenants.tenant import Tenant
+
+__all__ = ["TenantsResource", "AsyncTenantsResource"]
+
+
+class TenantsResource(SyncAPIResource):
+ @cached_property
+ def account_types(self) -> AccountTypesResource:
+ return AccountTypesResource(self._client)
+
+ @cached_property
+ def accounts(self) -> AccountsResource:
+ return AccountsResource(self._client)
+
+ @cached_property
+ def entitlements(self) -> EntitlementsResource:
+ return EntitlementsResource(self._client)
+
+ @cached_property
+ def memberships(self) -> MembershipsResource:
+ return MembershipsResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> TenantsResourceWithRawResponse:
+ """
+ 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 TenantsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> TenantsResourceWithStreamingResponse:
+ """
+ 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 TenantsResourceWithStreamingResponse(self)
+
+ def get(
+ self,
+ tenant_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,
+ ) -> Tenant:
+ """
+ Retrieves a Tenant by Tenant ID.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not tenant_id:
+ raise ValueError(f"Expected a non-empty value for `tenant_id` but received {tenant_id!r}")
+ return self._get(
+ path_template("/tenants/{tenant_id}", tenant_id=tenant_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Tenant]._unwrapper,
+ ),
+ cast_to=cast(Type[Tenant], ResultWrapper[Tenant]),
+ )
+
+
+class AsyncTenantsResource(AsyncAPIResource):
+ @cached_property
+ def account_types(self) -> AsyncAccountTypesResource:
+ return AsyncAccountTypesResource(self._client)
+
+ @cached_property
+ def accounts(self) -> AsyncAccountsResource:
+ return AsyncAccountsResource(self._client)
+
+ @cached_property
+ def entitlements(self) -> AsyncEntitlementsResource:
+ return AsyncEntitlementsResource(self._client)
+
+ @cached_property
+ def memberships(self) -> AsyncMembershipsResource:
+ return AsyncMembershipsResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncTenantsResourceWithRawResponse:
+ """
+ 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 AsyncTenantsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncTenantsResourceWithStreamingResponse:
+ """
+ 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 AsyncTenantsResourceWithStreamingResponse(self)
+
+ async def get(
+ self,
+ tenant_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,
+ ) -> Tenant:
+ """
+ Retrieves a Tenant by Tenant ID.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not tenant_id:
+ raise ValueError(f"Expected a non-empty value for `tenant_id` but received {tenant_id!r}")
+ return await self._get(
+ path_template("/tenants/{tenant_id}", tenant_id=tenant_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Tenant]._unwrapper,
+ ),
+ cast_to=cast(Type[Tenant], ResultWrapper[Tenant]),
+ )
+
+
+class TenantsResourceWithRawResponse:
+ def __init__(self, tenants: TenantsResource) -> None:
+ self._tenants = tenants
+
+ self.get = to_raw_response_wrapper(
+ tenants.get,
+ )
+
+ @cached_property
+ def account_types(self) -> AccountTypesResourceWithRawResponse:
+ return AccountTypesResourceWithRawResponse(self._tenants.account_types)
+
+ @cached_property
+ def accounts(self) -> AccountsResourceWithRawResponse:
+ return AccountsResourceWithRawResponse(self._tenants.accounts)
+
+ @cached_property
+ def entitlements(self) -> EntitlementsResourceWithRawResponse:
+ return EntitlementsResourceWithRawResponse(self._tenants.entitlements)
+
+ @cached_property
+ def memberships(self) -> MembershipsResourceWithRawResponse:
+ return MembershipsResourceWithRawResponse(self._tenants.memberships)
+
+
+class AsyncTenantsResourceWithRawResponse:
+ def __init__(self, tenants: AsyncTenantsResource) -> None:
+ self._tenants = tenants
+
+ self.get = async_to_raw_response_wrapper(
+ tenants.get,
+ )
+
+ @cached_property
+ def account_types(self) -> AsyncAccountTypesResourceWithRawResponse:
+ return AsyncAccountTypesResourceWithRawResponse(self._tenants.account_types)
+
+ @cached_property
+ def accounts(self) -> AsyncAccountsResourceWithRawResponse:
+ return AsyncAccountsResourceWithRawResponse(self._tenants.accounts)
+
+ @cached_property
+ def entitlements(self) -> AsyncEntitlementsResourceWithRawResponse:
+ return AsyncEntitlementsResourceWithRawResponse(self._tenants.entitlements)
+
+ @cached_property
+ def memberships(self) -> AsyncMembershipsResourceWithRawResponse:
+ return AsyncMembershipsResourceWithRawResponse(self._tenants.memberships)
+
+
+class TenantsResourceWithStreamingResponse:
+ def __init__(self, tenants: TenantsResource) -> None:
+ self._tenants = tenants
+
+ self.get = to_streamed_response_wrapper(
+ tenants.get,
+ )
+
+ @cached_property
+ def account_types(self) -> AccountTypesResourceWithStreamingResponse:
+ return AccountTypesResourceWithStreamingResponse(self._tenants.account_types)
+
+ @cached_property
+ def accounts(self) -> AccountsResourceWithStreamingResponse:
+ return AccountsResourceWithStreamingResponse(self._tenants.accounts)
+
+ @cached_property
+ def entitlements(self) -> EntitlementsResourceWithStreamingResponse:
+ return EntitlementsResourceWithStreamingResponse(self._tenants.entitlements)
+
+ @cached_property
+ def memberships(self) -> MembershipsResourceWithStreamingResponse:
+ return MembershipsResourceWithStreamingResponse(self._tenants.memberships)
+
+
+class AsyncTenantsResourceWithStreamingResponse:
+ def __init__(self, tenants: AsyncTenantsResource) -> None:
+ self._tenants = tenants
+
+ self.get = async_to_streamed_response_wrapper(
+ tenants.get,
+ )
+
+ @cached_property
+ def account_types(self) -> AsyncAccountTypesResourceWithStreamingResponse:
+ return AsyncAccountTypesResourceWithStreamingResponse(self._tenants.account_types)
+
+ @cached_property
+ def accounts(self) -> AsyncAccountsResourceWithStreamingResponse:
+ return AsyncAccountsResourceWithStreamingResponse(self._tenants.accounts)
+
+ @cached_property
+ def entitlements(self) -> AsyncEntitlementsResourceWithStreamingResponse:
+ return AsyncEntitlementsResourceWithStreamingResponse(self._tenants.entitlements)
+
+ @cached_property
+ def memberships(self) -> AsyncMembershipsResourceWithStreamingResponse:
+ return AsyncMembershipsResourceWithStreamingResponse(self._tenants.memberships)
diff --git a/src/cloudflare/resources/user/__init__.py b/src/cloudflare/resources/user/__init__.py
index 1ae3753c27c..55ded107699 100644
--- a/src/cloudflare/resources/user/__init__.py
+++ b/src/cloudflare/resources/user/__init__.py
@@ -32,6 +32,14 @@
InvitesResourceWithStreamingResponse,
AsyncInvitesResourceWithStreamingResponse,
)
+from .tenants import (
+ TenantsResource,
+ AsyncTenantsResource,
+ TenantsResourceWithRawResponse,
+ AsyncTenantsResourceWithRawResponse,
+ TenantsResourceWithStreamingResponse,
+ AsyncTenantsResourceWithStreamingResponse,
+)
from .audit_logs import (
AuditLogsResource,
AsyncAuditLogsResource,
@@ -88,6 +96,12 @@
"AsyncSubscriptionsResourceWithRawResponse",
"SubscriptionsResourceWithStreamingResponse",
"AsyncSubscriptionsResourceWithStreamingResponse",
+ "TenantsResource",
+ "AsyncTenantsResource",
+ "TenantsResourceWithRawResponse",
+ "AsyncTenantsResourceWithRawResponse",
+ "TenantsResourceWithStreamingResponse",
+ "AsyncTenantsResourceWithStreamingResponse",
"TokensResource",
"AsyncTokensResource",
"TokensResourceWithRawResponse",
diff --git a/src/cloudflare/resources/user/api.md b/src/cloudflare/resources/user/api.md
index b3e52694624..43dbaa4e0b2 100644
--- a/src/cloudflare/resources/user/api.md
+++ b/src/cloudflare/resources/user/api.md
@@ -85,6 +85,12 @@ Methods:
- client.user.subscriptions.delete(identifier) -> SubscriptionDeleteResponse
- client.user.subscriptions.get() -> SyncSinglePage[Subscription]
+## Tenants
+
+Methods:
+
+- client.user.tenants.list() -> SyncSinglePage[Organization]
+
## Tokens
Types:
diff --git a/src/cloudflare/resources/user/tenants.py b/src/cloudflare/resources/user/tenants.py
new file mode 100644
index 00000000000..3f46301eb9f
--- /dev/null
+++ b/src/cloudflare/resources/user/tenants.py
@@ -0,0 +1,138 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from ..._types import Body, Query, Headers, NotGiven, not_given
+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 ...pagination import SyncSinglePage, AsyncSinglePage
+from ..._base_client import AsyncPaginator, make_request_options
+from ...types.organizations.organization import Organization
+
+__all__ = ["TenantsResource", "AsyncTenantsResource"]
+
+
+class TenantsResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> TenantsResourceWithRawResponse:
+ """
+ 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 TenantsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> TenantsResourceWithStreamingResponse:
+ """
+ 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 TenantsResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ *,
+ # 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[Organization]:
+ """Retrieves list of tenants the authenticated user / method has access to."""
+ return self._get_api_list(
+ "/user/tenants",
+ page=SyncSinglePage[Organization],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=Organization,
+ )
+
+
+class AsyncTenantsResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncTenantsResourceWithRawResponse:
+ """
+ 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 AsyncTenantsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncTenantsResourceWithStreamingResponse:
+ """
+ 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 AsyncTenantsResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ *,
+ # 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[Organization, AsyncSinglePage[Organization]]:
+ """Retrieves list of tenants the authenticated user / method has access to."""
+ return self._get_api_list(
+ "/user/tenants",
+ page=AsyncSinglePage[Organization],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=Organization,
+ )
+
+
+class TenantsResourceWithRawResponse:
+ def __init__(self, tenants: TenantsResource) -> None:
+ self._tenants = tenants
+
+ self.list = to_raw_response_wrapper(
+ tenants.list,
+ )
+
+
+class AsyncTenantsResourceWithRawResponse:
+ def __init__(self, tenants: AsyncTenantsResource) -> None:
+ self._tenants = tenants
+
+ self.list = async_to_raw_response_wrapper(
+ tenants.list,
+ )
+
+
+class TenantsResourceWithStreamingResponse:
+ def __init__(self, tenants: TenantsResource) -> None:
+ self._tenants = tenants
+
+ self.list = to_streamed_response_wrapper(
+ tenants.list,
+ )
+
+
+class AsyncTenantsResourceWithStreamingResponse:
+ def __init__(self, tenants: AsyncTenantsResource) -> None:
+ self._tenants = tenants
+
+ self.list = async_to_streamed_response_wrapper(
+ tenants.list,
+ )
diff --git a/src/cloudflare/resources/user/user.py b/src/cloudflare/resources/user/user.py
index da999f1c09e..60793fda83b 100644
--- a/src/cloudflare/resources/user/user.py
+++ b/src/cloudflare/resources/user/user.py
@@ -14,6 +14,14 @@
InvitesResourceWithStreamingResponse,
AsyncInvitesResourceWithStreamingResponse,
)
+from .tenants import (
+ TenantsResource,
+ AsyncTenantsResource,
+ TenantsResourceWithRawResponse,
+ AsyncTenantsResourceWithRawResponse,
+ TenantsResourceWithStreamingResponse,
+ AsyncTenantsResourceWithStreamingResponse,
+)
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
from ..._utils import maybe_transform, async_maybe_transform
from ..._compat import cached_property
@@ -94,6 +102,10 @@ def organizations(self) -> OrganizationsResource:
def subscriptions(self) -> SubscriptionsResource:
return SubscriptionsResource(self._client)
+ @cached_property
+ def tenants(self) -> TenantsResource:
+ return TenantsResource(self._client)
+
@cached_property
def tokens(self) -> TokensResource:
return TokensResource(self._client)
@@ -221,6 +233,10 @@ def organizations(self) -> AsyncOrganizationsResource:
def subscriptions(self) -> AsyncSubscriptionsResource:
return AsyncSubscriptionsResource(self._client)
+ @cached_property
+ def tenants(self) -> AsyncTenantsResource:
+ return AsyncTenantsResource(self._client)
+
@cached_property
def tokens(self) -> AsyncTokensResource:
return AsyncTokensResource(self._client)
@@ -358,6 +374,10 @@ def organizations(self) -> OrganizationsResourceWithRawResponse:
def subscriptions(self) -> SubscriptionsResourceWithRawResponse:
return SubscriptionsResourceWithRawResponse(self._user.subscriptions)
+ @cached_property
+ def tenants(self) -> TenantsResourceWithRawResponse:
+ return TenantsResourceWithRawResponse(self._user.tenants)
+
@cached_property
def tokens(self) -> TokensResourceWithRawResponse:
return TokensResourceWithRawResponse(self._user.tokens)
@@ -394,6 +414,10 @@ def organizations(self) -> AsyncOrganizationsResourceWithRawResponse:
def subscriptions(self) -> AsyncSubscriptionsResourceWithRawResponse:
return AsyncSubscriptionsResourceWithRawResponse(self._user.subscriptions)
+ @cached_property
+ def tenants(self) -> AsyncTenantsResourceWithRawResponse:
+ return AsyncTenantsResourceWithRawResponse(self._user.tenants)
+
@cached_property
def tokens(self) -> AsyncTokensResourceWithRawResponse:
return AsyncTokensResourceWithRawResponse(self._user.tokens)
@@ -430,6 +454,10 @@ def organizations(self) -> OrganizationsResourceWithStreamingResponse:
def subscriptions(self) -> SubscriptionsResourceWithStreamingResponse:
return SubscriptionsResourceWithStreamingResponse(self._user.subscriptions)
+ @cached_property
+ def tenants(self) -> TenantsResourceWithStreamingResponse:
+ return TenantsResourceWithStreamingResponse(self._user.tenants)
+
@cached_property
def tokens(self) -> TokensResourceWithStreamingResponse:
return TokensResourceWithStreamingResponse(self._user.tokens)
@@ -466,6 +494,10 @@ def organizations(self) -> AsyncOrganizationsResourceWithStreamingResponse:
def subscriptions(self) -> AsyncSubscriptionsResourceWithStreamingResponse:
return AsyncSubscriptionsResourceWithStreamingResponse(self._user.subscriptions)
+ @cached_property
+ def tenants(self) -> AsyncTenantsResourceWithStreamingResponse:
+ return AsyncTenantsResourceWithStreamingResponse(self._user.tenants)
+
@cached_property
def tokens(self) -> AsyncTokensResourceWithStreamingResponse:
return AsyncTokensResourceWithStreamingResponse(self._user.tokens)
diff --git a/src/cloudflare/types/tenants/__init__.py b/src/cloudflare/types/tenants/__init__.py
new file mode 100644
index 00000000000..bcce8ccb6f5
--- /dev/null
+++ b/src/cloudflare/types/tenants/__init__.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .tenant import Tenant as Tenant
+from .tenant_account import TenantAccount as TenantAccount
+from .tenant_membership import TenantMembership as TenantMembership
+from .tenant_entitlements import TenantEntitlements as TenantEntitlements
+from .account_type_list_response import AccountTypeListResponse as AccountTypeListResponse
diff --git a/src/cloudflare/types/tenants/account_type_list_response.py b/src/cloudflare/types/tenants/account_type_list_response.py
new file mode 100644
index 00000000000..9583cbe105d
--- /dev/null
+++ b/src/cloudflare/types/tenants/account_type_list_response.py
@@ -0,0 +1,7 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import TypeAlias
+
+__all__ = ["AccountTypeListResponse"]
+
+AccountTypeListResponse: TypeAlias = str
diff --git a/src/cloudflare/types/tenants/tenant.py b/src/cloudflare/types/tenants/tenant.py
new file mode 100644
index 00000000000..8d8fb67b791
--- /dev/null
+++ b/src/cloudflare/types/tenants/tenant.py
@@ -0,0 +1,66 @@
+# 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__ = ["Tenant", "TenantContacts", "TenantMetadata", "TenantMetadataDNS", "TenantMetadataDNSNSPool", "TenantUnit"]
+
+
+class TenantContacts(BaseModel):
+ email: Optional[str] = None
+
+ website: Optional[str] = None
+
+
+class TenantMetadataDNSNSPool(BaseModel):
+ primary: Optional[str] = None
+
+ secondary: Optional[str] = None
+
+
+class TenantMetadataDNS(BaseModel):
+ ns_pool: TenantMetadataDNSNSPool
+
+
+class TenantMetadata(BaseModel):
+ dns: Optional[TenantMetadataDNS] = None
+
+
+class TenantUnit(BaseModel):
+ unit_memberships: List[object]
+
+ unit_metadata: object
+
+ unit_name: str
+
+ unit_status: str
+
+ unit_tag: str
+
+
+class Tenant(BaseModel):
+ cdate: datetime
+
+ edate: datetime
+
+ tenant_contacts: TenantContacts
+
+ tenant_labels: List[str]
+
+ tenant_metadata: TenantMetadata
+
+ tenant_name: str
+
+ tenant_network: object
+
+ tenant_status: str
+
+ tenant_tag: str
+
+ tenant_type: str
+
+ tenant_units: List[TenantUnit]
+
+ customer_id: Optional[str] = None
diff --git a/src/cloudflare/types/tenants/tenant_account.py b/src/cloudflare/types/tenants/tenant_account.py
new file mode 100644
index 00000000000..1f07c7cf657
--- /dev/null
+++ b/src/cloudflare/types/tenants/tenant_account.py
@@ -0,0 +1,45 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["TenantAccount", "Settings"]
+
+
+class Settings(BaseModel):
+ abuse_contact_email: Optional[str] = None
+
+ access_approval_expiry: Optional[datetime] = None
+
+ api_access_enabled: Optional[bool] = None
+
+ default_nameservers: Optional[str] = None
+ """
+ Use
+ [DNS Settings](https://developers.cloudflare.com/api/operations/dns-settings-for-an-account-list-dns-settings)
+ instead. Deprecated.
+ """
+
+ enforce_twofactor: Optional[bool] = None
+
+ use_account_custom_ns_by_default: Optional[bool] = None
+ """
+ Use
+ [DNS Settings](https://developers.cloudflare.com/api/operations/dns-settings-for-an-account-list-dns-settings)
+ instead. Deprecated.
+ """
+
+
+class TenantAccount(BaseModel):
+ id: str
+
+ created_on: datetime
+
+ name: Optional[str] = None
+
+ settings: Settings
+
+ type: Literal["standard", "enterprise"]
diff --git a/src/cloudflare/types/tenants/tenant_entitlements.py b/src/cloudflare/types/tenants/tenant_entitlements.py
new file mode 100644
index 00000000000..a404e4e34b1
--- /dev/null
+++ b/src/cloudflare/types/tenants/tenant_entitlements.py
@@ -0,0 +1,100 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Union, Optional
+from typing_extensions import Literal, TypeAlias
+
+from ..._models import BaseModel
+
+__all__ = [
+ "TenantEntitlements",
+ "AllowAddSubdomain",
+ "AllowAutoAcceptInvites",
+ "CNAMESetupAllowed",
+ "CustomEntitlement",
+ "CustomEntitlementAllocation",
+ "CustomEntitlementAllocationOrganizationsAPIMaxCountAllocation",
+ "CustomEntitlementAllocationOrganizationsAPIBoolAllocation",
+ "CustomEntitlementAllocationOrganizationsAPINullAllocation",
+ "CustomEntitlementFeature",
+ "MhsCertificateCount",
+ "PartialSetupAllowed",
+]
+
+
+class AllowAddSubdomain(BaseModel):
+ type: Literal["bool"]
+
+ value: bool
+
+
+class AllowAutoAcceptInvites(BaseModel):
+ type: Literal["bool"]
+
+ value: bool
+
+
+class CNAMESetupAllowed(BaseModel):
+ type: Literal["bool"]
+
+ value: bool
+
+
+class CustomEntitlementAllocationOrganizationsAPIMaxCountAllocation(BaseModel):
+ type: Literal["max_count"]
+
+ value: int
+
+
+class CustomEntitlementAllocationOrganizationsAPIBoolAllocation(BaseModel):
+ type: Literal["bool"]
+
+ value: bool
+
+
+class CustomEntitlementAllocationOrganizationsAPINullAllocation(BaseModel):
+ type: Literal[""]
+
+ value: Optional[object] = None
+
+
+CustomEntitlementAllocation: TypeAlias = Union[
+ CustomEntitlementAllocationOrganizationsAPIMaxCountAllocation,
+ CustomEntitlementAllocationOrganizationsAPIBoolAllocation,
+ CustomEntitlementAllocationOrganizationsAPINullAllocation,
+]
+
+
+class CustomEntitlementFeature(BaseModel):
+ key: str
+
+
+class CustomEntitlement(BaseModel):
+ allocation: CustomEntitlementAllocation
+
+ feature: CustomEntitlementFeature
+
+
+class MhsCertificateCount(BaseModel):
+ type: Literal["max_count"]
+
+ value: int
+
+
+class PartialSetupAllowed(BaseModel):
+ type: Literal["bool"]
+
+ value: bool
+
+
+class TenantEntitlements(BaseModel):
+ allow_add_subdomain: AllowAddSubdomain
+
+ allow_auto_accept_invites: AllowAutoAcceptInvites
+
+ cname_setup_allowed: CNAMESetupAllowed
+
+ custom_entitlements: Optional[List[CustomEntitlement]] = None
+
+ mhs_certificate_count: MhsCertificateCount
+
+ partial_setup_allowed: PartialSetupAllowed
diff --git a/src/cloudflare/types/tenants/tenant_membership.py b/src/cloudflare/types/tenants/tenant_membership.py
new file mode 100644
index 00000000000..45ca42966e3
--- /dev/null
+++ b/src/cloudflare/types/tenants/tenant_membership.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from ..._models import BaseModel
+
+__all__ = ["TenantMembership"]
+
+
+class TenantMembership(BaseModel):
+ user_email: str
+
+ user_name: str
+
+ user_tag: str
diff --git a/tests/api_resources/tenants/__init__.py b/tests/api_resources/tenants/__init__.py
new file mode 100644
index 00000000000..fd8019a9a1a
--- /dev/null
+++ b/tests/api_resources/tenants/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/tenants/test_account_types.py b/tests/api_resources/tenants/test_account_types.py
new file mode 100644
index 00000000000..27a9312c379
--- /dev/null
+++ b/tests/api_resources/tenants/test_account_types.py
@@ -0,0 +1,101 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare.pagination import SyncSinglePage, AsyncSinglePage
+from cloudflare.types.tenants import AccountTypeListResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestAccountTypes:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_list(self, client: Cloudflare) -> None:
+ account_type = client.tenants.account_types.list(
+ "tenant_id",
+ )
+ assert_matches_type(SyncSinglePage[AccountTypeListResponse], account_type, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Cloudflare) -> None:
+ response = client.tenants.account_types.with_raw_response.list(
+ "tenant_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ account_type = response.parse()
+ assert_matches_type(SyncSinglePage[AccountTypeListResponse], account_type, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Cloudflare) -> None:
+ with client.tenants.account_types.with_streaming_response.list(
+ "tenant_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ account_type = response.parse()
+ assert_matches_type(SyncSinglePage[AccountTypeListResponse], account_type, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_list(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `tenant_id` but received ''"):
+ client.tenants.account_types.with_raw_response.list(
+ "",
+ )
+
+
+class TestAsyncAccountTypes:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncCloudflare) -> None:
+ account_type = await async_client.tenants.account_types.list(
+ "tenant_id",
+ )
+ assert_matches_type(AsyncSinglePage[AccountTypeListResponse], account_type, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.tenants.account_types.with_raw_response.list(
+ "tenant_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ account_type = await response.parse()
+ assert_matches_type(AsyncSinglePage[AccountTypeListResponse], account_type, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.tenants.account_types.with_streaming_response.list(
+ "tenant_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ account_type = await response.parse()
+ assert_matches_type(AsyncSinglePage[AccountTypeListResponse], account_type, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `tenant_id` but received ''"):
+ await async_client.tenants.account_types.with_raw_response.list(
+ "",
+ )
diff --git a/tests/api_resources/tenants/test_accounts.py b/tests/api_resources/tenants/test_accounts.py
new file mode 100644
index 00000000000..d953e879695
--- /dev/null
+++ b/tests/api_resources/tenants/test_accounts.py
@@ -0,0 +1,101 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare.pagination import SyncSinglePage, AsyncSinglePage
+from cloudflare.types.tenants import TenantAccount
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestAccounts:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_list(self, client: Cloudflare) -> None:
+ account = client.tenants.accounts.list(
+ "tenant_id",
+ )
+ assert_matches_type(SyncSinglePage[TenantAccount], account, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Cloudflare) -> None:
+ response = client.tenants.accounts.with_raw_response.list(
+ "tenant_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ account = response.parse()
+ assert_matches_type(SyncSinglePage[TenantAccount], account, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Cloudflare) -> None:
+ with client.tenants.accounts.with_streaming_response.list(
+ "tenant_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ account = response.parse()
+ assert_matches_type(SyncSinglePage[TenantAccount], account, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_list(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `tenant_id` but received ''"):
+ client.tenants.accounts.with_raw_response.list(
+ "",
+ )
+
+
+class TestAsyncAccounts:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncCloudflare) -> None:
+ account = await async_client.tenants.accounts.list(
+ "tenant_id",
+ )
+ assert_matches_type(AsyncSinglePage[TenantAccount], account, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.tenants.accounts.with_raw_response.list(
+ "tenant_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ account = await response.parse()
+ assert_matches_type(AsyncSinglePage[TenantAccount], account, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.tenants.accounts.with_streaming_response.list(
+ "tenant_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ account = await response.parse()
+ assert_matches_type(AsyncSinglePage[TenantAccount], account, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `tenant_id` but received ''"):
+ await async_client.tenants.accounts.with_raw_response.list(
+ "",
+ )
diff --git a/tests/api_resources/tenants/test_entitlements.py b/tests/api_resources/tenants/test_entitlements.py
new file mode 100644
index 00000000000..fce9a351a94
--- /dev/null
+++ b/tests/api_resources/tenants/test_entitlements.py
@@ -0,0 +1,100 @@
+# 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.tenants import TenantEntitlements
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestEntitlements:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_get(self, client: Cloudflare) -> None:
+ entitlement = client.tenants.entitlements.get(
+ "tenant_id",
+ )
+ assert_matches_type(TenantEntitlements, entitlement, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Cloudflare) -> None:
+ response = client.tenants.entitlements.with_raw_response.get(
+ "tenant_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ entitlement = response.parse()
+ assert_matches_type(TenantEntitlements, entitlement, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Cloudflare) -> None:
+ with client.tenants.entitlements.with_streaming_response.get(
+ "tenant_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ entitlement = response.parse()
+ assert_matches_type(TenantEntitlements, entitlement, 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 `tenant_id` but received ''"):
+ client.tenants.entitlements.with_raw_response.get(
+ "",
+ )
+
+
+class TestAsyncEntitlements:
+ 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:
+ entitlement = await async_client.tenants.entitlements.get(
+ "tenant_id",
+ )
+ assert_matches_type(TenantEntitlements, entitlement, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.tenants.entitlements.with_raw_response.get(
+ "tenant_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ entitlement = await response.parse()
+ assert_matches_type(TenantEntitlements, entitlement, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.tenants.entitlements.with_streaming_response.get(
+ "tenant_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ entitlement = await response.parse()
+ assert_matches_type(TenantEntitlements, entitlement, 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 `tenant_id` but received ''"):
+ await async_client.tenants.entitlements.with_raw_response.get(
+ "",
+ )
diff --git a/tests/api_resources/tenants/test_memberships.py b/tests/api_resources/tenants/test_memberships.py
new file mode 100644
index 00000000000..fd70477e87f
--- /dev/null
+++ b/tests/api_resources/tenants/test_memberships.py
@@ -0,0 +1,101 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare.pagination import SyncSinglePage, AsyncSinglePage
+from cloudflare.types.tenants import TenantMembership
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestMemberships:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_list(self, client: Cloudflare) -> None:
+ membership = client.tenants.memberships.list(
+ "tenant_id",
+ )
+ assert_matches_type(SyncSinglePage[TenantMembership], membership, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Cloudflare) -> None:
+ response = client.tenants.memberships.with_raw_response.list(
+ "tenant_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ membership = response.parse()
+ assert_matches_type(SyncSinglePage[TenantMembership], membership, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Cloudflare) -> None:
+ with client.tenants.memberships.with_streaming_response.list(
+ "tenant_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ membership = response.parse()
+ assert_matches_type(SyncSinglePage[TenantMembership], membership, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_list(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `tenant_id` but received ''"):
+ client.tenants.memberships.with_raw_response.list(
+ "",
+ )
+
+
+class TestAsyncMemberships:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncCloudflare) -> None:
+ membership = await async_client.tenants.memberships.list(
+ "tenant_id",
+ )
+ assert_matches_type(AsyncSinglePage[TenantMembership], membership, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.tenants.memberships.with_raw_response.list(
+ "tenant_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ membership = await response.parse()
+ assert_matches_type(AsyncSinglePage[TenantMembership], membership, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.tenants.memberships.with_streaming_response.list(
+ "tenant_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ membership = await response.parse()
+ assert_matches_type(AsyncSinglePage[TenantMembership], membership, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `tenant_id` but received ''"):
+ await async_client.tenants.memberships.with_raw_response.list(
+ "",
+ )
diff --git a/tests/api_resources/test_tenants.py b/tests/api_resources/test_tenants.py
new file mode 100644
index 00000000000..5b9b1ffb98a
--- /dev/null
+++ b/tests/api_resources/test_tenants.py
@@ -0,0 +1,100 @@
+# 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.tenants import Tenant
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestTenants:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_get(self, client: Cloudflare) -> None:
+ tenant = client.tenants.get(
+ "tenant_id",
+ )
+ assert_matches_type(Tenant, tenant, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Cloudflare) -> None:
+ response = client.tenants.with_raw_response.get(
+ "tenant_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ tenant = response.parse()
+ assert_matches_type(Tenant, tenant, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Cloudflare) -> None:
+ with client.tenants.with_streaming_response.get(
+ "tenant_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ tenant = response.parse()
+ assert_matches_type(Tenant, tenant, 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 `tenant_id` but received ''"):
+ client.tenants.with_raw_response.get(
+ "",
+ )
+
+
+class TestAsyncTenants:
+ 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:
+ tenant = await async_client.tenants.get(
+ "tenant_id",
+ )
+ assert_matches_type(Tenant, tenant, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.tenants.with_raw_response.get(
+ "tenant_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ tenant = await response.parse()
+ assert_matches_type(Tenant, tenant, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.tenants.with_streaming_response.get(
+ "tenant_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ tenant = await response.parse()
+ assert_matches_type(Tenant, tenant, 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 `tenant_id` but received ''"):
+ await async_client.tenants.with_raw_response.get(
+ "",
+ )
diff --git a/tests/api_resources/user/test_tenants.py b/tests/api_resources/user/test_tenants.py
new file mode 100644
index 00000000000..17e7b732394
--- /dev/null
+++ b/tests/api_resources/user/test_tenants.py
@@ -0,0 +1,75 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare.pagination import SyncSinglePage, AsyncSinglePage
+from cloudflare.types.organizations import Organization
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestTenants:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_list(self, client: Cloudflare) -> None:
+ tenant = client.user.tenants.list()
+ assert_matches_type(SyncSinglePage[Organization], tenant, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Cloudflare) -> None:
+ response = client.user.tenants.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ tenant = response.parse()
+ assert_matches_type(SyncSinglePage[Organization], tenant, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Cloudflare) -> None:
+ with client.user.tenants.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ tenant = response.parse()
+ assert_matches_type(SyncSinglePage[Organization], tenant, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncTenants:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncCloudflare) -> None:
+ tenant = await async_client.user.tenants.list()
+ assert_matches_type(AsyncSinglePage[Organization], tenant, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.user.tenants.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ tenant = await response.parse()
+ assert_matches_type(AsyncSinglePage[Organization], tenant, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.user.tenants.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ tenant = await response.parse()
+ assert_matches_type(AsyncSinglePage[Organization], tenant, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
From 5bb529c2eabe4ce0c23cddbf8073c6a025dc3024 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 12 Jun 2026 16:28:21 +0000
Subject: [PATCH 05/23] feat: feat(ct_alerter): add CT alerting subscription
endpoint mappings
* feat(ct_alerter): add CT alerting subscription endpoint mappings
---
.stats.yml | 6 +-
src/cloudflare/resources/zones/__init__.py | 14 +
src/cloudflare/resources/zones/api.md | 15 +
src/cloudflare/resources/zones/ct/__init__.py | 33 ++
src/cloudflare/resources/zones/ct/alerting.py | 321 ++++++++++++++++++
src/cloudflare/resources/zones/ct/ct.py | 102 ++++++
src/cloudflare/resources/zones/zones.py | 32 ++
src/cloudflare/types/zones/ct/__init__.py | 7 +
.../types/zones/ct/alerting_edit_params.py | 25 ++
.../types/zones/ct/alerting_edit_response.py | 22 ++
.../types/zones/ct/alerting_get_response.py | 22 ++
tests/api_resources/zones/ct/__init__.py | 1 +
tests/api_resources/zones/ct/test_alerting.py | 202 +++++++++++
13 files changed, 799 insertions(+), 3 deletions(-)
create mode 100644 src/cloudflare/resources/zones/ct/__init__.py
create mode 100644 src/cloudflare/resources/zones/ct/alerting.py
create mode 100644 src/cloudflare/resources/zones/ct/ct.py
create mode 100644 src/cloudflare/types/zones/ct/__init__.py
create mode 100644 src/cloudflare/types/zones/ct/alerting_edit_params.py
create mode 100644 src/cloudflare/types/zones/ct/alerting_edit_response.py
create mode 100644 src/cloudflare/types/zones/ct/alerting_get_response.py
create mode 100644 tests/api_resources/zones/ct/__init__.py
create mode 100644 tests/api_resources/zones/ct/test_alerting.py
diff --git a/.stats.yml b/.stats.yml
index 7a5ea3ca675..e6d0b45f66c 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 2382
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-cee99874469854ece2870d6467b8e2b37b96f773e0f706b974fad60c518f34c4.yml
+configured_endpoints: 2384
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-6012008a5e33c942c333948a76013de3cc2778fd81976766d0a8807c2904a4bb.yml
openapi_spec_hash: 7bfe2cfc93064c81db893a09bc1ba5c9
-config_hash: ec5b9d51fe96b49ca07d180985847027
+config_hash: fb7701532a56b6f947632365deb733af
diff --git a/src/cloudflare/resources/zones/__init__.py b/src/cloudflare/resources/zones/__init__.py
index 7233dc3b2e6..a1dbf0e266e 100644
--- a/src/cloudflare/resources/zones/__init__.py
+++ b/src/cloudflare/resources/zones/__init__.py
@@ -1,5 +1,13 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+from .ct import (
+ CTResource,
+ AsyncCTResource,
+ CTResourceWithRawResponse,
+ AsyncCTResourceWithRawResponse,
+ CTResourceWithStreamingResponse,
+ AsyncCTResourceWithStreamingResponse,
+)
from .holds import (
HoldsResource,
AsyncHoldsResource,
@@ -122,6 +130,12 @@
"AsyncRatePlansResourceWithRawResponse",
"RatePlansResourceWithStreamingResponse",
"AsyncRatePlansResourceWithStreamingResponse",
+ "CTResource",
+ "AsyncCTResource",
+ "CTResourceWithRawResponse",
+ "AsyncCTResourceWithRawResponse",
+ "CTResourceWithStreamingResponse",
+ "AsyncCTResourceWithStreamingResponse",
"ZonesResource",
"AsyncZonesResource",
"ZonesResourceWithRawResponse",
diff --git a/src/cloudflare/resources/zones/api.md b/src/cloudflare/resources/zones/api.md
index a6b73560a00..6db20ad0a99 100644
--- a/src/cloudflare/resources/zones/api.md
+++ b/src/cloudflare/resources/zones/api.md
@@ -186,3 +186,18 @@ from cloudflare.types.zones import RatePlanGetResponse
Methods:
- client.zones.rate_plans.get(\*, zone_id) -> SyncSinglePage[RatePlanGetResponse]
+
+## CT
+
+### Alerting
+
+Types:
+
+```python
+from cloudflare.types.zones.ct import AlertingEditResponse, AlertingGetResponse
+```
+
+Methods:
+
+- client.zones.ct.alerting.edit(\*, zone_id, \*\*params) -> Optional[AlertingEditResponse]
+- client.zones.ct.alerting.get(\*, zone_id) -> Optional[AlertingGetResponse]
diff --git a/src/cloudflare/resources/zones/ct/__init__.py b/src/cloudflare/resources/zones/ct/__init__.py
new file mode 100644
index 00000000000..a4cd108a8a7
--- /dev/null
+++ b/src/cloudflare/resources/zones/ct/__init__.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .ct import (
+ CTResource,
+ AsyncCTResource,
+ CTResourceWithRawResponse,
+ AsyncCTResourceWithRawResponse,
+ CTResourceWithStreamingResponse,
+ AsyncCTResourceWithStreamingResponse,
+)
+from .alerting import (
+ AlertingResource,
+ AsyncAlertingResource,
+ AlertingResourceWithRawResponse,
+ AsyncAlertingResourceWithRawResponse,
+ AlertingResourceWithStreamingResponse,
+ AsyncAlertingResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "AlertingResource",
+ "AsyncAlertingResource",
+ "AlertingResourceWithRawResponse",
+ "AsyncAlertingResourceWithRawResponse",
+ "AlertingResourceWithStreamingResponse",
+ "AsyncAlertingResourceWithStreamingResponse",
+ "CTResource",
+ "AsyncCTResource",
+ "CTResourceWithRawResponse",
+ "AsyncCTResourceWithRawResponse",
+ "CTResourceWithStreamingResponse",
+ "AsyncCTResourceWithStreamingResponse",
+]
diff --git a/src/cloudflare/resources/zones/ct/alerting.py b/src/cloudflare/resources/zones/ct/alerting.py
new file mode 100644
index 00000000000..67d6df6dcd1
--- /dev/null
+++ b/src/cloudflare/resources/zones/ct/alerting.py
@@ -0,0 +1,321 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Type, Optional, cast
+
+import httpx
+
+from ...._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
+from ...._utils import path_template, maybe_transform, async_maybe_transform
+from ...._compat import cached_property
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from ...._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ...._wrappers import ResultWrapper
+from ...._base_client import make_request_options
+from ....types.zones.ct import alerting_edit_params
+from ....types.zones.ct.alerting_get_response import AlertingGetResponse
+from ....types.zones.ct.alerting_edit_response import AlertingEditResponse
+
+__all__ = ["AlertingResource", "AsyncAlertingResource"]
+
+
+class AlertingResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AlertingResourceWithRawResponse:
+ """
+ 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 AlertingResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AlertingResourceWithStreamingResponse:
+ """
+ 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 AlertingResourceWithStreamingResponse(self)
+
+ def edit(
+ self,
+ *,
+ zone_id: str,
+ enabled: bool,
+ emails: SequenceNotStr[str] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[AlertingEditResponse]:
+ """
+ Create or update the Certificate Transparency alerting subscription for a zone.
+ Enables or disables email notifications when certificates are issued for the
+ zone's domains. For Free and Pro zones, the subscription is toggled on or off
+ using the enabled field. Notification emails are sent to all users with SSL
+ permissions on the zone. For Business and Enterprise zones, the emails field is
+ required and controls which addresses receive alerts. Setting emails to an empty
+ list disables the subscription regardless of the enabled field. A maximum of 10
+ email addresses may be configured.
+
+ Args:
+ zone_id: Identifier.
+
+ enabled: Whether CT alerting is enabled for the zone.
+
+ emails: Email addresses that receive CT alert notifications. Only present and
+ configurable for Business and Enterprise zones. Maximum of 10 addresses. For
+ Free and Pro zones, notifications are sent to all users with SSL permissions on
+ the zone.
+
+ 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 zone_id:
+ raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
+ return self._patch(
+ path_template("/zones/{zone_id}/ct/alerting", zone_id=zone_id),
+ body=maybe_transform(
+ {
+ "enabled": enabled,
+ "emails": emails,
+ },
+ alerting_edit_params.AlertingEditParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[AlertingEditResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[AlertingEditResponse]], ResultWrapper[AlertingEditResponse]),
+ )
+
+ def get(
+ self,
+ *,
+ zone_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[AlertingGetResponse]:
+ """
+ Retrieve the Certificate Transparency alerting subscription settings for a zone.
+ Returns whether CT monitoring is enabled and, for Business and Enterprise zones,
+ the list of email addresses that receive alerts.
+
+ Args:
+ zone_id: 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 zone_id:
+ raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
+ return self._get(
+ path_template("/zones/{zone_id}/ct/alerting", zone_id=zone_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[AlertingGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[AlertingGetResponse]], ResultWrapper[AlertingGetResponse]),
+ )
+
+
+class AsyncAlertingResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncAlertingResourceWithRawResponse:
+ """
+ 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 AsyncAlertingResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncAlertingResourceWithStreamingResponse:
+ """
+ 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 AsyncAlertingResourceWithStreamingResponse(self)
+
+ async def edit(
+ self,
+ *,
+ zone_id: str,
+ enabled: bool,
+ emails: SequenceNotStr[str] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[AlertingEditResponse]:
+ """
+ Create or update the Certificate Transparency alerting subscription for a zone.
+ Enables or disables email notifications when certificates are issued for the
+ zone's domains. For Free and Pro zones, the subscription is toggled on or off
+ using the enabled field. Notification emails are sent to all users with SSL
+ permissions on the zone. For Business and Enterprise zones, the emails field is
+ required and controls which addresses receive alerts. Setting emails to an empty
+ list disables the subscription regardless of the enabled field. A maximum of 10
+ email addresses may be configured.
+
+ Args:
+ zone_id: Identifier.
+
+ enabled: Whether CT alerting is enabled for the zone.
+
+ emails: Email addresses that receive CT alert notifications. Only present and
+ configurable for Business and Enterprise zones. Maximum of 10 addresses. For
+ Free and Pro zones, notifications are sent to all users with SSL permissions on
+ the zone.
+
+ 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 zone_id:
+ raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
+ return await self._patch(
+ path_template("/zones/{zone_id}/ct/alerting", zone_id=zone_id),
+ body=await async_maybe_transform(
+ {
+ "enabled": enabled,
+ "emails": emails,
+ },
+ alerting_edit_params.AlertingEditParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[AlertingEditResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[AlertingEditResponse]], ResultWrapper[AlertingEditResponse]),
+ )
+
+ async def get(
+ self,
+ *,
+ zone_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[AlertingGetResponse]:
+ """
+ Retrieve the Certificate Transparency alerting subscription settings for a zone.
+ Returns whether CT monitoring is enabled and, for Business and Enterprise zones,
+ the list of email addresses that receive alerts.
+
+ Args:
+ zone_id: 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 zone_id:
+ raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
+ return await self._get(
+ path_template("/zones/{zone_id}/ct/alerting", zone_id=zone_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[AlertingGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[AlertingGetResponse]], ResultWrapper[AlertingGetResponse]),
+ )
+
+
+class AlertingResourceWithRawResponse:
+ def __init__(self, alerting: AlertingResource) -> None:
+ self._alerting = alerting
+
+ self.edit = to_raw_response_wrapper(
+ alerting.edit,
+ )
+ self.get = to_raw_response_wrapper(
+ alerting.get,
+ )
+
+
+class AsyncAlertingResourceWithRawResponse:
+ def __init__(self, alerting: AsyncAlertingResource) -> None:
+ self._alerting = alerting
+
+ self.edit = async_to_raw_response_wrapper(
+ alerting.edit,
+ )
+ self.get = async_to_raw_response_wrapper(
+ alerting.get,
+ )
+
+
+class AlertingResourceWithStreamingResponse:
+ def __init__(self, alerting: AlertingResource) -> None:
+ self._alerting = alerting
+
+ self.edit = to_streamed_response_wrapper(
+ alerting.edit,
+ )
+ self.get = to_streamed_response_wrapper(
+ alerting.get,
+ )
+
+
+class AsyncAlertingResourceWithStreamingResponse:
+ def __init__(self, alerting: AsyncAlertingResource) -> None:
+ self._alerting = alerting
+
+ self.edit = async_to_streamed_response_wrapper(
+ alerting.edit,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ alerting.get,
+ )
diff --git a/src/cloudflare/resources/zones/ct/ct.py b/src/cloudflare/resources/zones/ct/ct.py
new file mode 100644
index 00000000000..9c5ee575f93
--- /dev/null
+++ b/src/cloudflare/resources/zones/ct/ct.py
@@ -0,0 +1,102 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .alerting import (
+ AlertingResource,
+ AsyncAlertingResource,
+ AlertingResourceWithRawResponse,
+ AsyncAlertingResourceWithRawResponse,
+ AlertingResourceWithStreamingResponse,
+ AsyncAlertingResourceWithStreamingResponse,
+)
+from ...._compat import cached_property
+from ...._resource import SyncAPIResource, AsyncAPIResource
+
+__all__ = ["CTResource", "AsyncCTResource"]
+
+
+class CTResource(SyncAPIResource):
+ @cached_property
+ def alerting(self) -> AlertingResource:
+ return AlertingResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> CTResourceWithRawResponse:
+ """
+ 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 CTResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> CTResourceWithStreamingResponse:
+ """
+ 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 CTResourceWithStreamingResponse(self)
+
+
+class AsyncCTResource(AsyncAPIResource):
+ @cached_property
+ def alerting(self) -> AsyncAlertingResource:
+ return AsyncAlertingResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncCTResourceWithRawResponse:
+ """
+ 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 AsyncCTResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncCTResourceWithStreamingResponse:
+ """
+ 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 AsyncCTResourceWithStreamingResponse(self)
+
+
+class CTResourceWithRawResponse:
+ def __init__(self, ct: CTResource) -> None:
+ self._ct = ct
+
+ @cached_property
+ def alerting(self) -> AlertingResourceWithRawResponse:
+ return AlertingResourceWithRawResponse(self._ct.alerting)
+
+
+class AsyncCTResourceWithRawResponse:
+ def __init__(self, ct: AsyncCTResource) -> None:
+ self._ct = ct
+
+ @cached_property
+ def alerting(self) -> AsyncAlertingResourceWithRawResponse:
+ return AsyncAlertingResourceWithRawResponse(self._ct.alerting)
+
+
+class CTResourceWithStreamingResponse:
+ def __init__(self, ct: CTResource) -> None:
+ self._ct = ct
+
+ @cached_property
+ def alerting(self) -> AlertingResourceWithStreamingResponse:
+ return AlertingResourceWithStreamingResponse(self._ct.alerting)
+
+
+class AsyncCTResourceWithStreamingResponse:
+ def __init__(self, ct: AsyncCTResource) -> None:
+ self._ct = ct
+
+ @cached_property
+ def alerting(self) -> AsyncAlertingResourceWithStreamingResponse:
+ return AsyncAlertingResourceWithStreamingResponse(self._ct.alerting)
diff --git a/src/cloudflare/resources/zones/zones.py b/src/cloudflare/resources/zones/zones.py
index ceba8dfd843..0e7551eda3f 100644
--- a/src/cloudflare/resources/zones/zones.py
+++ b/src/cloudflare/resources/zones/zones.py
@@ -7,6 +7,14 @@
import httpx
+from .ct.ct import (
+ CTResource,
+ AsyncCTResource,
+ CTResourceWithRawResponse,
+ AsyncCTResourceWithRawResponse,
+ CTResourceWithStreamingResponse,
+ AsyncCTResourceWithStreamingResponse,
+)
from .holds import (
HoldsResource,
AsyncHoldsResource,
@@ -125,6 +133,10 @@ def plans(self) -> PlansResource:
def rate_plans(self) -> RatePlansResource:
return RatePlansResource(self._client)
+ @cached_property
+ def ct(self) -> CTResource:
+ return CTResource(self._client)
+
@cached_property
def with_raw_response(self) -> ZonesResourceWithRawResponse:
"""
@@ -459,6 +471,10 @@ def plans(self) -> AsyncPlansResource:
def rate_plans(self) -> AsyncRatePlansResource:
return AsyncRatePlansResource(self._client)
+ @cached_property
+ def ct(self) -> AsyncCTResource:
+ return AsyncCTResource(self._client)
+
@cached_property
def with_raw_response(self) -> AsyncZonesResourceWithRawResponse:
"""
@@ -812,6 +828,10 @@ def plans(self) -> PlansResourceWithRawResponse:
def rate_plans(self) -> RatePlansResourceWithRawResponse:
return RatePlansResourceWithRawResponse(self._zones.rate_plans)
+ @cached_property
+ def ct(self) -> CTResourceWithRawResponse:
+ return CTResourceWithRawResponse(self._zones.ct)
+
class AsyncZonesResourceWithRawResponse:
def __init__(self, zones: AsyncZonesResource) -> None:
@@ -865,6 +885,10 @@ def plans(self) -> AsyncPlansResourceWithRawResponse:
def rate_plans(self) -> AsyncRatePlansResourceWithRawResponse:
return AsyncRatePlansResourceWithRawResponse(self._zones.rate_plans)
+ @cached_property
+ def ct(self) -> AsyncCTResourceWithRawResponse:
+ return AsyncCTResourceWithRawResponse(self._zones.ct)
+
class ZonesResourceWithStreamingResponse:
def __init__(self, zones: ZonesResource) -> None:
@@ -918,6 +942,10 @@ def plans(self) -> PlansResourceWithStreamingResponse:
def rate_plans(self) -> RatePlansResourceWithStreamingResponse:
return RatePlansResourceWithStreamingResponse(self._zones.rate_plans)
+ @cached_property
+ def ct(self) -> CTResourceWithStreamingResponse:
+ return CTResourceWithStreamingResponse(self._zones.ct)
+
class AsyncZonesResourceWithStreamingResponse:
def __init__(self, zones: AsyncZonesResource) -> None:
@@ -970,3 +998,7 @@ def plans(self) -> AsyncPlansResourceWithStreamingResponse:
@cached_property
def rate_plans(self) -> AsyncRatePlansResourceWithStreamingResponse:
return AsyncRatePlansResourceWithStreamingResponse(self._zones.rate_plans)
+
+ @cached_property
+ def ct(self) -> AsyncCTResourceWithStreamingResponse:
+ return AsyncCTResourceWithStreamingResponse(self._zones.ct)
diff --git a/src/cloudflare/types/zones/ct/__init__.py b/src/cloudflare/types/zones/ct/__init__.py
new file mode 100644
index 00000000000..909a687ec71
--- /dev/null
+++ b/src/cloudflare/types/zones/ct/__init__.py
@@ -0,0 +1,7 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .alerting_edit_params import AlertingEditParams as AlertingEditParams
+from .alerting_get_response import AlertingGetResponse as AlertingGetResponse
+from .alerting_edit_response import AlertingEditResponse as AlertingEditResponse
diff --git a/src/cloudflare/types/zones/ct/alerting_edit_params.py b/src/cloudflare/types/zones/ct/alerting_edit_params.py
new file mode 100644
index 00000000000..b3d6a8e947f
--- /dev/null
+++ b/src/cloudflare/types/zones/ct/alerting_edit_params.py
@@ -0,0 +1,25 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+from ...._types import SequenceNotStr
+
+__all__ = ["AlertingEditParams"]
+
+
+class AlertingEditParams(TypedDict, total=False):
+ zone_id: Required[str]
+ """Identifier."""
+
+ enabled: Required[bool]
+ """Whether CT alerting is enabled for the zone."""
+
+ emails: SequenceNotStr[str]
+ """Email addresses that receive CT alert notifications.
+
+ Only present and configurable for Business and Enterprise zones. Maximum of 10
+ addresses. For Free and Pro zones, notifications are sent to all users with SSL
+ permissions on the zone.
+ """
diff --git a/src/cloudflare/types/zones/ct/alerting_edit_response.py b/src/cloudflare/types/zones/ct/alerting_edit_response.py
new file mode 100644
index 00000000000..e855753cb2b
--- /dev/null
+++ b/src/cloudflare/types/zones/ct/alerting_edit_response.py
@@ -0,0 +1,22 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+
+from ...._models import BaseModel
+
+__all__ = ["AlertingEditResponse"]
+
+
+class AlertingEditResponse(BaseModel):
+ """Certificate Transparency alerting subscription settings for a zone."""
+
+ enabled: bool
+ """Whether CT alerting is enabled for the zone."""
+
+ emails: Optional[List[str]] = None
+ """Email addresses that receive CT alert notifications.
+
+ Only present and configurable for Business and Enterprise zones. Maximum of 10
+ addresses. For Free and Pro zones, notifications are sent to all users with SSL
+ permissions on the zone.
+ """
diff --git a/src/cloudflare/types/zones/ct/alerting_get_response.py b/src/cloudflare/types/zones/ct/alerting_get_response.py
new file mode 100644
index 00000000000..9f99c606452
--- /dev/null
+++ b/src/cloudflare/types/zones/ct/alerting_get_response.py
@@ -0,0 +1,22 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+
+from ...._models import BaseModel
+
+__all__ = ["AlertingGetResponse"]
+
+
+class AlertingGetResponse(BaseModel):
+ """Certificate Transparency alerting subscription settings for a zone."""
+
+ enabled: bool
+ """Whether CT alerting is enabled for the zone."""
+
+ emails: Optional[List[str]] = None
+ """Email addresses that receive CT alert notifications.
+
+ Only present and configurable for Business and Enterprise zones. Maximum of 10
+ addresses. For Free and Pro zones, notifications are sent to all users with SSL
+ permissions on the zone.
+ """
diff --git a/tests/api_resources/zones/ct/__init__.py b/tests/api_resources/zones/ct/__init__.py
new file mode 100644
index 00000000000..fd8019a9a1a
--- /dev/null
+++ b/tests/api_resources/zones/ct/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/zones/ct/test_alerting.py b/tests/api_resources/zones/ct/test_alerting.py
new file mode 100644
index 00000000000..da5a5520f63
--- /dev/null
+++ b/tests/api_resources/zones/ct/test_alerting.py
@@ -0,0 +1,202 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, Optional, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare.types.zones.ct import AlertingGetResponse, AlertingEditResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestAlerting:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_edit(self, client: Cloudflare) -> None:
+ alerting = client.zones.ct.alerting.edit(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ enabled=True,
+ )
+ assert_matches_type(Optional[AlertingEditResponse], alerting, path=["response"])
+
+ @parametrize
+ def test_method_edit_with_all_params(self, client: Cloudflare) -> None:
+ alerting = client.zones.ct.alerting.edit(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ enabled=True,
+ emails=["security@example.com", "admin@example.com"],
+ )
+ assert_matches_type(Optional[AlertingEditResponse], alerting, path=["response"])
+
+ @parametrize
+ def test_raw_response_edit(self, client: Cloudflare) -> None:
+ response = client.zones.ct.alerting.with_raw_response.edit(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ enabled=True,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ alerting = response.parse()
+ assert_matches_type(Optional[AlertingEditResponse], alerting, path=["response"])
+
+ @parametrize
+ def test_streaming_response_edit(self, client: Cloudflare) -> None:
+ with client.zones.ct.alerting.with_streaming_response.edit(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ enabled=True,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ alerting = response.parse()
+ assert_matches_type(Optional[AlertingEditResponse], alerting, 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 `zone_id` but received ''"):
+ client.zones.ct.alerting.with_raw_response.edit(
+ zone_id="",
+ enabled=True,
+ )
+
+ @parametrize
+ def test_method_get(self, client: Cloudflare) -> None:
+ alerting = client.zones.ct.alerting.get(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[AlertingGetResponse], alerting, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Cloudflare) -> None:
+ response = client.zones.ct.alerting.with_raw_response.get(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ alerting = response.parse()
+ assert_matches_type(Optional[AlertingGetResponse], alerting, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Cloudflare) -> None:
+ with client.zones.ct.alerting.with_streaming_response.get(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ alerting = response.parse()
+ assert_matches_type(Optional[AlertingGetResponse], alerting, 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 `zone_id` but received ''"):
+ client.zones.ct.alerting.with_raw_response.get(
+ zone_id="",
+ )
+
+
+class TestAsyncAlerting:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_edit(self, async_client: AsyncCloudflare) -> None:
+ alerting = await async_client.zones.ct.alerting.edit(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ enabled=True,
+ )
+ assert_matches_type(Optional[AlertingEditResponse], alerting, path=["response"])
+
+ @parametrize
+ async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ alerting = await async_client.zones.ct.alerting.edit(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ enabled=True,
+ emails=["security@example.com", "admin@example.com"],
+ )
+ assert_matches_type(Optional[AlertingEditResponse], alerting, path=["response"])
+
+ @parametrize
+ async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zones.ct.alerting.with_raw_response.edit(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ enabled=True,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ alerting = await response.parse()
+ assert_matches_type(Optional[AlertingEditResponse], alerting, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zones.ct.alerting.with_streaming_response.edit(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ enabled=True,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ alerting = await response.parse()
+ assert_matches_type(Optional[AlertingEditResponse], alerting, 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 `zone_id` but received ''"):
+ await async_client.zones.ct.alerting.with_raw_response.edit(
+ zone_id="",
+ enabled=True,
+ )
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncCloudflare) -> None:
+ alerting = await async_client.zones.ct.alerting.get(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[AlertingGetResponse], alerting, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zones.ct.alerting.with_raw_response.get(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ alerting = await response.parse()
+ assert_matches_type(Optional[AlertingGetResponse], alerting, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zones.ct.alerting.with_streaming_response.get(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ alerting = await response.parse()
+ assert_matches_type(Optional[AlertingGetResponse], alerting, 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 `zone_id` but received ''"):
+ await async_client.zones.ct.alerting.with_raw_response.get(
+ zone_id="",
+ )
From 14409ae57215d40d8982f2d54ff468ee55f0d9e2 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 12 Jun 2026 16:34:23 +0000
Subject: [PATCH 06/23] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index e6d0b45f66c..520f40d4b19 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 2384
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-6012008a5e33c942c333948a76013de3cc2778fd81976766d0a8807c2904a4bb.yml
-openapi_spec_hash: 7bfe2cfc93064c81db893a09bc1ba5c9
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-26f2b8a62b20eb7829a0f63fd151e0d686ecd8a74df0de92dca619d9be4e56c3.yml
+openapi_spec_hash: 57e8c989b187e750d4e452107a366012
config_hash: fb7701532a56b6f947632365deb733af
From 04f9feedb6d7486c1dd9bd5e497d67f9007b937a Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 13 Jun 2026 16:01:04 +0000
Subject: [PATCH 07/23] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 520f40d4b19..a8ab7c81ac9 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 2384
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-26f2b8a62b20eb7829a0f63fd151e0d686ecd8a74df0de92dca619d9be4e56c3.yml
-openapi_spec_hash: 57e8c989b187e750d4e452107a366012
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-186ce298b2b9100c3a2c715676ef88496e55851386a813fe48a23f9f2027d611.yml
+openapi_spec_hash: 4c42b2bb7e243c211a3d7190293deb80
config_hash: fb7701532a56b6f947632365deb733af
From 2fcdb132488eb2e2c16e893e6c65dd52a057b0ed Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 13 Jun 2026 17:22:09 +0000
Subject: [PATCH 08/23] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index a8ab7c81ac9..ebfd6c7c716 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 2384
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-186ce298b2b9100c3a2c715676ef88496e55851386a813fe48a23f9f2027d611.yml
-openapi_spec_hash: 4c42b2bb7e243c211a3d7190293deb80
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-9b61446b55171aa38da18b38e810faa3e20849eb411dd9e117e4024fc6bb7b79.yml
+openapi_spec_hash: 6086f90449d79fc36b2f7b1ee73ccc9b
config_hash: fb7701532a56b6f947632365deb733af
From 16d8e61409044d13b9ed94a46b4afbf69dd8caaf Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 15 Jun 2026 10:51:15 +0000
Subject: [PATCH 09/23] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index ebfd6c7c716..dd3ba7c40f0 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 2384
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-9b61446b55171aa38da18b38e810faa3e20849eb411dd9e117e4024fc6bb7b79.yml
-openapi_spec_hash: 6086f90449d79fc36b2f7b1ee73ccc9b
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-25de2cebd5c7324cf3baadd40bd56b09214a47e228122dfdb8c3fdaeeea2d792.yml
+openapi_spec_hash: a83153022e4ef3e4ba6b295d4b053ca3
config_hash: fb7701532a56b6f947632365deb733af
From eeec39a7ab478625ead7a1e6276c1c258ff574fd Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 15 Jun 2026 15:16:49 +0000
Subject: [PATCH 10/23] chore(api): update composite API spec
---
.stats.yml | 4 ++--
src/cloudflare/resources/radar/ai/inference/inference.py | 8 ++++----
src/cloudflare/resources/radar/ai/inference/summary.py | 8 ++++----
.../radar/ai/inference/timeseries_groups/summary.py | 8 ++++----
src/cloudflare/types/radar/ai/bot_summary_v2_response.py | 4 +++-
.../types/radar/ai/bot_timeseries_groups_response.py | 4 +++-
src/cloudflare/types/radar/ai/bot_timeseries_response.py | 4 +++-
.../types/radar/ai/bots/summary_user_agent_response.py | 4 +++-
.../types/radar/ai/inference/summary_model_response.py | 4 +++-
.../types/radar/ai/inference/summary_task_response.py | 4 +++-
.../timeseries_groups/summary_model_response.py | 4 +++-
.../inference/timeseries_groups/summary_task_response.py | 4 +++-
.../types/radar/ai/inference_summary_v2_response.py | 4 +++-
.../radar/ai/inference_timeseries_groups_v2_response.py | 4 +++-
.../radar/ai/markdown_for_agent_summary_response.py | 4 +++-
.../radar/ai/markdown_for_agent_timeseries_response.py | 4 +++-
.../types/radar/ai/timeseries_group_summary_response.py | 4 +++-
.../ai/timeseries_group_timeseries_groups_response.py | 4 +++-
.../radar/ai/timeseries_group_timeseries_response.py | 4 +++-
.../radar/ai/timeseries_group_user_agent_response.py | 4 +++-
.../types/radar/as112/summary_dnssec_response.py | 4 +++-
.../types/radar/as112/summary_edns_response.py | 4 +++-
.../types/radar/as112/summary_ip_version_response.py | 4 +++-
.../types/radar/as112/summary_protocol_response.py | 4 +++-
.../types/radar/as112/summary_query_type_response.py | 4 +++-
.../types/radar/as112/summary_response_codes_response.py | 4 +++-
.../radar/as112/timeseries_group_dnssec_response.py | 4 +++-
.../types/radar/as112/timeseries_group_edns_response.py | 4 +++-
.../radar/as112/timeseries_group_ip_version_response.py | 4 +++-
.../radar/as112/timeseries_group_protocol_response.py | 4 +++-
.../radar/as112/timeseries_group_query_type_response.py | 4 +++-
.../as112/timeseries_group_response_codes_response.py | 4 +++-
src/cloudflare/types/radar/as112/top_dnssec_response.py | 2 ++
src/cloudflare/types/radar/as112/top_edns_response.py | 2 ++
.../types/radar/as112/top_ip_version_response.py | 2 ++
.../types/radar/as112/top_locations_response.py | 2 ++
src/cloudflare/types/radar/as112_summary_v2_response.py | 4 +++-
.../types/radar/as112_timeseries_groups_v2_response.py | 4 +++-
src/cloudflare/types/radar/as112_timeseries_response.py | 4 +++-
.../radar/attacks/layer3/summary_bitrate_response.py | 4 +++-
.../radar/attacks/layer3/summary_duration_response.py | 4 +++-
.../radar/attacks/layer3/summary_industry_response.py | 4 +++-
.../radar/attacks/layer3/summary_ip_version_response.py | 4 +++-
.../radar/attacks/layer3/summary_protocol_response.py | 4 +++-
.../radar/attacks/layer3/summary_vector_response.py | 4 +++-
.../radar/attacks/layer3/summary_vertical_response.py | 4 +++-
.../attacks/layer3/timeseries_group_bitrate_response.py | 4 +++-
.../attacks/layer3/timeseries_group_duration_response.py | 4 +++-
.../attacks/layer3/timeseries_group_industry_response.py | 4 +++-
.../layer3/timeseries_group_ip_version_response.py | 4 +++-
.../attacks/layer3/timeseries_group_protocol_response.py | 4 +++-
.../attacks/layer3/timeseries_group_vector_response.py | 4 +++-
.../attacks/layer3/timeseries_group_vertical_response.py | 4 +++-
.../radar/attacks/layer3/top/location_origin_response.py | 2 ++
.../radar/attacks/layer3/top/location_target_response.py | 2 ++
.../types/radar/attacks/layer3/top_attacks_response.py | 2 ++
.../types/radar/attacks/layer3/top_industry_response.py | 2 ++
.../types/radar/attacks/layer3/top_vertical_response.py | 2 ++
.../types/radar/attacks/layer3_summary_v2_response.py | 4 +++-
.../attacks/layer3_timeseries_groups_v2_response.py | 4 +++-
.../types/radar/attacks/layer3_timeseries_response.py | 4 +++-
.../radar/attacks/layer7/summary_http_method_response.py | 4 +++-
.../attacks/layer7/summary_http_version_response.py | 4 +++-
.../radar/attacks/layer7/summary_industry_response.py | 4 +++-
.../radar/attacks/layer7/summary_ip_version_response.py | 4 +++-
.../attacks/layer7/summary_managed_rules_response.py | 4 +++-
.../layer7/summary_mitigation_product_response.py | 4 +++-
.../radar/attacks/layer7/summary_vertical_response.py | 4 +++-
.../layer7/timeseries_group_http_method_response.py | 4 +++-
.../layer7/timeseries_group_http_version_response.py | 4 +++-
.../attacks/layer7/timeseries_group_industry_response.py | 4 +++-
.../layer7/timeseries_group_ip_version_response.py | 4 +++-
.../layer7/timeseries_group_managed_rules_response.py | 4 +++-
.../timeseries_group_mitigation_product_response.py | 4 +++-
.../attacks/layer7/timeseries_group_vertical_response.py | 4 +++-
.../radar/attacks/layer7/top/ase_origin_response.py | 2 ++
.../radar/attacks/layer7/top/location_origin_response.py | 2 ++
.../radar/attacks/layer7/top/location_target_response.py | 2 ++
.../types/radar/attacks/layer7/top_attacks_response.py | 2 ++
.../types/radar/attacks/layer7/top_industry_response.py | 2 ++
.../types/radar/attacks/layer7/top_vertical_response.py | 2 ++
.../types/radar/attacks/layer7_summary_v2_response.py | 4 +++-
.../attacks/layer7_timeseries_groups_v2_response.py | 4 +++-
.../types/radar/attacks/layer7_timeseries_response.py | 4 +++-
src/cloudflare/types/radar/bgp/ip_timeseries_response.py | 2 ++
src/cloudflare/types/radar/bgp_timeseries_response.py | 4 +++-
src/cloudflare/types/radar/bot_summary_response.py | 4 +++-
.../types/radar/bot_timeseries_groups_response.py | 4 +++-
src/cloudflare/types/radar/bot_timeseries_response.py | 4 +++-
.../types/radar/bots/web_crawler_summary_response.py | 4 +++-
.../radar/bots/web_crawler_timeseries_groups_response.py | 4 +++-
src/cloudflare/types/radar/ct_summary_response.py | 4 +++-
.../types/radar/ct_timeseries_groups_response.py | 4 +++-
src/cloudflare/types/radar/ct_timeseries_response.py | 4 +++-
.../types/radar/dns/summary_cache_hit_response.py | 4 +++-
.../types/radar/dns/summary_dnssec_aware_response.py | 4 +++-
.../types/radar/dns/summary_dnssec_e2e_response.py | 4 +++-
.../types/radar/dns/summary_dnssec_response.py | 4 +++-
.../types/radar/dns/summary_ip_version_response.py | 4 +++-
.../types/radar/dns/summary_matching_answer_response.py | 4 +++-
.../types/radar/dns/summary_protocol_response.py | 4 +++-
.../types/radar/dns/summary_query_type_response.py | 4 +++-
.../types/radar/dns/summary_response_code_response.py | 4 +++-
.../types/radar/dns/summary_response_ttl_response.py | 4 +++-
.../radar/dns/timeseries_group_cache_hit_response.py | 4 +++-
.../radar/dns/timeseries_group_dnssec_aware_response.py | 4 +++-
.../radar/dns/timeseries_group_dnssec_e2e_response.py | 4 +++-
.../types/radar/dns/timeseries_group_dnssec_response.py | 4 +++-
.../radar/dns/timeseries_group_ip_version_response.py | 4 +++-
.../dns/timeseries_group_matching_answer_response.py | 4 +++-
.../radar/dns/timeseries_group_protocol_response.py | 4 +++-
.../radar/dns/timeseries_group_query_type_response.py | 4 +++-
.../radar/dns/timeseries_group_response_code_response.py | 4 +++-
.../radar/dns/timeseries_group_response_ttl_response.py | 4 +++-
src/cloudflare/types/radar/dns/top_ases_response.py | 2 ++
src/cloudflare/types/radar/dns/top_locations_response.py | 2 ++
src/cloudflare/types/radar/dns_summary_v2_response.py | 4 +++-
.../types/radar/dns_timeseries_groups_v2_response.py | 4 +++-
src/cloudflare/types/radar/dns_timeseries_response.py | 4 +++-
.../types/radar/email/routing/summary_arc_response.py | 4 +++-
.../types/radar/email/routing/summary_dkim_response.py | 4 +++-
.../types/radar/email/routing/summary_dmarc_response.py | 4 +++-
.../radar/email/routing/summary_encrypted_response.py | 4 +++-
.../radar/email/routing/summary_ip_version_response.py | 4 +++-
.../types/radar/email/routing/summary_spf_response.py | 4 +++-
.../radar/email/routing/timeseries_group_arc_response.py | 4 +++-
.../email/routing/timeseries_group_dkim_response.py | 4 +++-
.../email/routing/timeseries_group_dmarc_response.py | 4 +++-
.../email/routing/timeseries_group_encrypted_response.py | 4 +++-
.../routing/timeseries_group_ip_version_response.py | 4 +++-
.../radar/email/routing/timeseries_group_spf_response.py | 4 +++-
.../types/radar/email/routing_summary_v2_response.py | 4 +++-
.../radar/email/routing_timeseries_groups_v2_response.py | 4 +++-
.../types/radar/email/security/summary_arc_response.py | 4 +++-
.../types/radar/email/security/summary_dkim_response.py | 4 +++-
.../types/radar/email/security/summary_dmarc_response.py | 4 +++-
.../radar/email/security/summary_malicious_response.py | 4 +++-
.../types/radar/email/security/summary_spam_response.py | 4 +++-
.../types/radar/email/security/summary_spf_response.py | 4 +++-
.../types/radar/email/security/summary_spoof_response.py | 4 +++-
.../email/security/summary_threat_category_response.py | 4 +++-
.../radar/email/security/summary_tls_version_response.py | 4 +++-
.../email/security/timeseries_group_arc_response.py | 4 +++-
.../email/security/timeseries_group_dkim_response.py | 4 +++-
.../email/security/timeseries_group_dmarc_response.py | 4 +++-
.../security/timeseries_group_malicious_response.py | 4 +++-
.../email/security/timeseries_group_spam_response.py | 4 +++-
.../email/security/timeseries_group_spf_response.py | 4 +++-
.../email/security/timeseries_group_spoof_response.py | 4 +++-
.../timeseries_group_threat_category_response.py | 4 +++-
.../security/timeseries_group_tls_version_response.py | 4 +++-
.../types/radar/email/security/top/tld_get_response.py | 2 ++
.../email/security/top/tlds/malicious_get_response.py | 2 ++
.../radar/email/security/top/tlds/spam_get_response.py | 2 ++
.../radar/email/security/top/tlds/spoof_get_response.py | 2 ++
.../types/radar/email/security_summary_v2_response.py | 4 +++-
.../email/security_timeseries_groups_v2_response.py | 4 +++-
src/cloudflare/types/radar/entities/asn_list_response.py | 9 ++++++++-
src/cloudflare/types/radar/http/ase_get_response.py | 2 ++
.../types/radar/http/ases/bot_class_get_response.py | 2 ++
.../types/radar/http/ases/browser_family_get_response.py | 2 ++
.../types/radar/http/ases/device_type_get_response.py | 2 ++
.../types/radar/http/ases/http_method_get_response.py | 2 ++
.../types/radar/http/ases/http_protocol_get_response.py | 2 ++
.../types/radar/http/ases/ip_version_get_response.py | 2 ++
src/cloudflare/types/radar/http/ases/os_get_response.py | 2 ++
.../types/radar/http/ases/tls_version_get_response.py | 2 ++
src/cloudflare/types/radar/http/location_get_response.py | 2 ++
.../types/radar/http/locations/bot_class_get_response.py | 2 ++
.../radar/http/locations/browser_family_get_response.py | 2 ++
.../radar/http/locations/device_type_get_response.py | 2 ++
.../radar/http/locations/http_method_get_response.py | 2 ++
.../radar/http/locations/http_protocol_get_response.py | 2 ++
.../radar/http/locations/ip_version_get_response.py | 2 ++
.../types/radar/http/locations/os_get_response.py | 2 ++
.../radar/http/locations/tls_version_get_response.py | 2 ++
.../types/radar/http/summary_bot_class_response.py | 4 +++-
.../types/radar/http/summary_device_type_response.py | 4 +++-
.../types/radar/http/summary_http_protocol_response.py | 4 +++-
.../types/radar/http/summary_http_version_response.py | 4 +++-
.../types/radar/http/summary_ip_version_response.py | 4 +++-
src/cloudflare/types/radar/http/summary_os_response.py | 4 +++-
.../types/radar/http/summary_post_quantum_response.py | 4 +++-
.../types/radar/http/summary_tls_version_response.py | 4 +++-
.../radar/http/timeseries_group_bot_class_response.py | 4 +++-
.../http/timeseries_group_browser_family_response.py | 4 +++-
.../radar/http/timeseries_group_browser_response.py | 4 +++-
.../radar/http/timeseries_group_device_type_response.py | 4 +++-
.../http/timeseries_group_http_protocol_response.py | 4 +++-
.../radar/http/timeseries_group_http_version_response.py | 4 +++-
.../radar/http/timeseries_group_ip_version_response.py | 4 +++-
.../types/radar/http/timeseries_group_os_response.py | 4 +++-
.../radar/http/timeseries_group_post_quantum_response.py | 4 +++-
.../radar/http/timeseries_group_tls_version_response.py | 4 +++-
.../types/radar/http/top_browser_family_response.py | 2 ++
src/cloudflare/types/radar/http/top_browser_response.py | 2 ++
src/cloudflare/types/radar/http_summary_v2_response.py | 4 +++-
.../types/radar/http_timeseries_groups_v2_response.py | 4 +++-
src/cloudflare/types/radar/http_timeseries_response.py | 4 +++-
.../types/radar/leaked_credential_summary_v2_response.py | 4 +++-
.../leaked_credential_timeseries_groups_v2_response.py | 4 +++-
.../leaked_credentials/summary_bot_class_response.py | 4 +++-
.../leaked_credentials/summary_compromised_response.py | 4 +++-
.../timeseries_group_bot_class_response.py | 4 +++-
.../timeseries_group_compromised_response.py | 4 +++-
src/cloudflare/types/radar/netflows/top_ases_response.py | 2 ++
.../types/radar/netflows/top_locations_response.py | 2 ++
src/cloudflare/types/radar/netflows_summary_response.py | 4 +++-
.../types/radar/netflows_summary_v2_response.py | 4 +++-
.../types/radar/netflows_timeseries_groups_response.py | 4 +++-
.../types/radar/netflows_timeseries_response.py | 4 +++-
.../types/radar/post_quantum/origin_summary_response.py | 4 +++-
.../post_quantum/origin_timeseries_groups_response.py | 4 +++-
.../types/radar/quality/iqi_summary_response.py | 4 +++-
.../radar/quality/iqi_timeseries_groups_response.py | 4 +++-
.../types/radar/quality/speed/top_ases_response.py | 2 ++
.../types/radar/quality/speed/top_locations_response.py | 2 ++
.../types/radar/quality/speed_histogram_response.py | 4 +++-
.../types/radar/quality/speed_summary_response.py | 4 +++-
.../internet_service_timeseries_groups_response.py | 4 +++-
.../types/radar/ranking/internet_service_top_response.py | 2 ++
.../types/radar/ranking_timeseries_groups_response.py | 4 +++-
src/cloudflare/types/radar/ranking_top_response.py | 2 ++
.../robots_txt/top/user_agent_directive_response.py | 2 ++
.../radar/robots_txt/top_domain_categories_response.py | 2 ++
.../types/radar/tcp_resets_timeout_summary_response.py | 4 +++-
.../tcp_resets_timeout_timeseries_groups_response.py | 4 +++-
.../types/radar/verified_bots/top_bots_response.py | 2 ++
.../types/radar/verified_bots/top_categories_response.py | 2 ++
229 files changed, 642 insertions(+), 187 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index dd3ba7c40f0..e35843d9f07 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 2384
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-25de2cebd5c7324cf3baadd40bd56b09214a47e228122dfdb8c3fdaeeea2d792.yml
-openapi_spec_hash: a83153022e4ef3e4ba6b295d4b053ca3
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-471f2a9448b10c4c887be1fce3238a5f0ad296e80077090093fc9f52a0d99675.yml
+openapi_spec_hash: c072a4a84aa2d1de3b656ae5fe7967f8
config_hash: fb7701532a56b6f947632365deb733af
diff --git a/src/cloudflare/resources/radar/ai/inference/inference.py b/src/cloudflare/resources/radar/ai/inference/inference.py
index 133f6fbe226..c196afdd2bb 100644
--- a/src/cloudflare/resources/radar/ai/inference/inference.py
+++ b/src/cloudflare/resources/radar/ai/inference/inference.py
@@ -92,7 +92,7 @@ def summary_v2(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> InferenceSummaryV2Response:
"""
- Retrieves an aggregated summary of unique accounts using Workers AI inference
+ Retrieves an aggregated summary of the number of inferences run on Workers AI,
grouped by the specified dimension.
Args:
@@ -186,7 +186,7 @@ def timeseries_groups_v2(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> InferenceTimeseriesGroupsV2Response:
"""
- Retrieves the distribution of unique accounts using Workers AI inference,
+ Retrieves the distribution of the number of inferences run on Workers AI,
grouped by the specified dimension over time.
Args:
@@ -316,7 +316,7 @@ async def summary_v2(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> InferenceSummaryV2Response:
"""
- Retrieves an aggregated summary of unique accounts using Workers AI inference
+ Retrieves an aggregated summary of the number of inferences run on Workers AI,
grouped by the specified dimension.
Args:
@@ -410,7 +410,7 @@ async def timeseries_groups_v2(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> InferenceTimeseriesGroupsV2Response:
"""
- Retrieves the distribution of unique accounts using Workers AI inference,
+ Retrieves the distribution of the number of inferences run on Workers AI,
grouped by the specified dimension over time.
Args:
diff --git a/src/cloudflare/resources/radar/ai/inference/summary.py b/src/cloudflare/resources/radar/ai/inference/summary.py
index 713876a908e..c5b41e2c528 100644
--- a/src/cloudflare/resources/radar/ai/inference/summary.py
+++ b/src/cloudflare/resources/radar/ai/inference/summary.py
@@ -68,7 +68,7 @@ def model(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> SummaryModelResponse:
"""
- Retrieves the distribution of unique accounts by model.
+ Retrieves the distribution of the number of inferences by model.
Args:
date_end: End of the date range (inclusive).
@@ -138,7 +138,7 @@ def task(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> SummaryTaskResponse:
"""
- Retrieves the distribution of unique accounts by task.
+ Retrieves the distribution of the number of inferences by task.
Args:
date_end: End of the date range (inclusive).
@@ -229,7 +229,7 @@ async def model(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> SummaryModelResponse:
"""
- Retrieves the distribution of unique accounts by model.
+ Retrieves the distribution of the number of inferences by model.
Args:
date_end: End of the date range (inclusive).
@@ -299,7 +299,7 @@ async def task(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> SummaryTaskResponse:
"""
- Retrieves the distribution of unique accounts by task.
+ Retrieves the distribution of the number of inferences by task.
Args:
date_end: End of the date range (inclusive).
diff --git a/src/cloudflare/resources/radar/ai/inference/timeseries_groups/summary.py b/src/cloudflare/resources/radar/ai/inference/timeseries_groups/summary.py
index 3b660d9edb4..a9baf59b822 100644
--- a/src/cloudflare/resources/radar/ai/inference/timeseries_groups/summary.py
+++ b/src/cloudflare/resources/radar/ai/inference/timeseries_groups/summary.py
@@ -69,7 +69,7 @@ def model(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> SummaryModelResponse:
"""
- Retrieves the distribution of unique accounts by model over time.
+ Retrieves the distribution of the number of inferences by model over time.
Args:
agg_interval: Aggregation interval of the results (e.g., in 15 minutes or 1 hour intervals).
@@ -145,7 +145,7 @@ def task(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> SummaryTaskResponse:
"""
- Retrieves the distribution of unique accounts by task over time.
+ Retrieves the distribution of the number of inferences by task over time.
Args:
agg_interval: Aggregation interval of the results (e.g., in 15 minutes or 1 hour intervals).
@@ -242,7 +242,7 @@ async def model(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> SummaryModelResponse:
"""
- Retrieves the distribution of unique accounts by model over time.
+ Retrieves the distribution of the number of inferences by model over time.
Args:
agg_interval: Aggregation interval of the results (e.g., in 15 minutes or 1 hour intervals).
@@ -318,7 +318,7 @@ async def task(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> SummaryTaskResponse:
"""
- Retrieves the distribution of unique accounts by task over time.
+ Retrieves the distribution of the number of inferences by task over time.
Args:
agg_interval: Aggregation interval of the results (e.g., in 15 minutes or 1 hour intervals).
diff --git a/src/cloudflare/types/radar/ai/bot_summary_v2_response.py b/src/cloudflare/types/radar/ai/bot_summary_v2_response.py
index fb7c6418428..69594fe418f 100644
--- a/src/cloudflare/types/radar/ai/bot_summary_v2_response.py
+++ b/src/cloudflare/types/radar/ai/bot_summary_v2_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/ai/bot_timeseries_groups_response.py b/src/cloudflare/types/radar/ai/bot_timeseries_groups_response.py
index e448b09bfe3..5aa1bec255e 100644
--- a/src/cloudflare/types/radar/ai/bot_timeseries_groups_response.py
+++ b/src/cloudflare/types/radar/ai/bot_timeseries_groups_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/ai/bot_timeseries_response.py b/src/cloudflare/types/radar/ai/bot_timeseries_response.py
index b71ad68c705..349e2f54671 100644
--- a/src/cloudflare/types/radar/ai/bot_timeseries_response.py
+++ b/src/cloudflare/types/radar/ai/bot_timeseries_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/ai/bots/summary_user_agent_response.py b/src/cloudflare/types/radar/ai/bots/summary_user_agent_response.py
index ee5641e5b26..aba5992a5f6 100644
--- a/src/cloudflare/types/radar/ai/bots/summary_user_agent_response.py
+++ b/src/cloudflare/types/radar/ai/bots/summary_user_agent_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/ai/inference/summary_model_response.py b/src/cloudflare/types/radar/ai/inference/summary_model_response.py
index 4c99017eaa9..4e5bfa9797c 100644
--- a/src/cloudflare/types/radar/ai/inference/summary_model_response.py
+++ b/src/cloudflare/types/radar/ai/inference/summary_model_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/ai/inference/summary_task_response.py b/src/cloudflare/types/radar/ai/inference/summary_task_response.py
index fd9c9ea732b..3ca0810579d 100644
--- a/src/cloudflare/types/radar/ai/inference/summary_task_response.py
+++ b/src/cloudflare/types/radar/ai/inference/summary_task_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/ai/inference/timeseries_groups/summary_model_response.py b/src/cloudflare/types/radar/ai/inference/timeseries_groups/summary_model_response.py
index f930f07fbdc..cdff1bc4a7c 100644
--- a/src/cloudflare/types/radar/ai/inference/timeseries_groups/summary_model_response.py
+++ b/src/cloudflare/types/radar/ai/inference/timeseries_groups/summary_model_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/ai/inference/timeseries_groups/summary_task_response.py b/src/cloudflare/types/radar/ai/inference/timeseries_groups/summary_task_response.py
index c539d7d4e0e..e815013ef3a 100644
--- a/src/cloudflare/types/radar/ai/inference/timeseries_groups/summary_task_response.py
+++ b/src/cloudflare/types/radar/ai/inference/timeseries_groups/summary_task_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/ai/inference_summary_v2_response.py b/src/cloudflare/types/radar/ai/inference_summary_v2_response.py
index e45dc345d65..9f3fd58f73e 100644
--- a/src/cloudflare/types/radar/ai/inference_summary_v2_response.py
+++ b/src/cloudflare/types/radar/ai/inference_summary_v2_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/ai/inference_timeseries_groups_v2_response.py b/src/cloudflare/types/radar/ai/inference_timeseries_groups_v2_response.py
index d8c67c5fe67..3feeb2fca8b 100644
--- a/src/cloudflare/types/radar/ai/inference_timeseries_groups_v2_response.py
+++ b/src/cloudflare/types/radar/ai/inference_timeseries_groups_v2_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/ai/markdown_for_agent_summary_response.py b/src/cloudflare/types/radar/ai/markdown_for_agent_summary_response.py
index a57750d0fca..acc2d4daaa6 100644
--- a/src/cloudflare/types/radar/ai/markdown_for_agent_summary_response.py
+++ b/src/cloudflare/types/radar/ai/markdown_for_agent_summary_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/ai/markdown_for_agent_timeseries_response.py b/src/cloudflare/types/radar/ai/markdown_for_agent_timeseries_response.py
index 165e883b2fa..67eaa85dd5c 100644
--- a/src/cloudflare/types/radar/ai/markdown_for_agent_timeseries_response.py
+++ b/src/cloudflare/types/radar/ai/markdown_for_agent_timeseries_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/ai/timeseries_group_summary_response.py b/src/cloudflare/types/radar/ai/timeseries_group_summary_response.py
index 3c8e27d5838..bf87588e2e5 100644
--- a/src/cloudflare/types/radar/ai/timeseries_group_summary_response.py
+++ b/src/cloudflare/types/radar/ai/timeseries_group_summary_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/ai/timeseries_group_timeseries_groups_response.py b/src/cloudflare/types/radar/ai/timeseries_group_timeseries_groups_response.py
index a666366d717..6be506ff8a0 100644
--- a/src/cloudflare/types/radar/ai/timeseries_group_timeseries_groups_response.py
+++ b/src/cloudflare/types/radar/ai/timeseries_group_timeseries_groups_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/ai/timeseries_group_timeseries_response.py b/src/cloudflare/types/radar/ai/timeseries_group_timeseries_response.py
index 89bf10123f4..6010086324a 100644
--- a/src/cloudflare/types/radar/ai/timeseries_group_timeseries_response.py
+++ b/src/cloudflare/types/radar/ai/timeseries_group_timeseries_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/ai/timeseries_group_user_agent_response.py b/src/cloudflare/types/radar/ai/timeseries_group_user_agent_response.py
index 499de99147c..444a90beff0 100644
--- a/src/cloudflare/types/radar/ai/timeseries_group_user_agent_response.py
+++ b/src/cloudflare/types/radar/ai/timeseries_group_user_agent_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/as112/summary_dnssec_response.py b/src/cloudflare/types/radar/as112/summary_dnssec_response.py
index 9784acaae95..b79eb3d25d7 100644
--- a/src/cloudflare/types/radar/as112/summary_dnssec_response.py
+++ b/src/cloudflare/types/radar/as112/summary_dnssec_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/as112/summary_edns_response.py b/src/cloudflare/types/radar/as112/summary_edns_response.py
index 7a0209c9ea4..43ef91f545a 100644
--- a/src/cloudflare/types/radar/as112/summary_edns_response.py
+++ b/src/cloudflare/types/radar/as112/summary_edns_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/as112/summary_ip_version_response.py b/src/cloudflare/types/radar/as112/summary_ip_version_response.py
index c73c7cf94ab..cd6964bac8f 100644
--- a/src/cloudflare/types/radar/as112/summary_ip_version_response.py
+++ b/src/cloudflare/types/radar/as112/summary_ip_version_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/as112/summary_protocol_response.py b/src/cloudflare/types/radar/as112/summary_protocol_response.py
index ffa0f33760b..54f7c527841 100644
--- a/src/cloudflare/types/radar/as112/summary_protocol_response.py
+++ b/src/cloudflare/types/radar/as112/summary_protocol_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/as112/summary_query_type_response.py b/src/cloudflare/types/radar/as112/summary_query_type_response.py
index ae1ab1c7571..eb11c86049c 100644
--- a/src/cloudflare/types/radar/as112/summary_query_type_response.py
+++ b/src/cloudflare/types/radar/as112/summary_query_type_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/as112/summary_response_codes_response.py b/src/cloudflare/types/radar/as112/summary_response_codes_response.py
index a71960387da..37f4448963e 100644
--- a/src/cloudflare/types/radar/as112/summary_response_codes_response.py
+++ b/src/cloudflare/types/radar/as112/summary_response_codes_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/as112/timeseries_group_dnssec_response.py b/src/cloudflare/types/radar/as112/timeseries_group_dnssec_response.py
index 9afeebe79ed..03e0fd5eb4d 100644
--- a/src/cloudflare/types/radar/as112/timeseries_group_dnssec_response.py
+++ b/src/cloudflare/types/radar/as112/timeseries_group_dnssec_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/as112/timeseries_group_edns_response.py b/src/cloudflare/types/radar/as112/timeseries_group_edns_response.py
index 5ee42c158d4..0efda4c15c5 100644
--- a/src/cloudflare/types/radar/as112/timeseries_group_edns_response.py
+++ b/src/cloudflare/types/radar/as112/timeseries_group_edns_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/as112/timeseries_group_ip_version_response.py b/src/cloudflare/types/radar/as112/timeseries_group_ip_version_response.py
index 6f047f9a1e4..cb292e9d4d5 100644
--- a/src/cloudflare/types/radar/as112/timeseries_group_ip_version_response.py
+++ b/src/cloudflare/types/radar/as112/timeseries_group_ip_version_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/as112/timeseries_group_protocol_response.py b/src/cloudflare/types/radar/as112/timeseries_group_protocol_response.py
index 25cdf9ccc54..8f6b76ce59c 100644
--- a/src/cloudflare/types/radar/as112/timeseries_group_protocol_response.py
+++ b/src/cloudflare/types/radar/as112/timeseries_group_protocol_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/as112/timeseries_group_query_type_response.py b/src/cloudflare/types/radar/as112/timeseries_group_query_type_response.py
index 34bd30918f0..f7f6f9b9d1b 100644
--- a/src/cloudflare/types/radar/as112/timeseries_group_query_type_response.py
+++ b/src/cloudflare/types/radar/as112/timeseries_group_query_type_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/as112/timeseries_group_response_codes_response.py b/src/cloudflare/types/radar/as112/timeseries_group_response_codes_response.py
index ddedbbe5aa9..d9746cce411 100644
--- a/src/cloudflare/types/radar/as112/timeseries_group_response_codes_response.py
+++ b/src/cloudflare/types/radar/as112/timeseries_group_response_codes_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/as112/top_dnssec_response.py b/src/cloudflare/types/radar/as112/top_dnssec_response.py
index 12bc24271e3..83a71604128 100644
--- a/src/cloudflare/types/radar/as112/top_dnssec_response.py
+++ b/src/cloudflare/types/radar/as112/top_dnssec_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/as112/top_edns_response.py b/src/cloudflare/types/radar/as112/top_edns_response.py
index be94fa8c5f9..1f82a8c443e 100644
--- a/src/cloudflare/types/radar/as112/top_edns_response.py
+++ b/src/cloudflare/types/radar/as112/top_edns_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/as112/top_ip_version_response.py b/src/cloudflare/types/radar/as112/top_ip_version_response.py
index 344444fc533..c74c3a6e9d7 100644
--- a/src/cloudflare/types/radar/as112/top_ip_version_response.py
+++ b/src/cloudflare/types/radar/as112/top_ip_version_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/as112/top_locations_response.py b/src/cloudflare/types/radar/as112/top_locations_response.py
index 769fffedb1a..693391ae114 100644
--- a/src/cloudflare/types/radar/as112/top_locations_response.py
+++ b/src/cloudflare/types/radar/as112/top_locations_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/as112_summary_v2_response.py b/src/cloudflare/types/radar/as112_summary_v2_response.py
index 78c5ce93993..66e68fbe875 100644
--- a/src/cloudflare/types/radar/as112_summary_v2_response.py
+++ b/src/cloudflare/types/radar/as112_summary_v2_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/as112_timeseries_groups_v2_response.py b/src/cloudflare/types/radar/as112_timeseries_groups_v2_response.py
index db41246e6c9..08c24a06487 100644
--- a/src/cloudflare/types/radar/as112_timeseries_groups_v2_response.py
+++ b/src/cloudflare/types/radar/as112_timeseries_groups_v2_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/as112_timeseries_response.py b/src/cloudflare/types/radar/as112_timeseries_response.py
index 7f2c4e07cac..118cb941b75 100644
--- a/src/cloudflare/types/radar/as112_timeseries_response.py
+++ b/src/cloudflare/types/radar/as112_timeseries_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer3/summary_bitrate_response.py b/src/cloudflare/types/radar/attacks/layer3/summary_bitrate_response.py
index 6a6d4c493fe..0d360491719 100644
--- a/src/cloudflare/types/radar/attacks/layer3/summary_bitrate_response.py
+++ b/src/cloudflare/types/radar/attacks/layer3/summary_bitrate_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer3/summary_duration_response.py b/src/cloudflare/types/radar/attacks/layer3/summary_duration_response.py
index 85661847a79..53dffbf12cd 100644
--- a/src/cloudflare/types/radar/attacks/layer3/summary_duration_response.py
+++ b/src/cloudflare/types/radar/attacks/layer3/summary_duration_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer3/summary_industry_response.py b/src/cloudflare/types/radar/attacks/layer3/summary_industry_response.py
index 50d2b9b6fdb..b2862686ba1 100644
--- a/src/cloudflare/types/radar/attacks/layer3/summary_industry_response.py
+++ b/src/cloudflare/types/radar/attacks/layer3/summary_industry_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer3/summary_ip_version_response.py b/src/cloudflare/types/radar/attacks/layer3/summary_ip_version_response.py
index 63a07734f7b..e2d5fb89b04 100644
--- a/src/cloudflare/types/radar/attacks/layer3/summary_ip_version_response.py
+++ b/src/cloudflare/types/radar/attacks/layer3/summary_ip_version_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer3/summary_protocol_response.py b/src/cloudflare/types/radar/attacks/layer3/summary_protocol_response.py
index 02e0a65aa27..f7b97e86002 100644
--- a/src/cloudflare/types/radar/attacks/layer3/summary_protocol_response.py
+++ b/src/cloudflare/types/radar/attacks/layer3/summary_protocol_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer3/summary_vector_response.py b/src/cloudflare/types/radar/attacks/layer3/summary_vector_response.py
index 1ddbd33ae39..0526f126d84 100644
--- a/src/cloudflare/types/radar/attacks/layer3/summary_vector_response.py
+++ b/src/cloudflare/types/radar/attacks/layer3/summary_vector_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer3/summary_vertical_response.py b/src/cloudflare/types/radar/attacks/layer3/summary_vertical_response.py
index ceab1b2728f..e516ba64e8d 100644
--- a/src/cloudflare/types/radar/attacks/layer3/summary_vertical_response.py
+++ b/src/cloudflare/types/radar/attacks/layer3/summary_vertical_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer3/timeseries_group_bitrate_response.py b/src/cloudflare/types/radar/attacks/layer3/timeseries_group_bitrate_response.py
index 6f7e17fa15e..2df27bb221d 100644
--- a/src/cloudflare/types/radar/attacks/layer3/timeseries_group_bitrate_response.py
+++ b/src/cloudflare/types/radar/attacks/layer3/timeseries_group_bitrate_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer3/timeseries_group_duration_response.py b/src/cloudflare/types/radar/attacks/layer3/timeseries_group_duration_response.py
index 2f69edbd7e8..02d08048bab 100644
--- a/src/cloudflare/types/radar/attacks/layer3/timeseries_group_duration_response.py
+++ b/src/cloudflare/types/radar/attacks/layer3/timeseries_group_duration_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer3/timeseries_group_industry_response.py b/src/cloudflare/types/radar/attacks/layer3/timeseries_group_industry_response.py
index 61ecc717aa7..3a8e406c780 100644
--- a/src/cloudflare/types/radar/attacks/layer3/timeseries_group_industry_response.py
+++ b/src/cloudflare/types/radar/attacks/layer3/timeseries_group_industry_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer3/timeseries_group_ip_version_response.py b/src/cloudflare/types/radar/attacks/layer3/timeseries_group_ip_version_response.py
index 712fa9458e8..813292e1ac8 100644
--- a/src/cloudflare/types/radar/attacks/layer3/timeseries_group_ip_version_response.py
+++ b/src/cloudflare/types/radar/attacks/layer3/timeseries_group_ip_version_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer3/timeseries_group_protocol_response.py b/src/cloudflare/types/radar/attacks/layer3/timeseries_group_protocol_response.py
index 666ec57c4ef..21362bdb527 100644
--- a/src/cloudflare/types/radar/attacks/layer3/timeseries_group_protocol_response.py
+++ b/src/cloudflare/types/radar/attacks/layer3/timeseries_group_protocol_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer3/timeseries_group_vector_response.py b/src/cloudflare/types/radar/attacks/layer3/timeseries_group_vector_response.py
index 4370bd1b06b..2476a4ad76d 100644
--- a/src/cloudflare/types/radar/attacks/layer3/timeseries_group_vector_response.py
+++ b/src/cloudflare/types/radar/attacks/layer3/timeseries_group_vector_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer3/timeseries_group_vertical_response.py b/src/cloudflare/types/radar/attacks/layer3/timeseries_group_vertical_response.py
index 165f50db0a4..0f31f74b72b 100644
--- a/src/cloudflare/types/radar/attacks/layer3/timeseries_group_vertical_response.py
+++ b/src/cloudflare/types/radar/attacks/layer3/timeseries_group_vertical_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer3/top/location_origin_response.py b/src/cloudflare/types/radar/attacks/layer3/top/location_origin_response.py
index ddf5ac81e7c..ca01a5e3b1f 100644
--- a/src/cloudflare/types/radar/attacks/layer3/top/location_origin_response.py
+++ b/src/cloudflare/types/radar/attacks/layer3/top/location_origin_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer3/top/location_target_response.py b/src/cloudflare/types/radar/attacks/layer3/top/location_target_response.py
index 751e2a5ad77..d1c0bdbae56 100644
--- a/src/cloudflare/types/radar/attacks/layer3/top/location_target_response.py
+++ b/src/cloudflare/types/radar/attacks/layer3/top/location_target_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer3/top_attacks_response.py b/src/cloudflare/types/radar/attacks/layer3/top_attacks_response.py
index a203bf565a2..2ad9fe82e67 100644
--- a/src/cloudflare/types/radar/attacks/layer3/top_attacks_response.py
+++ b/src/cloudflare/types/radar/attacks/layer3/top_attacks_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer3/top_industry_response.py b/src/cloudflare/types/radar/attacks/layer3/top_industry_response.py
index 33cc3a86267..51c1aded152 100644
--- a/src/cloudflare/types/radar/attacks/layer3/top_industry_response.py
+++ b/src/cloudflare/types/radar/attacks/layer3/top_industry_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer3/top_vertical_response.py b/src/cloudflare/types/radar/attacks/layer3/top_vertical_response.py
index a097494189e..0fec48356f3 100644
--- a/src/cloudflare/types/radar/attacks/layer3/top_vertical_response.py
+++ b/src/cloudflare/types/radar/attacks/layer3/top_vertical_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer3_summary_v2_response.py b/src/cloudflare/types/radar/attacks/layer3_summary_v2_response.py
index dfbe5f43621..c2a6dcf86af 100644
--- a/src/cloudflare/types/radar/attacks/layer3_summary_v2_response.py
+++ b/src/cloudflare/types/radar/attacks/layer3_summary_v2_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer3_timeseries_groups_v2_response.py b/src/cloudflare/types/radar/attacks/layer3_timeseries_groups_v2_response.py
index a26ca9f8867..d5e1b33f4f2 100644
--- a/src/cloudflare/types/radar/attacks/layer3_timeseries_groups_v2_response.py
+++ b/src/cloudflare/types/radar/attacks/layer3_timeseries_groups_v2_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer3_timeseries_response.py b/src/cloudflare/types/radar/attacks/layer3_timeseries_response.py
index 410a439c79b..201b14bcff9 100644
--- a/src/cloudflare/types/radar/attacks/layer3_timeseries_response.py
+++ b/src/cloudflare/types/radar/attacks/layer3_timeseries_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer7/summary_http_method_response.py b/src/cloudflare/types/radar/attacks/layer7/summary_http_method_response.py
index 3e989b9f213..6a42fcd5f60 100644
--- a/src/cloudflare/types/radar/attacks/layer7/summary_http_method_response.py
+++ b/src/cloudflare/types/radar/attacks/layer7/summary_http_method_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer7/summary_http_version_response.py b/src/cloudflare/types/radar/attacks/layer7/summary_http_version_response.py
index af238297552..5452a7e2c21 100644
--- a/src/cloudflare/types/radar/attacks/layer7/summary_http_version_response.py
+++ b/src/cloudflare/types/radar/attacks/layer7/summary_http_version_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer7/summary_industry_response.py b/src/cloudflare/types/radar/attacks/layer7/summary_industry_response.py
index 50d2b9b6fdb..b2862686ba1 100644
--- a/src/cloudflare/types/radar/attacks/layer7/summary_industry_response.py
+++ b/src/cloudflare/types/radar/attacks/layer7/summary_industry_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer7/summary_ip_version_response.py b/src/cloudflare/types/radar/attacks/layer7/summary_ip_version_response.py
index 275934ca339..35723bcbcc5 100644
--- a/src/cloudflare/types/radar/attacks/layer7/summary_ip_version_response.py
+++ b/src/cloudflare/types/radar/attacks/layer7/summary_ip_version_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer7/summary_managed_rules_response.py b/src/cloudflare/types/radar/attacks/layer7/summary_managed_rules_response.py
index 634d53aa718..91e99be5336 100644
--- a/src/cloudflare/types/radar/attacks/layer7/summary_managed_rules_response.py
+++ b/src/cloudflare/types/radar/attacks/layer7/summary_managed_rules_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer7/summary_mitigation_product_response.py b/src/cloudflare/types/radar/attacks/layer7/summary_mitigation_product_response.py
index 03e39670de8..31d6132cfc8 100644
--- a/src/cloudflare/types/radar/attacks/layer7/summary_mitigation_product_response.py
+++ b/src/cloudflare/types/radar/attacks/layer7/summary_mitigation_product_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer7/summary_vertical_response.py b/src/cloudflare/types/radar/attacks/layer7/summary_vertical_response.py
index ceab1b2728f..e516ba64e8d 100644
--- a/src/cloudflare/types/radar/attacks/layer7/summary_vertical_response.py
+++ b/src/cloudflare/types/radar/attacks/layer7/summary_vertical_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer7/timeseries_group_http_method_response.py b/src/cloudflare/types/radar/attacks/layer7/timeseries_group_http_method_response.py
index 782976a9a3b..87c4c9b9fec 100644
--- a/src/cloudflare/types/radar/attacks/layer7/timeseries_group_http_method_response.py
+++ b/src/cloudflare/types/radar/attacks/layer7/timeseries_group_http_method_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer7/timeseries_group_http_version_response.py b/src/cloudflare/types/radar/attacks/layer7/timeseries_group_http_version_response.py
index 60f4b3137ec..2749c5ef181 100644
--- a/src/cloudflare/types/radar/attacks/layer7/timeseries_group_http_version_response.py
+++ b/src/cloudflare/types/radar/attacks/layer7/timeseries_group_http_version_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer7/timeseries_group_industry_response.py b/src/cloudflare/types/radar/attacks/layer7/timeseries_group_industry_response.py
index 61ecc717aa7..3a8e406c780 100644
--- a/src/cloudflare/types/radar/attacks/layer7/timeseries_group_industry_response.py
+++ b/src/cloudflare/types/radar/attacks/layer7/timeseries_group_industry_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer7/timeseries_group_ip_version_response.py b/src/cloudflare/types/radar/attacks/layer7/timeseries_group_ip_version_response.py
index 712fa9458e8..813292e1ac8 100644
--- a/src/cloudflare/types/radar/attacks/layer7/timeseries_group_ip_version_response.py
+++ b/src/cloudflare/types/radar/attacks/layer7/timeseries_group_ip_version_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer7/timeseries_group_managed_rules_response.py b/src/cloudflare/types/radar/attacks/layer7/timeseries_group_managed_rules_response.py
index 79afb24771a..dc4b60b6ab7 100644
--- a/src/cloudflare/types/radar/attacks/layer7/timeseries_group_managed_rules_response.py
+++ b/src/cloudflare/types/radar/attacks/layer7/timeseries_group_managed_rules_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer7/timeseries_group_mitigation_product_response.py b/src/cloudflare/types/radar/attacks/layer7/timeseries_group_mitigation_product_response.py
index 11a4129bdd1..165faba3d1c 100644
--- a/src/cloudflare/types/radar/attacks/layer7/timeseries_group_mitigation_product_response.py
+++ b/src/cloudflare/types/radar/attacks/layer7/timeseries_group_mitigation_product_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer7/timeseries_group_vertical_response.py b/src/cloudflare/types/radar/attacks/layer7/timeseries_group_vertical_response.py
index 165f50db0a4..0f31f74b72b 100644
--- a/src/cloudflare/types/radar/attacks/layer7/timeseries_group_vertical_response.py
+++ b/src/cloudflare/types/radar/attacks/layer7/timeseries_group_vertical_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer7/top/ase_origin_response.py b/src/cloudflare/types/radar/attacks/layer7/top/ase_origin_response.py
index fc2262e132e..edc59706793 100644
--- a/src/cloudflare/types/radar/attacks/layer7/top/ase_origin_response.py
+++ b/src/cloudflare/types/radar/attacks/layer7/top/ase_origin_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer7/top/location_origin_response.py b/src/cloudflare/types/radar/attacks/layer7/top/location_origin_response.py
index ddf5ac81e7c..ca01a5e3b1f 100644
--- a/src/cloudflare/types/radar/attacks/layer7/top/location_origin_response.py
+++ b/src/cloudflare/types/radar/attacks/layer7/top/location_origin_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer7/top/location_target_response.py b/src/cloudflare/types/radar/attacks/layer7/top/location_target_response.py
index 751e2a5ad77..d1c0bdbae56 100644
--- a/src/cloudflare/types/radar/attacks/layer7/top/location_target_response.py
+++ b/src/cloudflare/types/radar/attacks/layer7/top/location_target_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer7/top_attacks_response.py b/src/cloudflare/types/radar/attacks/layer7/top_attacks_response.py
index 760ab2ff1a6..4a96ad1f5f2 100644
--- a/src/cloudflare/types/radar/attacks/layer7/top_attacks_response.py
+++ b/src/cloudflare/types/radar/attacks/layer7/top_attacks_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer7/top_industry_response.py b/src/cloudflare/types/radar/attacks/layer7/top_industry_response.py
index 33cc3a86267..51c1aded152 100644
--- a/src/cloudflare/types/radar/attacks/layer7/top_industry_response.py
+++ b/src/cloudflare/types/radar/attacks/layer7/top_industry_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer7/top_vertical_response.py b/src/cloudflare/types/radar/attacks/layer7/top_vertical_response.py
index a097494189e..0fec48356f3 100644
--- a/src/cloudflare/types/radar/attacks/layer7/top_vertical_response.py
+++ b/src/cloudflare/types/radar/attacks/layer7/top_vertical_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer7_summary_v2_response.py b/src/cloudflare/types/radar/attacks/layer7_summary_v2_response.py
index be84e69d16d..77825daf2d6 100644
--- a/src/cloudflare/types/radar/attacks/layer7_summary_v2_response.py
+++ b/src/cloudflare/types/radar/attacks/layer7_summary_v2_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer7_timeseries_groups_v2_response.py b/src/cloudflare/types/radar/attacks/layer7_timeseries_groups_v2_response.py
index 3c753ebcd11..fceac0a9702 100644
--- a/src/cloudflare/types/radar/attacks/layer7_timeseries_groups_v2_response.py
+++ b/src/cloudflare/types/radar/attacks/layer7_timeseries_groups_v2_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/attacks/layer7_timeseries_response.py b/src/cloudflare/types/radar/attacks/layer7_timeseries_response.py
index f3ddae2c5ac..a09edef83a7 100644
--- a/src/cloudflare/types/radar/attacks/layer7_timeseries_response.py
+++ b/src/cloudflare/types/radar/attacks/layer7_timeseries_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/bgp/ip_timeseries_response.py b/src/cloudflare/types/radar/bgp/ip_timeseries_response.py
index eb6d764477e..9196f643016 100644
--- a/src/cloudflare/types/radar/bgp/ip_timeseries_response.py
+++ b/src/cloudflare/types/radar/bgp/ip_timeseries_response.py
@@ -72,6 +72,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/bgp_timeseries_response.py b/src/cloudflare/types/radar/bgp_timeseries_response.py
index 3d1de097e18..fbd789e60d8 100644
--- a/src/cloudflare/types/radar/bgp_timeseries_response.py
+++ b/src/cloudflare/types/radar/bgp_timeseries_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/bot_summary_response.py b/src/cloudflare/types/radar/bot_summary_response.py
index 6bccc521e67..0e300712b70 100644
--- a/src/cloudflare/types/radar/bot_summary_response.py
+++ b/src/cloudflare/types/radar/bot_summary_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/bot_timeseries_groups_response.py b/src/cloudflare/types/radar/bot_timeseries_groups_response.py
index 5f485ac4752..64041355098 100644
--- a/src/cloudflare/types/radar/bot_timeseries_groups_response.py
+++ b/src/cloudflare/types/radar/bot_timeseries_groups_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/bot_timeseries_response.py b/src/cloudflare/types/radar/bot_timeseries_response.py
index a9bdd0830c1..87f8086524b 100644
--- a/src/cloudflare/types/radar/bot_timeseries_response.py
+++ b/src/cloudflare/types/radar/bot_timeseries_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/bots/web_crawler_summary_response.py b/src/cloudflare/types/radar/bots/web_crawler_summary_response.py
index f096a53432f..4e6e6321697 100644
--- a/src/cloudflare/types/radar/bots/web_crawler_summary_response.py
+++ b/src/cloudflare/types/radar/bots/web_crawler_summary_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/bots/web_crawler_timeseries_groups_response.py b/src/cloudflare/types/radar/bots/web_crawler_timeseries_groups_response.py
index 1f581b30554..4dae21c5d81 100644
--- a/src/cloudflare/types/radar/bots/web_crawler_timeseries_groups_response.py
+++ b/src/cloudflare/types/radar/bots/web_crawler_timeseries_groups_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/ct_summary_response.py b/src/cloudflare/types/radar/ct_summary_response.py
index 3202682bc40..e27dfe4b618 100644
--- a/src/cloudflare/types/radar/ct_summary_response.py
+++ b/src/cloudflare/types/radar/ct_summary_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List, Union
+from typing import Dict, List, Union, Optional
from datetime import datetime
from typing_extensions import Literal, TypeAlias
@@ -74,6 +74,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/ct_timeseries_groups_response.py b/src/cloudflare/types/radar/ct_timeseries_groups_response.py
index 93cfd543c43..98df2f377fd 100644
--- a/src/cloudflare/types/radar/ct_timeseries_groups_response.py
+++ b/src/cloudflare/types/radar/ct_timeseries_groups_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List, Union
+from typing import TYPE_CHECKING, Dict, List, Union, Optional
from datetime import datetime
from typing_extensions import Literal, TypeAlias
@@ -75,6 +75,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/ct_timeseries_response.py b/src/cloudflare/types/radar/ct_timeseries_response.py
index 7d2768fea7c..bd83e732aa3 100644
--- a/src/cloudflare/types/radar/ct_timeseries_response.py
+++ b/src/cloudflare/types/radar/ct_timeseries_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns/summary_cache_hit_response.py b/src/cloudflare/types/radar/dns/summary_cache_hit_response.py
index 2c8af1b6e95..a834ceedaea 100644
--- a/src/cloudflare/types/radar/dns/summary_cache_hit_response.py
+++ b/src/cloudflare/types/radar/dns/summary_cache_hit_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns/summary_dnssec_aware_response.py b/src/cloudflare/types/radar/dns/summary_dnssec_aware_response.py
index 6bcd072b66d..86c3ff54c5c 100644
--- a/src/cloudflare/types/radar/dns/summary_dnssec_aware_response.py
+++ b/src/cloudflare/types/radar/dns/summary_dnssec_aware_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns/summary_dnssec_e2e_response.py b/src/cloudflare/types/radar/dns/summary_dnssec_e2e_response.py
index 5cdcff8148c..b10a4253201 100644
--- a/src/cloudflare/types/radar/dns/summary_dnssec_e2e_response.py
+++ b/src/cloudflare/types/radar/dns/summary_dnssec_e2e_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns/summary_dnssec_response.py b/src/cloudflare/types/radar/dns/summary_dnssec_response.py
index a8a517edc9c..5b665dfee07 100644
--- a/src/cloudflare/types/radar/dns/summary_dnssec_response.py
+++ b/src/cloudflare/types/radar/dns/summary_dnssec_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns/summary_ip_version_response.py b/src/cloudflare/types/radar/dns/summary_ip_version_response.py
index c73c7cf94ab..cd6964bac8f 100644
--- a/src/cloudflare/types/radar/dns/summary_ip_version_response.py
+++ b/src/cloudflare/types/radar/dns/summary_ip_version_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns/summary_matching_answer_response.py b/src/cloudflare/types/radar/dns/summary_matching_answer_response.py
index fe26eaf7b38..942ea690560 100644
--- a/src/cloudflare/types/radar/dns/summary_matching_answer_response.py
+++ b/src/cloudflare/types/radar/dns/summary_matching_answer_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns/summary_protocol_response.py b/src/cloudflare/types/radar/dns/summary_protocol_response.py
index ffa0f33760b..54f7c527841 100644
--- a/src/cloudflare/types/radar/dns/summary_protocol_response.py
+++ b/src/cloudflare/types/radar/dns/summary_protocol_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns/summary_query_type_response.py b/src/cloudflare/types/radar/dns/summary_query_type_response.py
index ae1ab1c7571..eb11c86049c 100644
--- a/src/cloudflare/types/radar/dns/summary_query_type_response.py
+++ b/src/cloudflare/types/radar/dns/summary_query_type_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns/summary_response_code_response.py b/src/cloudflare/types/radar/dns/summary_response_code_response.py
index 6b9439caef4..5857421eac8 100644
--- a/src/cloudflare/types/radar/dns/summary_response_code_response.py
+++ b/src/cloudflare/types/radar/dns/summary_response_code_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns/summary_response_ttl_response.py b/src/cloudflare/types/radar/dns/summary_response_ttl_response.py
index 9bb7e3c1ce4..4fd3b6b0da0 100644
--- a/src/cloudflare/types/radar/dns/summary_response_ttl_response.py
+++ b/src/cloudflare/types/radar/dns/summary_response_ttl_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns/timeseries_group_cache_hit_response.py b/src/cloudflare/types/radar/dns/timeseries_group_cache_hit_response.py
index 9befda91fc2..068cb6d9cb1 100644
--- a/src/cloudflare/types/radar/dns/timeseries_group_cache_hit_response.py
+++ b/src/cloudflare/types/radar/dns/timeseries_group_cache_hit_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns/timeseries_group_dnssec_aware_response.py b/src/cloudflare/types/radar/dns/timeseries_group_dnssec_aware_response.py
index 6ad939335f7..15a0da17a82 100644
--- a/src/cloudflare/types/radar/dns/timeseries_group_dnssec_aware_response.py
+++ b/src/cloudflare/types/radar/dns/timeseries_group_dnssec_aware_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns/timeseries_group_dnssec_e2e_response.py b/src/cloudflare/types/radar/dns/timeseries_group_dnssec_e2e_response.py
index 3c2aa8ffa5f..92b7546f5a6 100644
--- a/src/cloudflare/types/radar/dns/timeseries_group_dnssec_e2e_response.py
+++ b/src/cloudflare/types/radar/dns/timeseries_group_dnssec_e2e_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns/timeseries_group_dnssec_response.py b/src/cloudflare/types/radar/dns/timeseries_group_dnssec_response.py
index a2566d2a450..08c89a280c2 100644
--- a/src/cloudflare/types/radar/dns/timeseries_group_dnssec_response.py
+++ b/src/cloudflare/types/radar/dns/timeseries_group_dnssec_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns/timeseries_group_ip_version_response.py b/src/cloudflare/types/radar/dns/timeseries_group_ip_version_response.py
index 6f047f9a1e4..cb292e9d4d5 100644
--- a/src/cloudflare/types/radar/dns/timeseries_group_ip_version_response.py
+++ b/src/cloudflare/types/radar/dns/timeseries_group_ip_version_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns/timeseries_group_matching_answer_response.py b/src/cloudflare/types/radar/dns/timeseries_group_matching_answer_response.py
index ed4960305b1..08e229c92a8 100644
--- a/src/cloudflare/types/radar/dns/timeseries_group_matching_answer_response.py
+++ b/src/cloudflare/types/radar/dns/timeseries_group_matching_answer_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns/timeseries_group_protocol_response.py b/src/cloudflare/types/radar/dns/timeseries_group_protocol_response.py
index 25cdf9ccc54..8f6b76ce59c 100644
--- a/src/cloudflare/types/radar/dns/timeseries_group_protocol_response.py
+++ b/src/cloudflare/types/radar/dns/timeseries_group_protocol_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns/timeseries_group_query_type_response.py b/src/cloudflare/types/radar/dns/timeseries_group_query_type_response.py
index 34bd30918f0..f7f6f9b9d1b 100644
--- a/src/cloudflare/types/radar/dns/timeseries_group_query_type_response.py
+++ b/src/cloudflare/types/radar/dns/timeseries_group_query_type_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns/timeseries_group_response_code_response.py b/src/cloudflare/types/radar/dns/timeseries_group_response_code_response.py
index b7a24af12e9..946e3d6c6e3 100644
--- a/src/cloudflare/types/radar/dns/timeseries_group_response_code_response.py
+++ b/src/cloudflare/types/radar/dns/timeseries_group_response_code_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns/timeseries_group_response_ttl_response.py b/src/cloudflare/types/radar/dns/timeseries_group_response_ttl_response.py
index 8c0ac7038d8..0f101292d54 100644
--- a/src/cloudflare/types/radar/dns/timeseries_group_response_ttl_response.py
+++ b/src/cloudflare/types/radar/dns/timeseries_group_response_ttl_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns/top_ases_response.py b/src/cloudflare/types/radar/dns/top_ases_response.py
index f685c56c0b2..e6a300f7621 100644
--- a/src/cloudflare/types/radar/dns/top_ases_response.py
+++ b/src/cloudflare/types/radar/dns/top_ases_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns/top_locations_response.py b/src/cloudflare/types/radar/dns/top_locations_response.py
index 769fffedb1a..693391ae114 100644
--- a/src/cloudflare/types/radar/dns/top_locations_response.py
+++ b/src/cloudflare/types/radar/dns/top_locations_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns_summary_v2_response.py b/src/cloudflare/types/radar/dns_summary_v2_response.py
index 1037878f611..1f495dd8107 100644
--- a/src/cloudflare/types/radar/dns_summary_v2_response.py
+++ b/src/cloudflare/types/radar/dns_summary_v2_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns_timeseries_groups_v2_response.py b/src/cloudflare/types/radar/dns_timeseries_groups_v2_response.py
index a0010f5494b..af3e2b01eb4 100644
--- a/src/cloudflare/types/radar/dns_timeseries_groups_v2_response.py
+++ b/src/cloudflare/types/radar/dns_timeseries_groups_v2_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/dns_timeseries_response.py b/src/cloudflare/types/radar/dns_timeseries_response.py
index 49dd2738272..8ea3fdb6477 100644
--- a/src/cloudflare/types/radar/dns_timeseries_response.py
+++ b/src/cloudflare/types/radar/dns_timeseries_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/routing/summary_arc_response.py b/src/cloudflare/types/radar/email/routing/summary_arc_response.py
index 4d69d4b99d9..59c7d80c786 100644
--- a/src/cloudflare/types/radar/email/routing/summary_arc_response.py
+++ b/src/cloudflare/types/radar/email/routing/summary_arc_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/routing/summary_dkim_response.py b/src/cloudflare/types/radar/email/routing/summary_dkim_response.py
index 29cb4c47445..e7612b54c0c 100644
--- a/src/cloudflare/types/radar/email/routing/summary_dkim_response.py
+++ b/src/cloudflare/types/radar/email/routing/summary_dkim_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/routing/summary_dmarc_response.py b/src/cloudflare/types/radar/email/routing/summary_dmarc_response.py
index f0068fdc733..fbc098b6bc6 100644
--- a/src/cloudflare/types/radar/email/routing/summary_dmarc_response.py
+++ b/src/cloudflare/types/radar/email/routing/summary_dmarc_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/routing/summary_encrypted_response.py b/src/cloudflare/types/radar/email/routing/summary_encrypted_response.py
index 7839185cdd3..6f1decc2760 100644
--- a/src/cloudflare/types/radar/email/routing/summary_encrypted_response.py
+++ b/src/cloudflare/types/radar/email/routing/summary_encrypted_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/routing/summary_ip_version_response.py b/src/cloudflare/types/radar/email/routing/summary_ip_version_response.py
index 63a07734f7b..e2d5fb89b04 100644
--- a/src/cloudflare/types/radar/email/routing/summary_ip_version_response.py
+++ b/src/cloudflare/types/radar/email/routing/summary_ip_version_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/routing/summary_spf_response.py b/src/cloudflare/types/radar/email/routing/summary_spf_response.py
index f052a467858..bf61ca1656a 100644
--- a/src/cloudflare/types/radar/email/routing/summary_spf_response.py
+++ b/src/cloudflare/types/radar/email/routing/summary_spf_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/routing/timeseries_group_arc_response.py b/src/cloudflare/types/radar/email/routing/timeseries_group_arc_response.py
index f794bc222d9..ff78c6b5a20 100644
--- a/src/cloudflare/types/radar/email/routing/timeseries_group_arc_response.py
+++ b/src/cloudflare/types/radar/email/routing/timeseries_group_arc_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/routing/timeseries_group_dkim_response.py b/src/cloudflare/types/radar/email/routing/timeseries_group_dkim_response.py
index 2175032f6df..10457c5c5aa 100644
--- a/src/cloudflare/types/radar/email/routing/timeseries_group_dkim_response.py
+++ b/src/cloudflare/types/radar/email/routing/timeseries_group_dkim_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/routing/timeseries_group_dmarc_response.py b/src/cloudflare/types/radar/email/routing/timeseries_group_dmarc_response.py
index af824448ea3..9760e9e941e 100644
--- a/src/cloudflare/types/radar/email/routing/timeseries_group_dmarc_response.py
+++ b/src/cloudflare/types/radar/email/routing/timeseries_group_dmarc_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/routing/timeseries_group_encrypted_response.py b/src/cloudflare/types/radar/email/routing/timeseries_group_encrypted_response.py
index 5d7425073da..552557c37a5 100644
--- a/src/cloudflare/types/radar/email/routing/timeseries_group_encrypted_response.py
+++ b/src/cloudflare/types/radar/email/routing/timeseries_group_encrypted_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/routing/timeseries_group_ip_version_response.py b/src/cloudflare/types/radar/email/routing/timeseries_group_ip_version_response.py
index 5edd0161517..8d6513c374b 100644
--- a/src/cloudflare/types/radar/email/routing/timeseries_group_ip_version_response.py
+++ b/src/cloudflare/types/radar/email/routing/timeseries_group_ip_version_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/routing/timeseries_group_spf_response.py b/src/cloudflare/types/radar/email/routing/timeseries_group_spf_response.py
index 6c8e5d03f39..ba150c01826 100644
--- a/src/cloudflare/types/radar/email/routing/timeseries_group_spf_response.py
+++ b/src/cloudflare/types/radar/email/routing/timeseries_group_spf_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/routing_summary_v2_response.py b/src/cloudflare/types/radar/email/routing_summary_v2_response.py
index 63b7bf4be63..de722fa64d7 100644
--- a/src/cloudflare/types/radar/email/routing_summary_v2_response.py
+++ b/src/cloudflare/types/radar/email/routing_summary_v2_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/routing_timeseries_groups_v2_response.py b/src/cloudflare/types/radar/email/routing_timeseries_groups_v2_response.py
index 1b064a0ccc6..14d184c5221 100644
--- a/src/cloudflare/types/radar/email/routing_timeseries_groups_v2_response.py
+++ b/src/cloudflare/types/radar/email/routing_timeseries_groups_v2_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/security/summary_arc_response.py b/src/cloudflare/types/radar/email/security/summary_arc_response.py
index 4d69d4b99d9..59c7d80c786 100644
--- a/src/cloudflare/types/radar/email/security/summary_arc_response.py
+++ b/src/cloudflare/types/radar/email/security/summary_arc_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/security/summary_dkim_response.py b/src/cloudflare/types/radar/email/security/summary_dkim_response.py
index 29cb4c47445..e7612b54c0c 100644
--- a/src/cloudflare/types/radar/email/security/summary_dkim_response.py
+++ b/src/cloudflare/types/radar/email/security/summary_dkim_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/security/summary_dmarc_response.py b/src/cloudflare/types/radar/email/security/summary_dmarc_response.py
index f0068fdc733..fbc098b6bc6 100644
--- a/src/cloudflare/types/radar/email/security/summary_dmarc_response.py
+++ b/src/cloudflare/types/radar/email/security/summary_dmarc_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/security/summary_malicious_response.py b/src/cloudflare/types/radar/email/security/summary_malicious_response.py
index 992e40274f6..61b36ca6763 100644
--- a/src/cloudflare/types/radar/email/security/summary_malicious_response.py
+++ b/src/cloudflare/types/radar/email/security/summary_malicious_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/security/summary_spam_response.py b/src/cloudflare/types/radar/email/security/summary_spam_response.py
index d1887a06c06..677c3c1599f 100644
--- a/src/cloudflare/types/radar/email/security/summary_spam_response.py
+++ b/src/cloudflare/types/radar/email/security/summary_spam_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/security/summary_spf_response.py b/src/cloudflare/types/radar/email/security/summary_spf_response.py
index f052a467858..bf61ca1656a 100644
--- a/src/cloudflare/types/radar/email/security/summary_spf_response.py
+++ b/src/cloudflare/types/radar/email/security/summary_spf_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/security/summary_spoof_response.py b/src/cloudflare/types/radar/email/security/summary_spoof_response.py
index 9865f46d642..0a63a2386b1 100644
--- a/src/cloudflare/types/radar/email/security/summary_spoof_response.py
+++ b/src/cloudflare/types/radar/email/security/summary_spoof_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/security/summary_threat_category_response.py b/src/cloudflare/types/radar/email/security/summary_threat_category_response.py
index d0fa7a7a84d..7609b567b46 100644
--- a/src/cloudflare/types/radar/email/security/summary_threat_category_response.py
+++ b/src/cloudflare/types/radar/email/security/summary_threat_category_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/security/summary_tls_version_response.py b/src/cloudflare/types/radar/email/security/summary_tls_version_response.py
index 2370529a831..a89af0fb586 100644
--- a/src/cloudflare/types/radar/email/security/summary_tls_version_response.py
+++ b/src/cloudflare/types/radar/email/security/summary_tls_version_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/security/timeseries_group_arc_response.py b/src/cloudflare/types/radar/email/security/timeseries_group_arc_response.py
index f794bc222d9..ff78c6b5a20 100644
--- a/src/cloudflare/types/radar/email/security/timeseries_group_arc_response.py
+++ b/src/cloudflare/types/radar/email/security/timeseries_group_arc_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/security/timeseries_group_dkim_response.py b/src/cloudflare/types/radar/email/security/timeseries_group_dkim_response.py
index 2175032f6df..10457c5c5aa 100644
--- a/src/cloudflare/types/radar/email/security/timeseries_group_dkim_response.py
+++ b/src/cloudflare/types/radar/email/security/timeseries_group_dkim_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/security/timeseries_group_dmarc_response.py b/src/cloudflare/types/radar/email/security/timeseries_group_dmarc_response.py
index af824448ea3..9760e9e941e 100644
--- a/src/cloudflare/types/radar/email/security/timeseries_group_dmarc_response.py
+++ b/src/cloudflare/types/radar/email/security/timeseries_group_dmarc_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/security/timeseries_group_malicious_response.py b/src/cloudflare/types/radar/email/security/timeseries_group_malicious_response.py
index 259eecd2e1f..497a2f56492 100644
--- a/src/cloudflare/types/radar/email/security/timeseries_group_malicious_response.py
+++ b/src/cloudflare/types/radar/email/security/timeseries_group_malicious_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/security/timeseries_group_spam_response.py b/src/cloudflare/types/radar/email/security/timeseries_group_spam_response.py
index 7b97ba85120..c934ffe8537 100644
--- a/src/cloudflare/types/radar/email/security/timeseries_group_spam_response.py
+++ b/src/cloudflare/types/radar/email/security/timeseries_group_spam_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/security/timeseries_group_spf_response.py b/src/cloudflare/types/radar/email/security/timeseries_group_spf_response.py
index 6c8e5d03f39..ba150c01826 100644
--- a/src/cloudflare/types/radar/email/security/timeseries_group_spf_response.py
+++ b/src/cloudflare/types/radar/email/security/timeseries_group_spf_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/security/timeseries_group_spoof_response.py b/src/cloudflare/types/radar/email/security/timeseries_group_spoof_response.py
index 04fe2c4b789..5eba504db5d 100644
--- a/src/cloudflare/types/radar/email/security/timeseries_group_spoof_response.py
+++ b/src/cloudflare/types/radar/email/security/timeseries_group_spoof_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/security/timeseries_group_threat_category_response.py b/src/cloudflare/types/radar/email/security/timeseries_group_threat_category_response.py
index 61b82e6df48..d139e0b21ce 100644
--- a/src/cloudflare/types/radar/email/security/timeseries_group_threat_category_response.py
+++ b/src/cloudflare/types/radar/email/security/timeseries_group_threat_category_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/security/timeseries_group_tls_version_response.py b/src/cloudflare/types/radar/email/security/timeseries_group_tls_version_response.py
index d5edabd5367..6d9b5846f99 100644
--- a/src/cloudflare/types/radar/email/security/timeseries_group_tls_version_response.py
+++ b/src/cloudflare/types/radar/email/security/timeseries_group_tls_version_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/security/top/tld_get_response.py b/src/cloudflare/types/radar/email/security/top/tld_get_response.py
index 97395a5f335..67d50cef584 100644
--- a/src/cloudflare/types/radar/email/security/top/tld_get_response.py
+++ b/src/cloudflare/types/radar/email/security/top/tld_get_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/security/top/tlds/malicious_get_response.py b/src/cloudflare/types/radar/email/security/top/tlds/malicious_get_response.py
index 897c38f61ce..e8731b0037a 100644
--- a/src/cloudflare/types/radar/email/security/top/tlds/malicious_get_response.py
+++ b/src/cloudflare/types/radar/email/security/top/tlds/malicious_get_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/security/top/tlds/spam_get_response.py b/src/cloudflare/types/radar/email/security/top/tlds/spam_get_response.py
index 4d2b2c90b5f..ea90c7121db 100644
--- a/src/cloudflare/types/radar/email/security/top/tlds/spam_get_response.py
+++ b/src/cloudflare/types/radar/email/security/top/tlds/spam_get_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/security/top/tlds/spoof_get_response.py b/src/cloudflare/types/radar/email/security/top/tlds/spoof_get_response.py
index e6c0777a185..7eb889e7adc 100644
--- a/src/cloudflare/types/radar/email/security/top/tlds/spoof_get_response.py
+++ b/src/cloudflare/types/radar/email/security/top/tlds/spoof_get_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/security_summary_v2_response.py b/src/cloudflare/types/radar/email/security_summary_v2_response.py
index 53cdb0bb538..6620f820edc 100644
--- a/src/cloudflare/types/radar/email/security_summary_v2_response.py
+++ b/src/cloudflare/types/radar/email/security_summary_v2_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/email/security_timeseries_groups_v2_response.py b/src/cloudflare/types/radar/email/security_timeseries_groups_v2_response.py
index 2248365b971..64b38cadf7a 100644
--- a/src/cloudflare/types/radar/email/security_timeseries_groups_v2_response.py
+++ b/src/cloudflare/types/radar/email/security_timeseries_groups_v2_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/entities/asn_list_response.py b/src/cloudflare/types/radar/entities/asn_list_response.py
index 9a6d5b811ca..4ecb4de1ec3 100644
--- a/src/cloudflare/types/radar/entities/asn_list_response.py
+++ b/src/cloudflare/types/radar/entities/asn_list_response.py
@@ -6,7 +6,12 @@
from ...._models import BaseModel
-__all__ = ["ASNListResponse", "ASN"]
+__all__ = ["ASNListResponse", "ASN", "ASNEstimatedUsers"]
+
+
+class ASNEstimatedUsers(BaseModel):
+ estimated_users: Optional[int] = FieldInfo(alias="estimatedUsers", default=None)
+ """Total estimated users."""
class ASN(BaseModel):
@@ -16,6 +21,8 @@ class ASN(BaseModel):
country_name: str = FieldInfo(alias="countryName")
+ estimated_users: ASNEstimatedUsers = FieldInfo(alias="estimatedUsers")
+
name: str
aka: Optional[str] = None
diff --git a/src/cloudflare/types/radar/http/ase_get_response.py b/src/cloudflare/types/radar/http/ase_get_response.py
index 057053085ad..dec648a5e53 100644
--- a/src/cloudflare/types/radar/http/ase_get_response.py
+++ b/src/cloudflare/types/radar/http/ase_get_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/ases/bot_class_get_response.py b/src/cloudflare/types/radar/http/ases/bot_class_get_response.py
index e466ffacad6..3a9cea219a4 100644
--- a/src/cloudflare/types/radar/http/ases/bot_class_get_response.py
+++ b/src/cloudflare/types/radar/http/ases/bot_class_get_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/ases/browser_family_get_response.py b/src/cloudflare/types/radar/http/ases/browser_family_get_response.py
index 8f204c5a612..bc0b4e4a50a 100644
--- a/src/cloudflare/types/radar/http/ases/browser_family_get_response.py
+++ b/src/cloudflare/types/radar/http/ases/browser_family_get_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/ases/device_type_get_response.py b/src/cloudflare/types/radar/http/ases/device_type_get_response.py
index 6e5b7f161d0..c2cb89a7384 100644
--- a/src/cloudflare/types/radar/http/ases/device_type_get_response.py
+++ b/src/cloudflare/types/radar/http/ases/device_type_get_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/ases/http_method_get_response.py b/src/cloudflare/types/radar/http/ases/http_method_get_response.py
index da88f7cf95f..2c25a395ebd 100644
--- a/src/cloudflare/types/radar/http/ases/http_method_get_response.py
+++ b/src/cloudflare/types/radar/http/ases/http_method_get_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/ases/http_protocol_get_response.py b/src/cloudflare/types/radar/http/ases/http_protocol_get_response.py
index aeb2833d011..f5625f19e18 100644
--- a/src/cloudflare/types/radar/http/ases/http_protocol_get_response.py
+++ b/src/cloudflare/types/radar/http/ases/http_protocol_get_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/ases/ip_version_get_response.py b/src/cloudflare/types/radar/http/ases/ip_version_get_response.py
index 267488f6431..d2b14fca2be 100644
--- a/src/cloudflare/types/radar/http/ases/ip_version_get_response.py
+++ b/src/cloudflare/types/radar/http/ases/ip_version_get_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/ases/os_get_response.py b/src/cloudflare/types/radar/http/ases/os_get_response.py
index b1b43b9a4ee..64f6e605c3c 100644
--- a/src/cloudflare/types/radar/http/ases/os_get_response.py
+++ b/src/cloudflare/types/radar/http/ases/os_get_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/ases/tls_version_get_response.py b/src/cloudflare/types/radar/http/ases/tls_version_get_response.py
index e3ba28601d7..6ef1300fc5e 100644
--- a/src/cloudflare/types/radar/http/ases/tls_version_get_response.py
+++ b/src/cloudflare/types/radar/http/ases/tls_version_get_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/location_get_response.py b/src/cloudflare/types/radar/http/location_get_response.py
index dd7c049b11d..c3e39123879 100644
--- a/src/cloudflare/types/radar/http/location_get_response.py
+++ b/src/cloudflare/types/radar/http/location_get_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/locations/bot_class_get_response.py b/src/cloudflare/types/radar/http/locations/bot_class_get_response.py
index 0443c0b2f78..edbad935516 100644
--- a/src/cloudflare/types/radar/http/locations/bot_class_get_response.py
+++ b/src/cloudflare/types/radar/http/locations/bot_class_get_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/locations/browser_family_get_response.py b/src/cloudflare/types/radar/http/locations/browser_family_get_response.py
index 1d28b93a506..fc2e87364fb 100644
--- a/src/cloudflare/types/radar/http/locations/browser_family_get_response.py
+++ b/src/cloudflare/types/radar/http/locations/browser_family_get_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/locations/device_type_get_response.py b/src/cloudflare/types/radar/http/locations/device_type_get_response.py
index 61781eede93..810f0e42750 100644
--- a/src/cloudflare/types/radar/http/locations/device_type_get_response.py
+++ b/src/cloudflare/types/radar/http/locations/device_type_get_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/locations/http_method_get_response.py b/src/cloudflare/types/radar/http/locations/http_method_get_response.py
index 626ee155c1d..100feacaab0 100644
--- a/src/cloudflare/types/radar/http/locations/http_method_get_response.py
+++ b/src/cloudflare/types/radar/http/locations/http_method_get_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/locations/http_protocol_get_response.py b/src/cloudflare/types/radar/http/locations/http_protocol_get_response.py
index c03b70ca252..78d3141e77d 100644
--- a/src/cloudflare/types/radar/http/locations/http_protocol_get_response.py
+++ b/src/cloudflare/types/radar/http/locations/http_protocol_get_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/locations/ip_version_get_response.py b/src/cloudflare/types/radar/http/locations/ip_version_get_response.py
index 17a28152528..c2867260d6e 100644
--- a/src/cloudflare/types/radar/http/locations/ip_version_get_response.py
+++ b/src/cloudflare/types/radar/http/locations/ip_version_get_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/locations/os_get_response.py b/src/cloudflare/types/radar/http/locations/os_get_response.py
index b4eadc435ef..37367999c9c 100644
--- a/src/cloudflare/types/radar/http/locations/os_get_response.py
+++ b/src/cloudflare/types/radar/http/locations/os_get_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/locations/tls_version_get_response.py b/src/cloudflare/types/radar/http/locations/tls_version_get_response.py
index 002f26143fc..2628cb19bfc 100644
--- a/src/cloudflare/types/radar/http/locations/tls_version_get_response.py
+++ b/src/cloudflare/types/radar/http/locations/tls_version_get_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/summary_bot_class_response.py b/src/cloudflare/types/radar/http/summary_bot_class_response.py
index afbd3010507..1618d81e5b2 100644
--- a/src/cloudflare/types/radar/http/summary_bot_class_response.py
+++ b/src/cloudflare/types/radar/http/summary_bot_class_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/summary_device_type_response.py b/src/cloudflare/types/radar/http/summary_device_type_response.py
index 698f161ed2b..1c228365cb4 100644
--- a/src/cloudflare/types/radar/http/summary_device_type_response.py
+++ b/src/cloudflare/types/radar/http/summary_device_type_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/summary_http_protocol_response.py b/src/cloudflare/types/radar/http/summary_http_protocol_response.py
index 175ee7a636c..0e5b95c1d06 100644
--- a/src/cloudflare/types/radar/http/summary_http_protocol_response.py
+++ b/src/cloudflare/types/radar/http/summary_http_protocol_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/summary_http_version_response.py b/src/cloudflare/types/radar/http/summary_http_version_response.py
index ae82c2137b4..eff64e3dedd 100644
--- a/src/cloudflare/types/radar/http/summary_http_version_response.py
+++ b/src/cloudflare/types/radar/http/summary_http_version_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/summary_ip_version_response.py b/src/cloudflare/types/radar/http/summary_ip_version_response.py
index c73c7cf94ab..cd6964bac8f 100644
--- a/src/cloudflare/types/radar/http/summary_ip_version_response.py
+++ b/src/cloudflare/types/radar/http/summary_ip_version_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/summary_os_response.py b/src/cloudflare/types/radar/http/summary_os_response.py
index ee1fa00b9c0..12acbbf4644 100644
--- a/src/cloudflare/types/radar/http/summary_os_response.py
+++ b/src/cloudflare/types/radar/http/summary_os_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/summary_post_quantum_response.py b/src/cloudflare/types/radar/http/summary_post_quantum_response.py
index 5153ef3c945..9d754f5af39 100644
--- a/src/cloudflare/types/radar/http/summary_post_quantum_response.py
+++ b/src/cloudflare/types/radar/http/summary_post_quantum_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/summary_tls_version_response.py b/src/cloudflare/types/radar/http/summary_tls_version_response.py
index 78bac27a4cf..e9a86952b4a 100644
--- a/src/cloudflare/types/radar/http/summary_tls_version_response.py
+++ b/src/cloudflare/types/radar/http/summary_tls_version_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/timeseries_group_bot_class_response.py b/src/cloudflare/types/radar/http/timeseries_group_bot_class_response.py
index 25f6571e89f..189c053f6c2 100644
--- a/src/cloudflare/types/radar/http/timeseries_group_bot_class_response.py
+++ b/src/cloudflare/types/radar/http/timeseries_group_bot_class_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/timeseries_group_browser_family_response.py b/src/cloudflare/types/radar/http/timeseries_group_browser_family_response.py
index cb0dc1360fb..e3c1a968a8d 100644
--- a/src/cloudflare/types/radar/http/timeseries_group_browser_family_response.py
+++ b/src/cloudflare/types/radar/http/timeseries_group_browser_family_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/timeseries_group_browser_response.py b/src/cloudflare/types/radar/http/timeseries_group_browser_response.py
index 3331f836452..9bce53cb6e4 100644
--- a/src/cloudflare/types/radar/http/timeseries_group_browser_response.py
+++ b/src/cloudflare/types/radar/http/timeseries_group_browser_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/timeseries_group_device_type_response.py b/src/cloudflare/types/radar/http/timeseries_group_device_type_response.py
index 473b5c8d9a7..647125605d6 100644
--- a/src/cloudflare/types/radar/http/timeseries_group_device_type_response.py
+++ b/src/cloudflare/types/radar/http/timeseries_group_device_type_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/timeseries_group_http_protocol_response.py b/src/cloudflare/types/radar/http/timeseries_group_http_protocol_response.py
index a2461f21c09..81d2f944b18 100644
--- a/src/cloudflare/types/radar/http/timeseries_group_http_protocol_response.py
+++ b/src/cloudflare/types/radar/http/timeseries_group_http_protocol_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/timeseries_group_http_version_response.py b/src/cloudflare/types/radar/http/timeseries_group_http_version_response.py
index b3a4f0fcfb1..4c1d13e6471 100644
--- a/src/cloudflare/types/radar/http/timeseries_group_http_version_response.py
+++ b/src/cloudflare/types/radar/http/timeseries_group_http_version_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/timeseries_group_ip_version_response.py b/src/cloudflare/types/radar/http/timeseries_group_ip_version_response.py
index f248fede91f..6cf6b141c04 100644
--- a/src/cloudflare/types/radar/http/timeseries_group_ip_version_response.py
+++ b/src/cloudflare/types/radar/http/timeseries_group_ip_version_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/timeseries_group_os_response.py b/src/cloudflare/types/radar/http/timeseries_group_os_response.py
index 980d4f9487c..60e15f72d0b 100644
--- a/src/cloudflare/types/radar/http/timeseries_group_os_response.py
+++ b/src/cloudflare/types/radar/http/timeseries_group_os_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/timeseries_group_post_quantum_response.py b/src/cloudflare/types/radar/http/timeseries_group_post_quantum_response.py
index b31bc2c0424..ad2d0a7f39e 100644
--- a/src/cloudflare/types/radar/http/timeseries_group_post_quantum_response.py
+++ b/src/cloudflare/types/radar/http/timeseries_group_post_quantum_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/timeseries_group_tls_version_response.py b/src/cloudflare/types/radar/http/timeseries_group_tls_version_response.py
index 9396994db09..c0991aecd14 100644
--- a/src/cloudflare/types/radar/http/timeseries_group_tls_version_response.py
+++ b/src/cloudflare/types/radar/http/timeseries_group_tls_version_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/top_browser_family_response.py b/src/cloudflare/types/radar/http/top_browser_family_response.py
index f895cf7d0b9..01ef51f81b0 100644
--- a/src/cloudflare/types/radar/http/top_browser_family_response.py
+++ b/src/cloudflare/types/radar/http/top_browser_family_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http/top_browser_response.py b/src/cloudflare/types/radar/http/top_browser_response.py
index 74712c28078..591eb65780f 100644
--- a/src/cloudflare/types/radar/http/top_browser_response.py
+++ b/src/cloudflare/types/radar/http/top_browser_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http_summary_v2_response.py b/src/cloudflare/types/radar/http_summary_v2_response.py
index 8b9c31f296c..758c542d2c7 100644
--- a/src/cloudflare/types/radar/http_summary_v2_response.py
+++ b/src/cloudflare/types/radar/http_summary_v2_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http_timeseries_groups_v2_response.py b/src/cloudflare/types/radar/http_timeseries_groups_v2_response.py
index 197ea50ecbe..22f2abbdef8 100644
--- a/src/cloudflare/types/radar/http_timeseries_groups_v2_response.py
+++ b/src/cloudflare/types/radar/http_timeseries_groups_v2_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/http_timeseries_response.py b/src/cloudflare/types/radar/http_timeseries_response.py
index 32ef330631d..dd63ddd82f4 100644
--- a/src/cloudflare/types/radar/http_timeseries_response.py
+++ b/src/cloudflare/types/radar/http_timeseries_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/leaked_credential_summary_v2_response.py b/src/cloudflare/types/radar/leaked_credential_summary_v2_response.py
index 66addb9b232..4093cc4a6ce 100644
--- a/src/cloudflare/types/radar/leaked_credential_summary_v2_response.py
+++ b/src/cloudflare/types/radar/leaked_credential_summary_v2_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/leaked_credential_timeseries_groups_v2_response.py b/src/cloudflare/types/radar/leaked_credential_timeseries_groups_v2_response.py
index 14bf74a6c4a..07cbcd7e017 100644
--- a/src/cloudflare/types/radar/leaked_credential_timeseries_groups_v2_response.py
+++ b/src/cloudflare/types/radar/leaked_credential_timeseries_groups_v2_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/leaked_credentials/summary_bot_class_response.py b/src/cloudflare/types/radar/leaked_credentials/summary_bot_class_response.py
index afbd3010507..1618d81e5b2 100644
--- a/src/cloudflare/types/radar/leaked_credentials/summary_bot_class_response.py
+++ b/src/cloudflare/types/radar/leaked_credentials/summary_bot_class_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/leaked_credentials/summary_compromised_response.py b/src/cloudflare/types/radar/leaked_credentials/summary_compromised_response.py
index 1164daca230..30d650305ea 100644
--- a/src/cloudflare/types/radar/leaked_credentials/summary_compromised_response.py
+++ b/src/cloudflare/types/radar/leaked_credentials/summary_compromised_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/leaked_credentials/timeseries_group_bot_class_response.py b/src/cloudflare/types/radar/leaked_credentials/timeseries_group_bot_class_response.py
index 25f6571e89f..189c053f6c2 100644
--- a/src/cloudflare/types/radar/leaked_credentials/timeseries_group_bot_class_response.py
+++ b/src/cloudflare/types/radar/leaked_credentials/timeseries_group_bot_class_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/leaked_credentials/timeseries_group_compromised_response.py b/src/cloudflare/types/radar/leaked_credentials/timeseries_group_compromised_response.py
index d2198c39168..7af113210af 100644
--- a/src/cloudflare/types/radar/leaked_credentials/timeseries_group_compromised_response.py
+++ b/src/cloudflare/types/radar/leaked_credentials/timeseries_group_compromised_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/netflows/top_ases_response.py b/src/cloudflare/types/radar/netflows/top_ases_response.py
index a17dfa3dfc6..8df60d427c9 100644
--- a/src/cloudflare/types/radar/netflows/top_ases_response.py
+++ b/src/cloudflare/types/radar/netflows/top_ases_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/netflows/top_locations_response.py b/src/cloudflare/types/radar/netflows/top_locations_response.py
index 769fffedb1a..693391ae114 100644
--- a/src/cloudflare/types/radar/netflows/top_locations_response.py
+++ b/src/cloudflare/types/radar/netflows/top_locations_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/netflows_summary_response.py b/src/cloudflare/types/radar/netflows_summary_response.py
index 0a16fe93b0a..e45fae470e0 100644
--- a/src/cloudflare/types/radar/netflows_summary_response.py
+++ b/src/cloudflare/types/radar/netflows_summary_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/netflows_summary_v2_response.py b/src/cloudflare/types/radar/netflows_summary_v2_response.py
index f01f57d71f1..a09bd8a57af 100644
--- a/src/cloudflare/types/radar/netflows_summary_v2_response.py
+++ b/src/cloudflare/types/radar/netflows_summary_v2_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/netflows_timeseries_groups_response.py b/src/cloudflare/types/radar/netflows_timeseries_groups_response.py
index d34b9e51e3c..67f528e4450 100644
--- a/src/cloudflare/types/radar/netflows_timeseries_groups_response.py
+++ b/src/cloudflare/types/radar/netflows_timeseries_groups_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/netflows_timeseries_response.py b/src/cloudflare/types/radar/netflows_timeseries_response.py
index 4bfadcc6b39..5c8f8120406 100644
--- a/src/cloudflare/types/radar/netflows_timeseries_response.py
+++ b/src/cloudflare/types/radar/netflows_timeseries_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/post_quantum/origin_summary_response.py b/src/cloudflare/types/radar/post_quantum/origin_summary_response.py
index 13c6f1e4089..2727348fc2b 100644
--- a/src/cloudflare/types/radar/post_quantum/origin_summary_response.py
+++ b/src/cloudflare/types/radar/post_quantum/origin_summary_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Dict, List
+from typing import Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -66,6 +66,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/post_quantum/origin_timeseries_groups_response.py b/src/cloudflare/types/radar/post_quantum/origin_timeseries_groups_response.py
index 90d8e47485d..2d36312b9f9 100644
--- a/src/cloudflare/types/radar/post_quantum/origin_timeseries_groups_response.py
+++ b/src/cloudflare/types/radar/post_quantum/origin_timeseries_groups_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/quality/iqi_summary_response.py b/src/cloudflare/types/radar/quality/iqi_summary_response.py
index 6a10397cc29..e596d057f5c 100644
--- a/src/cloudflare/types/radar/quality/iqi_summary_response.py
+++ b/src/cloudflare/types/radar/quality/iqi_summary_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/quality/iqi_timeseries_groups_response.py b/src/cloudflare/types/radar/quality/iqi_timeseries_groups_response.py
index 0c110337491..6ca3569f744 100644
--- a/src/cloudflare/types/radar/quality/iqi_timeseries_groups_response.py
+++ b/src/cloudflare/types/radar/quality/iqi_timeseries_groups_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List
+from typing import TYPE_CHECKING, Dict, List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/quality/speed/top_ases_response.py b/src/cloudflare/types/radar/quality/speed/top_ases_response.py
index 486d34026cc..2ef431a2ebc 100644
--- a/src/cloudflare/types/radar/quality/speed/top_ases_response.py
+++ b/src/cloudflare/types/radar/quality/speed/top_ases_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/quality/speed/top_locations_response.py b/src/cloudflare/types/radar/quality/speed/top_locations_response.py
index 9818f6086d2..dec776541fb 100644
--- a/src/cloudflare/types/radar/quality/speed/top_locations_response.py
+++ b/src/cloudflare/types/radar/quality/speed/top_locations_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/quality/speed_histogram_response.py b/src/cloudflare/types/radar/quality/speed_histogram_response.py
index ffd09307396..ac1acbab89b 100644
--- a/src/cloudflare/types/radar/quality/speed_histogram_response.py
+++ b/src/cloudflare/types/radar/quality/speed_histogram_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -75,6 +75,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/quality/speed_summary_response.py b/src/cloudflare/types/radar/quality/speed_summary_response.py
index c2dd186e3f7..fbfd14dc370 100644
--- a/src/cloudflare/types/radar/quality/speed_summary_response.py
+++ b/src/cloudflare/types/radar/quality/speed_summary_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/ranking/internet_service_timeseries_groups_response.py b/src/cloudflare/types/radar/ranking/internet_service_timeseries_groups_response.py
index ef30aa8a860..9cceaf12b9e 100644
--- a/src/cloudflare/types/radar/ranking/internet_service_timeseries_groups_response.py
+++ b/src/cloudflare/types/radar/ranking/internet_service_timeseries_groups_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List, Union
+from typing import TYPE_CHECKING, Dict, List, Union, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/ranking/internet_service_top_response.py b/src/cloudflare/types/radar/ranking/internet_service_top_response.py
index b8f52279a08..74273e77f17 100644
--- a/src/cloudflare/types/radar/ranking/internet_service_top_response.py
+++ b/src/cloudflare/types/radar/ranking/internet_service_top_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/ranking_timeseries_groups_response.py b/src/cloudflare/types/radar/ranking_timeseries_groups_response.py
index 29e55b96554..bbc70b02d33 100644
--- a/src/cloudflare/types/radar/ranking_timeseries_groups_response.py
+++ b/src/cloudflare/types/radar/ranking_timeseries_groups_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import TYPE_CHECKING, Dict, List, Union
+from typing import TYPE_CHECKING, Dict, List, Union, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/ranking_top_response.py b/src/cloudflare/types/radar/ranking_top_response.py
index 5d15a40c37e..f22e77018b7 100644
--- a/src/cloudflare/types/radar/ranking_top_response.py
+++ b/src/cloudflare/types/radar/ranking_top_response.py
@@ -68,6 +68,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/robots_txt/top/user_agent_directive_response.py b/src/cloudflare/types/radar/robots_txt/top/user_agent_directive_response.py
index 9db786ab97f..9fb97f69d3f 100644
--- a/src/cloudflare/types/radar/robots_txt/top/user_agent_directive_response.py
+++ b/src/cloudflare/types/radar/robots_txt/top/user_agent_directive_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/robots_txt/top_domain_categories_response.py b/src/cloudflare/types/radar/robots_txt/top_domain_categories_response.py
index c0e570715bf..79b6a5c83e8 100644
--- a/src/cloudflare/types/radar/robots_txt/top_domain_categories_response.py
+++ b/src/cloudflare/types/radar/robots_txt/top_domain_categories_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/tcp_resets_timeout_summary_response.py b/src/cloudflare/types/radar/tcp_resets_timeout_summary_response.py
index 0b9f3fde2b4..f3355180faa 100644
--- a/src/cloudflare/types/radar/tcp_resets_timeout_summary_response.py
+++ b/src/cloudflare/types/radar/tcp_resets_timeout_summary_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/tcp_resets_timeout_timeseries_groups_response.py b/src/cloudflare/types/radar/tcp_resets_timeout_timeseries_groups_response.py
index 708465f5c15..2d77177b36a 100644
--- a/src/cloudflare/types/radar/tcp_resets_timeout_timeseries_groups_response.py
+++ b/src/cloudflare/types/radar/tcp_resets_timeout_timeseries_groups_response.py
@@ -1,6 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/verified_bots/top_bots_response.py b/src/cloudflare/types/radar/verified_bots/top_bots_response.py
index cbb12a5b287..a9d7ca5231d 100644
--- a/src/cloudflare/types/radar/verified_bots/top_bots_response.py
+++ b/src/cloudflare/types/radar/verified_bots/top_bots_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
diff --git a/src/cloudflare/types/radar/verified_bots/top_categories_response.py b/src/cloudflare/types/radar/verified_bots/top_categories_response.py
index ad4643077d2..757de1688f6 100644
--- a/src/cloudflare/types/radar/verified_bots/top_categories_response.py
+++ b/src/cloudflare/types/radar/verified_bots/top_categories_response.py
@@ -67,6 +67,8 @@ class MetaConfidenceInfoAnnotation(BaseModel):
start_date: datetime = FieldInfo(alias="startDate")
+ tags: Optional[List[str]] = None
+
class MetaConfidenceInfo(BaseModel):
annotations: List[MetaConfidenceInfoAnnotation]
From b982ff391eab267ef16c719d0fc798d970292ed2 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 15 Jun 2026 16:42:28 +0000
Subject: [PATCH 11/23] feat: feat(ai_gateway): add custom_providers resource
* feat(ai_gateway): add custom_providers resource
---
.stats.yml | 6 +-
.../resources/ai_gateway/__init__.py | 14 +
.../resources/ai_gateway/ai_gateway.py | 32 ++
src/cloudflare/resources/ai_gateway/api.md | 20 +
.../resources/ai_gateway/custom_providers.py | 538 ++++++++++++++++++
src/cloudflare/types/ai_gateway/__init__.py | 6 +
.../custom_provider_create_params.py | 33 ++
.../custom_provider_create_response.py | 40 ++
.../custom_provider_delete_response.py | 40 ++
.../custom_provider_get_response.py | 40 ++
.../ai_gateway/custom_provider_list_params.py | 22 +
.../custom_provider_list_response.py | 40 ++
.../ai_gateway/test_custom_providers.py | 462 +++++++++++++++
13 files changed, 1290 insertions(+), 3 deletions(-)
create mode 100644 src/cloudflare/resources/ai_gateway/custom_providers.py
create mode 100644 src/cloudflare/types/ai_gateway/custom_provider_create_params.py
create mode 100644 src/cloudflare/types/ai_gateway/custom_provider_create_response.py
create mode 100644 src/cloudflare/types/ai_gateway/custom_provider_delete_response.py
create mode 100644 src/cloudflare/types/ai_gateway/custom_provider_get_response.py
create mode 100644 src/cloudflare/types/ai_gateway/custom_provider_list_params.py
create mode 100644 src/cloudflare/types/ai_gateway/custom_provider_list_response.py
create mode 100644 tests/api_resources/ai_gateway/test_custom_providers.py
diff --git a/.stats.yml b/.stats.yml
index e35843d9f07..0548f899893 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 2384
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-471f2a9448b10c4c887be1fce3238a5f0ad296e80077090093fc9f52a0d99675.yml
+configured_endpoints: 2388
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-1f58da61ef137d93446336e6c2c36bdd7bd1a6f56bb4ddb819090b7cecebe210.yml
openapi_spec_hash: c072a4a84aa2d1de3b656ae5fe7967f8
-config_hash: fb7701532a56b6f947632365deb733af
+config_hash: f81f9e27d86c53b33ee1f1f3654ef3c6
diff --git a/src/cloudflare/resources/ai_gateway/__init__.py b/src/cloudflare/resources/ai_gateway/__init__.py
index 1e953d202f6..38c4c3d8f6b 100644
--- a/src/cloudflare/resources/ai_gateway/__init__.py
+++ b/src/cloudflare/resources/ai_gateway/__init__.py
@@ -56,6 +56,14 @@
DynamicRoutingResourceWithStreamingResponse,
AsyncDynamicRoutingResourceWithStreamingResponse,
)
+from .custom_providers import (
+ CustomProvidersResource,
+ AsyncCustomProvidersResource,
+ CustomProvidersResourceWithRawResponse,
+ AsyncCustomProvidersResourceWithRawResponse,
+ CustomProvidersResourceWithStreamingResponse,
+ AsyncCustomProvidersResourceWithStreamingResponse,
+)
from .evaluation_types import (
EvaluationTypesResource,
AsyncEvaluationTypesResource,
@@ -80,6 +88,12 @@
"AsyncEvaluationTypesResourceWithRawResponse",
"EvaluationTypesResourceWithStreamingResponse",
"AsyncEvaluationTypesResourceWithStreamingResponse",
+ "CustomProvidersResource",
+ "AsyncCustomProvidersResource",
+ "CustomProvidersResourceWithRawResponse",
+ "AsyncCustomProvidersResourceWithRawResponse",
+ "CustomProvidersResourceWithStreamingResponse",
+ "AsyncCustomProvidersResourceWithStreamingResponse",
"LogsResource",
"AsyncLogsResource",
"LogsResourceWithRawResponse",
diff --git a/src/cloudflare/resources/ai_gateway/ai_gateway.py b/src/cloudflare/resources/ai_gateway/ai_gateway.py
index a2b415a26b5..234d874e107 100644
--- a/src/cloudflare/resources/ai_gateway/ai_gateway.py
+++ b/src/cloudflare/resources/ai_gateway/ai_gateway.py
@@ -68,6 +68,14 @@
DynamicRoutingResourceWithStreamingResponse,
AsyncDynamicRoutingResourceWithStreamingResponse,
)
+from .custom_providers import (
+ CustomProvidersResource,
+ AsyncCustomProvidersResource,
+ CustomProvidersResourceWithRawResponse,
+ AsyncCustomProvidersResourceWithRawResponse,
+ CustomProvidersResourceWithStreamingResponse,
+ AsyncCustomProvidersResourceWithStreamingResponse,
+)
from .evaluation_types import (
EvaluationTypesResource,
AsyncEvaluationTypesResource,
@@ -99,6 +107,10 @@ class AIGatewayResource(SyncAPIResource):
def evaluation_types(self) -> EvaluationTypesResource:
return EvaluationTypesResource(self._client)
+ @cached_property
+ def custom_providers(self) -> CustomProvidersResource:
+ return CustomProvidersResource(self._client)
+
@cached_property
def logs(self) -> LogsResource:
return LogsResource(self._client)
@@ -473,6 +485,10 @@ class AsyncAIGatewayResource(AsyncAPIResource):
def evaluation_types(self) -> AsyncEvaluationTypesResource:
return AsyncEvaluationTypesResource(self._client)
+ @cached_property
+ def custom_providers(self) -> AsyncCustomProvidersResource:
+ return AsyncCustomProvidersResource(self._client)
+
@cached_property
def logs(self) -> AsyncLogsResource:
return AsyncLogsResource(self._client)
@@ -866,6 +882,10 @@ def __init__(self, ai_gateway: AIGatewayResource) -> None:
def evaluation_types(self) -> EvaluationTypesResourceWithRawResponse:
return EvaluationTypesResourceWithRawResponse(self._ai_gateway.evaluation_types)
+ @cached_property
+ def custom_providers(self) -> CustomProvidersResourceWithRawResponse:
+ return CustomProvidersResourceWithRawResponse(self._ai_gateway.custom_providers)
+
@cached_property
def logs(self) -> LogsResourceWithRawResponse:
return LogsResourceWithRawResponse(self._ai_gateway.logs)
@@ -919,6 +939,10 @@ def __init__(self, ai_gateway: AsyncAIGatewayResource) -> None:
def evaluation_types(self) -> AsyncEvaluationTypesResourceWithRawResponse:
return AsyncEvaluationTypesResourceWithRawResponse(self._ai_gateway.evaluation_types)
+ @cached_property
+ def custom_providers(self) -> AsyncCustomProvidersResourceWithRawResponse:
+ return AsyncCustomProvidersResourceWithRawResponse(self._ai_gateway.custom_providers)
+
@cached_property
def logs(self) -> AsyncLogsResourceWithRawResponse:
return AsyncLogsResourceWithRawResponse(self._ai_gateway.logs)
@@ -972,6 +996,10 @@ def __init__(self, ai_gateway: AIGatewayResource) -> None:
def evaluation_types(self) -> EvaluationTypesResourceWithStreamingResponse:
return EvaluationTypesResourceWithStreamingResponse(self._ai_gateway.evaluation_types)
+ @cached_property
+ def custom_providers(self) -> CustomProvidersResourceWithStreamingResponse:
+ return CustomProvidersResourceWithStreamingResponse(self._ai_gateway.custom_providers)
+
@cached_property
def logs(self) -> LogsResourceWithStreamingResponse:
return LogsResourceWithStreamingResponse(self._ai_gateway.logs)
@@ -1025,6 +1053,10 @@ def __init__(self, ai_gateway: AsyncAIGatewayResource) -> None:
def evaluation_types(self) -> AsyncEvaluationTypesResourceWithStreamingResponse:
return AsyncEvaluationTypesResourceWithStreamingResponse(self._ai_gateway.evaluation_types)
+ @cached_property
+ def custom_providers(self) -> AsyncCustomProvidersResourceWithStreamingResponse:
+ return AsyncCustomProvidersResourceWithStreamingResponse(self._ai_gateway.custom_providers)
+
@cached_property
def logs(self) -> AsyncLogsResourceWithStreamingResponse:
return AsyncLogsResourceWithStreamingResponse(self._ai_gateway.logs)
diff --git a/src/cloudflare/resources/ai_gateway/api.md b/src/cloudflare/resources/ai_gateway/api.md
index a6e0343e9d6..4462aa09f4c 100644
--- a/src/cloudflare/resources/ai_gateway/api.md
+++ b/src/cloudflare/resources/ai_gateway/api.md
@@ -32,6 +32,26 @@ Methods:
- client.ai_gateway.evaluation_types.list(\*, account_id, \*\*params) -> SyncV4PagePaginationArray[EvaluationTypeListResponse]
+## CustomProviders
+
+Types:
+
+```python
+from cloudflare.types.ai_gateway import (
+ CustomProviderCreateResponse,
+ CustomProviderListResponse,
+ CustomProviderDeleteResponse,
+ CustomProviderGetResponse,
+)
+```
+
+Methods:
+
+- client.ai_gateway.custom_providers.create(\*, account_id, \*\*params) -> CustomProviderCreateResponse
+- client.ai_gateway.custom_providers.list(\*, account_id, \*\*params) -> SyncV4PagePaginationArray[CustomProviderListResponse]
+- client.ai_gateway.custom_providers.delete(id, \*, account_id) -> CustomProviderDeleteResponse
+- client.ai_gateway.custom_providers.get(id, \*, account_id) -> CustomProviderGetResponse
+
## Logs
Types:
diff --git a/src/cloudflare/resources/ai_gateway/custom_providers.py b/src/cloudflare/resources/ai_gateway/custom_providers.py
new file mode 100644
index 00000000000..5c6f32767b7
--- /dev/null
+++ b/src/cloudflare/resources/ai_gateway/custom_providers.py
@@ -0,0 +1,538 @@
+# 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 ...pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray
+from ..._base_client import AsyncPaginator, make_request_options
+from ...types.ai_gateway import custom_provider_list_params, custom_provider_create_params
+from ...types.ai_gateway.custom_provider_get_response import CustomProviderGetResponse
+from ...types.ai_gateway.custom_provider_list_response import CustomProviderListResponse
+from ...types.ai_gateway.custom_provider_create_response import CustomProviderCreateResponse
+from ...types.ai_gateway.custom_provider_delete_response import CustomProviderDeleteResponse
+
+__all__ = ["CustomProvidersResource", "AsyncCustomProvidersResource"]
+
+
+class CustomProvidersResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> CustomProvidersResourceWithRawResponse:
+ """
+ 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 CustomProvidersResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> CustomProvidersResourceWithStreamingResponse:
+ """
+ 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 CustomProvidersResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ *,
+ account_id: str,
+ base_url: str,
+ name: str,
+ slug: str,
+ beta: bool | Omit = omit,
+ curl_example: str | Omit = omit,
+ description: str | Omit = omit,
+ enable: bool | Omit = omit,
+ headers: str | Omit = omit,
+ js_example: str | Omit = omit,
+ link: str | Omit = omit,
+ position: int | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> CustomProviderCreateResponse:
+ """
+ Creates a new AI Gateway.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._post(
+ path_template("/accounts/{account_id}/ai-gateway/custom-providers", account_id=account_id),
+ body=maybe_transform(
+ {
+ "base_url": base_url,
+ "name": name,
+ "slug": slug,
+ "beta": beta,
+ "curl_example": curl_example,
+ "description": description,
+ "enable": enable,
+ "headers": headers,
+ "js_example": js_example,
+ "link": link,
+ "position": position,
+ },
+ custom_provider_create_params.CustomProviderCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[CustomProviderCreateResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[CustomProviderCreateResponse], ResultWrapper[CustomProviderCreateResponse]),
+ )
+
+ def list(
+ self,
+ *,
+ account_id: str,
+ beta: bool | Omit = omit,
+ enable: bool | Omit = omit,
+ page: int | Omit = omit,
+ per_page: int | Omit = omit,
+ search: 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,
+ ) -> SyncV4PagePaginationArray[CustomProviderListResponse]:
+ """
+ Lists all AI Gateway evaluator types configured for the account.
+
+ Args:
+ search: Search by id, name, slug
+
+ 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}/ai-gateway/custom-providers", account_id=account_id),
+ page=SyncV4PagePaginationArray[CustomProviderListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "beta": beta,
+ "enable": enable,
+ "page": page,
+ "per_page": per_page,
+ "search": search,
+ },
+ custom_provider_list_params.CustomProviderListParams,
+ ),
+ ),
+ model=CustomProviderListResponse,
+ )
+
+ def delete(
+ self,
+ 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,
+ ) -> CustomProviderDeleteResponse:
+ """
+ Deletes an AI Gateway dataset.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return self._delete(
+ path_template("/accounts/{account_id}/ai-gateway/custom-providers/{id}", account_id=account_id, id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[CustomProviderDeleteResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[CustomProviderDeleteResponse], ResultWrapper[CustomProviderDeleteResponse]),
+ )
+
+ def get(
+ self,
+ 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,
+ ) -> CustomProviderGetResponse:
+ """
+ Retrieves details for a specific AI Gateway dataset.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return self._get(
+ path_template("/accounts/{account_id}/ai-gateway/custom-providers/{id}", account_id=account_id, id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[CustomProviderGetResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[CustomProviderGetResponse], ResultWrapper[CustomProviderGetResponse]),
+ )
+
+
+class AsyncCustomProvidersResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncCustomProvidersResourceWithRawResponse:
+ """
+ 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 AsyncCustomProvidersResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncCustomProvidersResourceWithStreamingResponse:
+ """
+ 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 AsyncCustomProvidersResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ *,
+ account_id: str,
+ base_url: str,
+ name: str,
+ slug: str,
+ beta: bool | Omit = omit,
+ curl_example: str | Omit = omit,
+ description: str | Omit = omit,
+ enable: bool | Omit = omit,
+ headers: str | Omit = omit,
+ js_example: str | Omit = omit,
+ link: str | Omit = omit,
+ position: int | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> CustomProviderCreateResponse:
+ """
+ Creates a new AI Gateway.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return await self._post(
+ path_template("/accounts/{account_id}/ai-gateway/custom-providers", account_id=account_id),
+ body=await async_maybe_transform(
+ {
+ "base_url": base_url,
+ "name": name,
+ "slug": slug,
+ "beta": beta,
+ "curl_example": curl_example,
+ "description": description,
+ "enable": enable,
+ "headers": headers,
+ "js_example": js_example,
+ "link": link,
+ "position": position,
+ },
+ custom_provider_create_params.CustomProviderCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[CustomProviderCreateResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[CustomProviderCreateResponse], ResultWrapper[CustomProviderCreateResponse]),
+ )
+
+ def list(
+ self,
+ *,
+ account_id: str,
+ beta: bool | Omit = omit,
+ enable: bool | Omit = omit,
+ page: int | Omit = omit,
+ per_page: int | Omit = omit,
+ search: 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,
+ ) -> AsyncPaginator[CustomProviderListResponse, AsyncV4PagePaginationArray[CustomProviderListResponse]]:
+ """
+ Lists all AI Gateway evaluator types configured for the account.
+
+ Args:
+ search: Search by id, name, slug
+
+ 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}/ai-gateway/custom-providers", account_id=account_id),
+ page=AsyncV4PagePaginationArray[CustomProviderListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "beta": beta,
+ "enable": enable,
+ "page": page,
+ "per_page": per_page,
+ "search": search,
+ },
+ custom_provider_list_params.CustomProviderListParams,
+ ),
+ ),
+ model=CustomProviderListResponse,
+ )
+
+ async def delete(
+ self,
+ 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,
+ ) -> CustomProviderDeleteResponse:
+ """
+ Deletes an AI Gateway dataset.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return await self._delete(
+ path_template("/accounts/{account_id}/ai-gateway/custom-providers/{id}", account_id=account_id, id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[CustomProviderDeleteResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[CustomProviderDeleteResponse], ResultWrapper[CustomProviderDeleteResponse]),
+ )
+
+ async def get(
+ self,
+ 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,
+ ) -> CustomProviderGetResponse:
+ """
+ Retrieves details for a specific AI Gateway dataset.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return await self._get(
+ path_template("/accounts/{account_id}/ai-gateway/custom-providers/{id}", account_id=account_id, id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[CustomProviderGetResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[CustomProviderGetResponse], ResultWrapper[CustomProviderGetResponse]),
+ )
+
+
+class CustomProvidersResourceWithRawResponse:
+ def __init__(self, custom_providers: CustomProvidersResource) -> None:
+ self._custom_providers = custom_providers
+
+ self.create = to_raw_response_wrapper(
+ custom_providers.create,
+ )
+ self.list = to_raw_response_wrapper(
+ custom_providers.list,
+ )
+ self.delete = to_raw_response_wrapper(
+ custom_providers.delete,
+ )
+ self.get = to_raw_response_wrapper(
+ custom_providers.get,
+ )
+
+
+class AsyncCustomProvidersResourceWithRawResponse:
+ def __init__(self, custom_providers: AsyncCustomProvidersResource) -> None:
+ self._custom_providers = custom_providers
+
+ self.create = async_to_raw_response_wrapper(
+ custom_providers.create,
+ )
+ self.list = async_to_raw_response_wrapper(
+ custom_providers.list,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ custom_providers.delete,
+ )
+ self.get = async_to_raw_response_wrapper(
+ custom_providers.get,
+ )
+
+
+class CustomProvidersResourceWithStreamingResponse:
+ def __init__(self, custom_providers: CustomProvidersResource) -> None:
+ self._custom_providers = custom_providers
+
+ self.create = to_streamed_response_wrapper(
+ custom_providers.create,
+ )
+ self.list = to_streamed_response_wrapper(
+ custom_providers.list,
+ )
+ self.delete = to_streamed_response_wrapper(
+ custom_providers.delete,
+ )
+ self.get = to_streamed_response_wrapper(
+ custom_providers.get,
+ )
+
+
+class AsyncCustomProvidersResourceWithStreamingResponse:
+ def __init__(self, custom_providers: AsyncCustomProvidersResource) -> None:
+ self._custom_providers = custom_providers
+
+ self.create = async_to_streamed_response_wrapper(
+ custom_providers.create,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ custom_providers.list,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ custom_providers.delete,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ custom_providers.get,
+ )
diff --git a/src/cloudflare/types/ai_gateway/__init__.py b/src/cloudflare/types/ai_gateway/__init__.py
index 1fdf9d001f2..4772f625392 100644
--- a/src/cloudflare/types/ai_gateway/__init__.py
+++ b/src/cloudflare/types/ai_gateway/__init__.py
@@ -31,11 +31,15 @@
from .ai_gateway_update_response import AIGatewayUpdateResponse as AIGatewayUpdateResponse
from .evaluation_create_response import EvaluationCreateResponse as EvaluationCreateResponse
from .evaluation_delete_response import EvaluationDeleteResponse as EvaluationDeleteResponse
+from .custom_provider_list_params import CustomProviderListParams as CustomProviderListParams
from .dynamic_routing_list_params import DynamicRoutingListParams as DynamicRoutingListParams
from .evaluation_type_list_params import EvaluationTypeListParams as EvaluationTypeListParams
from .provider_config_list_params import ProviderConfigListParams as ProviderConfigListParams
from .billing_usage_history_params import BillingUsageHistoryParams as BillingUsageHistoryParams
+from .custom_provider_get_response import CustomProviderGetResponse as CustomProviderGetResponse
from .dynamic_routing_get_response import DynamicRoutingGetResponse as DynamicRoutingGetResponse
+from .custom_provider_create_params import CustomProviderCreateParams as CustomProviderCreateParams
+from .custom_provider_list_response import CustomProviderListResponse as CustomProviderListResponse
from .dynamic_routing_create_params import DynamicRoutingCreateParams as DynamicRoutingCreateParams
from .dynamic_routing_list_response import DynamicRoutingListResponse as DynamicRoutingListResponse
from .dynamic_routing_update_params import DynamicRoutingUpdateParams as DynamicRoutingUpdateParams
@@ -45,6 +49,8 @@
from .billing_invoice_history_params import BillingInvoiceHistoryParams as BillingInvoiceHistoryParams
from .billing_usage_history_response import BillingUsageHistoryResponse as BillingUsageHistoryResponse
from .billing_credit_balance_response import BillingCreditBalanceResponse as BillingCreditBalanceResponse
+from .custom_provider_create_response import CustomProviderCreateResponse as CustomProviderCreateResponse
+from .custom_provider_delete_response import CustomProviderDeleteResponse as CustomProviderDeleteResponse
from .dynamic_routing_create_response import DynamicRoutingCreateResponse as DynamicRoutingCreateResponse
from .dynamic_routing_delete_response import DynamicRoutingDeleteResponse as DynamicRoutingDeleteResponse
from .dynamic_routing_update_response import DynamicRoutingUpdateResponse as DynamicRoutingUpdateResponse
diff --git a/src/cloudflare/types/ai_gateway/custom_provider_create_params.py b/src/cloudflare/types/ai_gateway/custom_provider_create_params.py
new file mode 100644
index 00000000000..bcce88c3ddd
--- /dev/null
+++ b/src/cloudflare/types/ai_gateway/custom_provider_create_params.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["CustomProviderCreateParams"]
+
+
+class CustomProviderCreateParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ base_url: Required[str]
+
+ name: Required[str]
+
+ slug: Required[str]
+
+ beta: bool
+
+ curl_example: str
+
+ description: str
+
+ enable: bool
+
+ headers: str
+
+ js_example: str
+
+ link: str
+
+ position: int
diff --git a/src/cloudflare/types/ai_gateway/custom_provider_create_response.py b/src/cloudflare/types/ai_gateway/custom_provider_create_response.py
new file mode 100644
index 00000000000..70a560dc16a
--- /dev/null
+++ b/src/cloudflare/types/ai_gateway/custom_provider_create_response.py
@@ -0,0 +1,40 @@
+# 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__ = ["CustomProviderCreateResponse"]
+
+
+class CustomProviderCreateResponse(BaseModel):
+ id: str
+
+ base_url: str
+
+ created_at: datetime
+
+ modified_at: datetime
+
+ name: str
+
+ slug: str
+
+ beta: Optional[bool] = None
+
+ curl_example: Optional[str] = None
+
+ description: Optional[str] = None
+
+ enable: Optional[bool] = None
+
+ headers: Optional[str] = None
+
+ js_example: Optional[str] = None
+
+ link: Optional[str] = None
+
+ logo: Optional[str] = None
+
+ position: Optional[int] = None
diff --git a/src/cloudflare/types/ai_gateway/custom_provider_delete_response.py b/src/cloudflare/types/ai_gateway/custom_provider_delete_response.py
new file mode 100644
index 00000000000..85e667704f1
--- /dev/null
+++ b/src/cloudflare/types/ai_gateway/custom_provider_delete_response.py
@@ -0,0 +1,40 @@
+# 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__ = ["CustomProviderDeleteResponse"]
+
+
+class CustomProviderDeleteResponse(BaseModel):
+ id: str
+
+ base_url: str
+
+ created_at: datetime
+
+ modified_at: datetime
+
+ name: str
+
+ slug: str
+
+ beta: Optional[bool] = None
+
+ curl_example: Optional[str] = None
+
+ description: Optional[str] = None
+
+ enable: Optional[bool] = None
+
+ headers: Optional[str] = None
+
+ js_example: Optional[str] = None
+
+ link: Optional[str] = None
+
+ logo: Optional[str] = None
+
+ position: Optional[int] = None
diff --git a/src/cloudflare/types/ai_gateway/custom_provider_get_response.py b/src/cloudflare/types/ai_gateway/custom_provider_get_response.py
new file mode 100644
index 00000000000..f166de84e8b
--- /dev/null
+++ b/src/cloudflare/types/ai_gateway/custom_provider_get_response.py
@@ -0,0 +1,40 @@
+# 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__ = ["CustomProviderGetResponse"]
+
+
+class CustomProviderGetResponse(BaseModel):
+ id: str
+
+ base_url: str
+
+ created_at: datetime
+
+ modified_at: datetime
+
+ name: str
+
+ slug: str
+
+ beta: Optional[bool] = None
+
+ curl_example: Optional[str] = None
+
+ description: Optional[str] = None
+
+ enable: Optional[bool] = None
+
+ headers: Optional[str] = None
+
+ js_example: Optional[str] = None
+
+ link: Optional[str] = None
+
+ logo: Optional[str] = None
+
+ position: Optional[int] = None
diff --git a/src/cloudflare/types/ai_gateway/custom_provider_list_params.py b/src/cloudflare/types/ai_gateway/custom_provider_list_params.py
new file mode 100644
index 00000000000..56b6c233e9b
--- /dev/null
+++ b/src/cloudflare/types/ai_gateway/custom_provider_list_params.py
@@ -0,0 +1,22 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["CustomProviderListParams"]
+
+
+class CustomProviderListParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ beta: bool
+
+ enable: bool
+
+ page: int
+
+ per_page: int
+
+ search: str
+ """Search by id, name, slug"""
diff --git a/src/cloudflare/types/ai_gateway/custom_provider_list_response.py b/src/cloudflare/types/ai_gateway/custom_provider_list_response.py
new file mode 100644
index 00000000000..8b75cf9b096
--- /dev/null
+++ b/src/cloudflare/types/ai_gateway/custom_provider_list_response.py
@@ -0,0 +1,40 @@
+# 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__ = ["CustomProviderListResponse"]
+
+
+class CustomProviderListResponse(BaseModel):
+ id: str
+
+ base_url: str
+
+ created_at: datetime
+
+ modified_at: datetime
+
+ name: str
+
+ slug: str
+
+ beta: Optional[bool] = None
+
+ curl_example: Optional[str] = None
+
+ description: Optional[str] = None
+
+ enable: Optional[bool] = None
+
+ headers: Optional[str] = None
+
+ js_example: Optional[str] = None
+
+ link: Optional[str] = None
+
+ logo: Optional[str] = None
+
+ position: Optional[int] = None
diff --git a/tests/api_resources/ai_gateway/test_custom_providers.py b/tests/api_resources/ai_gateway/test_custom_providers.py
new file mode 100644
index 00000000000..abe025b77fe
--- /dev/null
+++ b/tests/api_resources/ai_gateway/test_custom_providers.py
@@ -0,0 +1,462 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray
+from cloudflare.types.ai_gateway import (
+ CustomProviderGetResponse,
+ CustomProviderListResponse,
+ CustomProviderCreateResponse,
+ CustomProviderDeleteResponse,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestCustomProviders:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: Cloudflare) -> None:
+ custom_provider = client.ai_gateway.custom_providers.create(
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ base_url="https://example.com",
+ name="name",
+ slug="slug",
+ )
+ assert_matches_type(CustomProviderCreateResponse, custom_provider, path=["response"])
+
+ @parametrize
+ def test_method_create_with_all_params(self, client: Cloudflare) -> None:
+ custom_provider = client.ai_gateway.custom_providers.create(
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ base_url="https://example.com",
+ name="name",
+ slug="slug",
+ beta=True,
+ curl_example="curl_example",
+ description="description",
+ enable=True,
+ headers="headers",
+ js_example="js_example",
+ link="link",
+ position=0,
+ )
+ assert_matches_type(CustomProviderCreateResponse, custom_provider, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Cloudflare) -> None:
+ response = client.ai_gateway.custom_providers.with_raw_response.create(
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ base_url="https://example.com",
+ name="name",
+ slug="slug",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ custom_provider = response.parse()
+ assert_matches_type(CustomProviderCreateResponse, custom_provider, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: Cloudflare) -> None:
+ with client.ai_gateway.custom_providers.with_streaming_response.create(
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ base_url="https://example.com",
+ name="name",
+ slug="slug",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ custom_provider = response.parse()
+ assert_matches_type(CustomProviderCreateResponse, custom_provider, 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.ai_gateway.custom_providers.with_raw_response.create(
+ account_id="",
+ base_url="https://example.com",
+ name="name",
+ slug="slug",
+ )
+
+ @parametrize
+ def test_method_list(self, client: Cloudflare) -> None:
+ custom_provider = client.ai_gateway.custom_providers.list(
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ )
+ assert_matches_type(SyncV4PagePaginationArray[CustomProviderListResponse], custom_provider, path=["response"])
+
+ @parametrize
+ def test_method_list_with_all_params(self, client: Cloudflare) -> None:
+ custom_provider = client.ai_gateway.custom_providers.list(
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ beta=True,
+ enable=True,
+ page=1,
+ per_page=1,
+ search="search",
+ )
+ assert_matches_type(SyncV4PagePaginationArray[CustomProviderListResponse], custom_provider, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Cloudflare) -> None:
+ response = client.ai_gateway.custom_providers.with_raw_response.list(
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ custom_provider = response.parse()
+ assert_matches_type(SyncV4PagePaginationArray[CustomProviderListResponse], custom_provider, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Cloudflare) -> None:
+ with client.ai_gateway.custom_providers.with_streaming_response.list(
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ custom_provider = response.parse()
+ assert_matches_type(
+ SyncV4PagePaginationArray[CustomProviderListResponse], custom_provider, path=["response"]
+ )
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_list(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.ai_gateway.custom_providers.with_raw_response.list(
+ account_id="",
+ )
+
+ @parametrize
+ def test_method_delete(self, client: Cloudflare) -> None:
+ custom_provider = client.ai_gateway.custom_providers.delete(
+ id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ )
+ assert_matches_type(CustomProviderDeleteResponse, custom_provider, path=["response"])
+
+ @parametrize
+ def test_raw_response_delete(self, client: Cloudflare) -> None:
+ response = client.ai_gateway.custom_providers.with_raw_response.delete(
+ id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ custom_provider = response.parse()
+ assert_matches_type(CustomProviderDeleteResponse, custom_provider, path=["response"])
+
+ @parametrize
+ def test_streaming_response_delete(self, client: Cloudflare) -> None:
+ with client.ai_gateway.custom_providers.with_streaming_response.delete(
+ id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ custom_provider = response.parse()
+ assert_matches_type(CustomProviderDeleteResponse, custom_provider, 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.ai_gateway.custom_providers.with_raw_response.delete(
+ id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.ai_gateway.custom_providers.with_raw_response.delete(
+ id="",
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ )
+
+ @parametrize
+ def test_method_get(self, client: Cloudflare) -> None:
+ custom_provider = client.ai_gateway.custom_providers.get(
+ id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ )
+ assert_matches_type(CustomProviderGetResponse, custom_provider, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Cloudflare) -> None:
+ response = client.ai_gateway.custom_providers.with_raw_response.get(
+ id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ custom_provider = response.parse()
+ assert_matches_type(CustomProviderGetResponse, custom_provider, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Cloudflare) -> None:
+ with client.ai_gateway.custom_providers.with_streaming_response.get(
+ id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ custom_provider = response.parse()
+ assert_matches_type(CustomProviderGetResponse, custom_provider, 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.ai_gateway.custom_providers.with_raw_response.get(
+ id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.ai_gateway.custom_providers.with_raw_response.get(
+ id="",
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ )
+
+
+class TestAsyncCustomProviders:
+ 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:
+ custom_provider = await async_client.ai_gateway.custom_providers.create(
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ base_url="https://example.com",
+ name="name",
+ slug="slug",
+ )
+ assert_matches_type(CustomProviderCreateResponse, custom_provider, path=["response"])
+
+ @parametrize
+ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ custom_provider = await async_client.ai_gateway.custom_providers.create(
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ base_url="https://example.com",
+ name="name",
+ slug="slug",
+ beta=True,
+ curl_example="curl_example",
+ description="description",
+ enable=True,
+ headers="headers",
+ js_example="js_example",
+ link="link",
+ position=0,
+ )
+ assert_matches_type(CustomProviderCreateResponse, custom_provider, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.ai_gateway.custom_providers.with_raw_response.create(
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ base_url="https://example.com",
+ name="name",
+ slug="slug",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ custom_provider = await response.parse()
+ assert_matches_type(CustomProviderCreateResponse, custom_provider, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.ai_gateway.custom_providers.with_streaming_response.create(
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ base_url="https://example.com",
+ name="name",
+ slug="slug",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ custom_provider = await response.parse()
+ assert_matches_type(CustomProviderCreateResponse, custom_provider, 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.ai_gateway.custom_providers.with_raw_response.create(
+ account_id="",
+ base_url="https://example.com",
+ name="name",
+ slug="slug",
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncCloudflare) -> None:
+ custom_provider = await async_client.ai_gateway.custom_providers.list(
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ )
+ assert_matches_type(AsyncV4PagePaginationArray[CustomProviderListResponse], custom_provider, path=["response"])
+
+ @parametrize
+ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ custom_provider = await async_client.ai_gateway.custom_providers.list(
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ beta=True,
+ enable=True,
+ page=1,
+ per_page=1,
+ search="search",
+ )
+ assert_matches_type(AsyncV4PagePaginationArray[CustomProviderListResponse], custom_provider, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.ai_gateway.custom_providers.with_raw_response.list(
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ custom_provider = await response.parse()
+ assert_matches_type(AsyncV4PagePaginationArray[CustomProviderListResponse], custom_provider, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.ai_gateway.custom_providers.with_streaming_response.list(
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ custom_provider = await response.parse()
+ assert_matches_type(
+ AsyncV4PagePaginationArray[CustomProviderListResponse], custom_provider, path=["response"]
+ )
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.ai_gateway.custom_providers.with_raw_response.list(
+ account_id="",
+ )
+
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncCloudflare) -> None:
+ custom_provider = await async_client.ai_gateway.custom_providers.delete(
+ id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ )
+ assert_matches_type(CustomProviderDeleteResponse, custom_provider, path=["response"])
+
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.ai_gateway.custom_providers.with_raw_response.delete(
+ id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ custom_provider = await response.parse()
+ assert_matches_type(CustomProviderDeleteResponse, custom_provider, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.ai_gateway.custom_providers.with_streaming_response.delete(
+ id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ custom_provider = await response.parse()
+ assert_matches_type(CustomProviderDeleteResponse, custom_provider, 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.ai_gateway.custom_providers.with_raw_response.delete(
+ id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.ai_gateway.custom_providers.with_raw_response.delete(
+ id="",
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ )
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncCloudflare) -> None:
+ custom_provider = await async_client.ai_gateway.custom_providers.get(
+ id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ )
+ assert_matches_type(CustomProviderGetResponse, custom_provider, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.ai_gateway.custom_providers.with_raw_response.get(
+ id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ custom_provider = await response.parse()
+ assert_matches_type(CustomProviderGetResponse, custom_provider, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.ai_gateway.custom_providers.with_streaming_response.get(
+ id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ custom_provider = await response.parse()
+ assert_matches_type(CustomProviderGetResponse, custom_provider, 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.ai_gateway.custom_providers.with_raw_response.get(
+ id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.ai_gateway.custom_providers.with_raw_response.get(
+ id="",
+ account_id="3ebbcb006d4d46d7bb6a8c7f14676cb0",
+ )
From 0ff89f99ddfbaf078d3b20eada5fd2bc4139fc65 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 15 Jun 2026 17:51:21 +0000
Subject: [PATCH 12/23] chore(api): update composite API spec
---
.stats.yml | 4 ++--
src/cloudflare/types/workers/script_update_params.py | 3 ++-
.../dispatch/namespaces/script_update_params.py | 3 ++-
3 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 0548f899893..dae43b8041f 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 2388
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-1f58da61ef137d93446336e6c2c36bdd7bd1a6f56bb4ddb819090b7cecebe210.yml
-openapi_spec_hash: c072a4a84aa2d1de3b656ae5fe7967f8
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-bc7ee140b4763ca4b45594b9db8d569431c061fb81c261ddb5a3a247973dd741.yml
+openapi_spec_hash: 30882bab9ab718768db2497c4638fe7d
config_hash: f81f9e27d86c53b33ee1f1f3654ef3c6
diff --git a/src/cloudflare/types/workers/script_update_params.py b/src/cloudflare/types/workers/script_update_params.py
index ba3f796cc5b..f36a1f99c41 100644
--- a/src/cloudflare/types/workers/script_update_params.py
+++ b/src/cloudflare/types/workers/script_update_params.py
@@ -970,7 +970,8 @@ class Metadata(TypedDict, total=False):
keep_assets: bool
"""
Retain assets which exist for a previously uploaded Worker version; used in lieu
- of providing a completion token.
+ of providing a completion token. An explicit `assets` upload takes precedence
+ over `keep_assets`.
"""
keep_bindings: SequenceNotStr[str]
diff --git a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/script_update_params.py b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/script_update_params.py
index acb9dace387..6d3ed03b9ac 100644
--- a/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/script_update_params.py
+++ b/src/cloudflare/types/workers_for_platforms/dispatch/namespaces/script_update_params.py
@@ -958,7 +958,8 @@ class Metadata(TypedDict, total=False):
keep_assets: bool
"""
Retain assets which exist for a previously uploaded Worker version; used in lieu
- of providing a completion token.
+ of providing a completion token. An explicit `assets` upload takes precedence
+ over `keep_assets`.
"""
keep_bindings: SequenceNotStr[str]
From 5d8e422736d8e044d2c73065cbb8595573b2656d Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 15 Jun 2026 18:48:10 +0000
Subject: [PATCH 13/23] feat: feat(api): map ipsec_tunnels/psk,
sites/app_policies and cf1_sites for magic-on-ramps
* fix(api): remove unnecessary skip_test_reason from ipsec_tunnels psk_set
psk_set was carrying a copied "TODO: investigate broken test" skip, but it is a new endpoint whose generated test has never run. Its closest analogue psk_generate (also POST) is unskipped and passes, and psk_set does not share the modified_ipsec_tunnel response wrapper that breaks the update/bulk_update tests. Removing the skip so the test runs; if it genuinely fails downstream it can be re-added with a concrete reason.
* fix(api): remove app_policies mapping from magic-on-ramps
app_policies has no implementation in conduit-api and none is planned, so mapping GET /accounts/{account_id}/magic/sites/{site_id}/app_policies would document a route that does not exist. Removing the skipped entry; psk_set and cf1_sites are unaffected.
* fix(api): add models, terraform, skip guards for magic-on-ramps resources
- Add skip_test_reason to psk_set (aligns with sibling update/bulk_update)
- Add skip guard to app_policies (aligns with sibling app_configuration)
- Add terraform.name and models block to cf1_sites
- Add models block to cf1_sites.ramps sub-resource
* feat(api): map cf1_sites and ramps for magic-on-ramps
Add cf1_sites resource with CRUD methods and ramps sub-resource
to magic_transit in Stainless config for SDK generation.
Ref: APIX-667, APIX-795
* feat(api): map ipsec_tunnels/psk and sites/app_policies for magic-on-ramps
Add Stainless config mappings for two undocumented routes from APIX-667:
- ipsec_tunnels.psk_set: POST /accounts/{account_id}/magic/ipsec_tunnels/psk
- sites.app_policies.list: GET /accounts/{account_id}/magic/sites/{site_id}/app_policies
---
.stats.yml | 6 +-
.../resources/magic_transit/__init__.py | 14 +
src/cloudflare/resources/magic_transit/api.md | 33 +
.../magic_transit/cf1_sites/__init__.py | 33 +
.../magic_transit/cf1_sites/cf1_sites.py | 655 ++++++++++++++++++
.../magic_transit/cf1_sites/ramps.py | 545 +++++++++++++++
.../resources/magic_transit/ipsec_tunnels.py | 124 +++-
.../resources/magic_transit/magic_transit.py | 32 +
.../types/magic_transit/__init__.py | 8 +
.../types/magic_transit/cf1_site.py | 29 +
.../magic_transit/cf1_site_create_params.py | 17 +
.../types/magic_transit/cf1_site_location.py | 18 +
.../magic_transit/cf1_site_location_param.py | 18 +
.../types/magic_transit/cf1_site_param.py | 22 +
.../magic_transit/cf1_site_update_params.py | 25 +
.../types/magic_transit/cf1_sites/__init__.py | 7 +
.../types/magic_transit/cf1_sites/ramp.py | 68 ++
.../cf1_sites/ramp_create_params.py | 28 +
.../magic_transit/cf1_sites/ramp_type.py | 7 +
.../ipsec_tunnel_psk_set_params.py | 29 +
.../ipsec_tunnel_psk_set_response.py | 32 +
.../magic_transit/cf1_sites/__init__.py | 1 +
.../magic_transit/cf1_sites/test_ramps.py | 517 ++++++++++++++
.../magic_transit/test_cf1_sites.py | 503 ++++++++++++++
.../magic_transit/test_ipsec_tunnels.py | 153 ++++
25 files changed, 2920 insertions(+), 4 deletions(-)
create mode 100644 src/cloudflare/resources/magic_transit/cf1_sites/__init__.py
create mode 100644 src/cloudflare/resources/magic_transit/cf1_sites/cf1_sites.py
create mode 100644 src/cloudflare/resources/magic_transit/cf1_sites/ramps.py
create mode 100644 src/cloudflare/types/magic_transit/cf1_site.py
create mode 100644 src/cloudflare/types/magic_transit/cf1_site_create_params.py
create mode 100644 src/cloudflare/types/magic_transit/cf1_site_location.py
create mode 100644 src/cloudflare/types/magic_transit/cf1_site_location_param.py
create mode 100644 src/cloudflare/types/magic_transit/cf1_site_param.py
create mode 100644 src/cloudflare/types/magic_transit/cf1_site_update_params.py
create mode 100644 src/cloudflare/types/magic_transit/cf1_sites/__init__.py
create mode 100644 src/cloudflare/types/magic_transit/cf1_sites/ramp.py
create mode 100644 src/cloudflare/types/magic_transit/cf1_sites/ramp_create_params.py
create mode 100644 src/cloudflare/types/magic_transit/cf1_sites/ramp_type.py
create mode 100644 src/cloudflare/types/magic_transit/ipsec_tunnel_psk_set_params.py
create mode 100644 src/cloudflare/types/magic_transit/ipsec_tunnel_psk_set_response.py
create mode 100644 tests/api_resources/magic_transit/cf1_sites/__init__.py
create mode 100644 tests/api_resources/magic_transit/cf1_sites/test_ramps.py
create mode 100644 tests/api_resources/magic_transit/test_cf1_sites.py
diff --git a/.stats.yml b/.stats.yml
index dae43b8041f..e058e97be9c 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 2388
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-bc7ee140b4763ca4b45594b9db8d569431c061fb81c261ddb5a3a247973dd741.yml
+configured_endpoints: 2398
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-2b344db846f73d18cb70c546df5b9ba346937191f97a00052bf626946391c7e2.yml
openapi_spec_hash: 30882bab9ab718768db2497c4638fe7d
-config_hash: f81f9e27d86c53b33ee1f1f3654ef3c6
+config_hash: 2f529580a17438fc62cd0b47db41b6f1
diff --git a/src/cloudflare/resources/magic_transit/__init__.py b/src/cloudflare/resources/magic_transit/__init__.py
index 205acea4112..553fe559fe1 100644
--- a/src/cloudflare/resources/magic_transit/__init__.py
+++ b/src/cloudflare/resources/magic_transit/__init__.py
@@ -32,6 +32,14 @@
RoutesResourceWithStreamingResponse,
AsyncRoutesResourceWithStreamingResponse,
)
+from .cf1_sites import (
+ Cf1SitesResource,
+ AsyncCf1SitesResource,
+ Cf1SitesResourceWithRawResponse,
+ AsyncCf1SitesResourceWithRawResponse,
+ Cf1SitesResourceWithStreamingResponse,
+ AsyncCf1SitesResourceWithStreamingResponse,
+)
from .connectors import (
ConnectorsResource,
AsyncConnectorsResource,
@@ -116,6 +124,12 @@
"AsyncConnectorsResourceWithRawResponse",
"ConnectorsResourceWithStreamingResponse",
"AsyncConnectorsResourceWithStreamingResponse",
+ "Cf1SitesResource",
+ "AsyncCf1SitesResource",
+ "Cf1SitesResourceWithRawResponse",
+ "AsyncCf1SitesResourceWithRawResponse",
+ "Cf1SitesResourceWithStreamingResponse",
+ "AsyncCf1SitesResourceWithStreamingResponse",
"PCAPsResource",
"AsyncPCAPsResource",
"PCAPsResourceWithRawResponse",
diff --git a/src/cloudflare/resources/magic_transit/api.md b/src/cloudflare/resources/magic_transit/api.md
index 2d200bccc35..c0049a0d38b 100644
--- a/src/cloudflare/resources/magic_transit/api.md
+++ b/src/cloudflare/resources/magic_transit/api.md
@@ -86,6 +86,7 @@ from cloudflare.types.magic_transit import (
IPSECTunnelBulkUpdateResponse,
IPSECTunnelGetResponse,
IPSECTunnelPSKGenerateResponse,
+ IPSECTunnelPSKSetResponse,
)
```
@@ -98,6 +99,7 @@ Methods:
- client.magic_transit.ipsec_tunnels.bulk_update(\*, account_id, \*\*params) -> IPSECTunnelBulkUpdateResponse
- client.magic_transit.ipsec_tunnels.get(ipsec_tunnel_id, \*, account_id) -> IPSECTunnelGetResponse
- client.magic_transit.ipsec_tunnels.psk_generate(ipsec_tunnel_id, \*, account_id, \*\*params) -> IPSECTunnelPSKGenerateResponse
+- client.magic_transit.ipsec_tunnels.psk_set(\*, account_id, \*\*params) -> IPSECTunnelPSKSetResponse
## Routes
@@ -275,6 +277,37 @@ Methods:
- client.magic_transit.connectors.snapshots.latest.list(connector_id, \*, account_id) -> LatestListResponse
+## Cf1Sites
+
+Types:
+
+```python
+from cloudflare.types.magic_transit import Cf1Site, Cf1SiteLocation
+```
+
+Methods:
+
+- client.magic_transit.cf1_sites.create(\*, account_id, \*\*params) -> SyncSinglePage[Cf1Site]
+- client.magic_transit.cf1_sites.update(cf1_site_id, \*, account_id, \*\*params) -> Cf1Site
+- client.magic_transit.cf1_sites.list(\*, account_id) -> SyncSinglePage[Cf1Site]
+- client.magic_transit.cf1_sites.delete(cf1_site_id, \*, account_id) -> Cf1Site
+- client.magic_transit.cf1_sites.get(cf1_site_id, \*, account_id) -> Cf1Site
+
+### Ramps
+
+Types:
+
+```python
+from cloudflare.types.magic_transit.cf1_sites import Ramp, RampType
+```
+
+Methods:
+
+- client.magic_transit.cf1_sites.ramps.create(cf1_site_id, \*, account_id, \*\*params) -> SyncSinglePage[Ramp]
+- client.magic_transit.cf1_sites.ramps.list(cf1_site_id, \*, account_id) -> SyncSinglePage[Ramp]
+- client.magic_transit.cf1_sites.ramps.delete(ramp_id, \*, account_id, cf1_site_id) -> Ramp
+- client.magic_transit.cf1_sites.ramps.get(ramp_id, \*, account_id, cf1_site_id) -> Ramp
+
## PCAPs
Types:
diff --git a/src/cloudflare/resources/magic_transit/cf1_sites/__init__.py b/src/cloudflare/resources/magic_transit/cf1_sites/__init__.py
new file mode 100644
index 00000000000..ab1e98d5ceb
--- /dev/null
+++ b/src/cloudflare/resources/magic_transit/cf1_sites/__init__.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .ramps import (
+ RampsResource,
+ AsyncRampsResource,
+ RampsResourceWithRawResponse,
+ AsyncRampsResourceWithRawResponse,
+ RampsResourceWithStreamingResponse,
+ AsyncRampsResourceWithStreamingResponse,
+)
+from .cf1_sites import (
+ Cf1SitesResource,
+ AsyncCf1SitesResource,
+ Cf1SitesResourceWithRawResponse,
+ AsyncCf1SitesResourceWithRawResponse,
+ Cf1SitesResourceWithStreamingResponse,
+ AsyncCf1SitesResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "RampsResource",
+ "AsyncRampsResource",
+ "RampsResourceWithRawResponse",
+ "AsyncRampsResourceWithRawResponse",
+ "RampsResourceWithStreamingResponse",
+ "AsyncRampsResourceWithStreamingResponse",
+ "Cf1SitesResource",
+ "AsyncCf1SitesResource",
+ "Cf1SitesResourceWithRawResponse",
+ "AsyncCf1SitesResourceWithRawResponse",
+ "Cf1SitesResourceWithStreamingResponse",
+ "AsyncCf1SitesResourceWithStreamingResponse",
+]
diff --git a/src/cloudflare/resources/magic_transit/cf1_sites/cf1_sites.py b/src/cloudflare/resources/magic_transit/cf1_sites/cf1_sites.py
new file mode 100644
index 00000000000..b5aed71af8f
--- /dev/null
+++ b/src/cloudflare/resources/magic_transit/cf1_sites/cf1_sites.py
@@ -0,0 +1,655 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Type, Iterable, cast
+
+import httpx
+
+from .ramps import (
+ RampsResource,
+ AsyncRampsResource,
+ RampsResourceWithRawResponse,
+ AsyncRampsResourceWithRawResponse,
+ RampsResourceWithStreamingResponse,
+ AsyncRampsResourceWithStreamingResponse,
+)
+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 ....pagination import SyncSinglePage, AsyncSinglePage
+from ...._base_client import AsyncPaginator, make_request_options
+from ....types.magic_transit import cf1_site_update_params
+from ....types.magic_transit.cf1_site import Cf1Site
+from ....types.magic_transit.cf1_site_param import Cf1SiteParam
+from ....types.magic_transit.cf1_site_location_param import Cf1SiteLocationParam
+
+__all__ = ["Cf1SitesResource", "AsyncCf1SitesResource"]
+
+
+class Cf1SitesResource(SyncAPIResource):
+ @cached_property
+ def ramps(self) -> RampsResource:
+ return RampsResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> Cf1SitesResourceWithRawResponse:
+ """
+ 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 Cf1SitesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> Cf1SitesResourceWithStreamingResponse:
+ """
+ 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 Cf1SitesResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ *,
+ account_id: str,
+ body: Iterable[Cf1SiteParam],
+ # 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[Cf1Site]:
+ """Creates new CF1 Sites for an account.
+
+ Each site must have a unique name within
+ the account.
+
+ Args:
+ account_id: 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}/magic/cf1_sites", account_id=account_id),
+ page=SyncSinglePage[Cf1Site],
+ body=maybe_transform(body, Iterable[Cf1SiteParam]),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=Cf1Site,
+ method="post",
+ )
+
+ def update(
+ self,
+ cf1_site_id: str,
+ *,
+ account_id: str,
+ description: str | Omit = omit,
+ location: Cf1SiteLocationParam | Omit = omit,
+ name: 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,
+ ) -> Cf1Site:
+ """Partially updates a specific CF1 Site for an account.
+
+ Only the fields included
+ in the request body are modified; omitted fields retain their existing values.
+
+ Args:
+ account_id: Identifier
+
+ cf1_site_id: Identifier
+
+ description: A human-provided description of the CF1 Site.
+
+ name: A human-provided name describing the CF1 Site that should be unique within the
+ account.
+
+ 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 cf1_site_id:
+ raise ValueError(f"Expected a non-empty value for `cf1_site_id` but received {cf1_site_id!r}")
+ return self._patch(
+ path_template(
+ "/accounts/{account_id}/magic/cf1_sites/{cf1_site_id}", account_id=account_id, cf1_site_id=cf1_site_id
+ ),
+ body=maybe_transform(
+ {
+ "description": description,
+ "location": location,
+ "name": name,
+ },
+ cf1_site_update_params.Cf1SiteUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Cf1Site]._unwrapper,
+ ),
+ cast_to=cast(Type[Cf1Site], ResultWrapper[Cf1Site]),
+ )
+
+ def list(
+ 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[Cf1Site]:
+ """Lists CF1 Sites associated with an account.
+
+ A CF1 Site represents a physical
+ customer network location with optional geographic coordinates.
+
+ Args:
+ account_id: 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}/magic/cf1_sites", account_id=account_id),
+ page=SyncSinglePage[Cf1Site],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=Cf1Site,
+ )
+
+ def delete(
+ self,
+ cf1_site_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,
+ ) -> Cf1Site:
+ """
+ Deletes a specific CF1 Site for an account.
+
+ Args:
+ account_id: Identifier
+
+ cf1_site_id: 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 cf1_site_id:
+ raise ValueError(f"Expected a non-empty value for `cf1_site_id` but received {cf1_site_id!r}")
+ return self._delete(
+ path_template(
+ "/accounts/{account_id}/magic/cf1_sites/{cf1_site_id}", account_id=account_id, cf1_site_id=cf1_site_id
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Cf1Site]._unwrapper,
+ ),
+ cast_to=cast(Type[Cf1Site], ResultWrapper[Cf1Site]),
+ )
+
+ def get(
+ self,
+ cf1_site_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,
+ ) -> Cf1Site:
+ """
+ Gets a specific CF1 Site for an account.
+
+ Args:
+ account_id: Identifier
+
+ cf1_site_id: 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 cf1_site_id:
+ raise ValueError(f"Expected a non-empty value for `cf1_site_id` but received {cf1_site_id!r}")
+ return self._get(
+ path_template(
+ "/accounts/{account_id}/magic/cf1_sites/{cf1_site_id}", account_id=account_id, cf1_site_id=cf1_site_id
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Cf1Site]._unwrapper,
+ ),
+ cast_to=cast(Type[Cf1Site], ResultWrapper[Cf1Site]),
+ )
+
+
+class AsyncCf1SitesResource(AsyncAPIResource):
+ @cached_property
+ def ramps(self) -> AsyncRampsResource:
+ return AsyncRampsResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncCf1SitesResourceWithRawResponse:
+ """
+ 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 AsyncCf1SitesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncCf1SitesResourceWithStreamingResponse:
+ """
+ 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 AsyncCf1SitesResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ *,
+ account_id: str,
+ body: Iterable[Cf1SiteParam],
+ # 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[Cf1Site, AsyncSinglePage[Cf1Site]]:
+ """Creates new CF1 Sites for an account.
+
+ Each site must have a unique name within
+ the account.
+
+ Args:
+ account_id: 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}/magic/cf1_sites", account_id=account_id),
+ page=AsyncSinglePage[Cf1Site],
+ body=maybe_transform(body, Iterable[Cf1SiteParam]),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=Cf1Site,
+ method="post",
+ )
+
+ async def update(
+ self,
+ cf1_site_id: str,
+ *,
+ account_id: str,
+ description: str | Omit = omit,
+ location: Cf1SiteLocationParam | Omit = omit,
+ name: 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,
+ ) -> Cf1Site:
+ """Partially updates a specific CF1 Site for an account.
+
+ Only the fields included
+ in the request body are modified; omitted fields retain their existing values.
+
+ Args:
+ account_id: Identifier
+
+ cf1_site_id: Identifier
+
+ description: A human-provided description of the CF1 Site.
+
+ name: A human-provided name describing the CF1 Site that should be unique within the
+ account.
+
+ 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 cf1_site_id:
+ raise ValueError(f"Expected a non-empty value for `cf1_site_id` but received {cf1_site_id!r}")
+ return await self._patch(
+ path_template(
+ "/accounts/{account_id}/magic/cf1_sites/{cf1_site_id}", account_id=account_id, cf1_site_id=cf1_site_id
+ ),
+ body=await async_maybe_transform(
+ {
+ "description": description,
+ "location": location,
+ "name": name,
+ },
+ cf1_site_update_params.Cf1SiteUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Cf1Site]._unwrapper,
+ ),
+ cast_to=cast(Type[Cf1Site], ResultWrapper[Cf1Site]),
+ )
+
+ def list(
+ 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[Cf1Site, AsyncSinglePage[Cf1Site]]:
+ """Lists CF1 Sites associated with an account.
+
+ A CF1 Site represents a physical
+ customer network location with optional geographic coordinates.
+
+ Args:
+ account_id: 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}/magic/cf1_sites", account_id=account_id),
+ page=AsyncSinglePage[Cf1Site],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=Cf1Site,
+ )
+
+ async def delete(
+ self,
+ cf1_site_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,
+ ) -> Cf1Site:
+ """
+ Deletes a specific CF1 Site for an account.
+
+ Args:
+ account_id: Identifier
+
+ cf1_site_id: 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 cf1_site_id:
+ raise ValueError(f"Expected a non-empty value for `cf1_site_id` but received {cf1_site_id!r}")
+ return await self._delete(
+ path_template(
+ "/accounts/{account_id}/magic/cf1_sites/{cf1_site_id}", account_id=account_id, cf1_site_id=cf1_site_id
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Cf1Site]._unwrapper,
+ ),
+ cast_to=cast(Type[Cf1Site], ResultWrapper[Cf1Site]),
+ )
+
+ async def get(
+ self,
+ cf1_site_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,
+ ) -> Cf1Site:
+ """
+ Gets a specific CF1 Site for an account.
+
+ Args:
+ account_id: Identifier
+
+ cf1_site_id: 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 cf1_site_id:
+ raise ValueError(f"Expected a non-empty value for `cf1_site_id` but received {cf1_site_id!r}")
+ return await self._get(
+ path_template(
+ "/accounts/{account_id}/magic/cf1_sites/{cf1_site_id}", account_id=account_id, cf1_site_id=cf1_site_id
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Cf1Site]._unwrapper,
+ ),
+ cast_to=cast(Type[Cf1Site], ResultWrapper[Cf1Site]),
+ )
+
+
+class Cf1SitesResourceWithRawResponse:
+ def __init__(self, cf1_sites: Cf1SitesResource) -> None:
+ self._cf1_sites = cf1_sites
+
+ self.create = to_raw_response_wrapper(
+ cf1_sites.create,
+ )
+ self.update = to_raw_response_wrapper(
+ cf1_sites.update,
+ )
+ self.list = to_raw_response_wrapper(
+ cf1_sites.list,
+ )
+ self.delete = to_raw_response_wrapper(
+ cf1_sites.delete,
+ )
+ self.get = to_raw_response_wrapper(
+ cf1_sites.get,
+ )
+
+ @cached_property
+ def ramps(self) -> RampsResourceWithRawResponse:
+ return RampsResourceWithRawResponse(self._cf1_sites.ramps)
+
+
+class AsyncCf1SitesResourceWithRawResponse:
+ def __init__(self, cf1_sites: AsyncCf1SitesResource) -> None:
+ self._cf1_sites = cf1_sites
+
+ self.create = async_to_raw_response_wrapper(
+ cf1_sites.create,
+ )
+ self.update = async_to_raw_response_wrapper(
+ cf1_sites.update,
+ )
+ self.list = async_to_raw_response_wrapper(
+ cf1_sites.list,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ cf1_sites.delete,
+ )
+ self.get = async_to_raw_response_wrapper(
+ cf1_sites.get,
+ )
+
+ @cached_property
+ def ramps(self) -> AsyncRampsResourceWithRawResponse:
+ return AsyncRampsResourceWithRawResponse(self._cf1_sites.ramps)
+
+
+class Cf1SitesResourceWithStreamingResponse:
+ def __init__(self, cf1_sites: Cf1SitesResource) -> None:
+ self._cf1_sites = cf1_sites
+
+ self.create = to_streamed_response_wrapper(
+ cf1_sites.create,
+ )
+ self.update = to_streamed_response_wrapper(
+ cf1_sites.update,
+ )
+ self.list = to_streamed_response_wrapper(
+ cf1_sites.list,
+ )
+ self.delete = to_streamed_response_wrapper(
+ cf1_sites.delete,
+ )
+ self.get = to_streamed_response_wrapper(
+ cf1_sites.get,
+ )
+
+ @cached_property
+ def ramps(self) -> RampsResourceWithStreamingResponse:
+ return RampsResourceWithStreamingResponse(self._cf1_sites.ramps)
+
+
+class AsyncCf1SitesResourceWithStreamingResponse:
+ def __init__(self, cf1_sites: AsyncCf1SitesResource) -> None:
+ self._cf1_sites = cf1_sites
+
+ self.create = async_to_streamed_response_wrapper(
+ cf1_sites.create,
+ )
+ self.update = async_to_streamed_response_wrapper(
+ cf1_sites.update,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ cf1_sites.list,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ cf1_sites.delete,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ cf1_sites.get,
+ )
+
+ @cached_property
+ def ramps(self) -> AsyncRampsResourceWithStreamingResponse:
+ return AsyncRampsResourceWithStreamingResponse(self._cf1_sites.ramps)
diff --git a/src/cloudflare/resources/magic_transit/cf1_sites/ramps.py b/src/cloudflare/resources/magic_transit/cf1_sites/ramps.py
new file mode 100644
index 00000000000..8b3ed161517
--- /dev/null
+++ b/src/cloudflare/resources/magic_transit/cf1_sites/ramps.py
@@ -0,0 +1,545 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Type, Iterable, cast
+
+import httpx
+
+from ...._types import Body, Query, Headers, NotGiven, not_given
+from ...._utils import path_template, maybe_transform
+from ...._compat import cached_property
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from ...._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ...._wrappers import ResultWrapper
+from ....pagination import SyncSinglePage, AsyncSinglePage
+from ...._base_client import AsyncPaginator, make_request_options
+from ....types.magic_transit.cf1_sites import ramp_create_params
+from ....types.magic_transit.cf1_sites.ramp import Ramp
+
+__all__ = ["RampsResource", "AsyncRampsResource"]
+
+
+class RampsResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> RampsResourceWithRawResponse:
+ """
+ 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 RampsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> RampsResourceWithStreamingResponse:
+ """
+ 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 RampsResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ cf1_site_id: str,
+ *,
+ account_id: str,
+ body: Iterable[ramp_create_params.Body],
+ # 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[Ramp]:
+ """
+ Creates ramps (network connections) for a CF1 Site.
+
+ Args:
+ account_id: Identifier
+
+ cf1_site_id: 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 cf1_site_id:
+ raise ValueError(f"Expected a non-empty value for `cf1_site_id` but received {cf1_site_id!r}")
+ return self._get_api_list(
+ path_template(
+ "/accounts/{account_id}/magic/cf1_sites/{cf1_site_id}/ramps",
+ account_id=account_id,
+ cf1_site_id=cf1_site_id,
+ ),
+ page=SyncSinglePage[Ramp],
+ body=maybe_transform(body, Iterable[ramp_create_params.Body]),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=Ramp,
+ method="post",
+ )
+
+ def list(
+ self,
+ cf1_site_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,
+ ) -> SyncSinglePage[Ramp]:
+ """Lists ramps (network connections) associated with a CF1 Site.
+
+ Ramps represent
+ GRE tunnels, IPsec tunnels, interconnects, or MCONN links.
+
+ Args:
+ account_id: Identifier
+
+ cf1_site_id: 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 cf1_site_id:
+ raise ValueError(f"Expected a non-empty value for `cf1_site_id` but received {cf1_site_id!r}")
+ return self._get_api_list(
+ path_template(
+ "/accounts/{account_id}/magic/cf1_sites/{cf1_site_id}/ramps",
+ account_id=account_id,
+ cf1_site_id=cf1_site_id,
+ ),
+ page=SyncSinglePage[Ramp],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=Ramp,
+ )
+
+ def delete(
+ self,
+ ramp_id: str,
+ *,
+ account_id: str,
+ cf1_site_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,
+ ) -> Ramp:
+ """
+ Deletes a specific ramp from a CF1 Site.
+
+ Args:
+ account_id: Identifier
+
+ cf1_site_id: Identifier
+
+ ramp_id: 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 cf1_site_id:
+ raise ValueError(f"Expected a non-empty value for `cf1_site_id` but received {cf1_site_id!r}")
+ if not ramp_id:
+ raise ValueError(f"Expected a non-empty value for `ramp_id` but received {ramp_id!r}")
+ return self._delete(
+ path_template(
+ "/accounts/{account_id}/magic/cf1_sites/{cf1_site_id}/ramps/{ramp_id}",
+ account_id=account_id,
+ cf1_site_id=cf1_site_id,
+ ramp_id=ramp_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Ramp]._unwrapper,
+ ),
+ cast_to=cast(Type[Ramp], ResultWrapper[Ramp]),
+ )
+
+ def get(
+ self,
+ ramp_id: str,
+ *,
+ account_id: str,
+ cf1_site_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,
+ ) -> Ramp:
+ """
+ Gets a specific ramp for a CF1 Site.
+
+ Args:
+ account_id: Identifier
+
+ cf1_site_id: Identifier
+
+ ramp_id: 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 cf1_site_id:
+ raise ValueError(f"Expected a non-empty value for `cf1_site_id` but received {cf1_site_id!r}")
+ if not ramp_id:
+ raise ValueError(f"Expected a non-empty value for `ramp_id` but received {ramp_id!r}")
+ return self._get(
+ path_template(
+ "/accounts/{account_id}/magic/cf1_sites/{cf1_site_id}/ramps/{ramp_id}",
+ account_id=account_id,
+ cf1_site_id=cf1_site_id,
+ ramp_id=ramp_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Ramp]._unwrapper,
+ ),
+ cast_to=cast(Type[Ramp], ResultWrapper[Ramp]),
+ )
+
+
+class AsyncRampsResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncRampsResourceWithRawResponse:
+ """
+ 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 AsyncRampsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncRampsResourceWithStreamingResponse:
+ """
+ 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 AsyncRampsResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ cf1_site_id: str,
+ *,
+ account_id: str,
+ body: Iterable[ramp_create_params.Body],
+ # 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[Ramp, AsyncSinglePage[Ramp]]:
+ """
+ Creates ramps (network connections) for a CF1 Site.
+
+ Args:
+ account_id: Identifier
+
+ cf1_site_id: 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 cf1_site_id:
+ raise ValueError(f"Expected a non-empty value for `cf1_site_id` but received {cf1_site_id!r}")
+ return self._get_api_list(
+ path_template(
+ "/accounts/{account_id}/magic/cf1_sites/{cf1_site_id}/ramps",
+ account_id=account_id,
+ cf1_site_id=cf1_site_id,
+ ),
+ page=AsyncSinglePage[Ramp],
+ body=maybe_transform(body, Iterable[ramp_create_params.Body]),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=Ramp,
+ method="post",
+ )
+
+ def list(
+ self,
+ cf1_site_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,
+ ) -> AsyncPaginator[Ramp, AsyncSinglePage[Ramp]]:
+ """Lists ramps (network connections) associated with a CF1 Site.
+
+ Ramps represent
+ GRE tunnels, IPsec tunnels, interconnects, or MCONN links.
+
+ Args:
+ account_id: Identifier
+
+ cf1_site_id: 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 cf1_site_id:
+ raise ValueError(f"Expected a non-empty value for `cf1_site_id` but received {cf1_site_id!r}")
+ return self._get_api_list(
+ path_template(
+ "/accounts/{account_id}/magic/cf1_sites/{cf1_site_id}/ramps",
+ account_id=account_id,
+ cf1_site_id=cf1_site_id,
+ ),
+ page=AsyncSinglePage[Ramp],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=Ramp,
+ )
+
+ async def delete(
+ self,
+ ramp_id: str,
+ *,
+ account_id: str,
+ cf1_site_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,
+ ) -> Ramp:
+ """
+ Deletes a specific ramp from a CF1 Site.
+
+ Args:
+ account_id: Identifier
+
+ cf1_site_id: Identifier
+
+ ramp_id: 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 cf1_site_id:
+ raise ValueError(f"Expected a non-empty value for `cf1_site_id` but received {cf1_site_id!r}")
+ if not ramp_id:
+ raise ValueError(f"Expected a non-empty value for `ramp_id` but received {ramp_id!r}")
+ return await self._delete(
+ path_template(
+ "/accounts/{account_id}/magic/cf1_sites/{cf1_site_id}/ramps/{ramp_id}",
+ account_id=account_id,
+ cf1_site_id=cf1_site_id,
+ ramp_id=ramp_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Ramp]._unwrapper,
+ ),
+ cast_to=cast(Type[Ramp], ResultWrapper[Ramp]),
+ )
+
+ async def get(
+ self,
+ ramp_id: str,
+ *,
+ account_id: str,
+ cf1_site_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,
+ ) -> Ramp:
+ """
+ Gets a specific ramp for a CF1 Site.
+
+ Args:
+ account_id: Identifier
+
+ cf1_site_id: Identifier
+
+ ramp_id: 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 cf1_site_id:
+ raise ValueError(f"Expected a non-empty value for `cf1_site_id` but received {cf1_site_id!r}")
+ if not ramp_id:
+ raise ValueError(f"Expected a non-empty value for `ramp_id` but received {ramp_id!r}")
+ return await self._get(
+ path_template(
+ "/accounts/{account_id}/magic/cf1_sites/{cf1_site_id}/ramps/{ramp_id}",
+ account_id=account_id,
+ cf1_site_id=cf1_site_id,
+ ramp_id=ramp_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Ramp]._unwrapper,
+ ),
+ cast_to=cast(Type[Ramp], ResultWrapper[Ramp]),
+ )
+
+
+class RampsResourceWithRawResponse:
+ def __init__(self, ramps: RampsResource) -> None:
+ self._ramps = ramps
+
+ self.create = to_raw_response_wrapper(
+ ramps.create,
+ )
+ self.list = to_raw_response_wrapper(
+ ramps.list,
+ )
+ self.delete = to_raw_response_wrapper(
+ ramps.delete,
+ )
+ self.get = to_raw_response_wrapper(
+ ramps.get,
+ )
+
+
+class AsyncRampsResourceWithRawResponse:
+ def __init__(self, ramps: AsyncRampsResource) -> None:
+ self._ramps = ramps
+
+ self.create = async_to_raw_response_wrapper(
+ ramps.create,
+ )
+ self.list = async_to_raw_response_wrapper(
+ ramps.list,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ ramps.delete,
+ )
+ self.get = async_to_raw_response_wrapper(
+ ramps.get,
+ )
+
+
+class RampsResourceWithStreamingResponse:
+ def __init__(self, ramps: RampsResource) -> None:
+ self._ramps = ramps
+
+ self.create = to_streamed_response_wrapper(
+ ramps.create,
+ )
+ self.list = to_streamed_response_wrapper(
+ ramps.list,
+ )
+ self.delete = to_streamed_response_wrapper(
+ ramps.delete,
+ )
+ self.get = to_streamed_response_wrapper(
+ ramps.get,
+ )
+
+
+class AsyncRampsResourceWithStreamingResponse:
+ def __init__(self, ramps: AsyncRampsResource) -> None:
+ self._ramps = ramps
+
+ self.create = async_to_streamed_response_wrapper(
+ ramps.create,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ ramps.list,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ ramps.delete,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ ramps.get,
+ )
diff --git a/src/cloudflare/resources/magic_transit/ipsec_tunnels.py b/src/cloudflare/resources/magic_transit/ipsec_tunnels.py
index b1b5dee87a5..aa65d36b481 100644
--- a/src/cloudflare/resources/magic_transit/ipsec_tunnels.py
+++ b/src/cloudflare/resources/magic_transit/ipsec_tunnels.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import Type, cast
+from typing import Type, Iterable, cast
import httpx
@@ -21,6 +21,7 @@
from ...types.magic_transit import (
ipsec_tunnel_create_params,
ipsec_tunnel_update_params,
+ ipsec_tunnel_psk_set_params,
ipsec_tunnel_bulk_update_params,
ipsec_tunnel_psk_generate_params,
)
@@ -29,6 +30,7 @@
from ...types.magic_transit.ipsec_tunnel_create_response import IPSECTunnelCreateResponse
from ...types.magic_transit.ipsec_tunnel_delete_response import IPSECTunnelDeleteResponse
from ...types.magic_transit.ipsec_tunnel_update_response import IPSECTunnelUpdateResponse
+from ...types.magic_transit.ipsec_tunnel_psk_set_response import IPSECTunnelPSKSetResponse
from ...types.magic_transit.ipsec_tunnel_bulk_update_response import IPSECTunnelBulkUpdateResponse
from ...types.magic_transit.ipsec_tunnel_psk_generate_response import IPSECTunnelPSKGenerateResponse
@@ -561,6 +563,60 @@ def psk_generate(
cast_to=cast(Type[IPSECTunnelPSKGenerateResponse], ResultWrapper[IPSECTunnelPSKGenerateResponse]),
)
+ def psk_set(
+ self,
+ *,
+ account_id: str,
+ psks: Iterable[ipsec_tunnel_psk_set_params.PSK],
+ validate_only: 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,
+ ) -> IPSECTunnelPSKSetResponse:
+ """Sets Pre-Shared Keys for multiple IPsec tunnels associated with an account.
+
+ Use
+ `?validate_only=true` as an optional query parameter to only run validation
+ without persisting changes. After PSKs are applied, they are immediately
+ persisted to Cloudflare's edge and cannot be retrieved later. Store the PSKs in
+ a safe place.
+
+ Args:
+ account_id: Identifier
+
+ psks: List of tunnel ID and PSK pairs.
+
+ validate_only: If `true`, only run validation without persisting changes.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._post(
+ path_template("/accounts/{account_id}/magic/ipsec_tunnels/psk", account_id=account_id),
+ body=maybe_transform({"psks": psks}, ipsec_tunnel_psk_set_params.IPSECTunnelPSKSetParams),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {"validate_only": validate_only}, ipsec_tunnel_psk_set_params.IPSECTunnelPSKSetParams
+ ),
+ post_parser=ResultWrapper[IPSECTunnelPSKSetResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[IPSECTunnelPSKSetResponse], ResultWrapper[IPSECTunnelPSKSetResponse]),
+ )
+
class AsyncIPSECTunnelsResource(AsyncAPIResource):
@cached_property
@@ -1088,6 +1144,60 @@ async def psk_generate(
cast_to=cast(Type[IPSECTunnelPSKGenerateResponse], ResultWrapper[IPSECTunnelPSKGenerateResponse]),
)
+ async def psk_set(
+ self,
+ *,
+ account_id: str,
+ psks: Iterable[ipsec_tunnel_psk_set_params.PSK],
+ validate_only: 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,
+ ) -> IPSECTunnelPSKSetResponse:
+ """Sets Pre-Shared Keys for multiple IPsec tunnels associated with an account.
+
+ Use
+ `?validate_only=true` as an optional query parameter to only run validation
+ without persisting changes. After PSKs are applied, they are immediately
+ persisted to Cloudflare's edge and cannot be retrieved later. Store the PSKs in
+ a safe place.
+
+ Args:
+ account_id: Identifier
+
+ psks: List of tunnel ID and PSK pairs.
+
+ validate_only: If `true`, only run validation without persisting changes.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return await self._post(
+ path_template("/accounts/{account_id}/magic/ipsec_tunnels/psk", account_id=account_id),
+ body=await async_maybe_transform({"psks": psks}, ipsec_tunnel_psk_set_params.IPSECTunnelPSKSetParams),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {"validate_only": validate_only}, ipsec_tunnel_psk_set_params.IPSECTunnelPSKSetParams
+ ),
+ post_parser=ResultWrapper[IPSECTunnelPSKSetResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[IPSECTunnelPSKSetResponse], ResultWrapper[IPSECTunnelPSKSetResponse]),
+ )
+
class IPSECTunnelsResourceWithRawResponse:
def __init__(self, ipsec_tunnels: IPSECTunnelsResource) -> None:
@@ -1114,6 +1224,9 @@ def __init__(self, ipsec_tunnels: IPSECTunnelsResource) -> None:
self.psk_generate = to_raw_response_wrapper(
ipsec_tunnels.psk_generate,
)
+ self.psk_set = to_raw_response_wrapper(
+ ipsec_tunnels.psk_set,
+ )
class AsyncIPSECTunnelsResourceWithRawResponse:
@@ -1141,6 +1254,9 @@ def __init__(self, ipsec_tunnels: AsyncIPSECTunnelsResource) -> None:
self.psk_generate = async_to_raw_response_wrapper(
ipsec_tunnels.psk_generate,
)
+ self.psk_set = async_to_raw_response_wrapper(
+ ipsec_tunnels.psk_set,
+ )
class IPSECTunnelsResourceWithStreamingResponse:
@@ -1168,6 +1284,9 @@ def __init__(self, ipsec_tunnels: IPSECTunnelsResource) -> None:
self.psk_generate = to_streamed_response_wrapper(
ipsec_tunnels.psk_generate,
)
+ self.psk_set = to_streamed_response_wrapper(
+ ipsec_tunnels.psk_set,
+ )
class AsyncIPSECTunnelsResourceWithStreamingResponse:
@@ -1195,3 +1314,6 @@ def __init__(self, ipsec_tunnels: AsyncIPSECTunnelsResource) -> None:
self.psk_generate = async_to_streamed_response_wrapper(
ipsec_tunnels.psk_generate,
)
+ self.psk_set = async_to_streamed_response_wrapper(
+ ipsec_tunnels.psk_set,
+ )
diff --git a/src/cloudflare/resources/magic_transit/magic_transit.py b/src/cloudflare/resources/magic_transit/magic_transit.py
index 25525b42650..d3b361778a6 100644
--- a/src/cloudflare/resources/magic_transit/magic_transit.py
+++ b/src/cloudflare/resources/magic_transit/magic_transit.py
@@ -60,6 +60,14 @@
CfInterconnectsResourceWithStreamingResponse,
AsyncCfInterconnectsResourceWithStreamingResponse,
)
+from .cf1_sites.cf1_sites import (
+ Cf1SitesResource,
+ AsyncCf1SitesResource,
+ Cf1SitesResourceWithRawResponse,
+ AsyncCf1SitesResourceWithRawResponse,
+ Cf1SitesResourceWithStreamingResponse,
+ AsyncCf1SitesResourceWithStreamingResponse,
+)
from .connectors.connectors import (
ConnectorsResource,
AsyncConnectorsResource,
@@ -101,6 +109,10 @@ def sites(self) -> SitesResource:
def connectors(self) -> ConnectorsResource:
return ConnectorsResource(self._client)
+ @cached_property
+ def cf1_sites(self) -> Cf1SitesResource:
+ return Cf1SitesResource(self._client)
+
@cached_property
def pcaps(self) -> PCAPsResource:
return PCAPsResource(self._client)
@@ -154,6 +166,10 @@ def sites(self) -> AsyncSitesResource:
def connectors(self) -> AsyncConnectorsResource:
return AsyncConnectorsResource(self._client)
+ @cached_property
+ def cf1_sites(self) -> AsyncCf1SitesResource:
+ return AsyncCf1SitesResource(self._client)
+
@cached_property
def pcaps(self) -> AsyncPCAPsResource:
return AsyncPCAPsResource(self._client)
@@ -210,6 +226,10 @@ def sites(self) -> SitesResourceWithRawResponse:
def connectors(self) -> ConnectorsResourceWithRawResponse:
return ConnectorsResourceWithRawResponse(self._magic_transit.connectors)
+ @cached_property
+ def cf1_sites(self) -> Cf1SitesResourceWithRawResponse:
+ return Cf1SitesResourceWithRawResponse(self._magic_transit.cf1_sites)
+
@cached_property
def pcaps(self) -> PCAPsResourceWithRawResponse:
return PCAPsResourceWithRawResponse(self._magic_transit.pcaps)
@@ -247,6 +267,10 @@ def sites(self) -> AsyncSitesResourceWithRawResponse:
def connectors(self) -> AsyncConnectorsResourceWithRawResponse:
return AsyncConnectorsResourceWithRawResponse(self._magic_transit.connectors)
+ @cached_property
+ def cf1_sites(self) -> AsyncCf1SitesResourceWithRawResponse:
+ return AsyncCf1SitesResourceWithRawResponse(self._magic_transit.cf1_sites)
+
@cached_property
def pcaps(self) -> AsyncPCAPsResourceWithRawResponse:
return AsyncPCAPsResourceWithRawResponse(self._magic_transit.pcaps)
@@ -284,6 +308,10 @@ def sites(self) -> SitesResourceWithStreamingResponse:
def connectors(self) -> ConnectorsResourceWithStreamingResponse:
return ConnectorsResourceWithStreamingResponse(self._magic_transit.connectors)
+ @cached_property
+ def cf1_sites(self) -> Cf1SitesResourceWithStreamingResponse:
+ return Cf1SitesResourceWithStreamingResponse(self._magic_transit.cf1_sites)
+
@cached_property
def pcaps(self) -> PCAPsResourceWithStreamingResponse:
return PCAPsResourceWithStreamingResponse(self._magic_transit.pcaps)
@@ -321,6 +349,10 @@ def sites(self) -> AsyncSitesResourceWithStreamingResponse:
def connectors(self) -> AsyncConnectorsResourceWithStreamingResponse:
return AsyncConnectorsResourceWithStreamingResponse(self._magic_transit.connectors)
+ @cached_property
+ def cf1_sites(self) -> AsyncCf1SitesResourceWithStreamingResponse:
+ return AsyncCf1SitesResourceWithStreamingResponse(self._magic_transit.cf1_sites)
+
@cached_property
def pcaps(self) -> AsyncPCAPsResourceWithStreamingResponse:
return AsyncPCAPsResourceWithStreamingResponse(self._magic_transit.pcaps)
diff --git a/src/cloudflare/types/magic_transit/__init__.py b/src/cloudflare/types/magic_transit/__init__.py
index bec3c88a56d..455a2bc470f 100644
--- a/src/cloudflare/types/magic_transit/__init__.py
+++ b/src/cloudflare/types/magic_transit/__init__.py
@@ -5,11 +5,13 @@
from .pcap import PCAP as PCAP
from .site import Site as Site
from .scope import Scope as Scope
+from .cf1_site import Cf1Site as Cf1Site
from .pcap_filter import PCAPFilter as PCAPFilter
from .scope_param import ScopeParam as ScopeParam
from .health_check import HealthCheck as HealthCheck
from .psk_metadata import PSKMetadata as PSKMetadata
from .site_location import SiteLocation as SiteLocation
+from .cf1_site_param import Cf1SiteParam as Cf1SiteParam
from .app_edit_params import AppEditParams as AppEditParams
from .site_edit_params import SiteEditParams as SiteEditParams
from .site_list_params import SiteListParams as SiteListParams
@@ -17,6 +19,7 @@
from .app_edit_response import AppEditResponse as AppEditResponse
from .app_list_response import AppListResponse as AppListResponse
from .app_update_params import AppUpdateParams as AppUpdateParams
+from .cf1_site_location import Cf1SiteLocation as Cf1SiteLocation
from .health_check_rate import HealthCheckRate as HealthCheckRate
from .health_check_type import HealthCheckType as HealthCheckType
from .pcap_filter_param import PCAPFilterParam as PCAPFilterParam
@@ -41,7 +44,10 @@
from .route_create_response import RouteCreateResponse as RouteCreateResponse
from .route_delete_response import RouteDeleteResponse as RouteDeleteResponse
from .route_update_response import RouteUpdateResponse as RouteUpdateResponse
+from .cf1_site_create_params import Cf1SiteCreateParams as Cf1SiteCreateParams
+from .cf1_site_update_params import Cf1SiteUpdateParams as Cf1SiteUpdateParams
from .connector_get_response import ConnectorGetResponse as ConnectorGetResponse
+from .cf1_site_location_param import Cf1SiteLocationParam as Cf1SiteLocationParam
from .connector_create_params import ConnectorCreateParams as ConnectorCreateParams
from .connector_edit_response import ConnectorEditResponse as ConnectorEditResponse
from .connector_list_response import ConnectorListResponse as ConnectorListResponse
@@ -62,6 +68,7 @@
from .ipsec_tunnel_list_response import IPSECTunnelListResponse as IPSECTunnelListResponse
from .ipsec_tunnel_update_params import IPSECTunnelUpdateParams as IPSECTunnelUpdateParams
from .route_bulk_update_response import RouteBulkUpdateResponse as RouteBulkUpdateResponse
+from .ipsec_tunnel_psk_set_params import IPSECTunnelPSKSetParams as IPSECTunnelPSKSetParams
from .cf_interconnect_get_response import CfInterconnectGetResponse as CfInterconnectGetResponse
from .ipsec_tunnel_create_response import IPSECTunnelCreateResponse as IPSECTunnelCreateResponse
from .ipsec_tunnel_delete_response import IPSECTunnelDeleteResponse as IPSECTunnelDeleteResponse
@@ -69,6 +76,7 @@
from .cf_interconnect_list_response import CfInterconnectListResponse as CfInterconnectListResponse
from .cf_interconnect_update_params import CfInterconnectUpdateParams as CfInterconnectUpdateParams
from .gre_tunnel_bulk_update_params import GRETunnelBulkUpdateParams as GRETunnelBulkUpdateParams
+from .ipsec_tunnel_psk_set_response import IPSECTunnelPSKSetResponse as IPSECTunnelPSKSetResponse
from .cf_interconnect_update_response import CfInterconnectUpdateResponse as CfInterconnectUpdateResponse
from .gre_tunnel_bulk_update_response import GRETunnelBulkUpdateResponse as GRETunnelBulkUpdateResponse
from .ipsec_tunnel_bulk_update_params import IPSECTunnelBulkUpdateParams as IPSECTunnelBulkUpdateParams
diff --git a/src/cloudflare/types/magic_transit/cf1_site.py b/src/cloudflare/types/magic_transit/cf1_site.py
new file mode 100644
index 00000000000..1d025eda69c
--- /dev/null
+++ b/src/cloudflare/types/magic_transit/cf1_site.py
@@ -0,0 +1,29 @@
+# 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
+from .cf1_site_location import Cf1SiteLocation
+
+__all__ = ["Cf1Site"]
+
+
+class Cf1Site(BaseModel):
+ name: str
+ """
+ A human-provided name describing the CF1 Site that should be unique within the
+ account.
+ """
+
+ id: Optional[str] = None
+ """Identifier"""
+
+ created_on: Optional[datetime] = None
+
+ description: Optional[str] = None
+ """A human-provided description of the CF1 Site."""
+
+ location: Optional[Cf1SiteLocation] = None
+
+ modified_on: Optional[datetime] = None
diff --git a/src/cloudflare/types/magic_transit/cf1_site_create_params.py b/src/cloudflare/types/magic_transit/cf1_site_create_params.py
new file mode 100644
index 00000000000..e8c6c6fbb8e
--- /dev/null
+++ b/src/cloudflare/types/magic_transit/cf1_site_create_params.py
@@ -0,0 +1,17 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable
+from typing_extensions import Required, TypedDict
+
+from .cf1_site_param import Cf1SiteParam
+
+__all__ = ["Cf1SiteCreateParams"]
+
+
+class Cf1SiteCreateParams(TypedDict, total=False):
+ account_id: Required[str]
+ """Identifier"""
+
+ body: Required[Iterable[Cf1SiteParam]]
diff --git a/src/cloudflare/types/magic_transit/cf1_site_location.py b/src/cloudflare/types/magic_transit/cf1_site_location.py
new file mode 100644
index 00000000000..ef848a85744
--- /dev/null
+++ b/src/cloudflare/types/magic_transit/cf1_site_location.py
@@ -0,0 +1,18 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from ..._models import BaseModel
+
+__all__ = ["Cf1SiteLocation"]
+
+
+class Cf1SiteLocation(BaseModel):
+ lat: Optional[float] = None
+ """Latitude of the CF1 Site."""
+
+ long: Optional[float] = None
+ """Longitude of the CF1 Site."""
+
+ name: Optional[str] = None
+ """Name of nearest town, city, or village."""
diff --git a/src/cloudflare/types/magic_transit/cf1_site_location_param.py b/src/cloudflare/types/magic_transit/cf1_site_location_param.py
new file mode 100644
index 00000000000..0eae3b7fc58
--- /dev/null
+++ b/src/cloudflare/types/magic_transit/cf1_site_location_param.py
@@ -0,0 +1,18 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypedDict
+
+__all__ = ["Cf1SiteLocationParam"]
+
+
+class Cf1SiteLocationParam(TypedDict, total=False):
+ lat: float
+ """Latitude of the CF1 Site."""
+
+ long: float
+ """Longitude of the CF1 Site."""
+
+ name: str
+ """Name of nearest town, city, or village."""
diff --git a/src/cloudflare/types/magic_transit/cf1_site_param.py b/src/cloudflare/types/magic_transit/cf1_site_param.py
new file mode 100644
index 00000000000..726a5fa2cf7
--- /dev/null
+++ b/src/cloudflare/types/magic_transit/cf1_site_param.py
@@ -0,0 +1,22 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+from .cf1_site_location_param import Cf1SiteLocationParam
+
+__all__ = ["Cf1SiteParam"]
+
+
+class Cf1SiteParam(TypedDict, total=False):
+ name: Required[str]
+ """
+ A human-provided name describing the CF1 Site that should be unique within the
+ account.
+ """
+
+ description: str
+ """A human-provided description of the CF1 Site."""
+
+ location: Cf1SiteLocationParam
diff --git a/src/cloudflare/types/magic_transit/cf1_site_update_params.py b/src/cloudflare/types/magic_transit/cf1_site_update_params.py
new file mode 100644
index 00000000000..15d2c6b6983
--- /dev/null
+++ b/src/cloudflare/types/magic_transit/cf1_site_update_params.py
@@ -0,0 +1,25 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+from .cf1_site_location_param import Cf1SiteLocationParam
+
+__all__ = ["Cf1SiteUpdateParams"]
+
+
+class Cf1SiteUpdateParams(TypedDict, total=False):
+ account_id: Required[str]
+ """Identifier"""
+
+ description: str
+ """A human-provided description of the CF1 Site."""
+
+ location: Cf1SiteLocationParam
+
+ name: str
+ """
+ A human-provided name describing the CF1 Site that should be unique within the
+ account.
+ """
diff --git a/src/cloudflare/types/magic_transit/cf1_sites/__init__.py b/src/cloudflare/types/magic_transit/cf1_sites/__init__.py
new file mode 100644
index 00000000000..557e9559af2
--- /dev/null
+++ b/src/cloudflare/types/magic_transit/cf1_sites/__init__.py
@@ -0,0 +1,7 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .ramp import Ramp as Ramp
+from .ramp_type import RampType as RampType
+from .ramp_create_params import RampCreateParams as RampCreateParams
diff --git a/src/cloudflare/types/magic_transit/cf1_sites/ramp.py b/src/cloudflare/types/magic_transit/cf1_sites/ramp.py
new file mode 100644
index 00000000000..55bd928c360
--- /dev/null
+++ b/src/cloudflare/types/magic_transit/cf1_sites/ramp.py
@@ -0,0 +1,68 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from datetime import datetime
+
+from .ramp_type import RampType
+from ...._models import BaseModel
+
+__all__ = ["Ramp", "GRE", "GREInterconnect", "IPSEC", "Mconn", "MplsInterconnect"]
+
+
+class GRE(BaseModel):
+ managed_by: Optional[str] = None
+ """URL reference to the source network resource that this ramp is managed by."""
+
+
+class GREInterconnect(BaseModel):
+ managed_by: Optional[str] = None
+ """URL reference to the source network resource that this ramp is managed by."""
+
+
+class IPSEC(BaseModel):
+ managed_by: Optional[str] = None
+ """URL reference to the source network resource that this ramp is managed by."""
+
+
+class Mconn(BaseModel):
+ managed_by: Optional[str] = None
+ """URL reference to the source network resource that this ramp is managed by."""
+
+
+class MplsInterconnect(BaseModel):
+ managed_by: Optional[str] = None
+ """URL reference to the source network resource that this ramp is managed by."""
+
+
+class Ramp(BaseModel):
+ id: str
+ """Identifier"""
+
+ created_on: datetime
+
+ modified_on: datetime
+
+ name: str
+ """
+ A human-provided name describing the ramp that should be unique within the CF1
+ Site.
+ """
+
+ type: RampType
+ """
+ The type of network connection (ramp) linking a CF1 Site to Cloudflare's
+ network.
+ """
+
+ description: Optional[str] = None
+ """A human-provided description of the ramp."""
+
+ gre: Optional[GRE] = None
+
+ gre_interconnect: Optional[GREInterconnect] = None
+
+ ipsec: Optional[IPSEC] = None
+
+ mconn: Optional[Mconn] = None
+
+ mpls_interconnect: Optional[MplsInterconnect] = None
diff --git a/src/cloudflare/types/magic_transit/cf1_sites/ramp_create_params.py b/src/cloudflare/types/magic_transit/cf1_sites/ramp_create_params.py
new file mode 100644
index 00000000000..ddcae3e4f92
--- /dev/null
+++ b/src/cloudflare/types/magic_transit/cf1_sites/ramp_create_params.py
@@ -0,0 +1,28 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable
+from typing_extensions import Required, TypedDict
+
+from .ramp_type import RampType
+
+__all__ = ["RampCreateParams", "Body"]
+
+
+class RampCreateParams(TypedDict, total=False):
+ account_id: Required[str]
+ """Identifier"""
+
+ body: Required[Iterable[Body]]
+
+
+class Body(TypedDict, total=False):
+ source_ramp_id: Required[str]
+ """Identifier of the source network resource to associate as a ramp."""
+
+ type: Required[RampType]
+ """
+ The type of network connection (ramp) linking a CF1 Site to Cloudflare's
+ network.
+ """
diff --git a/src/cloudflare/types/magic_transit/cf1_sites/ramp_type.py b/src/cloudflare/types/magic_transit/cf1_sites/ramp_type.py
new file mode 100644
index 00000000000..0ecb9263694
--- /dev/null
+++ b/src/cloudflare/types/magic_transit/cf1_sites/ramp_type.py
@@ -0,0 +1,7 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import Literal, TypeAlias
+
+__all__ = ["RampType"]
+
+RampType: TypeAlias = Literal["gre", "gre_interconnect", "mpls_interconnect", "mconn", "ipsec"]
diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_psk_set_params.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_psk_set_params.py
new file mode 100644
index 00000000000..447cc427d32
--- /dev/null
+++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_psk_set_params.py
@@ -0,0 +1,29 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable
+from typing_extensions import Required, TypedDict
+
+__all__ = ["IPSECTunnelPSKSetParams", "PSK"]
+
+
+class IPSECTunnelPSKSetParams(TypedDict, total=False):
+ account_id: Required[str]
+ """Identifier"""
+
+ psks: Required[Iterable[PSK]]
+ """List of tunnel ID and PSK pairs."""
+
+ validate_only: bool
+ """If `true`, only run validation without persisting changes."""
+
+
+class PSK(TypedDict, total=False):
+ """A PSK entry for a specific IPsec tunnel."""
+
+ id: Required[str]
+ """The ID of the IPsec tunnel."""
+
+ psk: Required[str]
+ """A randomly generated or provided string for use in the IPsec tunnel."""
diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_psk_set_response.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_psk_set_response.py
new file mode 100644
index 00000000000..ba2c5097be2
--- /dev/null
+++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_psk_set_response.py
@@ -0,0 +1,32 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict, Optional
+
+from ..._models import BaseModel
+from .psk_metadata import PSKMetadata
+
+__all__ = ["IPSECTunnelPSKSetResponse", "SuccessfullyAppliedPSKs"]
+
+
+class SuccessfullyAppliedPSKs(BaseModel):
+ """A successfully applied PSK for an IPsec tunnel."""
+
+ ipsec_id: str
+ """The IKE identifier used for this tunnel on the Cloudflare edge."""
+
+ ipsec_tunnel_id: str
+ """Identifier"""
+
+ psk: str
+ """A randomly generated or provided string for use in the IPsec tunnel."""
+
+ psk_metadata: PSKMetadata
+ """The PSK metadata that includes when the PSK was generated."""
+
+
+class IPSECTunnelPSKSetResponse(BaseModel):
+ successfully_applied_psks: Optional[Dict[str, SuccessfullyAppliedPSKs]] = None
+ """Map of tunnel IDs to successfully applied PSK details."""
+
+ unapplied_psks: Optional[Dict[str, str]] = None
+ """Map of tunnel IDs to failure reasons for PSKs that could not be applied."""
diff --git a/tests/api_resources/magic_transit/cf1_sites/__init__.py b/tests/api_resources/magic_transit/cf1_sites/__init__.py
new file mode 100644
index 00000000000..fd8019a9a1a
--- /dev/null
+++ b/tests/api_resources/magic_transit/cf1_sites/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/magic_transit/cf1_sites/test_ramps.py b/tests/api_resources/magic_transit/cf1_sites/test_ramps.py
new file mode 100644
index 00000000000..2ac5f4b1afa
--- /dev/null
+++ b/tests/api_resources/magic_transit/cf1_sites/test_ramps.py
@@ -0,0 +1,517 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare.pagination import SyncSinglePage, AsyncSinglePage
+from cloudflare.types.magic_transit.cf1_sites import Ramp
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestRamps:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: Cloudflare) -> None:
+ ramp = client.magic_transit.cf1_sites.ramps.create(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ body=[
+ {
+ "source_ramp_id": "023e105f4ecef8ad9ca31a8372d0c353",
+ "type": "gre",
+ }
+ ],
+ )
+ assert_matches_type(SyncSinglePage[Ramp], ramp, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Cloudflare) -> None:
+ response = client.magic_transit.cf1_sites.ramps.with_raw_response.create(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ body=[
+ {
+ "source_ramp_id": "023e105f4ecef8ad9ca31a8372d0c353",
+ "type": "gre",
+ }
+ ],
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ ramp = response.parse()
+ assert_matches_type(SyncSinglePage[Ramp], ramp, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: Cloudflare) -> None:
+ with client.magic_transit.cf1_sites.ramps.with_streaming_response.create(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ body=[
+ {
+ "source_ramp_id": "023e105f4ecef8ad9ca31a8372d0c353",
+ "type": "gre",
+ }
+ ],
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ ramp = response.parse()
+ assert_matches_type(SyncSinglePage[Ramp], ramp, 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.magic_transit.cf1_sites.ramps.with_raw_response.create(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ body=[
+ {
+ "source_ramp_id": "023e105f4ecef8ad9ca31a8372d0c353",
+ "type": "gre",
+ }
+ ],
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `cf1_site_id` but received ''"):
+ client.magic_transit.cf1_sites.ramps.with_raw_response.create(
+ cf1_site_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ body=[
+ {
+ "source_ramp_id": "023e105f4ecef8ad9ca31a8372d0c353",
+ "type": "gre",
+ }
+ ],
+ )
+
+ @parametrize
+ def test_method_list(self, client: Cloudflare) -> None:
+ ramp = client.magic_transit.cf1_sites.ramps.list(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(SyncSinglePage[Ramp], ramp, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Cloudflare) -> None:
+ response = client.magic_transit.cf1_sites.ramps.with_raw_response.list(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ ramp = response.parse()
+ assert_matches_type(SyncSinglePage[Ramp], ramp, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Cloudflare) -> None:
+ with client.magic_transit.cf1_sites.ramps.with_streaming_response.list(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ ramp = response.parse()
+ assert_matches_type(SyncSinglePage[Ramp], ramp, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_list(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.magic_transit.cf1_sites.ramps.with_raw_response.list(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `cf1_site_id` but received ''"):
+ client.magic_transit.cf1_sites.ramps.with_raw_response.list(
+ cf1_site_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ @parametrize
+ def test_method_delete(self, client: Cloudflare) -> None:
+ ramp = client.magic_transit.cf1_sites.ramps.delete(
+ ramp_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Ramp, ramp, path=["response"])
+
+ @parametrize
+ def test_raw_response_delete(self, client: Cloudflare) -> None:
+ response = client.magic_transit.cf1_sites.ramps.with_raw_response.delete(
+ ramp_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ ramp = response.parse()
+ assert_matches_type(Ramp, ramp, path=["response"])
+
+ @parametrize
+ def test_streaming_response_delete(self, client: Cloudflare) -> None:
+ with client.magic_transit.cf1_sites.ramps.with_streaming_response.delete(
+ ramp_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ ramp = response.parse()
+ assert_matches_type(Ramp, ramp, 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.magic_transit.cf1_sites.ramps.with_raw_response.delete(
+ ramp_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `cf1_site_id` but received ''"):
+ client.magic_transit.cf1_sites.ramps.with_raw_response.delete(
+ ramp_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ cf1_site_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `ramp_id` but received ''"):
+ client.magic_transit.cf1_sites.ramps.with_raw_response.delete(
+ ramp_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ @parametrize
+ def test_method_get(self, client: Cloudflare) -> None:
+ ramp = client.magic_transit.cf1_sites.ramps.get(
+ ramp_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Ramp, ramp, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Cloudflare) -> None:
+ response = client.magic_transit.cf1_sites.ramps.with_raw_response.get(
+ ramp_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ ramp = response.parse()
+ assert_matches_type(Ramp, ramp, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Cloudflare) -> None:
+ with client.magic_transit.cf1_sites.ramps.with_streaming_response.get(
+ ramp_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ ramp = response.parse()
+ assert_matches_type(Ramp, ramp, 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.magic_transit.cf1_sites.ramps.with_raw_response.get(
+ ramp_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `cf1_site_id` but received ''"):
+ client.magic_transit.cf1_sites.ramps.with_raw_response.get(
+ ramp_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ cf1_site_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `ramp_id` but received ''"):
+ client.magic_transit.cf1_sites.ramps.with_raw_response.get(
+ ramp_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+
+class TestAsyncRamps:
+ 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:
+ ramp = await async_client.magic_transit.cf1_sites.ramps.create(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ body=[
+ {
+ "source_ramp_id": "023e105f4ecef8ad9ca31a8372d0c353",
+ "type": "gre",
+ }
+ ],
+ )
+ assert_matches_type(AsyncSinglePage[Ramp], ramp, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.magic_transit.cf1_sites.ramps.with_raw_response.create(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ body=[
+ {
+ "source_ramp_id": "023e105f4ecef8ad9ca31a8372d0c353",
+ "type": "gre",
+ }
+ ],
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ ramp = await response.parse()
+ assert_matches_type(AsyncSinglePage[Ramp], ramp, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.magic_transit.cf1_sites.ramps.with_streaming_response.create(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ body=[
+ {
+ "source_ramp_id": "023e105f4ecef8ad9ca31a8372d0c353",
+ "type": "gre",
+ }
+ ],
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ ramp = await response.parse()
+ assert_matches_type(AsyncSinglePage[Ramp], ramp, 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.magic_transit.cf1_sites.ramps.with_raw_response.create(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ body=[
+ {
+ "source_ramp_id": "023e105f4ecef8ad9ca31a8372d0c353",
+ "type": "gre",
+ }
+ ],
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `cf1_site_id` but received ''"):
+ await async_client.magic_transit.cf1_sites.ramps.with_raw_response.create(
+ cf1_site_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ body=[
+ {
+ "source_ramp_id": "023e105f4ecef8ad9ca31a8372d0c353",
+ "type": "gre",
+ }
+ ],
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncCloudflare) -> None:
+ ramp = await async_client.magic_transit.cf1_sites.ramps.list(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(AsyncSinglePage[Ramp], ramp, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.magic_transit.cf1_sites.ramps.with_raw_response.list(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ ramp = await response.parse()
+ assert_matches_type(AsyncSinglePage[Ramp], ramp, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.magic_transit.cf1_sites.ramps.with_streaming_response.list(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ ramp = await response.parse()
+ assert_matches_type(AsyncSinglePage[Ramp], ramp, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.magic_transit.cf1_sites.ramps.with_raw_response.list(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `cf1_site_id` but received ''"):
+ await async_client.magic_transit.cf1_sites.ramps.with_raw_response.list(
+ cf1_site_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncCloudflare) -> None:
+ ramp = await async_client.magic_transit.cf1_sites.ramps.delete(
+ ramp_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Ramp, ramp, path=["response"])
+
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.magic_transit.cf1_sites.ramps.with_raw_response.delete(
+ ramp_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ ramp = await response.parse()
+ assert_matches_type(Ramp, ramp, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.magic_transit.cf1_sites.ramps.with_streaming_response.delete(
+ ramp_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ ramp = await response.parse()
+ assert_matches_type(Ramp, ramp, 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.magic_transit.cf1_sites.ramps.with_raw_response.delete(
+ ramp_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `cf1_site_id` but received ''"):
+ await async_client.magic_transit.cf1_sites.ramps.with_raw_response.delete(
+ ramp_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ cf1_site_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `ramp_id` but received ''"):
+ await async_client.magic_transit.cf1_sites.ramps.with_raw_response.delete(
+ ramp_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncCloudflare) -> None:
+ ramp = await async_client.magic_transit.cf1_sites.ramps.get(
+ ramp_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Ramp, ramp, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.magic_transit.cf1_sites.ramps.with_raw_response.get(
+ ramp_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ ramp = await response.parse()
+ assert_matches_type(Ramp, ramp, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.magic_transit.cf1_sites.ramps.with_streaming_response.get(
+ ramp_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ ramp = await response.parse()
+ assert_matches_type(Ramp, ramp, 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.magic_transit.cf1_sites.ramps.with_raw_response.get(
+ ramp_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `cf1_site_id` but received ''"):
+ await async_client.magic_transit.cf1_sites.ramps.with_raw_response.get(
+ ramp_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ cf1_site_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `ramp_id` but received ''"):
+ await async_client.magic_transit.cf1_sites.ramps.with_raw_response.get(
+ ramp_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
diff --git a/tests/api_resources/magic_transit/test_cf1_sites.py b/tests/api_resources/magic_transit/test_cf1_sites.py
new file mode 100644
index 00000000000..f8266055155
--- /dev/null
+++ b/tests/api_resources/magic_transit/test_cf1_sites.py
@@ -0,0 +1,503 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare.pagination import SyncSinglePage, AsyncSinglePage
+from cloudflare.types.magic_transit import Cf1Site
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestCf1Sites:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: Cloudflare) -> None:
+ cf1_site = client.magic_transit.cf1_sites.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ body=[{"name": "Pad 34"}],
+ )
+ assert_matches_type(SyncSinglePage[Cf1Site], cf1_site, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Cloudflare) -> None:
+ response = client.magic_transit.cf1_sites.with_raw_response.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ body=[{"name": "Pad 34"}],
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cf1_site = response.parse()
+ assert_matches_type(SyncSinglePage[Cf1Site], cf1_site, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: Cloudflare) -> None:
+ with client.magic_transit.cf1_sites.with_streaming_response.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ body=[{"name": "Pad 34"}],
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cf1_site = response.parse()
+ assert_matches_type(SyncSinglePage[Cf1Site], cf1_site, 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.magic_transit.cf1_sites.with_raw_response.create(
+ account_id="",
+ body=[{"name": "Pad 34"}],
+ )
+
+ @parametrize
+ def test_method_update(self, client: Cloudflare) -> None:
+ cf1_site = client.magic_transit.cf1_sites.update(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Cf1Site, cf1_site, path=["response"])
+
+ @parametrize
+ def test_method_update_with_all_params(self, client: Cloudflare) -> None:
+ cf1_site = client.magic_transit.cf1_sites.update(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ description="Launch Pad 34",
+ location={
+ "lat": 28.521339842093845,
+ "long": -80.56092644815843,
+ "name": "Cape Canaveral",
+ },
+ name="Pad 34",
+ )
+ assert_matches_type(Cf1Site, cf1_site, path=["response"])
+
+ @parametrize
+ def test_raw_response_update(self, client: Cloudflare) -> None:
+ response = client.magic_transit.cf1_sites.with_raw_response.update(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cf1_site = response.parse()
+ assert_matches_type(Cf1Site, cf1_site, path=["response"])
+
+ @parametrize
+ def test_streaming_response_update(self, client: Cloudflare) -> None:
+ with client.magic_transit.cf1_sites.with_streaming_response.update(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cf1_site = response.parse()
+ assert_matches_type(Cf1Site, cf1_site, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @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 ''"):
+ client.magic_transit.cf1_sites.with_raw_response.update(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `cf1_site_id` but received ''"):
+ client.magic_transit.cf1_sites.with_raw_response.update(
+ cf1_site_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ @parametrize
+ def test_method_list(self, client: Cloudflare) -> None:
+ cf1_site = client.magic_transit.cf1_sites.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(SyncSinglePage[Cf1Site], cf1_site, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Cloudflare) -> None:
+ response = client.magic_transit.cf1_sites.with_raw_response.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cf1_site = response.parse()
+ assert_matches_type(SyncSinglePage[Cf1Site], cf1_site, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Cloudflare) -> None:
+ with client.magic_transit.cf1_sites.with_streaming_response.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cf1_site = response.parse()
+ assert_matches_type(SyncSinglePage[Cf1Site], cf1_site, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_list(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.magic_transit.cf1_sites.with_raw_response.list(
+ account_id="",
+ )
+
+ @parametrize
+ def test_method_delete(self, client: Cloudflare) -> None:
+ cf1_site = client.magic_transit.cf1_sites.delete(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Cf1Site, cf1_site, path=["response"])
+
+ @parametrize
+ def test_raw_response_delete(self, client: Cloudflare) -> None:
+ response = client.magic_transit.cf1_sites.with_raw_response.delete(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cf1_site = response.parse()
+ assert_matches_type(Cf1Site, cf1_site, path=["response"])
+
+ @parametrize
+ def test_streaming_response_delete(self, client: Cloudflare) -> None:
+ with client.magic_transit.cf1_sites.with_streaming_response.delete(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cf1_site = response.parse()
+ assert_matches_type(Cf1Site, cf1_site, 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.magic_transit.cf1_sites.with_raw_response.delete(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `cf1_site_id` but received ''"):
+ client.magic_transit.cf1_sites.with_raw_response.delete(
+ cf1_site_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ @parametrize
+ def test_method_get(self, client: Cloudflare) -> None:
+ cf1_site = client.magic_transit.cf1_sites.get(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Cf1Site, cf1_site, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Cloudflare) -> None:
+ response = client.magic_transit.cf1_sites.with_raw_response.get(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cf1_site = response.parse()
+ assert_matches_type(Cf1Site, cf1_site, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Cloudflare) -> None:
+ with client.magic_transit.cf1_sites.with_streaming_response.get(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cf1_site = response.parse()
+ assert_matches_type(Cf1Site, cf1_site, 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.magic_transit.cf1_sites.with_raw_response.get(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `cf1_site_id` but received ''"):
+ client.magic_transit.cf1_sites.with_raw_response.get(
+ cf1_site_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+
+class TestAsyncCf1Sites:
+ 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:
+ cf1_site = await async_client.magic_transit.cf1_sites.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ body=[{"name": "Pad 34"}],
+ )
+ assert_matches_type(AsyncSinglePage[Cf1Site], cf1_site, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.magic_transit.cf1_sites.with_raw_response.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ body=[{"name": "Pad 34"}],
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cf1_site = await response.parse()
+ assert_matches_type(AsyncSinglePage[Cf1Site], cf1_site, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.magic_transit.cf1_sites.with_streaming_response.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ body=[{"name": "Pad 34"}],
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cf1_site = await response.parse()
+ assert_matches_type(AsyncSinglePage[Cf1Site], cf1_site, 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.magic_transit.cf1_sites.with_raw_response.create(
+ account_id="",
+ body=[{"name": "Pad 34"}],
+ )
+
+ @parametrize
+ async def test_method_update(self, async_client: AsyncCloudflare) -> None:
+ cf1_site = await async_client.magic_transit.cf1_sites.update(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Cf1Site, cf1_site, path=["response"])
+
+ @parametrize
+ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ cf1_site = await async_client.magic_transit.cf1_sites.update(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ description="Launch Pad 34",
+ location={
+ "lat": 28.521339842093845,
+ "long": -80.56092644815843,
+ "name": "Cape Canaveral",
+ },
+ name="Pad 34",
+ )
+ assert_matches_type(Cf1Site, cf1_site, path=["response"])
+
+ @parametrize
+ async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.magic_transit.cf1_sites.with_raw_response.update(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cf1_site = await response.parse()
+ assert_matches_type(Cf1Site, cf1_site, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.magic_transit.cf1_sites.with_streaming_response.update(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cf1_site = await response.parse()
+ assert_matches_type(Cf1Site, cf1_site, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @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 ''"):
+ await async_client.magic_transit.cf1_sites.with_raw_response.update(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `cf1_site_id` but received ''"):
+ await async_client.magic_transit.cf1_sites.with_raw_response.update(
+ cf1_site_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncCloudflare) -> None:
+ cf1_site = await async_client.magic_transit.cf1_sites.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(AsyncSinglePage[Cf1Site], cf1_site, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.magic_transit.cf1_sites.with_raw_response.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cf1_site = await response.parse()
+ assert_matches_type(AsyncSinglePage[Cf1Site], cf1_site, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.magic_transit.cf1_sites.with_streaming_response.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cf1_site = await response.parse()
+ assert_matches_type(AsyncSinglePage[Cf1Site], cf1_site, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.magic_transit.cf1_sites.with_raw_response.list(
+ account_id="",
+ )
+
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncCloudflare) -> None:
+ cf1_site = await async_client.magic_transit.cf1_sites.delete(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Cf1Site, cf1_site, path=["response"])
+
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.magic_transit.cf1_sites.with_raw_response.delete(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cf1_site = await response.parse()
+ assert_matches_type(Cf1Site, cf1_site, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.magic_transit.cf1_sites.with_streaming_response.delete(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cf1_site = await response.parse()
+ assert_matches_type(Cf1Site, cf1_site, 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.magic_transit.cf1_sites.with_raw_response.delete(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `cf1_site_id` but received ''"):
+ await async_client.magic_transit.cf1_sites.with_raw_response.delete(
+ cf1_site_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncCloudflare) -> None:
+ cf1_site = await async_client.magic_transit.cf1_sites.get(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Cf1Site, cf1_site, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.magic_transit.cf1_sites.with_raw_response.get(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cf1_site = await response.parse()
+ assert_matches_type(Cf1Site, cf1_site, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.magic_transit.cf1_sites.with_streaming_response.get(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cf1_site = await response.parse()
+ assert_matches_type(Cf1Site, cf1_site, 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.magic_transit.cf1_sites.with_raw_response.get(
+ cf1_site_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `cf1_site_id` but received ''"):
+ await async_client.magic_transit.cf1_sites.with_raw_response.get(
+ cf1_site_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
diff --git a/tests/api_resources/magic_transit/test_ipsec_tunnels.py b/tests/api_resources/magic_transit/test_ipsec_tunnels.py
index 01460e202f7..a9c532cf3eb 100644
--- a/tests/api_resources/magic_transit/test_ipsec_tunnels.py
+++ b/tests/api_resources/magic_transit/test_ipsec_tunnels.py
@@ -14,6 +14,7 @@
IPSECTunnelListResponse,
IPSECTunnelCreateResponse,
IPSECTunnelDeleteResponse,
+ IPSECTunnelPSKSetResponse,
IPSECTunnelUpdateResponse,
IPSECTunnelBulkUpdateResponse,
IPSECTunnelPSKGenerateResponse,
@@ -473,6 +474,82 @@ def test_path_params_psk_generate(self, client: Cloudflare) -> None:
body={},
)
+ @parametrize
+ def test_method_psk_set(self, client: Cloudflare) -> None:
+ ipsec_tunnel = client.magic_transit.ipsec_tunnels.psk_set(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ psks=[
+ {
+ "id": "023e105f4ecef8ad9ca31a8372d0c353",
+ "psk": "O3bwKSjnaoCxDoUxjcq4Rk8ZKkezQUiy",
+ }
+ ],
+ )
+ assert_matches_type(IPSECTunnelPSKSetResponse, ipsec_tunnel, path=["response"])
+
+ @parametrize
+ def test_method_psk_set_with_all_params(self, client: Cloudflare) -> None:
+ ipsec_tunnel = client.magic_transit.ipsec_tunnels.psk_set(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ psks=[
+ {
+ "id": "023e105f4ecef8ad9ca31a8372d0c353",
+ "psk": "O3bwKSjnaoCxDoUxjcq4Rk8ZKkezQUiy",
+ }
+ ],
+ validate_only=True,
+ )
+ assert_matches_type(IPSECTunnelPSKSetResponse, ipsec_tunnel, path=["response"])
+
+ @parametrize
+ def test_raw_response_psk_set(self, client: Cloudflare) -> None:
+ response = client.magic_transit.ipsec_tunnels.with_raw_response.psk_set(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ psks=[
+ {
+ "id": "023e105f4ecef8ad9ca31a8372d0c353",
+ "psk": "O3bwKSjnaoCxDoUxjcq4Rk8ZKkezQUiy",
+ }
+ ],
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ ipsec_tunnel = response.parse()
+ assert_matches_type(IPSECTunnelPSKSetResponse, ipsec_tunnel, path=["response"])
+
+ @parametrize
+ def test_streaming_response_psk_set(self, client: Cloudflare) -> None:
+ with client.magic_transit.ipsec_tunnels.with_streaming_response.psk_set(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ psks=[
+ {
+ "id": "023e105f4ecef8ad9ca31a8372d0c353",
+ "psk": "O3bwKSjnaoCxDoUxjcq4Rk8ZKkezQUiy",
+ }
+ ],
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ ipsec_tunnel = response.parse()
+ assert_matches_type(IPSECTunnelPSKSetResponse, ipsec_tunnel, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_psk_set(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.magic_transit.ipsec_tunnels.with_raw_response.psk_set(
+ account_id="",
+ psks=[
+ {
+ "id": "023e105f4ecef8ad9ca31a8372d0c353",
+ "psk": "O3bwKSjnaoCxDoUxjcq4Rk8ZKkezQUiy",
+ }
+ ],
+ )
+
class TestAsyncIPSECTunnels:
parametrize = pytest.mark.parametrize(
@@ -926,3 +1003,79 @@ async def test_path_params_psk_generate(self, async_client: AsyncCloudflare) ->
account_id="023e105f4ecef8ad9ca31a8372d0c353",
body={},
)
+
+ @parametrize
+ async def test_method_psk_set(self, async_client: AsyncCloudflare) -> None:
+ ipsec_tunnel = await async_client.magic_transit.ipsec_tunnels.psk_set(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ psks=[
+ {
+ "id": "023e105f4ecef8ad9ca31a8372d0c353",
+ "psk": "O3bwKSjnaoCxDoUxjcq4Rk8ZKkezQUiy",
+ }
+ ],
+ )
+ assert_matches_type(IPSECTunnelPSKSetResponse, ipsec_tunnel, path=["response"])
+
+ @parametrize
+ async def test_method_psk_set_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ ipsec_tunnel = await async_client.magic_transit.ipsec_tunnels.psk_set(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ psks=[
+ {
+ "id": "023e105f4ecef8ad9ca31a8372d0c353",
+ "psk": "O3bwKSjnaoCxDoUxjcq4Rk8ZKkezQUiy",
+ }
+ ],
+ validate_only=True,
+ )
+ assert_matches_type(IPSECTunnelPSKSetResponse, ipsec_tunnel, path=["response"])
+
+ @parametrize
+ async def test_raw_response_psk_set(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.magic_transit.ipsec_tunnels.with_raw_response.psk_set(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ psks=[
+ {
+ "id": "023e105f4ecef8ad9ca31a8372d0c353",
+ "psk": "O3bwKSjnaoCxDoUxjcq4Rk8ZKkezQUiy",
+ }
+ ],
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ ipsec_tunnel = await response.parse()
+ assert_matches_type(IPSECTunnelPSKSetResponse, ipsec_tunnel, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_psk_set(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.magic_transit.ipsec_tunnels.with_streaming_response.psk_set(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ psks=[
+ {
+ "id": "023e105f4ecef8ad9ca31a8372d0c353",
+ "psk": "O3bwKSjnaoCxDoUxjcq4Rk8ZKkezQUiy",
+ }
+ ],
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ ipsec_tunnel = await response.parse()
+ assert_matches_type(IPSECTunnelPSKSetResponse, ipsec_tunnel, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_psk_set(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.magic_transit.ipsec_tunnels.with_raw_response.psk_set(
+ account_id="",
+ psks=[
+ {
+ "id": "023e105f4ecef8ad9ca31a8372d0c353",
+ "psk": "O3bwKSjnaoCxDoUxjcq4Rk8ZKkezQUiy",
+ }
+ ],
+ )
From 3e26c739c29586ab33e05bb4dc6673d06748d013 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 15 Jun 2026 20:12:58 +0000
Subject: [PATCH 14/23] chore(api): update composite API spec
---
.stats.yml | 6 +-
src/cloudflare/resources/ssl/__init__.py | 14 +
src/cloudflare/resources/ssl/api.md | 13 +
.../resources/ssl/auto_origin_tls_kex.py | 289 ++++++++++++++++++
src/cloudflare/resources/ssl/ssl.py | 32 ++
src/cloudflare/types/ssl/__init__.py | 3 +
.../ssl/auto_origin_tls_kex_edit_params.py | 14 +
.../ssl/auto_origin_tls_kex_edit_response.py | 17 ++
.../ssl/auto_origin_tls_kex_get_response.py | 17 ++
.../ssl/test_auto_origin_tls_kex.py | 187 ++++++++++++
10 files changed, 589 insertions(+), 3 deletions(-)
create mode 100644 src/cloudflare/resources/ssl/auto_origin_tls_kex.py
create mode 100644 src/cloudflare/types/ssl/auto_origin_tls_kex_edit_params.py
create mode 100644 src/cloudflare/types/ssl/auto_origin_tls_kex_edit_response.py
create mode 100644 src/cloudflare/types/ssl/auto_origin_tls_kex_get_response.py
create mode 100644 tests/api_resources/ssl/test_auto_origin_tls_kex.py
diff --git a/.stats.yml b/.stats.yml
index e058e97be9c..1fab46f2fee 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 2398
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-2b344db846f73d18cb70c546df5b9ba346937191f97a00052bf626946391c7e2.yml
-openapi_spec_hash: 30882bab9ab718768db2497c4638fe7d
+configured_endpoints: 2400
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-da4c0f4dd7b41149a6b1b19b71ce12857f30a40c18f20de4a593b9a0a5b52b83.yml
+openapi_spec_hash: 5726e811dc83decf1d6deb48d37ceac2
config_hash: 2f529580a17438fc62cd0b47db41b6f1
diff --git a/src/cloudflare/resources/ssl/__init__.py b/src/cloudflare/resources/ssl/__init__.py
index 59245e44dfb..993c9403c31 100644
--- a/src/cloudflare/resources/ssl/__init__.py
+++ b/src/cloudflare/resources/ssl/__init__.py
@@ -48,6 +48,14 @@
CertificatePacksResourceWithStreamingResponse,
AsyncCertificatePacksResourceWithStreamingResponse,
)
+from .auto_origin_tls_kex import (
+ AutoOriginTLSKexResource,
+ AsyncAutoOriginTLSKexResource,
+ AutoOriginTLSKexResourceWithRawResponse,
+ AsyncAutoOriginTLSKexResourceWithRawResponse,
+ AutoOriginTLSKexResourceWithStreamingResponse,
+ AsyncAutoOriginTLSKexResourceWithStreamingResponse,
+)
__all__ = [
"AnalyzeResource",
@@ -68,6 +76,12 @@
"AsyncRecommendationsResourceWithRawResponse",
"RecommendationsResourceWithStreamingResponse",
"AsyncRecommendationsResourceWithStreamingResponse",
+ "AutoOriginTLSKexResource",
+ "AsyncAutoOriginTLSKexResource",
+ "AutoOriginTLSKexResourceWithRawResponse",
+ "AsyncAutoOriginTLSKexResourceWithRawResponse",
+ "AutoOriginTLSKexResourceWithStreamingResponse",
+ "AsyncAutoOriginTLSKexResourceWithStreamingResponse",
"UniversalResource",
"AsyncUniversalResource",
"UniversalResourceWithRawResponse",
diff --git a/src/cloudflare/resources/ssl/api.md b/src/cloudflare/resources/ssl/api.md
index 3d0e264b2a4..bd6b4cb1352 100644
--- a/src/cloudflare/resources/ssl/api.md
+++ b/src/cloudflare/resources/ssl/api.md
@@ -56,6 +56,19 @@ Methods:
- client.ssl.recommendations.get(\*, zone_id) -> RecommendationGetResponse
+## AutoOriginTLSKex
+
+Types:
+
+```python
+from cloudflare.types.ssl import AutoOriginTLSKexEditResponse, AutoOriginTLSKexGetResponse
+```
+
+Methods:
+
+- client.ssl.auto_origin_tls_kex.edit(\*, zone_id, \*\*params) -> AutoOriginTLSKexEditResponse
+- client.ssl.auto_origin_tls_kex.get(\*, zone_id) -> AutoOriginTLSKexGetResponse
+
## Universal
### Settings
diff --git a/src/cloudflare/resources/ssl/auto_origin_tls_kex.py b/src/cloudflare/resources/ssl/auto_origin_tls_kex.py
new file mode 100644
index 00000000000..2fa9df6bf72
--- /dev/null
+++ b/src/cloudflare/resources/ssl/auto_origin_tls_kex.py
@@ -0,0 +1,289 @@
+# 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, 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 ...types.ssl import auto_origin_tls_kex_edit_params
+from ..._base_client import make_request_options
+from ...types.ssl.auto_origin_tls_kex_get_response import AutoOriginTLSKexGetResponse
+from ...types.ssl.auto_origin_tls_kex_edit_response import AutoOriginTLSKexEditResponse
+
+__all__ = ["AutoOriginTLSKexResource", "AsyncAutoOriginTLSKexResource"]
+
+
+class AutoOriginTLSKexResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AutoOriginTLSKexResourceWithRawResponse:
+ """
+ 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 AutoOriginTLSKexResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AutoOriginTLSKexResourceWithStreamingResponse:
+ """
+ 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 AutoOriginTLSKexResourceWithStreamingResponse(self)
+
+ def edit(
+ self,
+ *,
+ zone_id: str,
+ enabled: bool,
+ # 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,
+ ) -> AutoOriginTLSKexEditResponse:
+ """
+ Enable or disable Auto-Origin TLS KEX selection for the zone by sending
+ `{"enabled": true}` or `{"enabled": false}`. When enabled, Cloudflare runs a
+ periodic scan of the zone's origins to determine the preferred key-exchange
+ algorithm and writes that preference to the edge so it is sent first in the TLS
+ ClientHello to the origin.
+
+ Args:
+ enabled: Controls enablement of Auto-Origin TLS KEX selection for the zone.
+
+ 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 zone_id:
+ raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
+ return self._patch(
+ path_template("/zones/{zone_id}/settings/auto_origin_tls_kex", zone_id=zone_id),
+ body=maybe_transform({"enabled": enabled}, auto_origin_tls_kex_edit_params.AutoOriginTLSKexEditParams),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[AutoOriginTLSKexEditResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[AutoOriginTLSKexEditResponse], ResultWrapper[AutoOriginTLSKexEditResponse]),
+ )
+
+ def get(
+ self,
+ *,
+ zone_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,
+ ) -> AutoOriginTLSKexGetResponse:
+ """
+ When enabled, Cloudflare automatically selects the preferred TLS key-exchange
+ algorithm to use when establishing the TLS connection to the zone's origin,
+ picking from the algorithms permitted by the zone's
+ `origin_tls_compliance_modes` setting. When disabled, the default key-exchange
+ ordering is used.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not zone_id:
+ raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
+ return self._get(
+ path_template("/zones/{zone_id}/settings/auto_origin_tls_kex", zone_id=zone_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[AutoOriginTLSKexGetResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[AutoOriginTLSKexGetResponse], ResultWrapper[AutoOriginTLSKexGetResponse]),
+ )
+
+
+class AsyncAutoOriginTLSKexResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncAutoOriginTLSKexResourceWithRawResponse:
+ """
+ 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 AsyncAutoOriginTLSKexResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncAutoOriginTLSKexResourceWithStreamingResponse:
+ """
+ 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 AsyncAutoOriginTLSKexResourceWithStreamingResponse(self)
+
+ async def edit(
+ self,
+ *,
+ zone_id: str,
+ enabled: bool,
+ # 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,
+ ) -> AutoOriginTLSKexEditResponse:
+ """
+ Enable or disable Auto-Origin TLS KEX selection for the zone by sending
+ `{"enabled": true}` or `{"enabled": false}`. When enabled, Cloudflare runs a
+ periodic scan of the zone's origins to determine the preferred key-exchange
+ algorithm and writes that preference to the edge so it is sent first in the TLS
+ ClientHello to the origin.
+
+ Args:
+ enabled: Controls enablement of Auto-Origin TLS KEX selection for the zone.
+
+ 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 zone_id:
+ raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
+ return await self._patch(
+ path_template("/zones/{zone_id}/settings/auto_origin_tls_kex", zone_id=zone_id),
+ body=await async_maybe_transform(
+ {"enabled": enabled}, auto_origin_tls_kex_edit_params.AutoOriginTLSKexEditParams
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[AutoOriginTLSKexEditResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[AutoOriginTLSKexEditResponse], ResultWrapper[AutoOriginTLSKexEditResponse]),
+ )
+
+ async def get(
+ self,
+ *,
+ zone_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,
+ ) -> AutoOriginTLSKexGetResponse:
+ """
+ When enabled, Cloudflare automatically selects the preferred TLS key-exchange
+ algorithm to use when establishing the TLS connection to the zone's origin,
+ picking from the algorithms permitted by the zone's
+ `origin_tls_compliance_modes` setting. When disabled, the default key-exchange
+ ordering is used.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not zone_id:
+ raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
+ return await self._get(
+ path_template("/zones/{zone_id}/settings/auto_origin_tls_kex", zone_id=zone_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[AutoOriginTLSKexGetResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[AutoOriginTLSKexGetResponse], ResultWrapper[AutoOriginTLSKexGetResponse]),
+ )
+
+
+class AutoOriginTLSKexResourceWithRawResponse:
+ def __init__(self, auto_origin_tls_kex: AutoOriginTLSKexResource) -> None:
+ self._auto_origin_tls_kex = auto_origin_tls_kex
+
+ self.edit = to_raw_response_wrapper(
+ auto_origin_tls_kex.edit,
+ )
+ self.get = to_raw_response_wrapper(
+ auto_origin_tls_kex.get,
+ )
+
+
+class AsyncAutoOriginTLSKexResourceWithRawResponse:
+ def __init__(self, auto_origin_tls_kex: AsyncAutoOriginTLSKexResource) -> None:
+ self._auto_origin_tls_kex = auto_origin_tls_kex
+
+ self.edit = async_to_raw_response_wrapper(
+ auto_origin_tls_kex.edit,
+ )
+ self.get = async_to_raw_response_wrapper(
+ auto_origin_tls_kex.get,
+ )
+
+
+class AutoOriginTLSKexResourceWithStreamingResponse:
+ def __init__(self, auto_origin_tls_kex: AutoOriginTLSKexResource) -> None:
+ self._auto_origin_tls_kex = auto_origin_tls_kex
+
+ self.edit = to_streamed_response_wrapper(
+ auto_origin_tls_kex.edit,
+ )
+ self.get = to_streamed_response_wrapper(
+ auto_origin_tls_kex.get,
+ )
+
+
+class AsyncAutoOriginTLSKexResourceWithStreamingResponse:
+ def __init__(self, auto_origin_tls_kex: AsyncAutoOriginTLSKexResource) -> None:
+ self._auto_origin_tls_kex = auto_origin_tls_kex
+
+ self.edit = async_to_streamed_response_wrapper(
+ auto_origin_tls_kex.edit,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ auto_origin_tls_kex.get,
+ )
diff --git a/src/cloudflare/resources/ssl/ssl.py b/src/cloudflare/resources/ssl/ssl.py
index c46c403db8b..dffad263b4f 100644
--- a/src/cloudflare/resources/ssl/ssl.py
+++ b/src/cloudflare/resources/ssl/ssl.py
@@ -28,6 +28,14 @@
RecommendationsResourceWithStreamingResponse,
AsyncRecommendationsResourceWithStreamingResponse,
)
+from .auto_origin_tls_kex import (
+ AutoOriginTLSKexResource,
+ AsyncAutoOriginTLSKexResource,
+ AutoOriginTLSKexResourceWithRawResponse,
+ AsyncAutoOriginTLSKexResourceWithRawResponse,
+ AutoOriginTLSKexResourceWithStreamingResponse,
+ AsyncAutoOriginTLSKexResourceWithStreamingResponse,
+)
from .universal.universal import (
UniversalResource,
AsyncUniversalResource,
@@ -61,6 +69,10 @@ def certificate_packs(self) -> CertificatePacksResource:
def recommendations(self) -> RecommendationsResource:
return RecommendationsResource(self._client)
+ @cached_property
+ def auto_origin_tls_kex(self) -> AutoOriginTLSKexResource:
+ return AutoOriginTLSKexResource(self._client)
+
@cached_property
def universal(self) -> UniversalResource:
return UniversalResource(self._client)
@@ -102,6 +114,10 @@ def certificate_packs(self) -> AsyncCertificatePacksResource:
def recommendations(self) -> AsyncRecommendationsResource:
return AsyncRecommendationsResource(self._client)
+ @cached_property
+ def auto_origin_tls_kex(self) -> AsyncAutoOriginTLSKexResource:
+ return AsyncAutoOriginTLSKexResource(self._client)
+
@cached_property
def universal(self) -> AsyncUniversalResource:
return AsyncUniversalResource(self._client)
@@ -146,6 +162,10 @@ def certificate_packs(self) -> CertificatePacksResourceWithRawResponse:
def recommendations(self) -> RecommendationsResourceWithRawResponse:
return RecommendationsResourceWithRawResponse(self._ssl.recommendations)
+ @cached_property
+ def auto_origin_tls_kex(self) -> AutoOriginTLSKexResourceWithRawResponse:
+ return AutoOriginTLSKexResourceWithRawResponse(self._ssl.auto_origin_tls_kex)
+
@cached_property
def universal(self) -> UniversalResourceWithRawResponse:
return UniversalResourceWithRawResponse(self._ssl.universal)
@@ -171,6 +191,10 @@ def certificate_packs(self) -> AsyncCertificatePacksResourceWithRawResponse:
def recommendations(self) -> AsyncRecommendationsResourceWithRawResponse:
return AsyncRecommendationsResourceWithRawResponse(self._ssl.recommendations)
+ @cached_property
+ def auto_origin_tls_kex(self) -> AsyncAutoOriginTLSKexResourceWithRawResponse:
+ return AsyncAutoOriginTLSKexResourceWithRawResponse(self._ssl.auto_origin_tls_kex)
+
@cached_property
def universal(self) -> AsyncUniversalResourceWithRawResponse:
return AsyncUniversalResourceWithRawResponse(self._ssl.universal)
@@ -196,6 +220,10 @@ def certificate_packs(self) -> CertificatePacksResourceWithStreamingResponse:
def recommendations(self) -> RecommendationsResourceWithStreamingResponse:
return RecommendationsResourceWithStreamingResponse(self._ssl.recommendations)
+ @cached_property
+ def auto_origin_tls_kex(self) -> AutoOriginTLSKexResourceWithStreamingResponse:
+ return AutoOriginTLSKexResourceWithStreamingResponse(self._ssl.auto_origin_tls_kex)
+
@cached_property
def universal(self) -> UniversalResourceWithStreamingResponse:
return UniversalResourceWithStreamingResponse(self._ssl.universal)
@@ -221,6 +249,10 @@ def certificate_packs(self) -> AsyncCertificatePacksResourceWithStreamingRespons
def recommendations(self) -> AsyncRecommendationsResourceWithStreamingResponse:
return AsyncRecommendationsResourceWithStreamingResponse(self._ssl.recommendations)
+ @cached_property
+ def auto_origin_tls_kex(self) -> AsyncAutoOriginTLSKexResourceWithStreamingResponse:
+ return AsyncAutoOriginTLSKexResourceWithStreamingResponse(self._ssl.auto_origin_tls_kex)
+
@cached_property
def universal(self) -> AsyncUniversalResourceWithStreamingResponse:
return AsyncUniversalResourceWithStreamingResponse(self._ssl.universal)
diff --git a/src/cloudflare/types/ssl/__init__.py b/src/cloudflare/types/ssl/__init__.py
index bc5ae8a0736..aeffbe95988 100644
--- a/src/cloudflare/types/ssl/__init__.py
+++ b/src/cloudflare/types/ssl/__init__.py
@@ -19,5 +19,8 @@
from .certificate_pack_create_params import CertificatePackCreateParams as CertificatePackCreateParams
from .certificate_pack_edit_response import CertificatePackEditResponse as CertificatePackEditResponse
from .certificate_pack_list_response import CertificatePackListResponse as CertificatePackListResponse
+from .auto_origin_tls_kex_edit_params import AutoOriginTLSKexEditParams as AutoOriginTLSKexEditParams
+from .auto_origin_tls_kex_get_response import AutoOriginTLSKexGetResponse as AutoOriginTLSKexGetResponse
from .certificate_pack_create_response import CertificatePackCreateResponse as CertificatePackCreateResponse
from .certificate_pack_delete_response import CertificatePackDeleteResponse as CertificatePackDeleteResponse
+from .auto_origin_tls_kex_edit_response import AutoOriginTLSKexEditResponse as AutoOriginTLSKexEditResponse
diff --git a/src/cloudflare/types/ssl/auto_origin_tls_kex_edit_params.py b/src/cloudflare/types/ssl/auto_origin_tls_kex_edit_params.py
new file mode 100644
index 00000000000..3d49f44fb9c
--- /dev/null
+++ b/src/cloudflare/types/ssl/auto_origin_tls_kex_edit_params.py
@@ -0,0 +1,14 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["AutoOriginTLSKexEditParams"]
+
+
+class AutoOriginTLSKexEditParams(TypedDict, total=False):
+ zone_id: Required[str]
+
+ enabled: Required[bool]
+ """Controls enablement of Auto-Origin TLS KEX selection for the zone."""
diff --git a/src/cloudflare/types/ssl/auto_origin_tls_kex_edit_response.py b/src/cloudflare/types/ssl/auto_origin_tls_kex_edit_response.py
new file mode 100644
index 00000000000..c805b04e769
--- /dev/null
+++ b/src/cloudflare/types/ssl/auto_origin_tls_kex_edit_response.py
@@ -0,0 +1,17 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from datetime import datetime
+
+from ..._models import BaseModel
+
+__all__ = ["AutoOriginTLSKexEditResponse"]
+
+
+class AutoOriginTLSKexEditResponse(BaseModel):
+ id: str
+
+ enabled: bool
+ """Whether Auto-Origin TLS KEX selection is enabled for the zone."""
+
+ modified_on: datetime
+ """Last time this setting was modified."""
diff --git a/src/cloudflare/types/ssl/auto_origin_tls_kex_get_response.py b/src/cloudflare/types/ssl/auto_origin_tls_kex_get_response.py
new file mode 100644
index 00000000000..355903375d1
--- /dev/null
+++ b/src/cloudflare/types/ssl/auto_origin_tls_kex_get_response.py
@@ -0,0 +1,17 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from datetime import datetime
+
+from ..._models import BaseModel
+
+__all__ = ["AutoOriginTLSKexGetResponse"]
+
+
+class AutoOriginTLSKexGetResponse(BaseModel):
+ id: str
+
+ enabled: bool
+ """Whether Auto-Origin TLS KEX selection is enabled for the zone."""
+
+ modified_on: datetime
+ """Last time this setting was modified."""
diff --git a/tests/api_resources/ssl/test_auto_origin_tls_kex.py b/tests/api_resources/ssl/test_auto_origin_tls_kex.py
new file mode 100644
index 00000000000..183c77ce71f
--- /dev/null
+++ b/tests/api_resources/ssl/test_auto_origin_tls_kex.py
@@ -0,0 +1,187 @@
+# 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.ssl import (
+ AutoOriginTLSKexGetResponse,
+ AutoOriginTLSKexEditResponse,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestAutoOriginTLSKex:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_edit(self, client: Cloudflare) -> None:
+ auto_origin_tls_kex = client.ssl.auto_origin_tls_kex.edit(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ enabled=True,
+ )
+ assert_matches_type(AutoOriginTLSKexEditResponse, auto_origin_tls_kex, path=["response"])
+
+ @parametrize
+ def test_raw_response_edit(self, client: Cloudflare) -> None:
+ response = client.ssl.auto_origin_tls_kex.with_raw_response.edit(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ enabled=True,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ auto_origin_tls_kex = response.parse()
+ assert_matches_type(AutoOriginTLSKexEditResponse, auto_origin_tls_kex, path=["response"])
+
+ @parametrize
+ def test_streaming_response_edit(self, client: Cloudflare) -> None:
+ with client.ssl.auto_origin_tls_kex.with_streaming_response.edit(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ enabled=True,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ auto_origin_tls_kex = response.parse()
+ assert_matches_type(AutoOriginTLSKexEditResponse, auto_origin_tls_kex, 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 `zone_id` but received ''"):
+ client.ssl.auto_origin_tls_kex.with_raw_response.edit(
+ zone_id="",
+ enabled=True,
+ )
+
+ @parametrize
+ def test_method_get(self, client: Cloudflare) -> None:
+ auto_origin_tls_kex = client.ssl.auto_origin_tls_kex.get(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(AutoOriginTLSKexGetResponse, auto_origin_tls_kex, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Cloudflare) -> None:
+ response = client.ssl.auto_origin_tls_kex.with_raw_response.get(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ auto_origin_tls_kex = response.parse()
+ assert_matches_type(AutoOriginTLSKexGetResponse, auto_origin_tls_kex, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Cloudflare) -> None:
+ with client.ssl.auto_origin_tls_kex.with_streaming_response.get(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ auto_origin_tls_kex = response.parse()
+ assert_matches_type(AutoOriginTLSKexGetResponse, auto_origin_tls_kex, 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 `zone_id` but received ''"):
+ client.ssl.auto_origin_tls_kex.with_raw_response.get(
+ zone_id="",
+ )
+
+
+class TestAsyncAutoOriginTLSKex:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_edit(self, async_client: AsyncCloudflare) -> None:
+ auto_origin_tls_kex = await async_client.ssl.auto_origin_tls_kex.edit(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ enabled=True,
+ )
+ assert_matches_type(AutoOriginTLSKexEditResponse, auto_origin_tls_kex, path=["response"])
+
+ @parametrize
+ async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.ssl.auto_origin_tls_kex.with_raw_response.edit(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ enabled=True,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ auto_origin_tls_kex = await response.parse()
+ assert_matches_type(AutoOriginTLSKexEditResponse, auto_origin_tls_kex, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.ssl.auto_origin_tls_kex.with_streaming_response.edit(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ enabled=True,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ auto_origin_tls_kex = await response.parse()
+ assert_matches_type(AutoOriginTLSKexEditResponse, auto_origin_tls_kex, 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 `zone_id` but received ''"):
+ await async_client.ssl.auto_origin_tls_kex.with_raw_response.edit(
+ zone_id="",
+ enabled=True,
+ )
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncCloudflare) -> None:
+ auto_origin_tls_kex = await async_client.ssl.auto_origin_tls_kex.get(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(AutoOriginTLSKexGetResponse, auto_origin_tls_kex, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.ssl.auto_origin_tls_kex.with_raw_response.get(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ auto_origin_tls_kex = await response.parse()
+ assert_matches_type(AutoOriginTLSKexGetResponse, auto_origin_tls_kex, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.ssl.auto_origin_tls_kex.with_streaming_response.get(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ auto_origin_tls_kex = await response.parse()
+ assert_matches_type(AutoOriginTLSKexGetResponse, auto_origin_tls_kex, 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 `zone_id` but received ''"):
+ await async_client.ssl.auto_origin_tls_kex.with_raw_response.get(
+ zone_id="",
+ )
From 3817b571d02b2d23f087bbdb574853632d0bc1db Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 15 Jun 2026 20:33:42 +0000
Subject: [PATCH 15/23] chore(api): update composite API spec
---
.stats.yml | 4 ++--
.../types/cloudforce_one/threat_event_create_response.py | 4 ++++
.../types/cloudforce_one/threat_event_edit_response.py | 4 ++++
.../types/cloudforce_one/threat_event_get_response.py | 4 ++++
.../types/cloudforce_one/threat_event_list_response.py | 4 ++++
.../types/cloudforce_one/threat_events/tag_create_response.py | 2 ++
6 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 1fab46f2fee..24fef8090eb 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 2400
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-da4c0f4dd7b41149a6b1b19b71ce12857f30a40c18f20de4a593b9a0a5b52b83.yml
-openapi_spec_hash: 5726e811dc83decf1d6deb48d37ceac2
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-dc45d49df27d76c4dac5f9050d933875dfd3c15e0c410ca91343d425d2ad7aeb.yml
+openapi_spec_hash: 5fd14ff0d2fe35b4cbc5b423d12e4f0b
config_hash: 2f529580a17438fc62cd0b47db41b6f1
diff --git a/src/cloudflare/types/cloudforce_one/threat_event_create_response.py b/src/cloudflare/types/cloudforce_one/threat_event_create_response.py
index a104809eff2..6a19d9f008d 100644
--- a/src/cloudflare/types/cloudforce_one/threat_event_create_response.py
+++ b/src/cloudflare/types/cloudforce_one/threat_event_create_response.py
@@ -14,6 +14,8 @@ class ThreatEventCreateResponse(BaseModel):
attacker_country: str = FieldInfo(alias="attackerCountry")
+ attacker_country_alpha3: str = FieldInfo(alias="attackerCountryAlpha3")
+
category: str
dataset_id: str = FieldInfo(alias="datasetId")
@@ -54,6 +56,8 @@ class ThreatEventCreateResponse(BaseModel):
target_country: str = FieldInfo(alias="targetCountry")
+ target_country_alpha3: str = FieldInfo(alias="targetCountryAlpha3")
+
target_industry: str = FieldInfo(alias="targetIndustry")
tlp: str
diff --git a/src/cloudflare/types/cloudforce_one/threat_event_edit_response.py b/src/cloudflare/types/cloudforce_one/threat_event_edit_response.py
index 2a2e152be4f..fc74fdf46a0 100644
--- a/src/cloudflare/types/cloudforce_one/threat_event_edit_response.py
+++ b/src/cloudflare/types/cloudforce_one/threat_event_edit_response.py
@@ -14,6 +14,8 @@ class ThreatEventEditResponse(BaseModel):
attacker_country: str = FieldInfo(alias="attackerCountry")
+ attacker_country_alpha3: str = FieldInfo(alias="attackerCountryAlpha3")
+
category: str
dataset_id: str = FieldInfo(alias="datasetId")
@@ -54,6 +56,8 @@ class ThreatEventEditResponse(BaseModel):
target_country: str = FieldInfo(alias="targetCountry")
+ target_country_alpha3: str = FieldInfo(alias="targetCountryAlpha3")
+
target_industry: str = FieldInfo(alias="targetIndustry")
tlp: str
diff --git a/src/cloudflare/types/cloudforce_one/threat_event_get_response.py b/src/cloudflare/types/cloudforce_one/threat_event_get_response.py
index 59d7951c119..2ab1b059a1a 100644
--- a/src/cloudflare/types/cloudforce_one/threat_event_get_response.py
+++ b/src/cloudflare/types/cloudforce_one/threat_event_get_response.py
@@ -14,6 +14,8 @@ class ThreatEventGetResponse(BaseModel):
attacker_country: str = FieldInfo(alias="attackerCountry")
+ attacker_country_alpha3: str = FieldInfo(alias="attackerCountryAlpha3")
+
category: str
dataset_id: str = FieldInfo(alias="datasetId")
@@ -54,6 +56,8 @@ class ThreatEventGetResponse(BaseModel):
target_country: str = FieldInfo(alias="targetCountry")
+ target_country_alpha3: str = FieldInfo(alias="targetCountryAlpha3")
+
target_industry: str = FieldInfo(alias="targetIndustry")
tlp: str
diff --git a/src/cloudflare/types/cloudforce_one/threat_event_list_response.py b/src/cloudflare/types/cloudforce_one/threat_event_list_response.py
index d18ff8dd865..df324dcc32f 100644
--- a/src/cloudflare/types/cloudforce_one/threat_event_list_response.py
+++ b/src/cloudflare/types/cloudforce_one/threat_event_list_response.py
@@ -15,6 +15,8 @@ class ThreatEventListResponseItem(BaseModel):
attacker_country: str = FieldInfo(alias="attackerCountry")
+ attacker_country_alpha3: str = FieldInfo(alias="attackerCountryAlpha3")
+
category: str
dataset_id: str = FieldInfo(alias="datasetId")
@@ -55,6 +57,8 @@ class ThreatEventListResponseItem(BaseModel):
target_country: str = FieldInfo(alias="targetCountry")
+ target_country_alpha3: str = FieldInfo(alias="targetCountryAlpha3")
+
target_industry: str = FieldInfo(alias="targetIndustry")
tlp: str
diff --git a/src/cloudflare/types/cloudforce_one/threat_events/tag_create_response.py b/src/cloudflare/types/cloudforce_one/threat_events/tag_create_response.py
index fc2f5c059e1..e1c09229a54 100644
--- a/src/cloudflare/types/cloudforce_one/threat_events/tag_create_response.py
+++ b/src/cloudflare/types/cloudforce_one/threat_events/tag_create_response.py
@@ -42,6 +42,8 @@ class TagCreateResponse(BaseModel):
origin_country_iso: Optional[str] = FieldInfo(alias="originCountryISO", default=None)
+ origin_country_iso_alpha3: Optional[str] = FieldInfo(alias="originCountryISOAlpha3", default=None)
+
priority: Optional[float] = None
sophistication_level: Optional[str] = FieldInfo(alias="sophisticationLevel", default=None)
From 05e802d1940e1b0bfe59a25c388b83f53edd238e Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 15 Jun 2026 21:46:47 +0000
Subject: [PATCH 16/23] chore(api): update composite API spec
---
.stats.yml | 4 +-
.../resources/intel/domains/bulks.py | 64 +++++++++++++++++--
.../types/intel/domains/bulk_get_params.py | 17 +++++
.../api_resources/intel/domains/test_bulks.py | 4 ++
4 files changed, 83 insertions(+), 6 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 24fef8090eb..419881036de 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 2400
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-dc45d49df27d76c4dac5f9050d933875dfd3c15e0c410ca91343d425d2ad7aeb.yml
-openapi_spec_hash: 5fd14ff0d2fe35b4cbc5b423d12e4f0b
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-7deeb9a4fdf922c923fc5b0148e7ca74ee56b8e9845a654d1f7f98de0b942c12.yml
+openapi_spec_hash: fdb8c462be6b2a6354e8d4f9e2340110
config_hash: 2f529580a17438fc62cd0b47db41b6f1
diff --git a/src/cloudflare/resources/intel/domains/bulks.py b/src/cloudflare/resources/intel/domains/bulks.py
index 3eb23666ef6..2a8ceb33633 100644
--- a/src/cloudflare/resources/intel/domains/bulks.py
+++ b/src/cloudflare/resources/intel/domains/bulks.py
@@ -49,6 +49,8 @@ def get(
*,
account_id: str,
domain: SequenceNotStr[str] | Omit = omit,
+ include_ranking: bool | Omit = omit,
+ skip_ranking: bool | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -57,13 +59,32 @@ def get(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> Optional[BulkGetResponse]:
"""
- Same as summary.
+ Returns security details and statistics about multiple domains in a single
+ request.
+
+ **Behavior change — domain ranking is becoming opt-in.** This endpoint
+ previously included domain ranking data in every response and accepted a
+ `skip_ranking=true` query parameter to opt out. That parameter is being
+ deprecated and ranking will no longer be returned by default. Callers that want
+ ranking data must pass `include_ranking=true`. The `skip_ranking` parameter will
+ be silently ignored once the change ships.
Args:
account_id: Identifier.
domain: Accepts multiple values like `?domain=cloudflare.com&domain=example.com`.
+ include_ranking: Whether to include domain ranking data in the response. Defaults to `false` —
+ ranking lookups are expensive at bulk scale and most callers do not need them.
+ Set to `true` to opt in. This parameter replaces the deprecated `skip_ranking`
+ (see below).
+
+ skip_ranking: **Deprecated.** Previously controlled whether the ranking lookup was skipped
+ (defaulted to `false`, meaning ranking ran). The endpoint's default behavior is
+ being flipped — ranking is now opt-in via `include_ranking=true` — and this
+ parameter will be silently ignored. Remove it from your callers and use
+ `include_ranking` instead.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -81,7 +102,14 @@ def get(
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
- query=maybe_transform({"domain": domain}, bulk_get_params.BulkGetParams),
+ query=maybe_transform(
+ {
+ "domain": domain,
+ "include_ranking": include_ranking,
+ "skip_ranking": skip_ranking,
+ },
+ bulk_get_params.BulkGetParams,
+ ),
post_parser=ResultWrapper[Optional[BulkGetResponse]]._unwrapper,
),
cast_to=cast(Type[Optional[BulkGetResponse]], ResultWrapper[BulkGetResponse]),
@@ -113,6 +141,8 @@ async def get(
*,
account_id: str,
domain: SequenceNotStr[str] | Omit = omit,
+ include_ranking: bool | Omit = omit,
+ skip_ranking: 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,
@@ -121,13 +151,32 @@ async def get(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> Optional[BulkGetResponse]:
"""
- Same as summary.
+ Returns security details and statistics about multiple domains in a single
+ request.
+
+ **Behavior change — domain ranking is becoming opt-in.** This endpoint
+ previously included domain ranking data in every response and accepted a
+ `skip_ranking=true` query parameter to opt out. That parameter is being
+ deprecated and ranking will no longer be returned by default. Callers that want
+ ranking data must pass `include_ranking=true`. The `skip_ranking` parameter will
+ be silently ignored once the change ships.
Args:
account_id: Identifier.
domain: Accepts multiple values like `?domain=cloudflare.com&domain=example.com`.
+ include_ranking: Whether to include domain ranking data in the response. Defaults to `false` —
+ ranking lookups are expensive at bulk scale and most callers do not need them.
+ Set to `true` to opt in. This parameter replaces the deprecated `skip_ranking`
+ (see below).
+
+ skip_ranking: **Deprecated.** Previously controlled whether the ranking lookup was skipped
+ (defaulted to `false`, meaning ranking ran). The endpoint's default behavior is
+ being flipped — ranking is now opt-in via `include_ranking=true` — and this
+ parameter will be silently ignored. Remove it from your callers and use
+ `include_ranking` instead.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -145,7 +194,14 @@ async def get(
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
- query=await async_maybe_transform({"domain": domain}, bulk_get_params.BulkGetParams),
+ query=await async_maybe_transform(
+ {
+ "domain": domain,
+ "include_ranking": include_ranking,
+ "skip_ranking": skip_ranking,
+ },
+ bulk_get_params.BulkGetParams,
+ ),
post_parser=ResultWrapper[Optional[BulkGetResponse]]._unwrapper,
),
cast_to=cast(Type[Optional[BulkGetResponse]], ResultWrapper[BulkGetResponse]),
diff --git a/src/cloudflare/types/intel/domains/bulk_get_params.py b/src/cloudflare/types/intel/domains/bulk_get_params.py
index 5fd9ed9f983..cf1d42c47bc 100644
--- a/src/cloudflare/types/intel/domains/bulk_get_params.py
+++ b/src/cloudflare/types/intel/domains/bulk_get_params.py
@@ -15,3 +15,20 @@ class BulkGetParams(TypedDict, total=False):
domain: SequenceNotStr[str]
"""Accepts multiple values like `?domain=cloudflare.com&domain=example.com`."""
+
+ include_ranking: bool
+ """Whether to include domain ranking data in the response.
+
+ Defaults to `false` — ranking lookups are expensive at bulk scale and most
+ callers do not need them. Set to `true` to opt in. This parameter replaces the
+ deprecated `skip_ranking` (see below).
+ """
+
+ skip_ranking: bool
+ """
+ **Deprecated.** Previously controlled whether the ranking lookup was skipped
+ (defaulted to `false`, meaning ranking ran). The endpoint's default behavior is
+ being flipped — ranking is now opt-in via `include_ranking=true` — and this
+ parameter will be silently ignored. Remove it from your callers and use
+ `include_ranking` instead.
+ """
diff --git a/tests/api_resources/intel/domains/test_bulks.py b/tests/api_resources/intel/domains/test_bulks.py
index 8a1c0480f60..b858ee7176d 100644
--- a/tests/api_resources/intel/domains/test_bulks.py
+++ b/tests/api_resources/intel/domains/test_bulks.py
@@ -29,6 +29,8 @@ def test_method_get_with_all_params(self, client: Cloudflare) -> None:
bulk = client.intel.domains.bulks.get(
account_id="023e105f4ecef8ad9ca31a8372d0c353",
domain=["string"],
+ include_ranking=True,
+ skip_ranking=True,
)
assert_matches_type(Optional[BulkGetResponse], bulk, path=["response"])
@@ -81,6 +83,8 @@ async def test_method_get_with_all_params(self, async_client: AsyncCloudflare) -
bulk = await async_client.intel.domains.bulks.get(
account_id="023e105f4ecef8ad9ca31a8372d0c353",
domain=["string"],
+ include_ranking=True,
+ skip_ranking=True,
)
assert_matches_type(Optional[BulkGetResponse], bulk, path=["response"])
From 656f97390d51da3e224e67f2305d6d46f7ae239a Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 16 Jun 2026 14:14:41 +0000
Subject: [PATCH 17/23] chore(api): update composite API spec
---
.stats.yml | 6 +-
src/cloudflare/_client.py | 49 ++
.../origin_tls_compliance_modes/__init__.py | 18 +
.../origin_tls_compliance_modes/api.md | 19 +
.../origin_tls_compliance_modes.py | 576 ++++++++++++++++++
.../origin_tls_compliance_modes/__init__.py | 19 +
...gin_tls_compliance_mode_delete_response.py | 20 +
.../origin_tls_compliance_mode_edit_params.py | 25 +
...rigin_tls_compliance_mode_edit_response.py | 31 +
...origin_tls_compliance_mode_get_response.py | 31 +
...rigin_tls_compliance_mode_update_params.py | 25 +
...gin_tls_compliance_mode_update_response.py | 31 +
.../test_origin_tls_compliance_modes.py | 389 ++++++++++++
13 files changed, 1236 insertions(+), 3 deletions(-)
create mode 100644 src/cloudflare/resources/origin_tls_compliance_modes/api.md
create mode 100644 src/cloudflare/resources/origin_tls_compliance_modes/origin_tls_compliance_modes.py
create mode 100644 src/cloudflare/types/origin_tls_compliance_modes/origin_tls_compliance_mode_delete_response.py
create mode 100644 src/cloudflare/types/origin_tls_compliance_modes/origin_tls_compliance_mode_edit_params.py
create mode 100644 src/cloudflare/types/origin_tls_compliance_modes/origin_tls_compliance_mode_edit_response.py
create mode 100644 src/cloudflare/types/origin_tls_compliance_modes/origin_tls_compliance_mode_get_response.py
create mode 100644 src/cloudflare/types/origin_tls_compliance_modes/origin_tls_compliance_mode_update_params.py
create mode 100644 src/cloudflare/types/origin_tls_compliance_modes/origin_tls_compliance_mode_update_response.py
create mode 100644 tests/api_resources/test_origin_tls_compliance_modes.py
diff --git a/.stats.yml b/.stats.yml
index 419881036de..8cf402669f4 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 2400
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-7deeb9a4fdf922c923fc5b0148e7ca74ee56b8e9845a654d1f7f98de0b942c12.yml
-openapi_spec_hash: fdb8c462be6b2a6354e8d4f9e2340110
+configured_endpoints: 2404
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-5b604e453c8856075fa29214c76cffcdceeec0577992cd0126a1dd4941cfb43e.yml
+openapi_spec_hash: 9be331253c989946b4df42615e242471
config_hash: 2f529580a17438fc62cd0b47db41b6f1
diff --git a/src/cloudflare/_client.py b/src/cloudflare/_client.py
index 5b1e77d948c..af5c148ccc9 100644
--- a/src/cloudflare/_client.py
+++ b/src/cloudflare/_client.py
@@ -151,6 +151,7 @@
leaked_credential_checks,
magic_network_monitoring,
tenant_custom_nameservers,
+ origin_tls_compliance_modes,
origin_post_quantum_encryption,
)
from .resources.ai.ai import AIResource, AsyncAIResource
@@ -311,6 +312,10 @@
TenantCustomNameserversResource,
AsyncTenantCustomNameserversResource,
)
+ from .resources.origin_tls_compliance_modes.origin_tls_compliance_modes import (
+ OriginTLSComplianceModesResource,
+ AsyncOriginTLSComplianceModesResource,
+ )
from .resources.origin_post_quantum_encryption.origin_post_quantum_encryption import (
OriginPostQuantumEncryptionResource,
AsyncOriginPostQuantumEncryptionResource,
@@ -906,6 +911,12 @@ def origin_post_quantum_encryption(self) -> OriginPostQuantumEncryptionResource:
return OriginPostQuantumEncryptionResource(self)
+ @cached_property
+ def origin_tls_compliance_modes(self) -> OriginTLSComplianceModesResource:
+ from .resources.origin_tls_compliance_modes import OriginTLSComplianceModesResource
+
+ return OriginTLSComplianceModesResource(self)
+
@cached_property
def google_tag_gateway(self) -> GoogleTagGatewayResource:
from .resources.google_tag_gateway import GoogleTagGatewayResource
@@ -1852,6 +1863,12 @@ def origin_post_quantum_encryption(self) -> AsyncOriginPostQuantumEncryptionReso
return AsyncOriginPostQuantumEncryptionResource(self)
+ @cached_property
+ def origin_tls_compliance_modes(self) -> AsyncOriginTLSComplianceModesResource:
+ from .resources.origin_tls_compliance_modes import AsyncOriginTLSComplianceModesResource
+
+ return AsyncOriginTLSComplianceModesResource(self)
+
@cached_property
def google_tag_gateway(self) -> AsyncGoogleTagGatewayResource:
from .resources.google_tag_gateway import AsyncGoogleTagGatewayResource
@@ -2720,6 +2737,14 @@ def origin_post_quantum_encryption(
return OriginPostQuantumEncryptionResourceWithRawResponse(self._client.origin_post_quantum_encryption)
+ @cached_property
+ def origin_tls_compliance_modes(
+ self,
+ ) -> origin_tls_compliance_modes.OriginTLSComplianceModesResourceWithRawResponse:
+ from .resources.origin_tls_compliance_modes import OriginTLSComplianceModesResourceWithRawResponse
+
+ return OriginTLSComplianceModesResourceWithRawResponse(self._client.origin_tls_compliance_modes)
+
@cached_property
def google_tag_gateway(self) -> google_tag_gateway.GoogleTagGatewayResourceWithRawResponse:
from .resources.google_tag_gateway import GoogleTagGatewayResourceWithRawResponse
@@ -3415,6 +3440,14 @@ def origin_post_quantum_encryption(
return AsyncOriginPostQuantumEncryptionResourceWithRawResponse(self._client.origin_post_quantum_encryption)
+ @cached_property
+ def origin_tls_compliance_modes(
+ self,
+ ) -> origin_tls_compliance_modes.AsyncOriginTLSComplianceModesResourceWithRawResponse:
+ from .resources.origin_tls_compliance_modes import AsyncOriginTLSComplianceModesResourceWithRawResponse
+
+ return AsyncOriginTLSComplianceModesResourceWithRawResponse(self._client.origin_tls_compliance_modes)
+
@cached_property
def google_tag_gateway(self) -> google_tag_gateway.AsyncGoogleTagGatewayResourceWithRawResponse:
from .resources.google_tag_gateway import AsyncGoogleTagGatewayResourceWithRawResponse
@@ -4110,6 +4143,14 @@ def origin_post_quantum_encryption(
return OriginPostQuantumEncryptionResourceWithStreamingResponse(self._client.origin_post_quantum_encryption)
+ @cached_property
+ def origin_tls_compliance_modes(
+ self,
+ ) -> origin_tls_compliance_modes.OriginTLSComplianceModesResourceWithStreamingResponse:
+ from .resources.origin_tls_compliance_modes import OriginTLSComplianceModesResourceWithStreamingResponse
+
+ return OriginTLSComplianceModesResourceWithStreamingResponse(self._client.origin_tls_compliance_modes)
+
@cached_property
def google_tag_gateway(self) -> google_tag_gateway.GoogleTagGatewayResourceWithStreamingResponse:
from .resources.google_tag_gateway import GoogleTagGatewayResourceWithStreamingResponse
@@ -4813,6 +4854,14 @@ def origin_post_quantum_encryption(
self._client.origin_post_quantum_encryption
)
+ @cached_property
+ def origin_tls_compliance_modes(
+ self,
+ ) -> origin_tls_compliance_modes.AsyncOriginTLSComplianceModesResourceWithStreamingResponse:
+ from .resources.origin_tls_compliance_modes import AsyncOriginTLSComplianceModesResourceWithStreamingResponse
+
+ return AsyncOriginTLSComplianceModesResourceWithStreamingResponse(self._client.origin_tls_compliance_modes)
+
@cached_property
def google_tag_gateway(self) -> google_tag_gateway.AsyncGoogleTagGatewayResourceWithStreamingResponse:
from .resources.google_tag_gateway import AsyncGoogleTagGatewayResourceWithStreamingResponse
diff --git a/src/cloudflare/resources/origin_tls_compliance_modes/__init__.py b/src/cloudflare/resources/origin_tls_compliance_modes/__init__.py
index fd8019a9a1a..d539993cb49 100644
--- a/src/cloudflare/resources/origin_tls_compliance_modes/__init__.py
+++ b/src/cloudflare/resources/origin_tls_compliance_modes/__init__.py
@@ -1 +1,19 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .origin_tls_compliance_modes import (
+ OriginTLSComplianceModesResource,
+ AsyncOriginTLSComplianceModesResource,
+ OriginTLSComplianceModesResourceWithRawResponse,
+ AsyncOriginTLSComplianceModesResourceWithRawResponse,
+ OriginTLSComplianceModesResourceWithStreamingResponse,
+ AsyncOriginTLSComplianceModesResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "OriginTLSComplianceModesResource",
+ "AsyncOriginTLSComplianceModesResource",
+ "OriginTLSComplianceModesResourceWithRawResponse",
+ "AsyncOriginTLSComplianceModesResourceWithRawResponse",
+ "OriginTLSComplianceModesResourceWithStreamingResponse",
+ "AsyncOriginTLSComplianceModesResourceWithStreamingResponse",
+]
diff --git a/src/cloudflare/resources/origin_tls_compliance_modes/api.md b/src/cloudflare/resources/origin_tls_compliance_modes/api.md
new file mode 100644
index 00000000000..7aa8cec08cf
--- /dev/null
+++ b/src/cloudflare/resources/origin_tls_compliance_modes/api.md
@@ -0,0 +1,19 @@
+# OriginTLSComplianceModes
+
+Types:
+
+```python
+from cloudflare.types.origin_tls_compliance_modes import (
+ OriginTLSComplianceModeUpdateResponse,
+ OriginTLSComplianceModeDeleteResponse,
+ OriginTLSComplianceModeEditResponse,
+ OriginTLSComplianceModeGetResponse,
+)
+```
+
+Methods:
+
+- client.origin_tls_compliance_modes.update(\*, zone_id, \*\*params) -> Optional[OriginTLSComplianceModeUpdateResponse]
+- client.origin_tls_compliance_modes.delete(\*, zone_id) -> Optional[OriginTLSComplianceModeDeleteResponse]
+- client.origin_tls_compliance_modes.edit(\*, zone_id, \*\*params) -> Optional[OriginTLSComplianceModeEditResponse]
+- client.origin_tls_compliance_modes.get(\*, zone_id) -> Optional[OriginTLSComplianceModeGetResponse]
diff --git a/src/cloudflare/resources/origin_tls_compliance_modes/origin_tls_compliance_modes.py b/src/cloudflare/resources/origin_tls_compliance_modes/origin_tls_compliance_modes.py
new file mode 100644
index 00000000000..77c6e28d99e
--- /dev/null
+++ b/src/cloudflare/resources/origin_tls_compliance_modes/origin_tls_compliance_modes.py
@@ -0,0 +1,576 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Type, Optional, cast
+
+import httpx
+
+from ..._types import Body, Query, Headers, NotGiven, SequenceNotStr, 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.origin_tls_compliance_modes import (
+ origin_tls_compliance_mode_edit_params,
+ origin_tls_compliance_mode_update_params,
+)
+from ...types.origin_tls_compliance_modes.origin_tls_compliance_mode_get_response import (
+ OriginTLSComplianceModeGetResponse,
+)
+from ...types.origin_tls_compliance_modes.origin_tls_compliance_mode_edit_response import (
+ OriginTLSComplianceModeEditResponse,
+)
+from ...types.origin_tls_compliance_modes.origin_tls_compliance_mode_delete_response import (
+ OriginTLSComplianceModeDeleteResponse,
+)
+from ...types.origin_tls_compliance_modes.origin_tls_compliance_mode_update_response import (
+ OriginTLSComplianceModeUpdateResponse,
+)
+
+__all__ = ["OriginTLSComplianceModesResource", "AsyncOriginTLSComplianceModesResource"]
+
+
+class OriginTLSComplianceModesResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> OriginTLSComplianceModesResourceWithRawResponse:
+ """
+ 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 OriginTLSComplianceModesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> OriginTLSComplianceModesResourceWithStreamingResponse:
+ """
+ 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 OriginTLSComplianceModesResourceWithStreamingResponse(self)
+
+ def update(
+ self,
+ *,
+ zone_id: str,
+ value: SequenceNotStr[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[OriginTLSComplianceModeUpdateResponse]:
+ """
+ Replace the entire set of TLS compliance modes for the zone with the list
+ provided in the request body. PUT performs a full replace, not a merge — any
+ modes not present in the request body are removed. The request body must be of
+ the form `{"value": ["fips", "pqh"]}`. Currently supported modes are `fips` and
+ `pqh`; an empty list clears the constraint. Future modes (e.g. `cnsa2`) may be
+ added; clients should treat unknown values as opaque strings. Invalid mode
+ values are rejected with a 4xx response.
+
+ Args:
+ zone_id: Identifier.
+
+ value: List of TLS compliance modes that constrain the key-exchange algorithms
+ Cloudflare may use when establishing the TLS connection to the zone's origin.
+ Currently supported values are `fips` (FIPS-approved curves) and `pqh`
+ (post-quantum hybrid). Future modes (e.g. `cnsa2`) may be added; clients should
+ treat unknown values as opaque strings. Multiple modes are combined as the
+ intersection of their permitted algorithm lists; selections whose intersection
+ is empty are rejected. An empty list clears the constraint.
+
+ 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 zone_id:
+ raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
+ return self._put(
+ path_template("/zones/{zone_id}/settings/origin_tls_compliance_modes", zone_id=zone_id),
+ body=maybe_transform(
+ {"value": value}, origin_tls_compliance_mode_update_params.OriginTLSComplianceModeUpdateParams
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[OriginTLSComplianceModeUpdateResponse]]._unwrapper,
+ ),
+ cast_to=cast(
+ Type[Optional[OriginTLSComplianceModeUpdateResponse]],
+ ResultWrapper[OriginTLSComplianceModeUpdateResponse],
+ ),
+ )
+
+ def delete(
+ self,
+ *,
+ zone_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[OriginTLSComplianceModeDeleteResponse]:
+ """
+ Delete the Origin TLS Compliance Modes setting for the zone, removing any
+ configured compliance constraint. After deletion, Cloudflare's default behavior
+ applies (no compliance filtering of the key-exchange algorithm list sent to the
+ origin).
+
+ Args:
+ zone_id: 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 zone_id:
+ raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
+ return self._delete(
+ path_template("/zones/{zone_id}/settings/origin_tls_compliance_modes", zone_id=zone_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[OriginTLSComplianceModeDeleteResponse]]._unwrapper,
+ ),
+ cast_to=cast(
+ Type[Optional[OriginTLSComplianceModeDeleteResponse]],
+ ResultWrapper[OriginTLSComplianceModeDeleteResponse],
+ ),
+ )
+
+ def edit(
+ self,
+ *,
+ zone_id: str,
+ value: SequenceNotStr[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[OriginTLSComplianceModeEditResponse]:
+ """Update the set of TLS compliance modes for the zone.
+
+ PATCH performs a full
+ replace of the modes list, not a merge — the request body is treated as the
+ complete new list, and any modes not present in it are removed. (To remove a
+ single mode from an existing configuration, send the updated list without it.)
+ The request body must be of the form `{"value": ["fips", "pqh"]}`. Currently
+ supported modes are `fips` and `pqh`; an empty list clears the constraint.
+ Future modes (e.g. `cnsa2`) may be added; clients should treat unknown values as
+ opaque strings. Invalid mode values are rejected with a 4xx response.
+
+ Args:
+ zone_id: Identifier.
+
+ value: List of TLS compliance modes that constrain the key-exchange algorithms
+ Cloudflare may use when establishing the TLS connection to the zone's origin.
+ Currently supported values are `fips` (FIPS-approved curves) and `pqh`
+ (post-quantum hybrid). Future modes (e.g. `cnsa2`) may be added; clients should
+ treat unknown values as opaque strings. Multiple modes are combined as the
+ intersection of their permitted algorithm lists; selections whose intersection
+ is empty are rejected. An empty list clears the constraint.
+
+ 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 zone_id:
+ raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
+ return self._patch(
+ path_template("/zones/{zone_id}/settings/origin_tls_compliance_modes", zone_id=zone_id),
+ body=maybe_transform(
+ {"value": value}, origin_tls_compliance_mode_edit_params.OriginTLSComplianceModeEditParams
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[OriginTLSComplianceModeEditResponse]]._unwrapper,
+ ),
+ cast_to=cast(
+ Type[Optional[OriginTLSComplianceModeEditResponse]], ResultWrapper[OriginTLSComplianceModeEditResponse]
+ ),
+ )
+
+ def get(
+ self,
+ *,
+ zone_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[OriginTLSComplianceModeGetResponse]:
+ """
+ Origin TLS Compliance Modes constrains the set of TLS key-exchange algorithms
+ Cloudflare may use when establishing the TLS connection to the zone's origin.
+ The value is a list of named compliance modes (currently `fips` and `pqh`).
+ Multiple modes are combined as the intersection of their permitted algorithm
+ lists. An empty list (or no rule configured) means no compliance constraint is
+ applied.
+
+ Args:
+ zone_id: 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 zone_id:
+ raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
+ return self._get(
+ path_template("/zones/{zone_id}/settings/origin_tls_compliance_modes", zone_id=zone_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[OriginTLSComplianceModeGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(
+ Type[Optional[OriginTLSComplianceModeGetResponse]], ResultWrapper[OriginTLSComplianceModeGetResponse]
+ ),
+ )
+
+
+class AsyncOriginTLSComplianceModesResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncOriginTLSComplianceModesResourceWithRawResponse:
+ """
+ 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 AsyncOriginTLSComplianceModesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncOriginTLSComplianceModesResourceWithStreamingResponse:
+ """
+ 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 AsyncOriginTLSComplianceModesResourceWithStreamingResponse(self)
+
+ async def update(
+ self,
+ *,
+ zone_id: str,
+ value: SequenceNotStr[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[OriginTLSComplianceModeUpdateResponse]:
+ """
+ Replace the entire set of TLS compliance modes for the zone with the list
+ provided in the request body. PUT performs a full replace, not a merge — any
+ modes not present in the request body are removed. The request body must be of
+ the form `{"value": ["fips", "pqh"]}`. Currently supported modes are `fips` and
+ `pqh`; an empty list clears the constraint. Future modes (e.g. `cnsa2`) may be
+ added; clients should treat unknown values as opaque strings. Invalid mode
+ values are rejected with a 4xx response.
+
+ Args:
+ zone_id: Identifier.
+
+ value: List of TLS compliance modes that constrain the key-exchange algorithms
+ Cloudflare may use when establishing the TLS connection to the zone's origin.
+ Currently supported values are `fips` (FIPS-approved curves) and `pqh`
+ (post-quantum hybrid). Future modes (e.g. `cnsa2`) may be added; clients should
+ treat unknown values as opaque strings. Multiple modes are combined as the
+ intersection of their permitted algorithm lists; selections whose intersection
+ is empty are rejected. An empty list clears the constraint.
+
+ 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 zone_id:
+ raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
+ return await self._put(
+ path_template("/zones/{zone_id}/settings/origin_tls_compliance_modes", zone_id=zone_id),
+ body=await async_maybe_transform(
+ {"value": value}, origin_tls_compliance_mode_update_params.OriginTLSComplianceModeUpdateParams
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[OriginTLSComplianceModeUpdateResponse]]._unwrapper,
+ ),
+ cast_to=cast(
+ Type[Optional[OriginTLSComplianceModeUpdateResponse]],
+ ResultWrapper[OriginTLSComplianceModeUpdateResponse],
+ ),
+ )
+
+ async def delete(
+ self,
+ *,
+ zone_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[OriginTLSComplianceModeDeleteResponse]:
+ """
+ Delete the Origin TLS Compliance Modes setting for the zone, removing any
+ configured compliance constraint. After deletion, Cloudflare's default behavior
+ applies (no compliance filtering of the key-exchange algorithm list sent to the
+ origin).
+
+ Args:
+ zone_id: 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 zone_id:
+ raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
+ return await self._delete(
+ path_template("/zones/{zone_id}/settings/origin_tls_compliance_modes", zone_id=zone_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[OriginTLSComplianceModeDeleteResponse]]._unwrapper,
+ ),
+ cast_to=cast(
+ Type[Optional[OriginTLSComplianceModeDeleteResponse]],
+ ResultWrapper[OriginTLSComplianceModeDeleteResponse],
+ ),
+ )
+
+ async def edit(
+ self,
+ *,
+ zone_id: str,
+ value: SequenceNotStr[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[OriginTLSComplianceModeEditResponse]:
+ """Update the set of TLS compliance modes for the zone.
+
+ PATCH performs a full
+ replace of the modes list, not a merge — the request body is treated as the
+ complete new list, and any modes not present in it are removed. (To remove a
+ single mode from an existing configuration, send the updated list without it.)
+ The request body must be of the form `{"value": ["fips", "pqh"]}`. Currently
+ supported modes are `fips` and `pqh`; an empty list clears the constraint.
+ Future modes (e.g. `cnsa2`) may be added; clients should treat unknown values as
+ opaque strings. Invalid mode values are rejected with a 4xx response.
+
+ Args:
+ zone_id: Identifier.
+
+ value: List of TLS compliance modes that constrain the key-exchange algorithms
+ Cloudflare may use when establishing the TLS connection to the zone's origin.
+ Currently supported values are `fips` (FIPS-approved curves) and `pqh`
+ (post-quantum hybrid). Future modes (e.g. `cnsa2`) may be added; clients should
+ treat unknown values as opaque strings. Multiple modes are combined as the
+ intersection of their permitted algorithm lists; selections whose intersection
+ is empty are rejected. An empty list clears the constraint.
+
+ 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 zone_id:
+ raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
+ return await self._patch(
+ path_template("/zones/{zone_id}/settings/origin_tls_compliance_modes", zone_id=zone_id),
+ body=await async_maybe_transform(
+ {"value": value}, origin_tls_compliance_mode_edit_params.OriginTLSComplianceModeEditParams
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[OriginTLSComplianceModeEditResponse]]._unwrapper,
+ ),
+ cast_to=cast(
+ Type[Optional[OriginTLSComplianceModeEditResponse]], ResultWrapper[OriginTLSComplianceModeEditResponse]
+ ),
+ )
+
+ async def get(
+ self,
+ *,
+ zone_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[OriginTLSComplianceModeGetResponse]:
+ """
+ Origin TLS Compliance Modes constrains the set of TLS key-exchange algorithms
+ Cloudflare may use when establishing the TLS connection to the zone's origin.
+ The value is a list of named compliance modes (currently `fips` and `pqh`).
+ Multiple modes are combined as the intersection of their permitted algorithm
+ lists. An empty list (or no rule configured) means no compliance constraint is
+ applied.
+
+ Args:
+ zone_id: 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 zone_id:
+ raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
+ return await self._get(
+ path_template("/zones/{zone_id}/settings/origin_tls_compliance_modes", zone_id=zone_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[OriginTLSComplianceModeGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(
+ Type[Optional[OriginTLSComplianceModeGetResponse]], ResultWrapper[OriginTLSComplianceModeGetResponse]
+ ),
+ )
+
+
+class OriginTLSComplianceModesResourceWithRawResponse:
+ def __init__(self, origin_tls_compliance_modes: OriginTLSComplianceModesResource) -> None:
+ self._origin_tls_compliance_modes = origin_tls_compliance_modes
+
+ self.update = to_raw_response_wrapper(
+ origin_tls_compliance_modes.update,
+ )
+ self.delete = to_raw_response_wrapper(
+ origin_tls_compliance_modes.delete,
+ )
+ self.edit = to_raw_response_wrapper(
+ origin_tls_compliance_modes.edit,
+ )
+ self.get = to_raw_response_wrapper(
+ origin_tls_compliance_modes.get,
+ )
+
+
+class AsyncOriginTLSComplianceModesResourceWithRawResponse:
+ def __init__(self, origin_tls_compliance_modes: AsyncOriginTLSComplianceModesResource) -> None:
+ self._origin_tls_compliance_modes = origin_tls_compliance_modes
+
+ self.update = async_to_raw_response_wrapper(
+ origin_tls_compliance_modes.update,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ origin_tls_compliance_modes.delete,
+ )
+ self.edit = async_to_raw_response_wrapper(
+ origin_tls_compliance_modes.edit,
+ )
+ self.get = async_to_raw_response_wrapper(
+ origin_tls_compliance_modes.get,
+ )
+
+
+class OriginTLSComplianceModesResourceWithStreamingResponse:
+ def __init__(self, origin_tls_compliance_modes: OriginTLSComplianceModesResource) -> None:
+ self._origin_tls_compliance_modes = origin_tls_compliance_modes
+
+ self.update = to_streamed_response_wrapper(
+ origin_tls_compliance_modes.update,
+ )
+ self.delete = to_streamed_response_wrapper(
+ origin_tls_compliance_modes.delete,
+ )
+ self.edit = to_streamed_response_wrapper(
+ origin_tls_compliance_modes.edit,
+ )
+ self.get = to_streamed_response_wrapper(
+ origin_tls_compliance_modes.get,
+ )
+
+
+class AsyncOriginTLSComplianceModesResourceWithStreamingResponse:
+ def __init__(self, origin_tls_compliance_modes: AsyncOriginTLSComplianceModesResource) -> None:
+ self._origin_tls_compliance_modes = origin_tls_compliance_modes
+
+ self.update = async_to_streamed_response_wrapper(
+ origin_tls_compliance_modes.update,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ origin_tls_compliance_modes.delete,
+ )
+ self.edit = async_to_streamed_response_wrapper(
+ origin_tls_compliance_modes.edit,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ origin_tls_compliance_modes.get,
+ )
diff --git a/src/cloudflare/types/origin_tls_compliance_modes/__init__.py b/src/cloudflare/types/origin_tls_compliance_modes/__init__.py
index f8ee8b14b1c..2755bcba0e7 100644
--- a/src/cloudflare/types/origin_tls_compliance_modes/__init__.py
+++ b/src/cloudflare/types/origin_tls_compliance_modes/__init__.py
@@ -1,3 +1,22 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from __future__ import annotations
+
+from .origin_tls_compliance_mode_edit_params import (
+ OriginTLSComplianceModeEditParams as OriginTLSComplianceModeEditParams,
+)
+from .origin_tls_compliance_mode_get_response import (
+ OriginTLSComplianceModeGetResponse as OriginTLSComplianceModeGetResponse,
+)
+from .origin_tls_compliance_mode_edit_response import (
+ OriginTLSComplianceModeEditResponse as OriginTLSComplianceModeEditResponse,
+)
+from .origin_tls_compliance_mode_update_params import (
+ OriginTLSComplianceModeUpdateParams as OriginTLSComplianceModeUpdateParams,
+)
+from .origin_tls_compliance_mode_delete_response import (
+ OriginTLSComplianceModeDeleteResponse as OriginTLSComplianceModeDeleteResponse,
+)
+from .origin_tls_compliance_mode_update_response import (
+ OriginTLSComplianceModeUpdateResponse as OriginTLSComplianceModeUpdateResponse,
+)
diff --git a/src/cloudflare/types/origin_tls_compliance_modes/origin_tls_compliance_mode_delete_response.py b/src/cloudflare/types/origin_tls_compliance_modes/origin_tls_compliance_mode_delete_response.py
new file mode 100644
index 00000000000..3b0e62be03a
--- /dev/null
+++ b/src/cloudflare/types/origin_tls_compliance_modes/origin_tls_compliance_mode_delete_response.py
@@ -0,0 +1,20 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["OriginTLSComplianceModeDeleteResponse"]
+
+
+class OriginTLSComplianceModeDeleteResponse(BaseModel):
+ id: Literal["origin_tls_compliance_modes"]
+ """The identifier of the caching setting."""
+
+ editable: bool
+ """Whether the setting is editable."""
+
+ modified_on: Optional[datetime] = None
+ """Last time this setting was modified."""
diff --git a/src/cloudflare/types/origin_tls_compliance_modes/origin_tls_compliance_mode_edit_params.py b/src/cloudflare/types/origin_tls_compliance_modes/origin_tls_compliance_mode_edit_params.py
new file mode 100644
index 00000000000..f4c80d02554
--- /dev/null
+++ b/src/cloudflare/types/origin_tls_compliance_modes/origin_tls_compliance_mode_edit_params.py
@@ -0,0 +1,25 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+from ..._types import SequenceNotStr
+
+__all__ = ["OriginTLSComplianceModeEditParams"]
+
+
+class OriginTLSComplianceModeEditParams(TypedDict, total=False):
+ zone_id: Required[str]
+ """Identifier."""
+
+ value: Required[SequenceNotStr[str]]
+ """
+ List of TLS compliance modes that constrain the key-exchange algorithms
+ Cloudflare may use when establishing the TLS connection to the zone's origin.
+ Currently supported values are `fips` (FIPS-approved curves) and `pqh`
+ (post-quantum hybrid). Future modes (e.g. `cnsa2`) may be added; clients should
+ treat unknown values as opaque strings. Multiple modes are combined as the
+ intersection of their permitted algorithm lists; selections whose intersection
+ is empty are rejected. An empty list clears the constraint.
+ """
diff --git a/src/cloudflare/types/origin_tls_compliance_modes/origin_tls_compliance_mode_edit_response.py b/src/cloudflare/types/origin_tls_compliance_modes/origin_tls_compliance_mode_edit_response.py
new file mode 100644
index 00000000000..23cae22c9d7
--- /dev/null
+++ b/src/cloudflare/types/origin_tls_compliance_modes/origin_tls_compliance_mode_edit_response.py
@@ -0,0 +1,31 @@
+# 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 ..._models import BaseModel
+
+__all__ = ["OriginTLSComplianceModeEditResponse"]
+
+
+class OriginTLSComplianceModeEditResponse(BaseModel):
+ id: Literal["origin_tls_compliance_modes"]
+ """The identifier of the caching setting."""
+
+ editable: bool
+ """Whether the setting is editable."""
+
+ value: List[str]
+ """
+ List of TLS compliance modes that constrain the key-exchange algorithms
+ Cloudflare may use when establishing the TLS connection to the zone's origin.
+ Currently supported values are `fips` (FIPS-approved curves) and `pqh`
+ (post-quantum hybrid). Future modes (e.g. `cnsa2`) may be added; clients should
+ treat unknown values as opaque strings. Multiple modes are combined as the
+ intersection of their permitted algorithm lists; selections whose intersection
+ is empty are rejected. An empty list clears the constraint.
+ """
+
+ modified_on: Optional[datetime] = None
+ """Last time this setting was modified."""
diff --git a/src/cloudflare/types/origin_tls_compliance_modes/origin_tls_compliance_mode_get_response.py b/src/cloudflare/types/origin_tls_compliance_modes/origin_tls_compliance_mode_get_response.py
new file mode 100644
index 00000000000..178724d1f11
--- /dev/null
+++ b/src/cloudflare/types/origin_tls_compliance_modes/origin_tls_compliance_mode_get_response.py
@@ -0,0 +1,31 @@
+# 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 ..._models import BaseModel
+
+__all__ = ["OriginTLSComplianceModeGetResponse"]
+
+
+class OriginTLSComplianceModeGetResponse(BaseModel):
+ id: Literal["origin_tls_compliance_modes"]
+ """The identifier of the caching setting."""
+
+ editable: bool
+ """Whether the setting is editable."""
+
+ value: List[str]
+ """
+ List of TLS compliance modes that constrain the key-exchange algorithms
+ Cloudflare may use when establishing the TLS connection to the zone's origin.
+ Currently supported values are `fips` (FIPS-approved curves) and `pqh`
+ (post-quantum hybrid). Future modes (e.g. `cnsa2`) may be added; clients should
+ treat unknown values as opaque strings. Multiple modes are combined as the
+ intersection of their permitted algorithm lists; selections whose intersection
+ is empty are rejected. An empty list clears the constraint.
+ """
+
+ modified_on: Optional[datetime] = None
+ """Last time this setting was modified."""
diff --git a/src/cloudflare/types/origin_tls_compliance_modes/origin_tls_compliance_mode_update_params.py b/src/cloudflare/types/origin_tls_compliance_modes/origin_tls_compliance_mode_update_params.py
new file mode 100644
index 00000000000..18252356b3f
--- /dev/null
+++ b/src/cloudflare/types/origin_tls_compliance_modes/origin_tls_compliance_mode_update_params.py
@@ -0,0 +1,25 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+from ..._types import SequenceNotStr
+
+__all__ = ["OriginTLSComplianceModeUpdateParams"]
+
+
+class OriginTLSComplianceModeUpdateParams(TypedDict, total=False):
+ zone_id: Required[str]
+ """Identifier."""
+
+ value: Required[SequenceNotStr[str]]
+ """
+ List of TLS compliance modes that constrain the key-exchange algorithms
+ Cloudflare may use when establishing the TLS connection to the zone's origin.
+ Currently supported values are `fips` (FIPS-approved curves) and `pqh`
+ (post-quantum hybrid). Future modes (e.g. `cnsa2`) may be added; clients should
+ treat unknown values as opaque strings. Multiple modes are combined as the
+ intersection of their permitted algorithm lists; selections whose intersection
+ is empty are rejected. An empty list clears the constraint.
+ """
diff --git a/src/cloudflare/types/origin_tls_compliance_modes/origin_tls_compliance_mode_update_response.py b/src/cloudflare/types/origin_tls_compliance_modes/origin_tls_compliance_mode_update_response.py
new file mode 100644
index 00000000000..4a4bcc66041
--- /dev/null
+++ b/src/cloudflare/types/origin_tls_compliance_modes/origin_tls_compliance_mode_update_response.py
@@ -0,0 +1,31 @@
+# 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 ..._models import BaseModel
+
+__all__ = ["OriginTLSComplianceModeUpdateResponse"]
+
+
+class OriginTLSComplianceModeUpdateResponse(BaseModel):
+ id: Literal["origin_tls_compliance_modes"]
+ """The identifier of the caching setting."""
+
+ editable: bool
+ """Whether the setting is editable."""
+
+ value: List[str]
+ """
+ List of TLS compliance modes that constrain the key-exchange algorithms
+ Cloudflare may use when establishing the TLS connection to the zone's origin.
+ Currently supported values are `fips` (FIPS-approved curves) and `pqh`
+ (post-quantum hybrid). Future modes (e.g. `cnsa2`) may be added; clients should
+ treat unknown values as opaque strings. Multiple modes are combined as the
+ intersection of their permitted algorithm lists; selections whose intersection
+ is empty are rejected. An empty list clears the constraint.
+ """
+
+ modified_on: Optional[datetime] = None
+ """Last time this setting was modified."""
diff --git a/tests/api_resources/test_origin_tls_compliance_modes.py b/tests/api_resources/test_origin_tls_compliance_modes.py
new file mode 100644
index 00000000000..e6bb3f71444
--- /dev/null
+++ b/tests/api_resources/test_origin_tls_compliance_modes.py
@@ -0,0 +1,389 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, Optional, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare.types.origin_tls_compliance_modes import (
+ OriginTLSComplianceModeGetResponse,
+ OriginTLSComplianceModeEditResponse,
+ OriginTLSComplianceModeDeleteResponse,
+ OriginTLSComplianceModeUpdateResponse,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestOriginTLSComplianceModes:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_update(self, client: Cloudflare) -> None:
+ origin_tls_compliance_mode = client.origin_tls_compliance_modes.update(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ value=["fips", "pqh"],
+ )
+ assert_matches_type(
+ Optional[OriginTLSComplianceModeUpdateResponse], origin_tls_compliance_mode, path=["response"]
+ )
+
+ @parametrize
+ def test_raw_response_update(self, client: Cloudflare) -> None:
+ response = client.origin_tls_compliance_modes.with_raw_response.update(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ value=["fips", "pqh"],
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ origin_tls_compliance_mode = response.parse()
+ assert_matches_type(
+ Optional[OriginTLSComplianceModeUpdateResponse], origin_tls_compliance_mode, path=["response"]
+ )
+
+ @parametrize
+ def test_streaming_response_update(self, client: Cloudflare) -> None:
+ with client.origin_tls_compliance_modes.with_streaming_response.update(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ value=["fips", "pqh"],
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ origin_tls_compliance_mode = response.parse()
+ assert_matches_type(
+ Optional[OriginTLSComplianceModeUpdateResponse], origin_tls_compliance_mode, path=["response"]
+ )
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_update(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
+ client.origin_tls_compliance_modes.with_raw_response.update(
+ zone_id="",
+ value=["fips", "pqh"],
+ )
+
+ @parametrize
+ def test_method_delete(self, client: Cloudflare) -> None:
+ origin_tls_compliance_mode = client.origin_tls_compliance_modes.delete(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(
+ Optional[OriginTLSComplianceModeDeleteResponse], origin_tls_compliance_mode, path=["response"]
+ )
+
+ @parametrize
+ def test_raw_response_delete(self, client: Cloudflare) -> None:
+ response = client.origin_tls_compliance_modes.with_raw_response.delete(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ origin_tls_compliance_mode = response.parse()
+ assert_matches_type(
+ Optional[OriginTLSComplianceModeDeleteResponse], origin_tls_compliance_mode, path=["response"]
+ )
+
+ @parametrize
+ def test_streaming_response_delete(self, client: Cloudflare) -> None:
+ with client.origin_tls_compliance_modes.with_streaming_response.delete(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ origin_tls_compliance_mode = response.parse()
+ assert_matches_type(
+ Optional[OriginTLSComplianceModeDeleteResponse], origin_tls_compliance_mode, 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 `zone_id` but received ''"):
+ client.origin_tls_compliance_modes.with_raw_response.delete(
+ zone_id="",
+ )
+
+ @parametrize
+ def test_method_edit(self, client: Cloudflare) -> None:
+ origin_tls_compliance_mode = client.origin_tls_compliance_modes.edit(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ value=["fips", "pqh"],
+ )
+ assert_matches_type(
+ Optional[OriginTLSComplianceModeEditResponse], origin_tls_compliance_mode, path=["response"]
+ )
+
+ @parametrize
+ def test_raw_response_edit(self, client: Cloudflare) -> None:
+ response = client.origin_tls_compliance_modes.with_raw_response.edit(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ value=["fips", "pqh"],
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ origin_tls_compliance_mode = response.parse()
+ assert_matches_type(
+ Optional[OriginTLSComplianceModeEditResponse], origin_tls_compliance_mode, path=["response"]
+ )
+
+ @parametrize
+ def test_streaming_response_edit(self, client: Cloudflare) -> None:
+ with client.origin_tls_compliance_modes.with_streaming_response.edit(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ value=["fips", "pqh"],
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ origin_tls_compliance_mode = response.parse()
+ assert_matches_type(
+ Optional[OriginTLSComplianceModeEditResponse], origin_tls_compliance_mode, 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 `zone_id` but received ''"):
+ client.origin_tls_compliance_modes.with_raw_response.edit(
+ zone_id="",
+ value=["fips", "pqh"],
+ )
+
+ @parametrize
+ def test_method_get(self, client: Cloudflare) -> None:
+ origin_tls_compliance_mode = client.origin_tls_compliance_modes.get(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[OriginTLSComplianceModeGetResponse], origin_tls_compliance_mode, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Cloudflare) -> None:
+ response = client.origin_tls_compliance_modes.with_raw_response.get(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ origin_tls_compliance_mode = response.parse()
+ assert_matches_type(Optional[OriginTLSComplianceModeGetResponse], origin_tls_compliance_mode, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Cloudflare) -> None:
+ with client.origin_tls_compliance_modes.with_streaming_response.get(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ origin_tls_compliance_mode = response.parse()
+ assert_matches_type(
+ Optional[OriginTLSComplianceModeGetResponse], origin_tls_compliance_mode, 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 `zone_id` but received ''"):
+ client.origin_tls_compliance_modes.with_raw_response.get(
+ zone_id="",
+ )
+
+
+class TestAsyncOriginTLSComplianceModes:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_update(self, async_client: AsyncCloudflare) -> None:
+ origin_tls_compliance_mode = await async_client.origin_tls_compliance_modes.update(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ value=["fips", "pqh"],
+ )
+ assert_matches_type(
+ Optional[OriginTLSComplianceModeUpdateResponse], origin_tls_compliance_mode, path=["response"]
+ )
+
+ @parametrize
+ async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.origin_tls_compliance_modes.with_raw_response.update(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ value=["fips", "pqh"],
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ origin_tls_compliance_mode = await response.parse()
+ assert_matches_type(
+ Optional[OriginTLSComplianceModeUpdateResponse], origin_tls_compliance_mode, path=["response"]
+ )
+
+ @parametrize
+ async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.origin_tls_compliance_modes.with_streaming_response.update(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ value=["fips", "pqh"],
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ origin_tls_compliance_mode = await response.parse()
+ assert_matches_type(
+ Optional[OriginTLSComplianceModeUpdateResponse], origin_tls_compliance_mode, path=["response"]
+ )
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_update(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
+ await async_client.origin_tls_compliance_modes.with_raw_response.update(
+ zone_id="",
+ value=["fips", "pqh"],
+ )
+
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncCloudflare) -> None:
+ origin_tls_compliance_mode = await async_client.origin_tls_compliance_modes.delete(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(
+ Optional[OriginTLSComplianceModeDeleteResponse], origin_tls_compliance_mode, path=["response"]
+ )
+
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.origin_tls_compliance_modes.with_raw_response.delete(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ origin_tls_compliance_mode = await response.parse()
+ assert_matches_type(
+ Optional[OriginTLSComplianceModeDeleteResponse], origin_tls_compliance_mode, path=["response"]
+ )
+
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.origin_tls_compliance_modes.with_streaming_response.delete(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ origin_tls_compliance_mode = await response.parse()
+ assert_matches_type(
+ Optional[OriginTLSComplianceModeDeleteResponse], origin_tls_compliance_mode, 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 `zone_id` but received ''"):
+ await async_client.origin_tls_compliance_modes.with_raw_response.delete(
+ zone_id="",
+ )
+
+ @parametrize
+ async def test_method_edit(self, async_client: AsyncCloudflare) -> None:
+ origin_tls_compliance_mode = await async_client.origin_tls_compliance_modes.edit(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ value=["fips", "pqh"],
+ )
+ assert_matches_type(
+ Optional[OriginTLSComplianceModeEditResponse], origin_tls_compliance_mode, path=["response"]
+ )
+
+ @parametrize
+ async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.origin_tls_compliance_modes.with_raw_response.edit(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ value=["fips", "pqh"],
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ origin_tls_compliance_mode = await response.parse()
+ assert_matches_type(
+ Optional[OriginTLSComplianceModeEditResponse], origin_tls_compliance_mode, path=["response"]
+ )
+
+ @parametrize
+ async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.origin_tls_compliance_modes.with_streaming_response.edit(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ value=["fips", "pqh"],
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ origin_tls_compliance_mode = await response.parse()
+ assert_matches_type(
+ Optional[OriginTLSComplianceModeEditResponse], origin_tls_compliance_mode, 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 `zone_id` but received ''"):
+ await async_client.origin_tls_compliance_modes.with_raw_response.edit(
+ zone_id="",
+ value=["fips", "pqh"],
+ )
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncCloudflare) -> None:
+ origin_tls_compliance_mode = await async_client.origin_tls_compliance_modes.get(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[OriginTLSComplianceModeGetResponse], origin_tls_compliance_mode, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.origin_tls_compliance_modes.with_raw_response.get(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ origin_tls_compliance_mode = await response.parse()
+ assert_matches_type(Optional[OriginTLSComplianceModeGetResponse], origin_tls_compliance_mode, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.origin_tls_compliance_modes.with_streaming_response.get(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ origin_tls_compliance_mode = await response.parse()
+ assert_matches_type(
+ Optional[OriginTLSComplianceModeGetResponse], origin_tls_compliance_mode, 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 `zone_id` but received ''"):
+ await async_client.origin_tls_compliance_modes.with_raw_response.get(
+ zone_id="",
+ )
From f94e4de91421e736243f75eee987c888f06d8f0b Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 16 Jun 2026 14:33:17 +0000
Subject: [PATCH 18/23] chore(api): update composite API spec
---
.stats.yml | 4 +--
.../instance_chat_completions_params.py | 3 +-
.../types/aisearch/instance_create_params.py | 15 ----------
.../aisearch/instance_create_response.py | 15 ----------
.../aisearch/instance_delete_response.py | 15 ----------
.../types/aisearch/instance_list_response.py | 15 ----------
.../types/aisearch/instance_read_response.py | 15 ----------
.../types/aisearch/instance_search_params.py | 3 +-
.../types/aisearch/instance_update_params.py | 15 ----------
.../aisearch/instance_update_response.py | 15 ----------
.../namespace_chat_completions_params.py | 3 +-
.../types/aisearch/namespace_search_params.py | 3 +-
.../instance_chat_completions_params.py | 3 +-
.../namespaces/instance_create_params.py | 15 ----------
.../namespaces/instance_create_response.py | 15 ----------
.../namespaces/instance_delete_response.py | 15 ----------
.../namespaces/instance_list_response.py | 15 ----------
.../namespaces/instance_read_response.py | 15 ----------
.../namespaces/instance_search_params.py | 3 +-
.../namespaces/instance_update_params.py | 15 ----------
.../namespaces/instance_update_response.py | 15 ----------
.../aisearch/namespaces/test_instances.py | 28 -------------------
.../api_resources/aisearch/test_instances.py | 28 -------------------
23 files changed, 14 insertions(+), 274 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 8cf402669f4..97d93a9d7f6 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 2404
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-5b604e453c8856075fa29214c76cffcdceeec0577992cd0126a1dd4941cfb43e.yml
-openapi_spec_hash: 9be331253c989946b4df42615e242471
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-860e0e21c46ccb06bc3d07c600d9f192572d700fbfda45f01c1df3c5da0bc828.yml
+openapi_spec_hash: ef2c85d912a4dc2a8f5cfa8a30293698
config_hash: 2f529580a17438fc62cd0b47db41b6f1
diff --git a/src/cloudflare/types/aisearch/instance_chat_completions_params.py b/src/cloudflare/types/aisearch/instance_chat_completions_params.py
index 706f77cd780..19281df437a 100644
--- a/src/cloudflare/types/aisearch/instance_chat_completions_params.py
+++ b/src/cloudflare/types/aisearch/instance_chat_completions_params.py
@@ -160,7 +160,8 @@ class AISearchOptionsRetrieval(TypedDict, total=False):
'and' restricts candidates to documents containing all query terms; 'or'
includes any document containing at least one term, ranked by BM25 relevance.
- Defaults to 'and'.
+ When omitted, falls back to the instance-level
+ retrieval_options.keyword_match_mode, then to 'and'.
"""
match_threshold: float
diff --git a/src/cloudflare/types/aisearch/instance_create_params.py b/src/cloudflare/types/aisearch/instance_create_params.py
index bd88ccd255c..be79caf516a 100644
--- a/src/cloudflare/types/aisearch/instance_create_params.py
+++ b/src/cloudflare/types/aisearch/instance_create_params.py
@@ -24,7 +24,6 @@
"RetrievalOptionsBoostBy",
"SourceParams",
"SourceParamsWebCrawler",
- "SourceParamsWebCrawlerCrawlOptions",
"SourceParamsWebCrawlerParseOptions",
"SourceParamsWebCrawlerParseOptionsContentSelector",
"SourceParamsWebCrawlerStoreOptions",
@@ -302,18 +301,6 @@ class RetrievalOptions(TypedDict, total=False):
"""
-class SourceParamsWebCrawlerCrawlOptions(TypedDict, total=False):
- depth: float
-
- include_external_links: bool
-
- include_subdomains: bool
-
- max_age: float
-
- source: Literal["all", "sitemaps", "links"]
-
-
class SourceParamsWebCrawlerParseOptionsContentSelector(TypedDict, total=False):
path: Required[str]
"""Glob pattern to match against the page URL path.
@@ -367,8 +354,6 @@ class SourceParamsWebCrawlerStoreOptions(TypedDict, total=False):
class SourceParamsWebCrawler(TypedDict, total=False):
- crawl_options: SourceParamsWebCrawlerCrawlOptions
-
parse_options: SourceParamsWebCrawlerParseOptions
parse_type: Literal["sitemap", "feed-rss", "crawl"]
diff --git a/src/cloudflare/types/aisearch/instance_create_response.py b/src/cloudflare/types/aisearch/instance_create_response.py
index ec9b56fae9a..37a4b5b463c 100644
--- a/src/cloudflare/types/aisearch/instance_create_response.py
+++ b/src/cloudflare/types/aisearch/instance_create_response.py
@@ -24,7 +24,6 @@
"RetrievalOptionsBoostBy",
"SourceParams",
"SourceParamsWebCrawler",
- "SourceParamsWebCrawlerCrawlOptions",
"SourceParamsWebCrawlerParseOptions",
"SourceParamsWebCrawlerParseOptionsContentSelector",
"SourceParamsWebCrawlerStoreOptions",
@@ -143,18 +142,6 @@ class RetrievalOptions(BaseModel):
"""
-class SourceParamsWebCrawlerCrawlOptions(BaseModel):
- depth: Optional[float] = None
-
- include_external_links: Optional[bool] = None
-
- include_subdomains: Optional[bool] = None
-
- max_age: Optional[float] = None
-
- source: Optional[Literal["all", "sitemaps", "links"]] = None
-
-
class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel):
path: str
"""Glob pattern to match against the page URL path.
@@ -208,8 +195,6 @@ class SourceParamsWebCrawlerStoreOptions(BaseModel):
class SourceParamsWebCrawler(BaseModel):
- crawl_options: Optional[SourceParamsWebCrawlerCrawlOptions] = None
-
parse_options: Optional[SourceParamsWebCrawlerParseOptions] = None
parse_type: Optional[Literal["sitemap", "feed-rss", "crawl"]] = None
diff --git a/src/cloudflare/types/aisearch/instance_delete_response.py b/src/cloudflare/types/aisearch/instance_delete_response.py
index 807424ef1d3..6d7604dac1f 100644
--- a/src/cloudflare/types/aisearch/instance_delete_response.py
+++ b/src/cloudflare/types/aisearch/instance_delete_response.py
@@ -24,7 +24,6 @@
"RetrievalOptionsBoostBy",
"SourceParams",
"SourceParamsWebCrawler",
- "SourceParamsWebCrawlerCrawlOptions",
"SourceParamsWebCrawlerParseOptions",
"SourceParamsWebCrawlerParseOptionsContentSelector",
"SourceParamsWebCrawlerStoreOptions",
@@ -143,18 +142,6 @@ class RetrievalOptions(BaseModel):
"""
-class SourceParamsWebCrawlerCrawlOptions(BaseModel):
- depth: Optional[float] = None
-
- include_external_links: Optional[bool] = None
-
- include_subdomains: Optional[bool] = None
-
- max_age: Optional[float] = None
-
- source: Optional[Literal["all", "sitemaps", "links"]] = None
-
-
class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel):
path: str
"""Glob pattern to match against the page URL path.
@@ -208,8 +195,6 @@ class SourceParamsWebCrawlerStoreOptions(BaseModel):
class SourceParamsWebCrawler(BaseModel):
- crawl_options: Optional[SourceParamsWebCrawlerCrawlOptions] = None
-
parse_options: Optional[SourceParamsWebCrawlerParseOptions] = None
parse_type: Optional[Literal["sitemap", "feed-rss", "crawl"]] = None
diff --git a/src/cloudflare/types/aisearch/instance_list_response.py b/src/cloudflare/types/aisearch/instance_list_response.py
index de63e870c02..b20a20234d0 100644
--- a/src/cloudflare/types/aisearch/instance_list_response.py
+++ b/src/cloudflare/types/aisearch/instance_list_response.py
@@ -24,7 +24,6 @@
"RetrievalOptionsBoostBy",
"SourceParams",
"SourceParamsWebCrawler",
- "SourceParamsWebCrawlerCrawlOptions",
"SourceParamsWebCrawlerParseOptions",
"SourceParamsWebCrawlerParseOptionsContentSelector",
"SourceParamsWebCrawlerStoreOptions",
@@ -143,18 +142,6 @@ class RetrievalOptions(BaseModel):
"""
-class SourceParamsWebCrawlerCrawlOptions(BaseModel):
- depth: Optional[float] = None
-
- include_external_links: Optional[bool] = None
-
- include_subdomains: Optional[bool] = None
-
- max_age: Optional[float] = None
-
- source: Optional[Literal["all", "sitemaps", "links"]] = None
-
-
class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel):
path: str
"""Glob pattern to match against the page URL path.
@@ -208,8 +195,6 @@ class SourceParamsWebCrawlerStoreOptions(BaseModel):
class SourceParamsWebCrawler(BaseModel):
- crawl_options: Optional[SourceParamsWebCrawlerCrawlOptions] = None
-
parse_options: Optional[SourceParamsWebCrawlerParseOptions] = None
parse_type: Optional[Literal["sitemap", "feed-rss", "crawl"]] = None
diff --git a/src/cloudflare/types/aisearch/instance_read_response.py b/src/cloudflare/types/aisearch/instance_read_response.py
index 22c7272c5ed..4a6f5acc7f5 100644
--- a/src/cloudflare/types/aisearch/instance_read_response.py
+++ b/src/cloudflare/types/aisearch/instance_read_response.py
@@ -24,7 +24,6 @@
"RetrievalOptionsBoostBy",
"SourceParams",
"SourceParamsWebCrawler",
- "SourceParamsWebCrawlerCrawlOptions",
"SourceParamsWebCrawlerParseOptions",
"SourceParamsWebCrawlerParseOptionsContentSelector",
"SourceParamsWebCrawlerStoreOptions",
@@ -143,18 +142,6 @@ class RetrievalOptions(BaseModel):
"""
-class SourceParamsWebCrawlerCrawlOptions(BaseModel):
- depth: Optional[float] = None
-
- include_external_links: Optional[bool] = None
-
- include_subdomains: Optional[bool] = None
-
- max_age: Optional[float] = None
-
- source: Optional[Literal["all", "sitemaps", "links"]] = None
-
-
class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel):
path: str
"""Glob pattern to match against the page URL path.
@@ -208,8 +195,6 @@ class SourceParamsWebCrawlerStoreOptions(BaseModel):
class SourceParamsWebCrawler(BaseModel):
- crawl_options: Optional[SourceParamsWebCrawlerCrawlOptions] = None
-
parse_options: Optional[SourceParamsWebCrawlerParseOptions] = None
parse_type: Optional[Literal["sitemap", "feed-rss", "crawl"]] = None
diff --git a/src/cloudflare/types/aisearch/instance_search_params.py b/src/cloudflare/types/aisearch/instance_search_params.py
index 4cc0d95413f..651bfa8c283 100644
--- a/src/cloudflare/types/aisearch/instance_search_params.py
+++ b/src/cloudflare/types/aisearch/instance_search_params.py
@@ -125,7 +125,8 @@ class AISearchOptionsRetrieval(TypedDict, total=False):
'and' restricts candidates to documents containing all query terms; 'or'
includes any document containing at least one term, ranked by BM25 relevance.
- Defaults to 'and'.
+ When omitted, falls back to the instance-level
+ retrieval_options.keyword_match_mode, then to 'and'.
"""
match_threshold: float
diff --git a/src/cloudflare/types/aisearch/instance_update_params.py b/src/cloudflare/types/aisearch/instance_update_params.py
index 78be3d28af4..8a18d50c332 100644
--- a/src/cloudflare/types/aisearch/instance_update_params.py
+++ b/src/cloudflare/types/aisearch/instance_update_params.py
@@ -24,7 +24,6 @@
"RetrievalOptionsBoostBy",
"SourceParams",
"SourceParamsWebCrawler",
- "SourceParamsWebCrawlerCrawlOptions",
"SourceParamsWebCrawlerParseOptions",
"SourceParamsWebCrawlerParseOptionsContentSelector",
"SourceParamsWebCrawlerStoreOptions",
@@ -337,18 +336,6 @@ class RetrievalOptions(TypedDict, total=False):
"""
-class SourceParamsWebCrawlerCrawlOptions(TypedDict, total=False):
- depth: float
-
- include_external_links: bool
-
- include_subdomains: bool
-
- max_age: float
-
- source: Literal["all", "sitemaps", "links"]
-
-
class SourceParamsWebCrawlerParseOptionsContentSelector(TypedDict, total=False):
path: Required[str]
"""Glob pattern to match against the page URL path.
@@ -402,8 +389,6 @@ class SourceParamsWebCrawlerStoreOptions(TypedDict, total=False):
class SourceParamsWebCrawler(TypedDict, total=False):
- crawl_options: SourceParamsWebCrawlerCrawlOptions
-
parse_options: SourceParamsWebCrawlerParseOptions
parse_type: Literal["sitemap", "feed-rss", "crawl"]
diff --git a/src/cloudflare/types/aisearch/instance_update_response.py b/src/cloudflare/types/aisearch/instance_update_response.py
index 76561cf4c1c..7df0d7a354d 100644
--- a/src/cloudflare/types/aisearch/instance_update_response.py
+++ b/src/cloudflare/types/aisearch/instance_update_response.py
@@ -24,7 +24,6 @@
"RetrievalOptionsBoostBy",
"SourceParams",
"SourceParamsWebCrawler",
- "SourceParamsWebCrawlerCrawlOptions",
"SourceParamsWebCrawlerParseOptions",
"SourceParamsWebCrawlerParseOptionsContentSelector",
"SourceParamsWebCrawlerStoreOptions",
@@ -143,18 +142,6 @@ class RetrievalOptions(BaseModel):
"""
-class SourceParamsWebCrawlerCrawlOptions(BaseModel):
- depth: Optional[float] = None
-
- include_external_links: Optional[bool] = None
-
- include_subdomains: Optional[bool] = None
-
- max_age: Optional[float] = None
-
- source: Optional[Literal["all", "sitemaps", "links"]] = None
-
-
class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel):
path: str
"""Glob pattern to match against the page URL path.
@@ -208,8 +195,6 @@ class SourceParamsWebCrawlerStoreOptions(BaseModel):
class SourceParamsWebCrawler(BaseModel):
- crawl_options: Optional[SourceParamsWebCrawlerCrawlOptions] = None
-
parse_options: Optional[SourceParamsWebCrawlerParseOptions] = None
parse_type: Optional[Literal["sitemap", "feed-rss", "crawl"]] = None
diff --git a/src/cloudflare/types/aisearch/namespace_chat_completions_params.py b/src/cloudflare/types/aisearch/namespace_chat_completions_params.py
index 919791b7189..ac8e80bc538 100644
--- a/src/cloudflare/types/aisearch/namespace_chat_completions_params.py
+++ b/src/cloudflare/types/aisearch/namespace_chat_completions_params.py
@@ -155,7 +155,8 @@ class AISearchOptionsRetrieval(TypedDict, total=False):
'and' restricts candidates to documents containing all query terms; 'or'
includes any document containing at least one term, ranked by BM25 relevance.
- Defaults to 'and'.
+ When omitted, falls back to the instance-level
+ retrieval_options.keyword_match_mode, then to 'and'.
"""
match_threshold: float
diff --git a/src/cloudflare/types/aisearch/namespace_search_params.py b/src/cloudflare/types/aisearch/namespace_search_params.py
index dcb44c99c7a..7c2346bbd6a 100644
--- a/src/cloudflare/types/aisearch/namespace_search_params.py
+++ b/src/cloudflare/types/aisearch/namespace_search_params.py
@@ -126,7 +126,8 @@ class AISearchOptionsRetrieval(TypedDict, total=False):
'and' restricts candidates to documents containing all query terms; 'or'
includes any document containing at least one term, ranked by BM25 relevance.
- Defaults to 'and'.
+ When omitted, falls back to the instance-level
+ retrieval_options.keyword_match_mode, then to 'and'.
"""
match_threshold: float
diff --git a/src/cloudflare/types/aisearch/namespaces/instance_chat_completions_params.py b/src/cloudflare/types/aisearch/namespaces/instance_chat_completions_params.py
index 534ed817572..08a6cb7b74a 100644
--- a/src/cloudflare/types/aisearch/namespaces/instance_chat_completions_params.py
+++ b/src/cloudflare/types/aisearch/namespaces/instance_chat_completions_params.py
@@ -162,7 +162,8 @@ class AISearchOptionsRetrieval(TypedDict, total=False):
'and' restricts candidates to documents containing all query terms; 'or'
includes any document containing at least one term, ranked by BM25 relevance.
- Defaults to 'and'.
+ When omitted, falls back to the instance-level
+ retrieval_options.keyword_match_mode, then to 'and'.
"""
match_threshold: float
diff --git a/src/cloudflare/types/aisearch/namespaces/instance_create_params.py b/src/cloudflare/types/aisearch/namespaces/instance_create_params.py
index 2cca94d4d85..77e564862d3 100644
--- a/src/cloudflare/types/aisearch/namespaces/instance_create_params.py
+++ b/src/cloudflare/types/aisearch/namespaces/instance_create_params.py
@@ -24,7 +24,6 @@
"RetrievalOptionsBoostBy",
"SourceParams",
"SourceParamsWebCrawler",
- "SourceParamsWebCrawlerCrawlOptions",
"SourceParamsWebCrawlerParseOptions",
"SourceParamsWebCrawlerParseOptionsContentSelector",
"SourceParamsWebCrawlerStoreOptions",
@@ -302,18 +301,6 @@ class RetrievalOptions(TypedDict, total=False):
"""
-class SourceParamsWebCrawlerCrawlOptions(TypedDict, total=False):
- depth: float
-
- include_external_links: bool
-
- include_subdomains: bool
-
- max_age: float
-
- source: Literal["all", "sitemaps", "links"]
-
-
class SourceParamsWebCrawlerParseOptionsContentSelector(TypedDict, total=False):
path: Required[str]
"""Glob pattern to match against the page URL path.
@@ -367,8 +354,6 @@ class SourceParamsWebCrawlerStoreOptions(TypedDict, total=False):
class SourceParamsWebCrawler(TypedDict, total=False):
- crawl_options: SourceParamsWebCrawlerCrawlOptions
-
parse_options: SourceParamsWebCrawlerParseOptions
parse_type: Literal["sitemap", "feed-rss", "crawl"]
diff --git a/src/cloudflare/types/aisearch/namespaces/instance_create_response.py b/src/cloudflare/types/aisearch/namespaces/instance_create_response.py
index 80dde13d1dc..964180501b5 100644
--- a/src/cloudflare/types/aisearch/namespaces/instance_create_response.py
+++ b/src/cloudflare/types/aisearch/namespaces/instance_create_response.py
@@ -24,7 +24,6 @@
"RetrievalOptionsBoostBy",
"SourceParams",
"SourceParamsWebCrawler",
- "SourceParamsWebCrawlerCrawlOptions",
"SourceParamsWebCrawlerParseOptions",
"SourceParamsWebCrawlerParseOptionsContentSelector",
"SourceParamsWebCrawlerStoreOptions",
@@ -143,18 +142,6 @@ class RetrievalOptions(BaseModel):
"""
-class SourceParamsWebCrawlerCrawlOptions(BaseModel):
- depth: Optional[float] = None
-
- include_external_links: Optional[bool] = None
-
- include_subdomains: Optional[bool] = None
-
- max_age: Optional[float] = None
-
- source: Optional[Literal["all", "sitemaps", "links"]] = None
-
-
class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel):
path: str
"""Glob pattern to match against the page URL path.
@@ -208,8 +195,6 @@ class SourceParamsWebCrawlerStoreOptions(BaseModel):
class SourceParamsWebCrawler(BaseModel):
- crawl_options: Optional[SourceParamsWebCrawlerCrawlOptions] = None
-
parse_options: Optional[SourceParamsWebCrawlerParseOptions] = None
parse_type: Optional[Literal["sitemap", "feed-rss", "crawl"]] = None
diff --git a/src/cloudflare/types/aisearch/namespaces/instance_delete_response.py b/src/cloudflare/types/aisearch/namespaces/instance_delete_response.py
index c19e7488db1..a2b6149ee80 100644
--- a/src/cloudflare/types/aisearch/namespaces/instance_delete_response.py
+++ b/src/cloudflare/types/aisearch/namespaces/instance_delete_response.py
@@ -24,7 +24,6 @@
"RetrievalOptionsBoostBy",
"SourceParams",
"SourceParamsWebCrawler",
- "SourceParamsWebCrawlerCrawlOptions",
"SourceParamsWebCrawlerParseOptions",
"SourceParamsWebCrawlerParseOptionsContentSelector",
"SourceParamsWebCrawlerStoreOptions",
@@ -143,18 +142,6 @@ class RetrievalOptions(BaseModel):
"""
-class SourceParamsWebCrawlerCrawlOptions(BaseModel):
- depth: Optional[float] = None
-
- include_external_links: Optional[bool] = None
-
- include_subdomains: Optional[bool] = None
-
- max_age: Optional[float] = None
-
- source: Optional[Literal["all", "sitemaps", "links"]] = None
-
-
class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel):
path: str
"""Glob pattern to match against the page URL path.
@@ -208,8 +195,6 @@ class SourceParamsWebCrawlerStoreOptions(BaseModel):
class SourceParamsWebCrawler(BaseModel):
- crawl_options: Optional[SourceParamsWebCrawlerCrawlOptions] = None
-
parse_options: Optional[SourceParamsWebCrawlerParseOptions] = None
parse_type: Optional[Literal["sitemap", "feed-rss", "crawl"]] = None
diff --git a/src/cloudflare/types/aisearch/namespaces/instance_list_response.py b/src/cloudflare/types/aisearch/namespaces/instance_list_response.py
index 88bd3244705..3b8e7ddf359 100644
--- a/src/cloudflare/types/aisearch/namespaces/instance_list_response.py
+++ b/src/cloudflare/types/aisearch/namespaces/instance_list_response.py
@@ -24,7 +24,6 @@
"RetrievalOptionsBoostBy",
"SourceParams",
"SourceParamsWebCrawler",
- "SourceParamsWebCrawlerCrawlOptions",
"SourceParamsWebCrawlerParseOptions",
"SourceParamsWebCrawlerParseOptionsContentSelector",
"SourceParamsWebCrawlerStoreOptions",
@@ -143,18 +142,6 @@ class RetrievalOptions(BaseModel):
"""
-class SourceParamsWebCrawlerCrawlOptions(BaseModel):
- depth: Optional[float] = None
-
- include_external_links: Optional[bool] = None
-
- include_subdomains: Optional[bool] = None
-
- max_age: Optional[float] = None
-
- source: Optional[Literal["all", "sitemaps", "links"]] = None
-
-
class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel):
path: str
"""Glob pattern to match against the page URL path.
@@ -208,8 +195,6 @@ class SourceParamsWebCrawlerStoreOptions(BaseModel):
class SourceParamsWebCrawler(BaseModel):
- crawl_options: Optional[SourceParamsWebCrawlerCrawlOptions] = None
-
parse_options: Optional[SourceParamsWebCrawlerParseOptions] = None
parse_type: Optional[Literal["sitemap", "feed-rss", "crawl"]] = None
diff --git a/src/cloudflare/types/aisearch/namespaces/instance_read_response.py b/src/cloudflare/types/aisearch/namespaces/instance_read_response.py
index 8294c914459..589d5cc29a5 100644
--- a/src/cloudflare/types/aisearch/namespaces/instance_read_response.py
+++ b/src/cloudflare/types/aisearch/namespaces/instance_read_response.py
@@ -24,7 +24,6 @@
"RetrievalOptionsBoostBy",
"SourceParams",
"SourceParamsWebCrawler",
- "SourceParamsWebCrawlerCrawlOptions",
"SourceParamsWebCrawlerParseOptions",
"SourceParamsWebCrawlerParseOptionsContentSelector",
"SourceParamsWebCrawlerStoreOptions",
@@ -143,18 +142,6 @@ class RetrievalOptions(BaseModel):
"""
-class SourceParamsWebCrawlerCrawlOptions(BaseModel):
- depth: Optional[float] = None
-
- include_external_links: Optional[bool] = None
-
- include_subdomains: Optional[bool] = None
-
- max_age: Optional[float] = None
-
- source: Optional[Literal["all", "sitemaps", "links"]] = None
-
-
class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel):
path: str
"""Glob pattern to match against the page URL path.
@@ -208,8 +195,6 @@ class SourceParamsWebCrawlerStoreOptions(BaseModel):
class SourceParamsWebCrawler(BaseModel):
- crawl_options: Optional[SourceParamsWebCrawlerCrawlOptions] = None
-
parse_options: Optional[SourceParamsWebCrawlerParseOptions] = None
parse_type: Optional[Literal["sitemap", "feed-rss", "crawl"]] = None
diff --git a/src/cloudflare/types/aisearch/namespaces/instance_search_params.py b/src/cloudflare/types/aisearch/namespaces/instance_search_params.py
index 7718fcc09ef..538b40318e7 100644
--- a/src/cloudflare/types/aisearch/namespaces/instance_search_params.py
+++ b/src/cloudflare/types/aisearch/namespaces/instance_search_params.py
@@ -127,7 +127,8 @@ class AISearchOptionsRetrieval(TypedDict, total=False):
'and' restricts candidates to documents containing all query terms; 'or'
includes any document containing at least one term, ranked by BM25 relevance.
- Defaults to 'and'.
+ When omitted, falls back to the instance-level
+ retrieval_options.keyword_match_mode, then to 'and'.
"""
match_threshold: float
diff --git a/src/cloudflare/types/aisearch/namespaces/instance_update_params.py b/src/cloudflare/types/aisearch/namespaces/instance_update_params.py
index aeafe6579b2..835af3a276a 100644
--- a/src/cloudflare/types/aisearch/namespaces/instance_update_params.py
+++ b/src/cloudflare/types/aisearch/namespaces/instance_update_params.py
@@ -24,7 +24,6 @@
"RetrievalOptionsBoostBy",
"SourceParams",
"SourceParamsWebCrawler",
- "SourceParamsWebCrawlerCrawlOptions",
"SourceParamsWebCrawlerParseOptions",
"SourceParamsWebCrawlerParseOptionsContentSelector",
"SourceParamsWebCrawlerStoreOptions",
@@ -339,18 +338,6 @@ class RetrievalOptions(TypedDict, total=False):
"""
-class SourceParamsWebCrawlerCrawlOptions(TypedDict, total=False):
- depth: float
-
- include_external_links: bool
-
- include_subdomains: bool
-
- max_age: float
-
- source: Literal["all", "sitemaps", "links"]
-
-
class SourceParamsWebCrawlerParseOptionsContentSelector(TypedDict, total=False):
path: Required[str]
"""Glob pattern to match against the page URL path.
@@ -404,8 +391,6 @@ class SourceParamsWebCrawlerStoreOptions(TypedDict, total=False):
class SourceParamsWebCrawler(TypedDict, total=False):
- crawl_options: SourceParamsWebCrawlerCrawlOptions
-
parse_options: SourceParamsWebCrawlerParseOptions
parse_type: Literal["sitemap", "feed-rss", "crawl"]
diff --git a/src/cloudflare/types/aisearch/namespaces/instance_update_response.py b/src/cloudflare/types/aisearch/namespaces/instance_update_response.py
index 0efe7979c5c..c16ba2b1a67 100644
--- a/src/cloudflare/types/aisearch/namespaces/instance_update_response.py
+++ b/src/cloudflare/types/aisearch/namespaces/instance_update_response.py
@@ -24,7 +24,6 @@
"RetrievalOptionsBoostBy",
"SourceParams",
"SourceParamsWebCrawler",
- "SourceParamsWebCrawlerCrawlOptions",
"SourceParamsWebCrawlerParseOptions",
"SourceParamsWebCrawlerParseOptionsContentSelector",
"SourceParamsWebCrawlerStoreOptions",
@@ -143,18 +142,6 @@ class RetrievalOptions(BaseModel):
"""
-class SourceParamsWebCrawlerCrawlOptions(BaseModel):
- depth: Optional[float] = None
-
- include_external_links: Optional[bool] = None
-
- include_subdomains: Optional[bool] = None
-
- max_age: Optional[float] = None
-
- source: Optional[Literal["all", "sitemaps", "links"]] = None
-
-
class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel):
path: str
"""Glob pattern to match against the page URL path.
@@ -208,8 +195,6 @@ class SourceParamsWebCrawlerStoreOptions(BaseModel):
class SourceParamsWebCrawler(BaseModel):
- crawl_options: Optional[SourceParamsWebCrawlerCrawlOptions] = None
-
parse_options: Optional[SourceParamsWebCrawlerParseOptions] = None
parse_type: Optional[Literal["sitemap", "feed-rss", "crawl"]] = None
diff --git a/tests/api_resources/aisearch/namespaces/test_instances.py b/tests/api_resources/aisearch/namespaces/test_instances.py
index fd694678253..6662d33e399 100644
--- a/tests/api_resources/aisearch/namespaces/test_instances.py
+++ b/tests/api_resources/aisearch/namespaces/test_instances.py
@@ -105,13 +105,6 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None:
"prefix": "prefix",
"r2_jurisdiction": "r2_jurisdiction",
"web_crawler": {
- "crawl_options": {
- "depth": 1,
- "include_external_links": True,
- "include_subdomains": True,
- "max_age": 0,
- "source": "all",
- },
"parse_options": {
"content_selector": [
{
@@ -266,13 +259,6 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None:
"prefix": "prefix",
"r2_jurisdiction": "r2_jurisdiction",
"web_crawler": {
- "crawl_options": {
- "depth": 1,
- "include_external_links": True,
- "include_subdomains": True,
- "max_age": 0,
- "source": "all",
- },
"parse_options": {
"content_selector": [
{
@@ -940,13 +926,6 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare
"prefix": "prefix",
"r2_jurisdiction": "r2_jurisdiction",
"web_crawler": {
- "crawl_options": {
- "depth": 1,
- "include_external_links": True,
- "include_subdomains": True,
- "max_age": 0,
- "source": "all",
- },
"parse_options": {
"content_selector": [
{
@@ -1101,13 +1080,6 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare
"prefix": "prefix",
"r2_jurisdiction": "r2_jurisdiction",
"web_crawler": {
- "crawl_options": {
- "depth": 1,
- "include_external_links": True,
- "include_subdomains": True,
- "max_age": 0,
- "source": "all",
- },
"parse_options": {
"content_selector": [
{
diff --git a/tests/api_resources/aisearch/test_instances.py b/tests/api_resources/aisearch/test_instances.py
index fcb88148c66..458d4f14faa 100644
--- a/tests/api_resources/aisearch/test_instances.py
+++ b/tests/api_resources/aisearch/test_instances.py
@@ -103,13 +103,6 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None:
"prefix": "prefix",
"r2_jurisdiction": "r2_jurisdiction",
"web_crawler": {
- "crawl_options": {
- "depth": 1,
- "include_external_links": True,
- "include_subdomains": True,
- "max_age": 0,
- "source": "all",
- },
"parse_options": {
"content_selector": [
{
@@ -252,13 +245,6 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None:
"prefix": "prefix",
"r2_jurisdiction": "r2_jurisdiction",
"web_crawler": {
- "crawl_options": {
- "depth": 1,
- "include_external_links": True,
- "include_subdomains": True,
- "max_age": 0,
- "source": "all",
- },
"parse_options": {
"content_selector": [
{
@@ -834,13 +820,6 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare
"prefix": "prefix",
"r2_jurisdiction": "r2_jurisdiction",
"web_crawler": {
- "crawl_options": {
- "depth": 1,
- "include_external_links": True,
- "include_subdomains": True,
- "max_age": 0,
- "source": "all",
- },
"parse_options": {
"content_selector": [
{
@@ -983,13 +962,6 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare
"prefix": "prefix",
"r2_jurisdiction": "r2_jurisdiction",
"web_crawler": {
- "crawl_options": {
- "depth": 1,
- "include_external_links": True,
- "include_subdomains": True,
- "max_age": 0,
- "source": "all",
- },
"parse_options": {
"content_selector": [
{
From c7202c9f9215a179b17362439c59b2e99566ab40 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 16 Jun 2026 15:55:54 +0000
Subject: [PATCH 19/23] chore(api): update composite API spec
---
.stats.yml | 4 ++--
.../devices/registration_get_response.py | 12 ++++++++++
.../devices/registration_list_response.py | 12 ++++++++++
.../devices/test_deployment_groups.py | 24 +++++++++----------
4 files changed, 38 insertions(+), 14 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 97d93a9d7f6..bdd3b2bd34f 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 2404
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-860e0e21c46ccb06bc3d07c600d9f192572d700fbfda45f01c1df3c5da0bc828.yml
-openapi_spec_hash: ef2c85d912a4dc2a8f5cfa8a30293698
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-12062ca747c6e0de56212973f1428209cd185869f1312b19e57168fc5b1e9b40.yml
+openapi_spec_hash: 0c2df0b38c6ec58b4fae1e4cf1fe04e7
config_hash: 2f529580a17438fc62cd0b47db41b6f1
diff --git a/src/cloudflare/types/zero_trust/devices/registration_get_response.py b/src/cloudflare/types/zero_trust/devices/registration_get_response.py
index 1acdc113e53..65677802d89 100644
--- a/src/cloudflare/types/zero_trust/devices/registration_get_response.py
+++ b/src/cloudflare/types/zero_trust/devices/registration_get_response.py
@@ -96,3 +96,15 @@ class RegistrationGetResponse(BaseModel):
"""Type of the tunnel - wireguard or masque."""
user: Optional[User] = None
+
+ virtual_ipv4: Optional[str] = None
+ """
+ The virtual IPv4 address assigned to the network interface of the tunnel for
+ this registration.
+ """
+
+ virtual_ipv6: Optional[str] = None
+ """
+ The virtual IPv6 address assigned to the network interface of the tunnel for
+ this registration.
+ """
diff --git a/src/cloudflare/types/zero_trust/devices/registration_list_response.py b/src/cloudflare/types/zero_trust/devices/registration_list_response.py
index 37fe8aedf48..da1ca406e56 100644
--- a/src/cloudflare/types/zero_trust/devices/registration_list_response.py
+++ b/src/cloudflare/types/zero_trust/devices/registration_list_response.py
@@ -96,3 +96,15 @@ class RegistrationListResponse(BaseModel):
"""Type of the tunnel - wireguard or masque."""
user: Optional[User] = None
+
+ virtual_ipv4: Optional[str] = None
+ """
+ The virtual IPv4 address assigned to the network interface of the tunnel for
+ this registration.
+ """
+
+ virtual_ipv6: Optional[str] = None
+ """
+ The virtual IPv6 address assigned to the network interface of the tunnel for
+ this registration.
+ """
diff --git a/tests/api_resources/zero_trust/devices/test_deployment_groups.py b/tests/api_resources/zero_trust/devices/test_deployment_groups.py
index 98dd6882828..0bdc467a7b2 100644
--- a/tests/api_resources/zero_trust/devices/test_deployment_groups.py
+++ b/tests/api_resources/zero_trust/devices/test_deployment_groups.py
@@ -30,7 +30,7 @@ def test_method_create(self, client: Cloudflare) -> None:
version_config=[
{
"target_environment": "windows",
- "version": "2026.5.234.0",
+ "version": "2026.6.234.0",
}
],
)
@@ -45,7 +45,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None:
version_config=[
{
"target_environment": "windows",
- "version": "2026.5.234.0",
+ "version": "2026.6.234.0",
}
],
policy_ids=["string"],
@@ -61,7 +61,7 @@ def test_raw_response_create(self, client: Cloudflare) -> None:
version_config=[
{
"target_environment": "windows",
- "version": "2026.5.234.0",
+ "version": "2026.6.234.0",
}
],
)
@@ -80,7 +80,7 @@ def test_streaming_response_create(self, client: Cloudflare) -> None:
version_config=[
{
"target_environment": "windows",
- "version": "2026.5.234.0",
+ "version": "2026.6.234.0",
}
],
) as response:
@@ -102,7 +102,7 @@ def test_path_params_create(self, client: Cloudflare) -> None:
version_config=[
{
"target_environment": "windows",
- "version": "2026.5.234.0",
+ "version": "2026.6.234.0",
}
],
)
@@ -231,7 +231,7 @@ def test_method_edit_with_all_params(self, client: Cloudflare) -> None:
version_config=[
{
"target_environment": "windows",
- "version": "2026.5.234.0",
+ "version": "2026.6.234.0",
}
],
)
@@ -347,7 +347,7 @@ async def test_method_create(self, async_client: AsyncCloudflare) -> None:
version_config=[
{
"target_environment": "windows",
- "version": "2026.5.234.0",
+ "version": "2026.6.234.0",
}
],
)
@@ -362,7 +362,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare
version_config=[
{
"target_environment": "windows",
- "version": "2026.5.234.0",
+ "version": "2026.6.234.0",
}
],
policy_ids=["string"],
@@ -378,7 +378,7 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None:
version_config=[
{
"target_environment": "windows",
- "version": "2026.5.234.0",
+ "version": "2026.6.234.0",
}
],
)
@@ -397,7 +397,7 @@ async def test_streaming_response_create(self, async_client: AsyncCloudflare) ->
version_config=[
{
"target_environment": "windows",
- "version": "2026.5.234.0",
+ "version": "2026.6.234.0",
}
],
) as response:
@@ -419,7 +419,7 @@ async def test_path_params_create(self, async_client: AsyncCloudflare) -> None:
version_config=[
{
"target_environment": "windows",
- "version": "2026.5.234.0",
+ "version": "2026.6.234.0",
}
],
)
@@ -548,7 +548,7 @@ async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare)
version_config=[
{
"target_environment": "windows",
- "version": "2026.5.234.0",
+ "version": "2026.6.234.0",
}
],
)
From f8e14b9b8ff1680b6f7bab894bfbd28e302786b1 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 16 Jun 2026 16:15:56 +0000
Subject: [PATCH 20/23] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index bdd3b2bd34f..e535a1177b8 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 2404
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-12062ca747c6e0de56212973f1428209cd185869f1312b19e57168fc5b1e9b40.yml
-openapi_spec_hash: 0c2df0b38c6ec58b4fae1e4cf1fe04e7
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-01af43038896f3ebdd07424a27f3f83dca96e5f1e36c05216fc0ab2071f65344.yml
+openapi_spec_hash: 21ff9ed0e9171694e7bd819a0418098d
config_hash: 2f529580a17438fc62cd0b47db41b6f1
From 25b2838e80939bbbd7b19272169d90d107c93940 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 16 Jun 2026 16:30:20 +0000
Subject: [PATCH 21/23] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index e535a1177b8..3e217ad4d8e 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 2404
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-01af43038896f3ebdd07424a27f3f83dca96e5f1e36c05216fc0ab2071f65344.yml
-openapi_spec_hash: 21ff9ed0e9171694e7bd819a0418098d
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-b0af4cb139f9df7339b8fb329dd6adddc6205c60257d25a13988e168af0ac607.yml
+openapi_spec_hash: 0cc3334f547b32a53fbfff7feedc3d3b
config_hash: 2f529580a17438fc62cd0b47db41b6f1
From 2b0e7388107c4110489484c2b38d4d9295b15af2 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 16 Jun 2026 19:38:51 +0000
Subject: [PATCH 22/23] chore(api): update composite API spec
---
.stats.yml | 4 ++--
.../resources/intel/domains/domains.py | 16 ++++++++++++++++
src/cloudflare/types/intel/domain_get_params.py | 9 +++++++++
tests/api_resources/intel/test_domains.py | 2 ++
4 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 3e217ad4d8e..ca71746c0ec 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 2404
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-b0af4cb139f9df7339b8fb329dd6adddc6205c60257d25a13988e168af0ac607.yml
-openapi_spec_hash: 0cc3334f547b32a53fbfff7feedc3d3b
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-874436f83bd9c383144c69da47c4b767bb9c6f4f2bb4945af58cf3b6015f0f62.yml
+openapi_spec_hash: beaf9a654991bf65d642e05c03460e4c
config_hash: 2f529580a17438fc62cd0b47db41b6f1
diff --git a/src/cloudflare/resources/intel/domains/domains.py b/src/cloudflare/resources/intel/domains/domains.py
index 3dd45d2fa47..801ff7cf6d3 100644
--- a/src/cloudflare/resources/intel/domains/domains.py
+++ b/src/cloudflare/resources/intel/domains/domains.py
@@ -62,6 +62,7 @@ def get(
account_id: str,
domain: str | Omit = omit,
skip_dns: bool | Omit = omit,
+ skip_ranking: 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,
@@ -77,6 +78,12 @@ def get(
skip_dns: Skip DNS resolution lookups for faster response.
+ skip_ranking: Skip the domain ranking lookup for faster responses. Defaults to `false`
+ (ranking is included). Set to `true` to opt out — primarily used by callers like
+ Cloudflare Radar that need to avoid a circular dependency when building the
+ domain details page. Note: the bulk endpoint (`/intel/domain/bulk`) uses
+ opposite defaults — see `include_ranking` there.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -98,6 +105,7 @@ def get(
{
"domain": domain,
"skip_dns": skip_dns,
+ "skip_ranking": skip_ranking,
},
domain_get_params.DomainGetParams,
),
@@ -137,6 +145,7 @@ async def get(
account_id: str,
domain: str | Omit = omit,
skip_dns: bool | Omit = omit,
+ skip_ranking: 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,
@@ -152,6 +161,12 @@ async def get(
skip_dns: Skip DNS resolution lookups for faster response.
+ skip_ranking: Skip the domain ranking lookup for faster responses. Defaults to `false`
+ (ranking is included). Set to `true` to opt out — primarily used by callers like
+ Cloudflare Radar that need to avoid a circular dependency when building the
+ domain details page. Note: the bulk endpoint (`/intel/domain/bulk`) uses
+ opposite defaults — see `include_ranking` there.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -173,6 +188,7 @@ async def get(
{
"domain": domain,
"skip_dns": skip_dns,
+ "skip_ranking": skip_ranking,
},
domain_get_params.DomainGetParams,
),
diff --git a/src/cloudflare/types/intel/domain_get_params.py b/src/cloudflare/types/intel/domain_get_params.py
index 42ba437d630..9fcd6a7493f 100644
--- a/src/cloudflare/types/intel/domain_get_params.py
+++ b/src/cloudflare/types/intel/domain_get_params.py
@@ -15,3 +15,12 @@ class DomainGetParams(TypedDict, total=False):
skip_dns: bool
"""Skip DNS resolution lookups for faster response."""
+
+ skip_ranking: bool
+ """Skip the domain ranking lookup for faster responses.
+
+ Defaults to `false` (ranking is included). Set to `true` to opt out — primarily
+ used by callers like Cloudflare Radar that need to avoid a circular dependency
+ when building the domain details page. Note: the bulk endpoint
+ (`/intel/domain/bulk`) uses opposite defaults — see `include_ranking` there.
+ """
diff --git a/tests/api_resources/intel/test_domains.py b/tests/api_resources/intel/test_domains.py
index ce9eeab3fa7..c70329d0ac6 100644
--- a/tests/api_resources/intel/test_domains.py
+++ b/tests/api_resources/intel/test_domains.py
@@ -30,6 +30,7 @@ def test_method_get_with_all_params(self, client: Cloudflare) -> None:
account_id="023e105f4ecef8ad9ca31a8372d0c353",
domain="domain",
skip_dns=True,
+ skip_ranking=True,
)
assert_matches_type(Optional[Domain], domain, path=["response"])
@@ -83,6 +84,7 @@ async def test_method_get_with_all_params(self, async_client: AsyncCloudflare) -
account_id="023e105f4ecef8ad9ca31a8372d0c353",
domain="domain",
skip_dns=True,
+ skip_ranking=True,
)
assert_matches_type(Optional[Domain], domain, path=["response"])
From 87ee8980fa8a1a2538159fca0f6cb77a6e4239dd Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 16 Jun 2026 20:40:24 +0000
Subject: [PATCH 23/23] release: 5.4.0
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 27 +++++++++++++++++++++++++++
pyproject.toml | 2 +-
src/cloudflare/_version.py | 2 +-
4 files changed, 30 insertions(+), 3 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 41010749b61..5f7bf2557f1 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "5.3.0"
+ ".": "5.4.0"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d206a406900..8dc3db92901 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,32 @@
# Changelog
+## 5.4.0 (2026-06-16)
+
+Full Changelog: [v5.3.0...v5.4.0](https://github.com/cloudflare/cloudflare-python/compare/v5.3.0...v5.4.0)
+
+### Features
+
+* feat(ai_gateway): add custom_providers resource ([b982ff3](https://github.com/cloudflare/cloudflare-python/commit/b982ff391eab267ef16c719d0fc798d970292ed2))
+* feat(api): map ipsec_tunnels/psk, sites/app_policies and cf1_sites for magic-on-ramps ([5d8e422](https://github.com/cloudflare/cloudflare-python/commit/5d8e422736d8e044d2c73065cbb8595573b2656d))
+* feat(ct_alerter): add CT alerting subscription endpoint mappings ([5bb529c](https://github.com/cloudflare/cloudflare-python/commit/5bb529c2eabe4ce0c23cddbf8073c6a025dc3024))
+* feat(tenants): add tenants resource SDK mapping [PT-2567] ([7677b4c](https://github.com/cloudflare/cloudflare-python/commit/7677b4c9566495b627b2cd90c9220268f9c6c46d))
+
+
+### Chores
+
+* **api:** update composite API spec ([2b0e738](https://github.com/cloudflare/cloudflare-python/commit/2b0e7388107c4110489484c2b38d4d9295b15af2))
+* **api:** update composite API spec ([c7202c9](https://github.com/cloudflare/cloudflare-python/commit/c7202c9f9215a179b17362439c59b2e99566ab40))
+* **api:** update composite API spec ([f94e4de](https://github.com/cloudflare/cloudflare-python/commit/f94e4de91421e736243f75eee987c888f06d8f0b))
+* **api:** update composite API spec ([656f973](https://github.com/cloudflare/cloudflare-python/commit/656f97390d51da3e224e67f2305d6d46f7ae239a))
+* **api:** update composite API spec ([05e802d](https://github.com/cloudflare/cloudflare-python/commit/05e802d1940e1b0bfe59a25c388b83f53edd238e))
+* **api:** update composite API spec ([3817b57](https://github.com/cloudflare/cloudflare-python/commit/3817b571d02b2d23f087bbdb574853632d0bc1db))
+* **api:** update composite API spec ([3e26c73](https://github.com/cloudflare/cloudflare-python/commit/3e26c739c29586ab33e05bb4dc6673d06748d013))
+* **api:** update composite API spec ([0ff89f9](https://github.com/cloudflare/cloudflare-python/commit/0ff89f99ddfbaf078d3b20eada5fd2bc4139fc65))
+* **api:** update composite API spec ([eeec39a](https://github.com/cloudflare/cloudflare-python/commit/eeec39a7ab478625ead7a1e6276c1c258ff574fd))
+* **api:** update composite API spec ([45260b9](https://github.com/cloudflare/cloudflare-python/commit/45260b91f48ed30eb69f1ecd184f245b03a59146))
+* **api:** update composite API spec ([72eb205](https://github.com/cloudflare/cloudflare-python/commit/72eb20551c18d2cae3dfbef960a12ff22b4a7de7))
+* **internal:** codegen related update ([86bdf98](https://github.com/cloudflare/cloudflare-python/commit/86bdf981e37d4b028f4e555d7e0b1e76324f23b3))
+
## 5.3.0 (2026-06-11)
Full Changelog: [v5.2.0...v5.3.0](https://github.com/cloudflare/cloudflare-python/compare/v5.2.0...v5.3.0)
diff --git a/pyproject.toml b/pyproject.toml
index ac02434250f..3b9bdb0a125 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "cloudflare"
-version = "5.3.0"
+version = "5.4.0"
description = "The official Python library for the cloudflare API"
dynamic = ["readme"]
license = "Apache-2.0"
diff --git a/src/cloudflare/_version.py b/src/cloudflare/_version.py
index 067c66a7bb6..a30ce34d23f 100644
--- a/src/cloudflare/_version.py
+++ b/src/cloudflare/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "cloudflare"
-__version__ = "5.3.0" # x-release-please-version
+__version__ = "5.4.0" # x-release-please-version