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 1/3] 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 2/3] 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 9bc715e49a4f6ab349e54523076f9c64e761e1a5 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 3/3] chore(api): update composite API spec --- .../resources/workflows/instances/events.py | 8 +++++ .../workflows/instances/instances.py | 16 ++++++++++ .../resources/workflows/instances/status.py | 32 +++++++++++++++++++ .../instances/event_create_params.py | 6 ++++ 4 files changed, 62 insertions(+) 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