diff --git a/.stats.yml b/.stats.yml
index 5239ee338ae..fdb7a7ae9c2 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,2 +1,2 @@
-configured_endpoints: 1467
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare%2Fcloudflare-ace2cb0a08aa00d1675be9b68d04f10c86943a39c5a405f740863e4da89b3057.yml
+configured_endpoints: 1480
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare%2Fcloudflare-a2d9b92dd116fb25fdcd7969ee039a099a9cea04182925b450f5dd5e3b4dedfb.yml
diff --git a/api.md b/api.md
index 0f0865fcd33..285a79e16fe 100644
--- a/api.md
+++ b/api.md
@@ -123,6 +123,20 @@ Methods:
- client.accounts.tokens.value.update(token_id, \*, account_id, \*\*params) -> str
+## Logs
+
+### Audit
+
+Types:
+
+```python
+from cloudflare.types.accounts.logs import AuditListResponse
+```
+
+Methods:
+
+- client.accounts.logs.audit.list(\*, account_id, \*\*params) -> SyncCursorLimitPagination[AuditListResponse]
+
# OriginCACertificates
Types:
@@ -3256,6 +3270,7 @@ from cloudflare.types.addressing.prefixes.bgp import BGPPrefix
Methods:
+- client.addressing.prefixes.bgp.prefixes.create(prefix_id, \*, account_id, \*\*params) -> Optional[BGPPrefix]
- client.addressing.prefixes.bgp.prefixes.list(prefix_id, \*, account_id) -> SyncSinglePage[BGPPrefix]
- client.addressing.prefixes.bgp.prefixes.edit(bgp_prefix_id, \*, account_id, prefix_id, \*\*params) -> Optional[BGPPrefix]
- client.addressing.prefixes.bgp.prefixes.get(bgp_prefix_id, \*, account_id, prefix_id) -> Optional[BGPPrefix]
@@ -5201,6 +5216,24 @@ from cloudflare.types.zero_trust import (
)
```
+### GatewayCA
+
+Types:
+
+```python
+from cloudflare.types.zero_trust.access import (
+ GatewayCACreateResponse,
+ GatewayCAListResponse,
+ GatewayCADeleteResponse,
+)
+```
+
+Methods:
+
+- client.zero_trust.access.gateway_ca.create(\*, account_id) -> Optional[GatewayCACreateResponse]
+- client.zero_trust.access.gateway_ca.list(\*, account_id) -> SyncSinglePage[GatewayCAListResponse]
+- client.zero_trust.access.gateway_ca.delete(certificate_id, \*, account_id) -> Optional[GatewayCADeleteResponse]
+
### Infrastructure
#### Targets
@@ -5938,6 +5971,48 @@ Methods:
- client.zero_trust.dlp.payload_logs.update(\*, account_id, \*\*params) -> Optional[PayloadLogUpdateResponse]
- client.zero_trust.dlp.payload_logs.get(\*, account_id) -> Optional[PayloadLogGetResponse]
+### Email
+
+#### AccountMapping
+
+Types:
+
+```python
+from cloudflare.types.zero_trust.dlp.email import (
+ AccountMappingCreateResponse,
+ AccountMappingGetResponse,
+)
+```
+
+Methods:
+
+- client.zero_trust.dlp.email.account_mapping.create(\*, account_id, \*\*params) -> Optional[AccountMappingCreateResponse]
+- client.zero_trust.dlp.email.account_mapping.get(\*, account_id) -> Optional[AccountMappingGetResponse]
+
+#### Rules
+
+Types:
+
+```python
+from cloudflare.types.zero_trust.dlp.email import (
+ RuleCreateResponse,
+ RuleUpdateResponse,
+ RuleListResponse,
+ RuleDeleteResponse,
+ RuleBulkEditResponse,
+ RuleGetResponse,
+)
+```
+
+Methods:
+
+- client.zero_trust.dlp.email.rules.create(\*, account_id, \*\*params) -> Optional[RuleCreateResponse]
+- client.zero_trust.dlp.email.rules.update(rule_id, \*, account_id, \*\*params) -> Optional[RuleUpdateResponse]
+- client.zero_trust.dlp.email.rules.list(\*, account_id) -> SyncSinglePage[RuleListResponse]
+- client.zero_trust.dlp.email.rules.delete(rule_id, \*, account_id) -> Optional[RuleDeleteResponse]
+- client.zero_trust.dlp.email.rules.bulk_edit(\*, account_id, \*\*params) -> Optional[RuleBulkEditResponse]
+- client.zero_trust.dlp.email.rules.get(rule_id, \*, account_id) -> Optional[RuleGetResponse]
+
### Profiles
Types:
diff --git a/src/cloudflare/resources/accounts/__init__.py b/src/cloudflare/resources/accounts/__init__.py
index f91d884a2b2..f136ec47000 100644
--- a/src/cloudflare/resources/accounts/__init__.py
+++ b/src/cloudflare/resources/accounts/__init__.py
@@ -1,5 +1,13 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+from .logs import (
+ LogsResource,
+ AsyncLogsResource,
+ LogsResourceWithRawResponse,
+ AsyncLogsResourceWithRawResponse,
+ LogsResourceWithStreamingResponse,
+ AsyncLogsResourceWithStreamingResponse,
+)
from .roles import (
RolesResource,
AsyncRolesResource,
@@ -66,6 +74,12 @@
"AsyncTokensResourceWithRawResponse",
"TokensResourceWithStreamingResponse",
"AsyncTokensResourceWithStreamingResponse",
+ "LogsResource",
+ "AsyncLogsResource",
+ "LogsResourceWithRawResponse",
+ "AsyncLogsResourceWithRawResponse",
+ "LogsResourceWithStreamingResponse",
+ "AsyncLogsResourceWithStreamingResponse",
"AccountsResource",
"AsyncAccountsResource",
"AccountsResourceWithRawResponse",
diff --git a/src/cloudflare/resources/accounts/accounts.py b/src/cloudflare/resources/accounts/accounts.py
index e6e9d0721a4..eba792cbcc5 100644
--- a/src/cloudflare/resources/accounts/accounts.py
+++ b/src/cloudflare/resources/accounts/accounts.py
@@ -29,6 +29,14 @@
async_maybe_transform,
)
from ..._compat import cached_property
+from .logs.logs import (
+ LogsResource,
+ AsyncLogsResource,
+ LogsResourceWithRawResponse,
+ AsyncLogsResourceWithRawResponse,
+ LogsResourceWithStreamingResponse,
+ AsyncLogsResourceWithStreamingResponse,
+)
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import (
to_raw_response_wrapper,
@@ -79,6 +87,10 @@ def subscriptions(self) -> SubscriptionsResource:
def tokens(self) -> TokensResource:
return TokensResource(self._client)
+ @cached_property
+ def logs(self) -> LogsResource:
+ return LogsResource(self._client)
+
@cached_property
def with_raw_response(self) -> AccountsResourceWithRawResponse:
"""
@@ -358,6 +370,10 @@ def subscriptions(self) -> AsyncSubscriptionsResource:
def tokens(self) -> AsyncTokensResource:
return AsyncTokensResource(self._client)
+ @cached_property
+ def logs(self) -> AsyncLogsResource:
+ return AsyncLogsResource(self._client)
+
@cached_property
def with_raw_response(self) -> AsyncAccountsResourceWithRawResponse:
"""
@@ -656,6 +672,10 @@ def subscriptions(self) -> SubscriptionsResourceWithRawResponse:
def tokens(self) -> TokensResourceWithRawResponse:
return TokensResourceWithRawResponse(self._accounts.tokens)
+ @cached_property
+ def logs(self) -> LogsResourceWithRawResponse:
+ return LogsResourceWithRawResponse(self._accounts.logs)
+
class AsyncAccountsResourceWithRawResponse:
def __init__(self, accounts: AsyncAccountsResource) -> None:
@@ -693,6 +713,10 @@ def subscriptions(self) -> AsyncSubscriptionsResourceWithRawResponse:
def tokens(self) -> AsyncTokensResourceWithRawResponse:
return AsyncTokensResourceWithRawResponse(self._accounts.tokens)
+ @cached_property
+ def logs(self) -> AsyncLogsResourceWithRawResponse:
+ return AsyncLogsResourceWithRawResponse(self._accounts.logs)
+
class AccountsResourceWithStreamingResponse:
def __init__(self, accounts: AccountsResource) -> None:
@@ -730,6 +754,10 @@ def subscriptions(self) -> SubscriptionsResourceWithStreamingResponse:
def tokens(self) -> TokensResourceWithStreamingResponse:
return TokensResourceWithStreamingResponse(self._accounts.tokens)
+ @cached_property
+ def logs(self) -> LogsResourceWithStreamingResponse:
+ return LogsResourceWithStreamingResponse(self._accounts.logs)
+
class AsyncAccountsResourceWithStreamingResponse:
def __init__(self, accounts: AsyncAccountsResource) -> None:
@@ -766,3 +794,7 @@ def subscriptions(self) -> AsyncSubscriptionsResourceWithStreamingResponse:
@cached_property
def tokens(self) -> AsyncTokensResourceWithStreamingResponse:
return AsyncTokensResourceWithStreamingResponse(self._accounts.tokens)
+
+ @cached_property
+ def logs(self) -> AsyncLogsResourceWithStreamingResponse:
+ return AsyncLogsResourceWithStreamingResponse(self._accounts.logs)
diff --git a/src/cloudflare/resources/accounts/logs/__init__.py b/src/cloudflare/resources/accounts/logs/__init__.py
new file mode 100644
index 00000000000..5d5ddcdb7e2
--- /dev/null
+++ b/src/cloudflare/resources/accounts/logs/__init__.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .logs import (
+ LogsResource,
+ AsyncLogsResource,
+ LogsResourceWithRawResponse,
+ AsyncLogsResourceWithRawResponse,
+ LogsResourceWithStreamingResponse,
+ AsyncLogsResourceWithStreamingResponse,
+)
+from .audit import (
+ AuditResource,
+ AsyncAuditResource,
+ AuditResourceWithRawResponse,
+ AsyncAuditResourceWithRawResponse,
+ AuditResourceWithStreamingResponse,
+ AsyncAuditResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "AuditResource",
+ "AsyncAuditResource",
+ "AuditResourceWithRawResponse",
+ "AsyncAuditResourceWithRawResponse",
+ "AuditResourceWithStreamingResponse",
+ "AsyncAuditResourceWithStreamingResponse",
+ "LogsResource",
+ "AsyncLogsResource",
+ "LogsResourceWithRawResponse",
+ "AsyncLogsResourceWithRawResponse",
+ "LogsResourceWithStreamingResponse",
+ "AsyncLogsResourceWithStreamingResponse",
+]
diff --git a/src/cloudflare/resources/accounts/logs/audit.py b/src/cloudflare/resources/accounts/logs/audit.py
new file mode 100644
index 00000000000..08893ade2e6
--- /dev/null
+++ b/src/cloudflare/resources/accounts/logs/audit.py
@@ -0,0 +1,426 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union
+from datetime import date, datetime
+from typing_extensions import Literal
+
+import httpx
+
+from ...._types import NOT_GIVEN, Body, Query, Headers, NotGiven
+from ...._utils import 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 SyncCursorLimitPagination, AsyncCursorLimitPagination
+from ...._base_client import AsyncPaginator, make_request_options
+from ....types.accounts.logs import audit_list_params
+from ....types.accounts.logs.audit_list_response import AuditListResponse
+
+__all__ = ["AuditResource", "AsyncAuditResource"]
+
+
+class AuditResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AuditResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return the
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return AuditResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AuditResourceWithStreamingResponse:
+ """
+ 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 AuditResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ *,
+ account_id: str,
+ before: Union[Union[str, date], Union[str, datetime]],
+ since: Union[Union[str, date], Union[str, datetime]],
+ account_name: str | NotGiven = NOT_GIVEN,
+ action_result: Literal["success", "failure"] | NotGiven = NOT_GIVEN,
+ action_type: Literal["create", "delete", "view", "update"] | NotGiven = NOT_GIVEN,
+ actor_context: Literal["api_key", "api_token", "dash", "oauth", "origin_ca_key"] | NotGiven = NOT_GIVEN,
+ actor_email: str | NotGiven = NOT_GIVEN,
+ actor_id: str | NotGiven = NOT_GIVEN,
+ actor_ip_address: str | NotGiven = NOT_GIVEN,
+ actor_token_id: str | NotGiven = NOT_GIVEN,
+ actor_token_name: str | NotGiven = NOT_GIVEN,
+ actor_type: Literal["cloudflare_admin", "account", "user"] | NotGiven = NOT_GIVEN,
+ audit_log_id: str | NotGiven = NOT_GIVEN,
+ cursor: str | NotGiven = NOT_GIVEN,
+ direction: Literal["desc", "asc"] | NotGiven = NOT_GIVEN,
+ limit: float | NotGiven = NOT_GIVEN,
+ raw_cf_rayid: str | NotGiven = NOT_GIVEN,
+ raw_method: str | NotGiven = NOT_GIVEN,
+ raw_status_code: int | NotGiven = NOT_GIVEN,
+ raw_uri: str | NotGiven = NOT_GIVEN,
+ resource_id: str | NotGiven = NOT_GIVEN,
+ resource_product: str | NotGiven = NOT_GIVEN,
+ resource_scope: Literal["accounts", "user", "zones"] | NotGiven = NOT_GIVEN,
+ resource_type: str | NotGiven = NOT_GIVEN,
+ zone_id: str | NotGiven = NOT_GIVEN,
+ zone_name: str | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
+ ) -> SyncCursorLimitPagination[AuditListResponse]:
+ """Gets a list of audit logs for an account.
+
+
This is the beta release
+ of Audit Logs Version 2. Since this is a beta version, there may be gaps or
+ missing entries in the available audit logs. Be aware of the following
+ limitations.
- Audit logs are available only for the past 30 days.
+
- Error handling is not yet implemented.
+
+ Args:
+ account_id: The unique id that identifies the account.
+
+ before: Filters actions based on a given timestamp, returning only logs that occurred
+ before the specified date.
+
+ since: Filters actions based on a given timestamp, returning only logs that occurred
+ after the specified date.
+
+ account_name: Filters by the account name.
+
+ action_result: Whether the action was successful or not.
+
+ action_type: Filters by the action type.
+
+ actor_context: Filters by the actor context.
+
+ actor_email: Filters by the actor's email address.
+
+ actor_id: Filters by the actor ID. This can be either the Account ID or User ID.
+
+ actor_ip_address: The IP address where the action was initiated.
+
+ actor_token_id: Filters by the API token ID when the actor context is an api_token or oauth.
+
+ actor_token_name: Filters by the API token name when the actor context is an api_token or oauth.
+
+ actor_type: Filters by the actor type.
+
+ audit_log_id: Finds a specific log by its ID.
+
+ cursor: The cursor is an opaque token used to paginate through large sets of records. It
+ indicates the position from which to continue when requesting the next set of
+ records. A valid cursor value can be obtained from the cursor object in the
+ result_info structure of a previous response.
+
+ direction: Sets sorting order.
+
+ limit: The number limits the objects to return. The cursor attribute may be used to
+ iterate over the next batch of objects if there are more than the limit.
+
+ raw_cf_rayid: Filters by the response CF Ray ID.
+
+ raw_method: The HTTP method for the API call.
+
+ raw_status_code: The response status code that was returned.
+
+ raw_uri: Filters by the request URI.
+
+ resource_id: Filters by the resource ID.
+
+ resource_product: Filters audit logs by the Cloudflare product associated with the changed
+ resource.
+
+ resource_scope: Filters by the resource scope, specifying whether the resource is associated
+ with an user, an account, or a zone.
+
+ resource_type: Filters audit logs based on the unique type of resource changed by the action.
+
+ zone_id: Filters by the zone ID.
+
+ zone_name: Filters by the zone name associated with the change.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the 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(
+ f"/accounts/{account_id}/logs/audit",
+ page=SyncCursorLimitPagination[AuditListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "before": before,
+ "since": since,
+ "account_name": account_name,
+ "action_result": action_result,
+ "action_type": action_type,
+ "actor_context": actor_context,
+ "actor_email": actor_email,
+ "actor_id": actor_id,
+ "actor_ip_address": actor_ip_address,
+ "actor_token_id": actor_token_id,
+ "actor_token_name": actor_token_name,
+ "actor_type": actor_type,
+ "audit_log_id": audit_log_id,
+ "cursor": cursor,
+ "direction": direction,
+ "limit": limit,
+ "raw_cf_rayid": raw_cf_rayid,
+ "raw_method": raw_method,
+ "raw_status_code": raw_status_code,
+ "raw_uri": raw_uri,
+ "resource_id": resource_id,
+ "resource_product": resource_product,
+ "resource_scope": resource_scope,
+ "resource_type": resource_type,
+ "zone_id": zone_id,
+ "zone_name": zone_name,
+ },
+ audit_list_params.AuditListParams,
+ ),
+ ),
+ model=AuditListResponse,
+ )
+
+
+class AsyncAuditResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncAuditResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return the
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncAuditResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncAuditResourceWithStreamingResponse:
+ """
+ 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 AsyncAuditResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ *,
+ account_id: str,
+ before: Union[Union[str, date], Union[str, datetime]],
+ since: Union[Union[str, date], Union[str, datetime]],
+ account_name: str | NotGiven = NOT_GIVEN,
+ action_result: Literal["success", "failure"] | NotGiven = NOT_GIVEN,
+ action_type: Literal["create", "delete", "view", "update"] | NotGiven = NOT_GIVEN,
+ actor_context: Literal["api_key", "api_token", "dash", "oauth", "origin_ca_key"] | NotGiven = NOT_GIVEN,
+ actor_email: str | NotGiven = NOT_GIVEN,
+ actor_id: str | NotGiven = NOT_GIVEN,
+ actor_ip_address: str | NotGiven = NOT_GIVEN,
+ actor_token_id: str | NotGiven = NOT_GIVEN,
+ actor_token_name: str | NotGiven = NOT_GIVEN,
+ actor_type: Literal["cloudflare_admin", "account", "user"] | NotGiven = NOT_GIVEN,
+ audit_log_id: str | NotGiven = NOT_GIVEN,
+ cursor: str | NotGiven = NOT_GIVEN,
+ direction: Literal["desc", "asc"] | NotGiven = NOT_GIVEN,
+ limit: float | NotGiven = NOT_GIVEN,
+ raw_cf_rayid: str | NotGiven = NOT_GIVEN,
+ raw_method: str | NotGiven = NOT_GIVEN,
+ raw_status_code: int | NotGiven = NOT_GIVEN,
+ raw_uri: str | NotGiven = NOT_GIVEN,
+ resource_id: str | NotGiven = NOT_GIVEN,
+ resource_product: str | NotGiven = NOT_GIVEN,
+ resource_scope: Literal["accounts", "user", "zones"] | NotGiven = NOT_GIVEN,
+ resource_type: str | NotGiven = NOT_GIVEN,
+ zone_id: str | NotGiven = NOT_GIVEN,
+ zone_name: str | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this 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[AuditListResponse, AsyncCursorLimitPagination[AuditListResponse]]:
+ """Gets a list of audit logs for an account.
+
+
This is the beta release
+ of Audit Logs Version 2. Since this is a beta version, there may be gaps or
+ missing entries in the available audit logs. Be aware of the following
+ limitations.
- Audit logs are available only for the past 30 days.
+
- Error handling is not yet implemented.
+
+ Args:
+ account_id: The unique id that identifies the account.
+
+ before: Filters actions based on a given timestamp, returning only logs that occurred
+ before the specified date.
+
+ since: Filters actions based on a given timestamp, returning only logs that occurred
+ after the specified date.
+
+ account_name: Filters by the account name.
+
+ action_result: Whether the action was successful or not.
+
+ action_type: Filters by the action type.
+
+ actor_context: Filters by the actor context.
+
+ actor_email: Filters by the actor's email address.
+
+ actor_id: Filters by the actor ID. This can be either the Account ID or User ID.
+
+ actor_ip_address: The IP address where the action was initiated.
+
+ actor_token_id: Filters by the API token ID when the actor context is an api_token or oauth.
+
+ actor_token_name: Filters by the API token name when the actor context is an api_token or oauth.
+
+ actor_type: Filters by the actor type.
+
+ audit_log_id: Finds a specific log by its ID.
+
+ cursor: The cursor is an opaque token used to paginate through large sets of records. It
+ indicates the position from which to continue when requesting the next set of
+ records. A valid cursor value can be obtained from the cursor object in the
+ result_info structure of a previous response.
+
+ direction: Sets sorting order.
+
+ limit: The number limits the objects to return. The cursor attribute may be used to
+ iterate over the next batch of objects if there are more than the limit.
+
+ raw_cf_rayid: Filters by the response CF Ray ID.
+
+ raw_method: The HTTP method for the API call.
+
+ raw_status_code: The response status code that was returned.
+
+ raw_uri: Filters by the request URI.
+
+ resource_id: Filters by the resource ID.
+
+ resource_product: Filters audit logs by the Cloudflare product associated with the changed
+ resource.
+
+ resource_scope: Filters by the resource scope, specifying whether the resource is associated
+ with an user, an account, or a zone.
+
+ resource_type: Filters audit logs based on the unique type of resource changed by the action.
+
+ zone_id: Filters by the zone ID.
+
+ zone_name: Filters by the zone name associated with the change.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the 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(
+ f"/accounts/{account_id}/logs/audit",
+ page=AsyncCursorLimitPagination[AuditListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "before": before,
+ "since": since,
+ "account_name": account_name,
+ "action_result": action_result,
+ "action_type": action_type,
+ "actor_context": actor_context,
+ "actor_email": actor_email,
+ "actor_id": actor_id,
+ "actor_ip_address": actor_ip_address,
+ "actor_token_id": actor_token_id,
+ "actor_token_name": actor_token_name,
+ "actor_type": actor_type,
+ "audit_log_id": audit_log_id,
+ "cursor": cursor,
+ "direction": direction,
+ "limit": limit,
+ "raw_cf_rayid": raw_cf_rayid,
+ "raw_method": raw_method,
+ "raw_status_code": raw_status_code,
+ "raw_uri": raw_uri,
+ "resource_id": resource_id,
+ "resource_product": resource_product,
+ "resource_scope": resource_scope,
+ "resource_type": resource_type,
+ "zone_id": zone_id,
+ "zone_name": zone_name,
+ },
+ audit_list_params.AuditListParams,
+ ),
+ ),
+ model=AuditListResponse,
+ )
+
+
+class AuditResourceWithRawResponse:
+ def __init__(self, audit: AuditResource) -> None:
+ self._audit = audit
+
+ self.list = to_raw_response_wrapper(
+ audit.list,
+ )
+
+
+class AsyncAuditResourceWithRawResponse:
+ def __init__(self, audit: AsyncAuditResource) -> None:
+ self._audit = audit
+
+ self.list = async_to_raw_response_wrapper(
+ audit.list,
+ )
+
+
+class AuditResourceWithStreamingResponse:
+ def __init__(self, audit: AuditResource) -> None:
+ self._audit = audit
+
+ self.list = to_streamed_response_wrapper(
+ audit.list,
+ )
+
+
+class AsyncAuditResourceWithStreamingResponse:
+ def __init__(self, audit: AsyncAuditResource) -> None:
+ self._audit = audit
+
+ self.list = async_to_streamed_response_wrapper(
+ audit.list,
+ )
diff --git a/src/cloudflare/resources/accounts/logs/logs.py b/src/cloudflare/resources/accounts/logs/logs.py
new file mode 100644
index 00000000000..475921543aa
--- /dev/null
+++ b/src/cloudflare/resources/accounts/logs/logs.py
@@ -0,0 +1,102 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .audit import (
+ AuditResource,
+ AsyncAuditResource,
+ AuditResourceWithRawResponse,
+ AsyncAuditResourceWithRawResponse,
+ AuditResourceWithStreamingResponse,
+ AsyncAuditResourceWithStreamingResponse,
+)
+from ...._compat import cached_property
+from ...._resource import SyncAPIResource, AsyncAPIResource
+
+__all__ = ["LogsResource", "AsyncLogsResource"]
+
+
+class LogsResource(SyncAPIResource):
+ @cached_property
+ def audit(self) -> AuditResource:
+ return AuditResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> LogsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return the
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return LogsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> LogsResourceWithStreamingResponse:
+ """
+ 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 LogsResourceWithStreamingResponse(self)
+
+
+class AsyncLogsResource(AsyncAPIResource):
+ @cached_property
+ def audit(self) -> AsyncAuditResource:
+ return AsyncAuditResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncLogsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return the
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncLogsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncLogsResourceWithStreamingResponse:
+ """
+ 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 AsyncLogsResourceWithStreamingResponse(self)
+
+
+class LogsResourceWithRawResponse:
+ def __init__(self, logs: LogsResource) -> None:
+ self._logs = logs
+
+ @cached_property
+ def audit(self) -> AuditResourceWithRawResponse:
+ return AuditResourceWithRawResponse(self._logs.audit)
+
+
+class AsyncLogsResourceWithRawResponse:
+ def __init__(self, logs: AsyncLogsResource) -> None:
+ self._logs = logs
+
+ @cached_property
+ def audit(self) -> AsyncAuditResourceWithRawResponse:
+ return AsyncAuditResourceWithRawResponse(self._logs.audit)
+
+
+class LogsResourceWithStreamingResponse:
+ def __init__(self, logs: LogsResource) -> None:
+ self._logs = logs
+
+ @cached_property
+ def audit(self) -> AuditResourceWithStreamingResponse:
+ return AuditResourceWithStreamingResponse(self._logs.audit)
+
+
+class AsyncLogsResourceWithStreamingResponse:
+ def __init__(self, logs: AsyncLogsResource) -> None:
+ self._logs = logs
+
+ @cached_property
+ def audit(self) -> AsyncAuditResourceWithStreamingResponse:
+ return AsyncAuditResourceWithStreamingResponse(self._logs.audit)
diff --git a/src/cloudflare/resources/addressing/prefixes/bgp/prefixes.py b/src/cloudflare/resources/addressing/prefixes/bgp/prefixes.py
index c99139e7d70..ce8640e9b41 100644
--- a/src/cloudflare/resources/addressing/prefixes/bgp/prefixes.py
+++ b/src/cloudflare/resources/addressing/prefixes/bgp/prefixes.py
@@ -22,7 +22,7 @@
from ....._wrappers import ResultWrapper
from .....pagination import SyncSinglePage, AsyncSinglePage
from ....._base_client import AsyncPaginator, make_request_options
-from .....types.addressing.prefixes.bgp import prefix_edit_params
+from .....types.addressing.prefixes.bgp import prefix_edit_params, prefix_create_params
from .....types.addressing.prefixes.bgp.bgp_prefix import BGPPrefix
__all__ = ["PrefixesResource", "AsyncPrefixesResource"]
@@ -48,6 +48,56 @@ def with_streaming_response(self) -> PrefixesResourceWithStreamingResponse:
"""
return PrefixesResourceWithStreamingResponse(self)
+ def create(
+ self,
+ prefix_id: str,
+ *,
+ account_id: str,
+ cidr: str | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this 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[BGPPrefix]:
+ """
+ Create a BGP prefix, controlling the BGP advertisement status of a specific
+ subnet. When created, BGP prefixes are initially withdrawn, and can be
+ advertised with the Update BGP Prefix API.
+
+ Args:
+ account_id: Identifier
+
+ prefix_id: Identifier
+
+ cidr: IP Prefix in Classless Inter-Domain Routing format.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the 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 prefix_id:
+ raise ValueError(f"Expected a non-empty value for `prefix_id` but received {prefix_id!r}")
+ return self._post(
+ f"/accounts/{account_id}/addressing/prefixes/{prefix_id}/bgp/prefixes",
+ body=maybe_transform({"cidr": cidr}, prefix_create_params.PrefixCreateParams),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[BGPPrefix]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[BGPPrefix]], ResultWrapper[BGPPrefix]),
+ )
+
def list(
self,
prefix_id: str,
@@ -215,6 +265,56 @@ def with_streaming_response(self) -> AsyncPrefixesResourceWithStreamingResponse:
"""
return AsyncPrefixesResourceWithStreamingResponse(self)
+ async def create(
+ self,
+ prefix_id: str,
+ *,
+ account_id: str,
+ cidr: str | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this 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[BGPPrefix]:
+ """
+ Create a BGP prefix, controlling the BGP advertisement status of a specific
+ subnet. When created, BGP prefixes are initially withdrawn, and can be
+ advertised with the Update BGP Prefix API.
+
+ Args:
+ account_id: Identifier
+
+ prefix_id: Identifier
+
+ cidr: IP Prefix in Classless Inter-Domain Routing format.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the 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 prefix_id:
+ raise ValueError(f"Expected a non-empty value for `prefix_id` but received {prefix_id!r}")
+ return await self._post(
+ f"/accounts/{account_id}/addressing/prefixes/{prefix_id}/bgp/prefixes",
+ body=await async_maybe_transform({"cidr": cidr}, prefix_create_params.PrefixCreateParams),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[BGPPrefix]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[BGPPrefix]], ResultWrapper[BGPPrefix]),
+ )
+
def list(
self,
prefix_id: str,
@@ -366,6 +466,9 @@ class PrefixesResourceWithRawResponse:
def __init__(self, prefixes: PrefixesResource) -> None:
self._prefixes = prefixes
+ self.create = to_raw_response_wrapper(
+ prefixes.create,
+ )
self.list = to_raw_response_wrapper(
prefixes.list,
)
@@ -381,6 +484,9 @@ class AsyncPrefixesResourceWithRawResponse:
def __init__(self, prefixes: AsyncPrefixesResource) -> None:
self._prefixes = prefixes
+ self.create = async_to_raw_response_wrapper(
+ prefixes.create,
+ )
self.list = async_to_raw_response_wrapper(
prefixes.list,
)
@@ -396,6 +502,9 @@ class PrefixesResourceWithStreamingResponse:
def __init__(self, prefixes: PrefixesResource) -> None:
self._prefixes = prefixes
+ self.create = to_streamed_response_wrapper(
+ prefixes.create,
+ )
self.list = to_streamed_response_wrapper(
prefixes.list,
)
@@ -411,6 +520,9 @@ class AsyncPrefixesResourceWithStreamingResponse:
def __init__(self, prefixes: AsyncPrefixesResource) -> None:
self._prefixes = prefixes
+ self.create = async_to_streamed_response_wrapper(
+ prefixes.create,
+ )
self.list = async_to_streamed_response_wrapper(
prefixes.list,
)
diff --git a/src/cloudflare/resources/zero_trust/access/__init__.py b/src/cloudflare/resources/zero_trust/access/__init__.py
index d368bdfbfc8..12bf11047ec 100644
--- a/src/cloudflare/resources/zero_trust/access/__init__.py
+++ b/src/cloudflare/resources/zero_trust/access/__init__.py
@@ -64,6 +64,14 @@
BookmarksResourceWithStreamingResponse,
AsyncBookmarksResourceWithStreamingResponse,
)
+from .gateway_ca import (
+ GatewayCAResource,
+ AsyncGatewayCAResource,
+ GatewayCAResourceWithRawResponse,
+ AsyncGatewayCAResourceWithRawResponse,
+ GatewayCAResourceWithStreamingResponse,
+ AsyncGatewayCAResourceWithStreamingResponse,
+)
from .applications import (
ApplicationsResource,
AsyncApplicationsResource,
@@ -106,6 +114,12 @@
)
__all__ = [
+ "GatewayCAResource",
+ "AsyncGatewayCAResource",
+ "GatewayCAResourceWithRawResponse",
+ "AsyncGatewayCAResourceWithRawResponse",
+ "GatewayCAResourceWithStreamingResponse",
+ "AsyncGatewayCAResourceWithStreamingResponse",
"InfrastructureResource",
"AsyncInfrastructureResource",
"InfrastructureResourceWithRawResponse",
diff --git a/src/cloudflare/resources/zero_trust/access/access.py b/src/cloudflare/resources/zero_trust/access/access.py
index c76631f16f5..d6aef830815 100644
--- a/src/cloudflare/resources/zero_trust/access/access.py
+++ b/src/cloudflare/resources/zero_trust/access/access.py
@@ -51,6 +51,14 @@
AsyncLogsResourceWithStreamingResponse,
)
from ...._compat import cached_property
+from .gateway_ca import (
+ GatewayCAResource,
+ AsyncGatewayCAResource,
+ GatewayCAResourceWithRawResponse,
+ AsyncGatewayCAResourceWithRawResponse,
+ GatewayCAResourceWithStreamingResponse,
+ AsyncGatewayCAResourceWithStreamingResponse,
+)
from .users.users import (
UsersResource,
AsyncUsersResource,
@@ -105,6 +113,10 @@
class AccessResource(SyncAPIResource):
+ @cached_property
+ def gateway_ca(self) -> GatewayCAResource:
+ return GatewayCAResource(self._client)
+
@cached_property
def infrastructure(self) -> InfrastructureResource:
return InfrastructureResource(self._client)
@@ -174,6 +186,10 @@ def with_streaming_response(self) -> AccessResourceWithStreamingResponse:
class AsyncAccessResource(AsyncAPIResource):
+ @cached_property
+ def gateway_ca(self) -> AsyncGatewayCAResource:
+ return AsyncGatewayCAResource(self._client)
+
@cached_property
def infrastructure(self) -> AsyncInfrastructureResource:
return AsyncInfrastructureResource(self._client)
@@ -246,6 +262,10 @@ class AccessResourceWithRawResponse:
def __init__(self, access: AccessResource) -> None:
self._access = access
+ @cached_property
+ def gateway_ca(self) -> GatewayCAResourceWithRawResponse:
+ return GatewayCAResourceWithRawResponse(self._access.gateway_ca)
+
@cached_property
def infrastructure(self) -> InfrastructureResourceWithRawResponse:
return InfrastructureResourceWithRawResponse(self._access.infrastructure)
@@ -299,6 +319,10 @@ class AsyncAccessResourceWithRawResponse:
def __init__(self, access: AsyncAccessResource) -> None:
self._access = access
+ @cached_property
+ def gateway_ca(self) -> AsyncGatewayCAResourceWithRawResponse:
+ return AsyncGatewayCAResourceWithRawResponse(self._access.gateway_ca)
+
@cached_property
def infrastructure(self) -> AsyncInfrastructureResourceWithRawResponse:
return AsyncInfrastructureResourceWithRawResponse(self._access.infrastructure)
@@ -352,6 +376,10 @@ class AccessResourceWithStreamingResponse:
def __init__(self, access: AccessResource) -> None:
self._access = access
+ @cached_property
+ def gateway_ca(self) -> GatewayCAResourceWithStreamingResponse:
+ return GatewayCAResourceWithStreamingResponse(self._access.gateway_ca)
+
@cached_property
def infrastructure(self) -> InfrastructureResourceWithStreamingResponse:
return InfrastructureResourceWithStreamingResponse(self._access.infrastructure)
@@ -405,6 +433,10 @@ class AsyncAccessResourceWithStreamingResponse:
def __init__(self, access: AsyncAccessResource) -> None:
self._access = access
+ @cached_property
+ def gateway_ca(self) -> AsyncGatewayCAResourceWithStreamingResponse:
+ return AsyncGatewayCAResourceWithStreamingResponse(self._access.gateway_ca)
+
@cached_property
def infrastructure(self) -> AsyncInfrastructureResourceWithStreamingResponse:
return AsyncInfrastructureResourceWithStreamingResponse(self._access.infrastructure)
diff --git a/src/cloudflare/resources/zero_trust/access/gateway_ca.py b/src/cloudflare/resources/zero_trust/access/gateway_ca.py
new file mode 100644
index 00000000000..d349400078f
--- /dev/null
+++ b/src/cloudflare/resources/zero_trust/access/gateway_ca.py
@@ -0,0 +1,365 @@
+# 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 NOT_GIVEN, Body, Query, Headers, NotGiven
+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.access.gateway_ca_list_response import GatewayCAListResponse
+from ....types.zero_trust.access.gateway_ca_create_response import GatewayCACreateResponse
+from ....types.zero_trust.access.gateway_ca_delete_response import GatewayCADeleteResponse
+
+__all__ = ["GatewayCAResource", "AsyncGatewayCAResource"]
+
+
+class GatewayCAResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> GatewayCAResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return the
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return GatewayCAResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> GatewayCAResourceWithStreamingResponse:
+ """
+ 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 GatewayCAResourceWithStreamingResponse(self)
+
+ def create(
+ 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,
+ ) -> Optional[GatewayCACreateResponse]:
+ """
+ Adds a new SSH Certificate Authority (CA).
+
+ Args:
+ account_id: Identifier
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._post(
+ f"/accounts/{account_id}/access/gateway_ca",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[GatewayCACreateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[GatewayCACreateResponse]], ResultWrapper[GatewayCACreateResponse]),
+ )
+
+ 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[GatewayCAListResponse]:
+ """
+ Lists SSH Certificate Authorities (CA).
+
+ Args:
+ account_id: Identifier
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._get_api_list(
+ f"/accounts/{account_id}/access/gateway_ca",
+ page=SyncSinglePage[GatewayCAListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=GatewayCAListResponse,
+ )
+
+ def delete(
+ self,
+ certificate_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[GatewayCADeleteResponse]:
+ """
+ Deletes an SSH Certificate Authority.
+
+ Args:
+ account_id: Identifier
+
+ certificate_id: UUID
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the 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 certificate_id:
+ raise ValueError(f"Expected a non-empty value for `certificate_id` but received {certificate_id!r}")
+ return self._delete(
+ f"/accounts/{account_id}/access/gateway_ca/{certificate_id}",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[GatewayCADeleteResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[GatewayCADeleteResponse]], ResultWrapper[GatewayCADeleteResponse]),
+ )
+
+
+class AsyncGatewayCAResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncGatewayCAResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return the
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncGatewayCAResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncGatewayCAResourceWithStreamingResponse:
+ """
+ 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 AsyncGatewayCAResourceWithStreamingResponse(self)
+
+ async def create(
+ 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,
+ ) -> Optional[GatewayCACreateResponse]:
+ """
+ Adds a new SSH Certificate Authority (CA).
+
+ Args:
+ account_id: Identifier
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return await self._post(
+ f"/accounts/{account_id}/access/gateway_ca",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[GatewayCACreateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[GatewayCACreateResponse]], ResultWrapper[GatewayCACreateResponse]),
+ )
+
+ 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[GatewayCAListResponse, AsyncSinglePage[GatewayCAListResponse]]:
+ """
+ Lists SSH Certificate Authorities (CA).
+
+ Args:
+ account_id: Identifier
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._get_api_list(
+ f"/accounts/{account_id}/access/gateway_ca",
+ page=AsyncSinglePage[GatewayCAListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=GatewayCAListResponse,
+ )
+
+ async def delete(
+ self,
+ certificate_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[GatewayCADeleteResponse]:
+ """
+ Deletes an SSH Certificate Authority.
+
+ Args:
+ account_id: Identifier
+
+ certificate_id: UUID
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the 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 certificate_id:
+ raise ValueError(f"Expected a non-empty value for `certificate_id` but received {certificate_id!r}")
+ return await self._delete(
+ f"/accounts/{account_id}/access/gateway_ca/{certificate_id}",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[GatewayCADeleteResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[GatewayCADeleteResponse]], ResultWrapper[GatewayCADeleteResponse]),
+ )
+
+
+class GatewayCAResourceWithRawResponse:
+ def __init__(self, gateway_ca: GatewayCAResource) -> None:
+ self._gateway_ca = gateway_ca
+
+ self.create = to_raw_response_wrapper(
+ gateway_ca.create,
+ )
+ self.list = to_raw_response_wrapper(
+ gateway_ca.list,
+ )
+ self.delete = to_raw_response_wrapper(
+ gateway_ca.delete,
+ )
+
+
+class AsyncGatewayCAResourceWithRawResponse:
+ def __init__(self, gateway_ca: AsyncGatewayCAResource) -> None:
+ self._gateway_ca = gateway_ca
+
+ self.create = async_to_raw_response_wrapper(
+ gateway_ca.create,
+ )
+ self.list = async_to_raw_response_wrapper(
+ gateway_ca.list,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ gateway_ca.delete,
+ )
+
+
+class GatewayCAResourceWithStreamingResponse:
+ def __init__(self, gateway_ca: GatewayCAResource) -> None:
+ self._gateway_ca = gateway_ca
+
+ self.create = to_streamed_response_wrapper(
+ gateway_ca.create,
+ )
+ self.list = to_streamed_response_wrapper(
+ gateway_ca.list,
+ )
+ self.delete = to_streamed_response_wrapper(
+ gateway_ca.delete,
+ )
+
+
+class AsyncGatewayCAResourceWithStreamingResponse:
+ def __init__(self, gateway_ca: AsyncGatewayCAResource) -> None:
+ self._gateway_ca = gateway_ca
+
+ self.create = async_to_streamed_response_wrapper(
+ gateway_ca.create,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ gateway_ca.list,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ gateway_ca.delete,
+ )
diff --git a/src/cloudflare/resources/zero_trust/dlp/__init__.py b/src/cloudflare/resources/zero_trust/dlp/__init__.py
index b3185380cfb..03f7e960404 100644
--- a/src/cloudflare/resources/zero_trust/dlp/__init__.py
+++ b/src/cloudflare/resources/zero_trust/dlp/__init__.py
@@ -8,6 +8,14 @@
DLPResourceWithStreamingResponse,
AsyncDLPResourceWithStreamingResponse,
)
+from .email import (
+ EmailResource,
+ AsyncEmailResource,
+ EmailResourceWithRawResponse,
+ AsyncEmailResourceWithRawResponse,
+ EmailResourceWithStreamingResponse,
+ AsyncEmailResourceWithStreamingResponse,
+)
from .limits import (
LimitsResource,
AsyncLimitsResource,
@@ -76,6 +84,12 @@
"AsyncPayloadLogsResourceWithRawResponse",
"PayloadLogsResourceWithStreamingResponse",
"AsyncPayloadLogsResourceWithStreamingResponse",
+ "EmailResource",
+ "AsyncEmailResource",
+ "EmailResourceWithRawResponse",
+ "AsyncEmailResourceWithRawResponse",
+ "EmailResourceWithStreamingResponse",
+ "AsyncEmailResourceWithStreamingResponse",
"ProfilesResource",
"AsyncProfilesResource",
"ProfilesResourceWithRawResponse",
diff --git a/src/cloudflare/resources/zero_trust/dlp/dlp.py b/src/cloudflare/resources/zero_trust/dlp/dlp.py
index 742d20a6233..2a5da23c2db 100644
--- a/src/cloudflare/resources/zero_trust/dlp/dlp.py
+++ b/src/cloudflare/resources/zero_trust/dlp/dlp.py
@@ -27,6 +27,14 @@
AsyncPatternsResourceWithStreamingResponse,
)
from ...._compat import cached_property
+from .email.email import (
+ EmailResource,
+ AsyncEmailResource,
+ EmailResourceWithRawResponse,
+ AsyncEmailResourceWithRawResponse,
+ EmailResourceWithStreamingResponse,
+ AsyncEmailResourceWithStreamingResponse,
+)
from ...._resource import SyncAPIResource, AsyncAPIResource
from .payload_logs import (
PayloadLogsResource,
@@ -69,6 +77,10 @@ def patterns(self) -> PatternsResource:
def payload_logs(self) -> PayloadLogsResource:
return PayloadLogsResource(self._client)
+ @cached_property
+ def email(self) -> EmailResource:
+ return EmailResource(self._client)
+
@cached_property
def profiles(self) -> ProfilesResource:
return ProfilesResource(self._client)
@@ -114,6 +126,10 @@ def patterns(self) -> AsyncPatternsResource:
def payload_logs(self) -> AsyncPayloadLogsResource:
return AsyncPayloadLogsResource(self._client)
+ @cached_property
+ def email(self) -> AsyncEmailResource:
+ return AsyncEmailResource(self._client)
+
@cached_property
def profiles(self) -> AsyncProfilesResource:
return AsyncProfilesResource(self._client)
@@ -162,6 +178,10 @@ def patterns(self) -> PatternsResourceWithRawResponse:
def payload_logs(self) -> PayloadLogsResourceWithRawResponse:
return PayloadLogsResourceWithRawResponse(self._dlp.payload_logs)
+ @cached_property
+ def email(self) -> EmailResourceWithRawResponse:
+ return EmailResourceWithRawResponse(self._dlp.email)
+
@cached_property
def profiles(self) -> ProfilesResourceWithRawResponse:
return ProfilesResourceWithRawResponse(self._dlp.profiles)
@@ -191,6 +211,10 @@ def patterns(self) -> AsyncPatternsResourceWithRawResponse:
def payload_logs(self) -> AsyncPayloadLogsResourceWithRawResponse:
return AsyncPayloadLogsResourceWithRawResponse(self._dlp.payload_logs)
+ @cached_property
+ def email(self) -> AsyncEmailResourceWithRawResponse:
+ return AsyncEmailResourceWithRawResponse(self._dlp.email)
+
@cached_property
def profiles(self) -> AsyncProfilesResourceWithRawResponse:
return AsyncProfilesResourceWithRawResponse(self._dlp.profiles)
@@ -220,6 +244,10 @@ def patterns(self) -> PatternsResourceWithStreamingResponse:
def payload_logs(self) -> PayloadLogsResourceWithStreamingResponse:
return PayloadLogsResourceWithStreamingResponse(self._dlp.payload_logs)
+ @cached_property
+ def email(self) -> EmailResourceWithStreamingResponse:
+ return EmailResourceWithStreamingResponse(self._dlp.email)
+
@cached_property
def profiles(self) -> ProfilesResourceWithStreamingResponse:
return ProfilesResourceWithStreamingResponse(self._dlp.profiles)
@@ -249,6 +277,10 @@ def patterns(self) -> AsyncPatternsResourceWithStreamingResponse:
def payload_logs(self) -> AsyncPayloadLogsResourceWithStreamingResponse:
return AsyncPayloadLogsResourceWithStreamingResponse(self._dlp.payload_logs)
+ @cached_property
+ def email(self) -> AsyncEmailResourceWithStreamingResponse:
+ return AsyncEmailResourceWithStreamingResponse(self._dlp.email)
+
@cached_property
def profiles(self) -> AsyncProfilesResourceWithStreamingResponse:
return AsyncProfilesResourceWithStreamingResponse(self._dlp.profiles)
diff --git a/src/cloudflare/resources/zero_trust/dlp/email/__init__.py b/src/cloudflare/resources/zero_trust/dlp/email/__init__.py
new file mode 100644
index 00000000000..bed0373f820
--- /dev/null
+++ b/src/cloudflare/resources/zero_trust/dlp/email/__init__.py
@@ -0,0 +1,47 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .email import (
+ EmailResource,
+ AsyncEmailResource,
+ EmailResourceWithRawResponse,
+ AsyncEmailResourceWithRawResponse,
+ EmailResourceWithStreamingResponse,
+ AsyncEmailResourceWithStreamingResponse,
+)
+from .rules import (
+ RulesResource,
+ AsyncRulesResource,
+ RulesResourceWithRawResponse,
+ AsyncRulesResourceWithRawResponse,
+ RulesResourceWithStreamingResponse,
+ AsyncRulesResourceWithStreamingResponse,
+)
+from .account_mapping import (
+ AccountMappingResource,
+ AsyncAccountMappingResource,
+ AccountMappingResourceWithRawResponse,
+ AsyncAccountMappingResourceWithRawResponse,
+ AccountMappingResourceWithStreamingResponse,
+ AsyncAccountMappingResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "AccountMappingResource",
+ "AsyncAccountMappingResource",
+ "AccountMappingResourceWithRawResponse",
+ "AsyncAccountMappingResourceWithRawResponse",
+ "AccountMappingResourceWithStreamingResponse",
+ "AsyncAccountMappingResourceWithStreamingResponse",
+ "RulesResource",
+ "AsyncRulesResource",
+ "RulesResourceWithRawResponse",
+ "AsyncRulesResourceWithRawResponse",
+ "RulesResourceWithStreamingResponse",
+ "AsyncRulesResourceWithStreamingResponse",
+ "EmailResource",
+ "AsyncEmailResource",
+ "EmailResourceWithRawResponse",
+ "AsyncEmailResourceWithRawResponse",
+ "EmailResourceWithStreamingResponse",
+ "AsyncEmailResourceWithStreamingResponse",
+]
diff --git a/src/cloudflare/resources/zero_trust/dlp/email/account_mapping.py b/src/cloudflare/resources/zero_trust/dlp/email/account_mapping.py
new file mode 100644
index 00000000000..d9c04a979d4
--- /dev/null
+++ b/src/cloudflare/resources/zero_trust/dlp/email/account_mapping.py
@@ -0,0 +1,274 @@
+# 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 NOT_GIVEN, Body, Query, Headers, NotGiven
+from ....._utils import (
+ 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.email import account_mapping_create_params
+from .....types.zero_trust.dlp.email.account_mapping_get_response import AccountMappingGetResponse
+from .....types.zero_trust.dlp.email.account_mapping_create_response import AccountMappingCreateResponse
+
+__all__ = ["AccountMappingResource", "AsyncAccountMappingResource"]
+
+
+class AccountMappingResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AccountMappingResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return the
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return AccountMappingResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AccountMappingResourceWithStreamingResponse:
+ """
+ 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 AccountMappingResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ *,
+ account_id: str,
+ auth_requirements: account_mapping_create_params.AuthRequirements,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this 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[AccountMappingCreateResponse]:
+ """
+ Create mapping
+
+ 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(
+ f"/accounts/{account_id}/dlp/email/account_mapping",
+ body=maybe_transform(
+ {"auth_requirements": auth_requirements}, account_mapping_create_params.AccountMappingCreateParams
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[AccountMappingCreateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[AccountMappingCreateResponse]], ResultWrapper[AccountMappingCreateResponse]),
+ )
+
+ def get(
+ 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,
+ ) -> Optional[AccountMappingGetResponse]:
+ """
+ Get mapping
+
+ 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(
+ f"/accounts/{account_id}/dlp/email/account_mapping",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[AccountMappingGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[AccountMappingGetResponse]], ResultWrapper[AccountMappingGetResponse]),
+ )
+
+
+class AsyncAccountMappingResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncAccountMappingResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return the
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncAccountMappingResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncAccountMappingResourceWithStreamingResponse:
+ """
+ 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 AsyncAccountMappingResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ *,
+ account_id: str,
+ auth_requirements: account_mapping_create_params.AuthRequirements,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this 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[AccountMappingCreateResponse]:
+ """
+ Create mapping
+
+ 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(
+ f"/accounts/{account_id}/dlp/email/account_mapping",
+ body=await async_maybe_transform(
+ {"auth_requirements": auth_requirements}, account_mapping_create_params.AccountMappingCreateParams
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[AccountMappingCreateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[AccountMappingCreateResponse]], ResultWrapper[AccountMappingCreateResponse]),
+ )
+
+ async def get(
+ 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,
+ ) -> Optional[AccountMappingGetResponse]:
+ """
+ Get mapping
+
+ 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._get(
+ f"/accounts/{account_id}/dlp/email/account_mapping",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[AccountMappingGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[AccountMappingGetResponse]], ResultWrapper[AccountMappingGetResponse]),
+ )
+
+
+class AccountMappingResourceWithRawResponse:
+ def __init__(self, account_mapping: AccountMappingResource) -> None:
+ self._account_mapping = account_mapping
+
+ self.create = to_raw_response_wrapper(
+ account_mapping.create,
+ )
+ self.get = to_raw_response_wrapper(
+ account_mapping.get,
+ )
+
+
+class AsyncAccountMappingResourceWithRawResponse:
+ def __init__(self, account_mapping: AsyncAccountMappingResource) -> None:
+ self._account_mapping = account_mapping
+
+ self.create = async_to_raw_response_wrapper(
+ account_mapping.create,
+ )
+ self.get = async_to_raw_response_wrapper(
+ account_mapping.get,
+ )
+
+
+class AccountMappingResourceWithStreamingResponse:
+ def __init__(self, account_mapping: AccountMappingResource) -> None:
+ self._account_mapping = account_mapping
+
+ self.create = to_streamed_response_wrapper(
+ account_mapping.create,
+ )
+ self.get = to_streamed_response_wrapper(
+ account_mapping.get,
+ )
+
+
+class AsyncAccountMappingResourceWithStreamingResponse:
+ def __init__(self, account_mapping: AsyncAccountMappingResource) -> None:
+ self._account_mapping = account_mapping
+
+ self.create = async_to_streamed_response_wrapper(
+ account_mapping.create,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ account_mapping.get,
+ )
diff --git a/src/cloudflare/resources/zero_trust/dlp/email/email.py b/src/cloudflare/resources/zero_trust/dlp/email/email.py
new file mode 100644
index 00000000000..5a860e81a40
--- /dev/null
+++ b/src/cloudflare/resources/zero_trust/dlp/email/email.py
@@ -0,0 +1,134 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .rules import (
+ RulesResource,
+ AsyncRulesResource,
+ RulesResourceWithRawResponse,
+ AsyncRulesResourceWithRawResponse,
+ RulesResourceWithStreamingResponse,
+ AsyncRulesResourceWithStreamingResponse,
+)
+from ....._compat import cached_property
+from ....._resource import SyncAPIResource, AsyncAPIResource
+from .account_mapping import (
+ AccountMappingResource,
+ AsyncAccountMappingResource,
+ AccountMappingResourceWithRawResponse,
+ AsyncAccountMappingResourceWithRawResponse,
+ AccountMappingResourceWithStreamingResponse,
+ AsyncAccountMappingResourceWithStreamingResponse,
+)
+
+__all__ = ["EmailResource", "AsyncEmailResource"]
+
+
+class EmailResource(SyncAPIResource):
+ @cached_property
+ def account_mapping(self) -> AccountMappingResource:
+ return AccountMappingResource(self._client)
+
+ @cached_property
+ def rules(self) -> RulesResource:
+ return RulesResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> EmailResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return the
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return EmailResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> EmailResourceWithStreamingResponse:
+ """
+ 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 EmailResourceWithStreamingResponse(self)
+
+
+class AsyncEmailResource(AsyncAPIResource):
+ @cached_property
+ def account_mapping(self) -> AsyncAccountMappingResource:
+ return AsyncAccountMappingResource(self._client)
+
+ @cached_property
+ def rules(self) -> AsyncRulesResource:
+ return AsyncRulesResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncEmailResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return the
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncEmailResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncEmailResourceWithStreamingResponse:
+ """
+ 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 AsyncEmailResourceWithStreamingResponse(self)
+
+
+class EmailResourceWithRawResponse:
+ def __init__(self, email: EmailResource) -> None:
+ self._email = email
+
+ @cached_property
+ def account_mapping(self) -> AccountMappingResourceWithRawResponse:
+ return AccountMappingResourceWithRawResponse(self._email.account_mapping)
+
+ @cached_property
+ def rules(self) -> RulesResourceWithRawResponse:
+ return RulesResourceWithRawResponse(self._email.rules)
+
+
+class AsyncEmailResourceWithRawResponse:
+ def __init__(self, email: AsyncEmailResource) -> None:
+ self._email = email
+
+ @cached_property
+ def account_mapping(self) -> AsyncAccountMappingResourceWithRawResponse:
+ return AsyncAccountMappingResourceWithRawResponse(self._email.account_mapping)
+
+ @cached_property
+ def rules(self) -> AsyncRulesResourceWithRawResponse:
+ return AsyncRulesResourceWithRawResponse(self._email.rules)
+
+
+class EmailResourceWithStreamingResponse:
+ def __init__(self, email: EmailResource) -> None:
+ self._email = email
+
+ @cached_property
+ def account_mapping(self) -> AccountMappingResourceWithStreamingResponse:
+ return AccountMappingResourceWithStreamingResponse(self._email.account_mapping)
+
+ @cached_property
+ def rules(self) -> RulesResourceWithStreamingResponse:
+ return RulesResourceWithStreamingResponse(self._email.rules)
+
+
+class AsyncEmailResourceWithStreamingResponse:
+ def __init__(self, email: AsyncEmailResource) -> None:
+ self._email = email
+
+ @cached_property
+ def account_mapping(self) -> AsyncAccountMappingResourceWithStreamingResponse:
+ return AsyncAccountMappingResourceWithStreamingResponse(self._email.account_mapping)
+
+ @cached_property
+ def rules(self) -> AsyncRulesResourceWithStreamingResponse:
+ return AsyncRulesResourceWithStreamingResponse(self._email.rules)
diff --git a/src/cloudflare/resources/zero_trust/dlp/email/rules.py b/src/cloudflare/resources/zero_trust/dlp/email/rules.py
new file mode 100644
index 00000000000..63906966157
--- /dev/null
+++ b/src/cloudflare/resources/zero_trust/dlp/email/rules.py
@@ -0,0 +1,701 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Dict, Type, Iterable, Optional, cast
+
+import httpx
+
+from ....._types import NOT_GIVEN, Body, Query, Headers, NotGiven
+from ....._utils import (
+ 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.email import rule_create_params, rule_update_params, rule_bulk_edit_params
+from .....types.zero_trust.dlp.email.rule_get_response import RuleGetResponse
+from .....types.zero_trust.dlp.email.rule_list_response import RuleListResponse
+from .....types.zero_trust.dlp.email.rule_create_response import RuleCreateResponse
+from .....types.zero_trust.dlp.email.rule_delete_response import RuleDeleteResponse
+from .....types.zero_trust.dlp.email.rule_update_response import RuleUpdateResponse
+from .....types.zero_trust.dlp.email.rule_bulk_edit_response import RuleBulkEditResponse
+
+__all__ = ["RulesResource", "AsyncRulesResource"]
+
+
+class RulesResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> RulesResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return the
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return RulesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> RulesResourceWithStreamingResponse:
+ """
+ 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 RulesResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ *,
+ account_id: str,
+ action: rule_create_params.Action,
+ conditions: Iterable[rule_create_params.Condition],
+ enabled: bool,
+ name: str,
+ description: Optional[str] | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this 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[RuleCreateResponse]:
+ """
+ Create email scanner rule
+
+ Args:
+ conditions: Rule is triggered if all conditions match
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the 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(
+ f"/accounts/{account_id}/dlp/email/rules",
+ body=maybe_transform(
+ {
+ "action": action,
+ "conditions": conditions,
+ "enabled": enabled,
+ "name": name,
+ "description": description,
+ },
+ rule_create_params.RuleCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[RuleCreateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[RuleCreateResponse]], ResultWrapper[RuleCreateResponse]),
+ )
+
+ def update(
+ self,
+ rule_id: str,
+ *,
+ account_id: str,
+ action: rule_update_params.Action,
+ conditions: Iterable[rule_update_params.Condition],
+ enabled: bool,
+ name: str,
+ description: Optional[str] | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this 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[RuleUpdateResponse]:
+ """
+ Update email scanner rule
+
+ Args:
+ conditions: Rule is triggered if all conditions match
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the 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 rule_id:
+ raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}")
+ return self._put(
+ f"/accounts/{account_id}/dlp/email/rules/{rule_id}",
+ body=maybe_transform(
+ {
+ "action": action,
+ "conditions": conditions,
+ "enabled": enabled,
+ "name": name,
+ "description": description,
+ },
+ rule_update_params.RuleUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[RuleUpdateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[RuleUpdateResponse]], ResultWrapper[RuleUpdateResponse]),
+ )
+
+ 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[RuleListResponse]:
+ """
+ Lists all email scanner rules for 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(
+ f"/accounts/{account_id}/dlp/email/rules",
+ page=SyncSinglePage[RuleListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=RuleListResponse,
+ )
+
+ def delete(
+ self,
+ rule_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[RuleDeleteResponse]:
+ """
+ Delete email scanner rule
+
+ 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 rule_id:
+ raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}")
+ return self._delete(
+ f"/accounts/{account_id}/dlp/email/rules/{rule_id}",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[RuleDeleteResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[RuleDeleteResponse]], ResultWrapper[RuleDeleteResponse]),
+ )
+
+ def bulk_edit(
+ self,
+ *,
+ account_id: str,
+ new_priorities: Dict[str, int],
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this 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[RuleBulkEditResponse]:
+ """
+ Update email scanner rule priorities
+
+ 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._patch(
+ f"/accounts/{account_id}/dlp/email/rules",
+ body=maybe_transform({"new_priorities": new_priorities}, rule_bulk_edit_params.RuleBulkEditParams),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[RuleBulkEditResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[RuleBulkEditResponse]], ResultWrapper[RuleBulkEditResponse]),
+ )
+
+ def get(
+ self,
+ rule_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[RuleGetResponse]:
+ """
+ Get an email scanner rule
+
+ 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 rule_id:
+ raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}")
+ return self._get(
+ f"/accounts/{account_id}/dlp/email/rules/{rule_id}",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[RuleGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[RuleGetResponse]], ResultWrapper[RuleGetResponse]),
+ )
+
+
+class AsyncRulesResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncRulesResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return the
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncRulesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncRulesResourceWithStreamingResponse:
+ """
+ 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 AsyncRulesResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ *,
+ account_id: str,
+ action: rule_create_params.Action,
+ conditions: Iterable[rule_create_params.Condition],
+ enabled: bool,
+ name: str,
+ description: Optional[str] | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this 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[RuleCreateResponse]:
+ """
+ Create email scanner rule
+
+ Args:
+ conditions: Rule is triggered if all conditions match
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the 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(
+ f"/accounts/{account_id}/dlp/email/rules",
+ body=await async_maybe_transform(
+ {
+ "action": action,
+ "conditions": conditions,
+ "enabled": enabled,
+ "name": name,
+ "description": description,
+ },
+ rule_create_params.RuleCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[RuleCreateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[RuleCreateResponse]], ResultWrapper[RuleCreateResponse]),
+ )
+
+ async def update(
+ self,
+ rule_id: str,
+ *,
+ account_id: str,
+ action: rule_update_params.Action,
+ conditions: Iterable[rule_update_params.Condition],
+ enabled: bool,
+ name: str,
+ description: Optional[str] | NotGiven = NOT_GIVEN,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this 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[RuleUpdateResponse]:
+ """
+ Update email scanner rule
+
+ Args:
+ conditions: Rule is triggered if all conditions match
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the 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 rule_id:
+ raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}")
+ return await self._put(
+ f"/accounts/{account_id}/dlp/email/rules/{rule_id}",
+ body=await async_maybe_transform(
+ {
+ "action": action,
+ "conditions": conditions,
+ "enabled": enabled,
+ "name": name,
+ "description": description,
+ },
+ rule_update_params.RuleUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[RuleUpdateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[RuleUpdateResponse]], ResultWrapper[RuleUpdateResponse]),
+ )
+
+ 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[RuleListResponse, AsyncSinglePage[RuleListResponse]]:
+ """
+ Lists all email scanner rules for 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(
+ f"/accounts/{account_id}/dlp/email/rules",
+ page=AsyncSinglePage[RuleListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=RuleListResponse,
+ )
+
+ async def delete(
+ self,
+ rule_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[RuleDeleteResponse]:
+ """
+ Delete email scanner rule
+
+ 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 rule_id:
+ raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}")
+ return await self._delete(
+ f"/accounts/{account_id}/dlp/email/rules/{rule_id}",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[RuleDeleteResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[RuleDeleteResponse]], ResultWrapper[RuleDeleteResponse]),
+ )
+
+ async def bulk_edit(
+ self,
+ *,
+ account_id: str,
+ new_priorities: Dict[str, int],
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this 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[RuleBulkEditResponse]:
+ """
+ Update email scanner rule priorities
+
+ 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._patch(
+ f"/accounts/{account_id}/dlp/email/rules",
+ body=await async_maybe_transform(
+ {"new_priorities": new_priorities}, rule_bulk_edit_params.RuleBulkEditParams
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[RuleBulkEditResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[RuleBulkEditResponse]], ResultWrapper[RuleBulkEditResponse]),
+ )
+
+ async def get(
+ self,
+ rule_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[RuleGetResponse]:
+ """
+ Get an email scanner rule
+
+ 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 rule_id:
+ raise ValueError(f"Expected a non-empty value for `rule_id` but received {rule_id!r}")
+ return await self._get(
+ f"/accounts/{account_id}/dlp/email/rules/{rule_id}",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[RuleGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[RuleGetResponse]], ResultWrapper[RuleGetResponse]),
+ )
+
+
+class RulesResourceWithRawResponse:
+ def __init__(self, rules: RulesResource) -> None:
+ self._rules = rules
+
+ self.create = to_raw_response_wrapper(
+ rules.create,
+ )
+ self.update = to_raw_response_wrapper(
+ rules.update,
+ )
+ self.list = to_raw_response_wrapper(
+ rules.list,
+ )
+ self.delete = to_raw_response_wrapper(
+ rules.delete,
+ )
+ self.bulk_edit = to_raw_response_wrapper(
+ rules.bulk_edit,
+ )
+ self.get = to_raw_response_wrapper(
+ rules.get,
+ )
+
+
+class AsyncRulesResourceWithRawResponse:
+ def __init__(self, rules: AsyncRulesResource) -> None:
+ self._rules = rules
+
+ self.create = async_to_raw_response_wrapper(
+ rules.create,
+ )
+ self.update = async_to_raw_response_wrapper(
+ rules.update,
+ )
+ self.list = async_to_raw_response_wrapper(
+ rules.list,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ rules.delete,
+ )
+ self.bulk_edit = async_to_raw_response_wrapper(
+ rules.bulk_edit,
+ )
+ self.get = async_to_raw_response_wrapper(
+ rules.get,
+ )
+
+
+class RulesResourceWithStreamingResponse:
+ def __init__(self, rules: RulesResource) -> None:
+ self._rules = rules
+
+ self.create = to_streamed_response_wrapper(
+ rules.create,
+ )
+ self.update = to_streamed_response_wrapper(
+ rules.update,
+ )
+ self.list = to_streamed_response_wrapper(
+ rules.list,
+ )
+ self.delete = to_streamed_response_wrapper(
+ rules.delete,
+ )
+ self.bulk_edit = to_streamed_response_wrapper(
+ rules.bulk_edit,
+ )
+ self.get = to_streamed_response_wrapper(
+ rules.get,
+ )
+
+
+class AsyncRulesResourceWithStreamingResponse:
+ def __init__(self, rules: AsyncRulesResource) -> None:
+ self._rules = rules
+
+ self.create = async_to_streamed_response_wrapper(
+ rules.create,
+ )
+ self.update = async_to_streamed_response_wrapper(
+ rules.update,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ rules.list,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ rules.delete,
+ )
+ self.bulk_edit = async_to_streamed_response_wrapper(
+ rules.bulk_edit,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ rules.get,
+ )
diff --git a/src/cloudflare/types/accounts/logs/__init__.py b/src/cloudflare/types/accounts/logs/__init__.py
new file mode 100644
index 00000000000..4db884733b2
--- /dev/null
+++ b/src/cloudflare/types/accounts/logs/__init__.py
@@ -0,0 +1,6 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .audit_list_params import AuditListParams as AuditListParams
+from .audit_list_response import AuditListResponse as AuditListResponse
diff --git a/src/cloudflare/types/accounts/logs/audit_list_params.py b/src/cloudflare/types/accounts/logs/audit_list_params.py
new file mode 100644
index 00000000000..3d2556f2f0d
--- /dev/null
+++ b/src/cloudflare/types/accounts/logs/audit_list_params.py
@@ -0,0 +1,115 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union
+from datetime import date, datetime
+from typing_extensions import Literal, Required, Annotated, TypedDict
+
+from ...._utils import PropertyInfo
+
+__all__ = ["AuditListParams"]
+
+
+class AuditListParams(TypedDict, total=False):
+ account_id: Required[str]
+ """The unique id that identifies the account."""
+
+ before: Required[Annotated[Union[Union[str, date], Union[str, datetime]], PropertyInfo(format="iso8601")]]
+ """
+ Filters actions based on a given timestamp, returning only logs that occurred
+ before the specified date.
+ """
+
+ since: Required[Annotated[Union[Union[str, date], Union[str, datetime]], PropertyInfo(format="iso8601")]]
+ """
+ Filters actions based on a given timestamp, returning only logs that occurred
+ after the specified date.
+ """
+
+ account_name: str
+ """Filters by the account name."""
+
+ action_result: Literal["success", "failure"]
+ """Whether the action was successful or not."""
+
+ action_type: Literal["create", "delete", "view", "update"]
+ """Filters by the action type."""
+
+ actor_context: Literal["api_key", "api_token", "dash", "oauth", "origin_ca_key"]
+ """Filters by the actor context."""
+
+ actor_email: str
+ """Filters by the actor's email address."""
+
+ actor_id: str
+ """Filters by the actor ID. This can be either the Account ID or User ID."""
+
+ actor_ip_address: str
+ """The IP address where the action was initiated."""
+
+ actor_token_id: str
+ """Filters by the API token ID when the actor context is an api_token or oauth."""
+
+ actor_token_name: str
+ """Filters by the API token name when the actor context is an api_token or oauth."""
+
+ actor_type: Literal["cloudflare_admin", "account", "user"]
+ """Filters by the actor type."""
+
+ audit_log_id: str
+ """Finds a specific log by its ID."""
+
+ cursor: str
+ """The cursor is an opaque token used to paginate through large sets of records.
+
+ It indicates the position from which to continue when requesting the next set of
+ records. A valid cursor value can be obtained from the cursor object in the
+ result_info structure of a previous response.
+ """
+
+ direction: Literal["desc", "asc"]
+ """Sets sorting order."""
+
+ limit: float
+ """The number limits the objects to return.
+
+ The cursor attribute may be used to iterate over the next batch of objects if
+ there are more than the limit.
+ """
+
+ raw_cf_rayid: Annotated[str, PropertyInfo(alias="raw_cf_ray_id")]
+ """Filters by the response CF Ray ID."""
+
+ raw_method: str
+ """The HTTP method for the API call."""
+
+ raw_status_code: int
+ """The response status code that was returned."""
+
+ raw_uri: str
+ """Filters by the request URI."""
+
+ resource_id: str
+ """Filters by the resource ID."""
+
+ resource_product: str
+ """
+ Filters audit logs by the Cloudflare product associated with the changed
+ resource.
+ """
+
+ resource_scope: Literal["accounts", "user", "zones"]
+ """
+ Filters by the resource scope, specifying whether the resource is associated
+ with an user, an account, or a zone.
+ """
+
+ resource_type: str
+ """Filters audit logs based on the unique type of resource changed by the action."""
+
+ zone_id: str
+ """Filters by the zone ID."""
+
+ zone_name: str
+ """Filters by the zone name associated with the change."""
diff --git a/src/cloudflare/types/accounts/logs/audit_list_response.py b/src/cloudflare/types/accounts/logs/audit_list_response.py
new file mode 100644
index 00000000000..ec2281163c6
--- /dev/null
+++ b/src/cloudflare/types/accounts/logs/audit_list_response.py
@@ -0,0 +1,124 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from pydantic import Field as FieldInfo
+
+from ...._models import BaseModel
+
+__all__ = ["AuditListResponse", "Account", "Action", "Actor", "Raw", "Resource", "Zone"]
+
+
+class Account(BaseModel):
+ id: Optional[str] = None
+ """A unique identifier for the account."""
+
+ name: Optional[str] = None
+ """A string that identifies the account name."""
+
+
+class Action(BaseModel):
+ description: Optional[str] = None
+ """A short description of the action performed."""
+
+ result: Optional[str] = None
+ """The result of the action, indicating success or failure."""
+
+ time: Optional[datetime] = None
+ """A timestamp indicating when the action was logged."""
+
+ type: Optional[str] = None
+ """A short string that describes the action that was performed."""
+
+
+class Actor(BaseModel):
+ id: Optional[str] = None
+ """The ID of the actor who performed the action.
+
+ If a user performed the action, this will be their User ID.
+ """
+
+ context: Optional[Literal["api_key", "api_token", "dash", "oauth", "origin_ca_key"]] = None
+
+ email: Optional[str] = None
+ """The email of the actor who performed the action."""
+
+ ip_address: Optional[str] = None
+ """The IP address of the request that performed the action."""
+
+ token_id: Optional[str] = None
+ """Filters by the API token ID when the actor context is an api_token."""
+
+ token_name: Optional[str] = None
+ """Filters by the API token name when the actor context is an api_token."""
+
+ type: Optional[Literal["user", "account", "cloudflare-admin"]] = None
+ """The type of actor."""
+
+
+class Raw(BaseModel):
+ cf_rayid: Optional[str] = FieldInfo(alias="cf_ray_id", default=None)
+ """The Cloudflare Ray ID for the request."""
+
+ method: Optional[str] = None
+ """The HTTP method of the request."""
+
+ status_code: Optional[int] = None
+ """The HTTP response status code returned by the API."""
+
+ uri: Optional[str] = None
+ """The URI of the request."""
+
+ user_agent: Optional[str] = None
+ """The client's user agent string sent with the request."""
+
+
+class Resource(BaseModel):
+ id: Optional[str] = None
+ """The unique identifier for the affected resource."""
+
+ product: Optional[str] = None
+ """The Cloudflare product associated with the resource."""
+
+ request: Optional[object] = None
+
+ response: Optional[object] = None
+
+ scope: Optional[object] = None
+ """The scope of the resource."""
+
+ type: Optional[str] = None
+ """The type of the resource."""
+
+
+class Zone(BaseModel):
+ id: Optional[str] = None
+ """A string that identifies the zone id."""
+
+ name: Optional[str] = None
+ """A string that identifies the zone name."""
+
+
+class AuditListResponse(BaseModel):
+ id: Optional[str] = None
+ """A unique identifier for the audit log entry."""
+
+ account: Optional[Account] = None
+ """Contains account related information."""
+
+ action: Optional[Action] = None
+ """Provides information about the action performed."""
+
+ actor: Optional[Actor] = None
+ """Provides details about the actor who performed the action."""
+
+ raw: Optional[Raw] = None
+ """Provides raw information about the request and response."""
+
+ resource: Optional[Resource] = None
+ """Provides details about the affected resource."""
+
+ zone: Optional[Zone] = None
+ """Provides details about the zone affected by the action."""
diff --git a/src/cloudflare/types/addressing/prefixes/bgp/__init__.py b/src/cloudflare/types/addressing/prefixes/bgp/__init__.py
index bf70ca01135..2deb665b9f5 100644
--- a/src/cloudflare/types/addressing/prefixes/bgp/__init__.py
+++ b/src/cloudflare/types/addressing/prefixes/bgp/__init__.py
@@ -7,6 +7,7 @@
from .prefix_edit_params import PrefixEditParams as PrefixEditParams
from .status_edit_params import StatusEditParams as StatusEditParams
from .status_get_response import StatusGetResponse as StatusGetResponse
+from .prefix_create_params import PrefixCreateParams as PrefixCreateParams
from .status_edit_response import StatusEditResponse as StatusEditResponse
from .binding_create_params import BindingCreateParams as BindingCreateParams
from .binding_delete_response import BindingDeleteResponse as BindingDeleteResponse
diff --git a/src/cloudflare/types/addressing/prefixes/bgp/prefix_create_params.py b/src/cloudflare/types/addressing/prefixes/bgp/prefix_create_params.py
new file mode 100644
index 00000000000..f9f0a43d08e
--- /dev/null
+++ b/src/cloudflare/types/addressing/prefixes/bgp/prefix_create_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
+
+__all__ = ["PrefixCreateParams"]
+
+
+class PrefixCreateParams(TypedDict, total=False):
+ account_id: Required[str]
+ """Identifier"""
+
+ cidr: str
+ """IP Prefix in Classless Inter-Domain Routing format."""
diff --git a/src/cloudflare/types/zero_trust/access/__init__.py b/src/cloudflare/types/zero_trust/access/__init__.py
index e4632f441c3..e5debe2e745 100644
--- a/src/cloudflare/types/zero_trust/access/__init__.py
+++ b/src/cloudflare/types/zero_trust/access/__init__.py
@@ -53,6 +53,7 @@
from .application_get_response import ApplicationGetResponse as ApplicationGetResponse
from .bookmark_delete_response import BookmarkDeleteResponse as BookmarkDeleteResponse
from .custom_page_without_html import CustomPageWithoutHTML as CustomPageWithoutHTML
+from .gateway_ca_list_response import GatewayCAListResponse as GatewayCAListResponse
from .application_create_params import ApplicationCreateParams as ApplicationCreateParams
from .application_list_response import ApplicationListResponse as ApplicationListResponse
from .application_update_params import ApplicationUpdateParams as ApplicationUpdateParams
@@ -62,6 +63,8 @@
from .custom_page_update_params import CustomPageUpdateParams as CustomPageUpdateParams
from .scim_config_mapping_param import SCIMConfigMappingParam as SCIMConfigMappingParam
from .service_token_list_params import ServiceTokenListParams as ServiceTokenListParams
+from .gateway_ca_create_response import GatewayCACreateResponse as GatewayCACreateResponse
+from .gateway_ca_delete_response import GatewayCADeleteResponse as GatewayCADeleteResponse
from .application_create_response import ApplicationCreateResponse as ApplicationCreateResponse
from .application_delete_response import ApplicationDeleteResponse as ApplicationDeleteResponse
from .application_update_response import ApplicationUpdateResponse as ApplicationUpdateResponse
diff --git a/src/cloudflare/types/zero_trust/access/gateway_ca_create_response.py b/src/cloudflare/types/zero_trust/access/gateway_ca_create_response.py
new file mode 100644
index 00000000000..42288b6edad
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/access/gateway_ca_create_response.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from ...._models import BaseModel
+
+__all__ = ["GatewayCACreateResponse"]
+
+
+class GatewayCACreateResponse(BaseModel):
+ id: Optional[str] = None
+ """The key ID of this certificate."""
+
+ public_key: Optional[str] = None
+ """The public key of this certificate."""
diff --git a/src/cloudflare/types/zero_trust/access/gateway_ca_delete_response.py b/src/cloudflare/types/zero_trust/access/gateway_ca_delete_response.py
new file mode 100644
index 00000000000..a30c09026e1
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/access/gateway_ca_delete_response.py
@@ -0,0 +1,12 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from ...._models import BaseModel
+
+__all__ = ["GatewayCADeleteResponse"]
+
+
+class GatewayCADeleteResponse(BaseModel):
+ id: Optional[str] = None
+ """UUID"""
diff --git a/src/cloudflare/types/zero_trust/access/gateway_ca_list_response.py b/src/cloudflare/types/zero_trust/access/gateway_ca_list_response.py
new file mode 100644
index 00000000000..4a1ebc3f0b2
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/access/gateway_ca_list_response.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from ...._models import BaseModel
+
+__all__ = ["GatewayCAListResponse"]
+
+
+class GatewayCAListResponse(BaseModel):
+ id: Optional[str] = None
+ """The key ID of this certificate."""
+
+ public_key: Optional[str] = None
+ """The public key of this certificate."""
diff --git a/src/cloudflare/types/zero_trust/dlp/dataset.py b/src/cloudflare/types/zero_trust/dlp/dataset.py
index a7f2b015e78..88fe2483702 100644
--- a/src/cloudflare/types/zero_trust/dlp/dataset.py
+++ b/src/cloudflare/types/zero_trust/dlp/dataset.py
@@ -45,6 +45,10 @@ class Dataset(BaseModel):
status: Literal["empty", "uploading", "processing", "failed", "complete"]
updated_at: datetime
+ """When the dataset was last updated.
+
+ This includes name or description changes as well as uploads.
+ """
uploads: List[Upload]
diff --git a/src/cloudflare/types/zero_trust/dlp/email/__init__.py b/src/cloudflare/types/zero_trust/dlp/email/__init__.py
new file mode 100644
index 00000000000..d6f82bc8871
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/email/__init__.py
@@ -0,0 +1,16 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .rule_get_response import RuleGetResponse as RuleGetResponse
+from .rule_create_params import RuleCreateParams as RuleCreateParams
+from .rule_list_response import RuleListResponse as RuleListResponse
+from .rule_update_params import RuleUpdateParams as RuleUpdateParams
+from .rule_create_response import RuleCreateResponse as RuleCreateResponse
+from .rule_delete_response import RuleDeleteResponse as RuleDeleteResponse
+from .rule_update_response import RuleUpdateResponse as RuleUpdateResponse
+from .rule_bulk_edit_params import RuleBulkEditParams as RuleBulkEditParams
+from .rule_bulk_edit_response import RuleBulkEditResponse as RuleBulkEditResponse
+from .account_mapping_get_response import AccountMappingGetResponse as AccountMappingGetResponse
+from .account_mapping_create_params import AccountMappingCreateParams as AccountMappingCreateParams
+from .account_mapping_create_response import AccountMappingCreateResponse as AccountMappingCreateResponse
diff --git a/src/cloudflare/types/zero_trust/dlp/email/account_mapping_create_params.py b/src/cloudflare/types/zero_trust/dlp/email/account_mapping_create_params.py
new file mode 100644
index 00000000000..0c6ebbedd48
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/email/account_mapping_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 List, Union
+from typing_extensions import Literal, Required, TypeAlias, TypedDict
+
+__all__ = ["AccountMappingCreateParams", "AuthRequirements", "AuthRequirementsUnionMember0", "AuthRequirementsType"]
+
+
+class AccountMappingCreateParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ auth_requirements: Required[AuthRequirements]
+
+
+class AuthRequirementsUnionMember0(TypedDict, total=False):
+ allowed_microsoft_organizations: Required[List[str]]
+
+ type: Required[Literal["Org"]]
+
+
+class AuthRequirementsType(TypedDict, total=False):
+ type: Required[Literal["NoAuth"]]
+
+
+AuthRequirements: TypeAlias = Union[AuthRequirementsUnionMember0, AuthRequirementsType]
diff --git a/src/cloudflare/types/zero_trust/dlp/email/account_mapping_create_response.py b/src/cloudflare/types/zero_trust/dlp/email/account_mapping_create_response.py
new file mode 100644
index 00000000000..5be7c141a7d
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/email/account_mapping_create_response.py
@@ -0,0 +1,27 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Union
+from typing_extensions import Literal, TypeAlias
+
+from ....._models import BaseModel
+
+__all__ = ["AccountMappingCreateResponse", "AuthRequirements", "AuthRequirementsUnionMember0", "AuthRequirementsType"]
+
+
+class AuthRequirementsUnionMember0(BaseModel):
+ allowed_microsoft_organizations: List[str]
+
+ type: Literal["Org"]
+
+
+class AuthRequirementsType(BaseModel):
+ type: Literal["NoAuth"]
+
+
+AuthRequirements: TypeAlias = Union[AuthRequirementsUnionMember0, AuthRequirementsType]
+
+
+class AccountMappingCreateResponse(BaseModel):
+ addin_identifier_token: str
+
+ auth_requirements: AuthRequirements
diff --git a/src/cloudflare/types/zero_trust/dlp/email/account_mapping_get_response.py b/src/cloudflare/types/zero_trust/dlp/email/account_mapping_get_response.py
new file mode 100644
index 00000000000..2b3be1a1c92
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/email/account_mapping_get_response.py
@@ -0,0 +1,27 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Union
+from typing_extensions import Literal, TypeAlias
+
+from ....._models import BaseModel
+
+__all__ = ["AccountMappingGetResponse", "AuthRequirements", "AuthRequirementsUnionMember0", "AuthRequirementsType"]
+
+
+class AuthRequirementsUnionMember0(BaseModel):
+ allowed_microsoft_organizations: List[str]
+
+ type: Literal["Org"]
+
+
+class AuthRequirementsType(BaseModel):
+ type: Literal["NoAuth"]
+
+
+AuthRequirements: TypeAlias = Union[AuthRequirementsUnionMember0, AuthRequirementsType]
+
+
+class AccountMappingGetResponse(BaseModel):
+ addin_identifier_token: str
+
+ auth_requirements: AuthRequirements
diff --git a/src/cloudflare/types/zero_trust/dlp/email/rule_bulk_edit_params.py b/src/cloudflare/types/zero_trust/dlp/email/rule_bulk_edit_params.py
new file mode 100644
index 00000000000..bd76fa7aa29
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/email/rule_bulk_edit_params.py
@@ -0,0 +1,14 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Dict
+from typing_extensions import Required, TypedDict
+
+__all__ = ["RuleBulkEditParams"]
+
+
+class RuleBulkEditParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ new_priorities: Required[Dict[str, int]]
diff --git a/src/cloudflare/types/zero_trust/dlp/email/rule_bulk_edit_response.py b/src/cloudflare/types/zero_trust/dlp/email/rule_bulk_edit_response.py
new file mode 100644
index 00000000000..55a9db93b90
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/email/rule_bulk_edit_response.py
@@ -0,0 +1,44 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ....._models import BaseModel
+
+__all__ = ["RuleBulkEditResponse", "Action", "Condition"]
+
+
+class Action(BaseModel):
+ action: Literal["Block"]
+
+ message: Optional[str] = None
+
+
+class Condition(BaseModel):
+ operator: Literal["InList", "NotInList", "MatchRegex", "NotMatchRegex"]
+
+ selector: Literal["Recipients", "Sender", "DLPProfiles"]
+
+ value: object
+
+
+class RuleBulkEditResponse(BaseModel):
+ action: Action
+
+ conditions: List[Condition]
+ """Rule is triggered if all conditions match"""
+
+ created_at: datetime
+
+ enabled: bool
+
+ name: str
+
+ priority: int
+
+ rule_id: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/email/rule_create_params.py b/src/cloudflare/types/zero_trust/dlp/email/rule_create_params.py
new file mode 100644
index 00000000000..8d1bf0f8cd2
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/email/rule_create_params.py
@@ -0,0 +1,37 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable, Optional
+from typing_extensions import Literal, Required, TypedDict
+
+__all__ = ["RuleCreateParams", "Action", "Condition"]
+
+
+class RuleCreateParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ action: Required[Action]
+
+ conditions: Required[Iterable[Condition]]
+ """Rule is triggered if all conditions match"""
+
+ enabled: Required[bool]
+
+ name: Required[str]
+
+ description: Optional[str]
+
+
+class Action(TypedDict, total=False):
+ action: Required[Literal["Block"]]
+
+ message: Optional[str]
+
+
+class Condition(TypedDict, total=False):
+ operator: Required[Literal["InList", "NotInList", "MatchRegex", "NotMatchRegex"]]
+
+ selector: Required[Literal["Recipients", "Sender", "DLPProfiles"]]
+
+ value: Required[object]
diff --git a/src/cloudflare/types/zero_trust/dlp/email/rule_create_response.py b/src/cloudflare/types/zero_trust/dlp/email/rule_create_response.py
new file mode 100644
index 00000000000..7077679dc93
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/email/rule_create_response.py
@@ -0,0 +1,44 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ....._models import BaseModel
+
+__all__ = ["RuleCreateResponse", "Action", "Condition"]
+
+
+class Action(BaseModel):
+ action: Literal["Block"]
+
+ message: Optional[str] = None
+
+
+class Condition(BaseModel):
+ operator: Literal["InList", "NotInList", "MatchRegex", "NotMatchRegex"]
+
+ selector: Literal["Recipients", "Sender", "DLPProfiles"]
+
+ value: object
+
+
+class RuleCreateResponse(BaseModel):
+ action: Action
+
+ conditions: List[Condition]
+ """Rule is triggered if all conditions match"""
+
+ created_at: datetime
+
+ enabled: bool
+
+ name: str
+
+ priority: int
+
+ rule_id: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/email/rule_delete_response.py b/src/cloudflare/types/zero_trust/dlp/email/rule_delete_response.py
new file mode 100644
index 00000000000..b67309d5e8a
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/email/rule_delete_response.py
@@ -0,0 +1,44 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ....._models import BaseModel
+
+__all__ = ["RuleDeleteResponse", "Action", "Condition"]
+
+
+class Action(BaseModel):
+ action: Literal["Block"]
+
+ message: Optional[str] = None
+
+
+class Condition(BaseModel):
+ operator: Literal["InList", "NotInList", "MatchRegex", "NotMatchRegex"]
+
+ selector: Literal["Recipients", "Sender", "DLPProfiles"]
+
+ value: object
+
+
+class RuleDeleteResponse(BaseModel):
+ action: Action
+
+ conditions: List[Condition]
+ """Rule is triggered if all conditions match"""
+
+ created_at: datetime
+
+ enabled: bool
+
+ name: str
+
+ priority: int
+
+ rule_id: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/email/rule_get_response.py b/src/cloudflare/types/zero_trust/dlp/email/rule_get_response.py
new file mode 100644
index 00000000000..75681ab045e
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/email/rule_get_response.py
@@ -0,0 +1,44 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ....._models import BaseModel
+
+__all__ = ["RuleGetResponse", "Action", "Condition"]
+
+
+class Action(BaseModel):
+ action: Literal["Block"]
+
+ message: Optional[str] = None
+
+
+class Condition(BaseModel):
+ operator: Literal["InList", "NotInList", "MatchRegex", "NotMatchRegex"]
+
+ selector: Literal["Recipients", "Sender", "DLPProfiles"]
+
+ value: object
+
+
+class RuleGetResponse(BaseModel):
+ action: Action
+
+ conditions: List[Condition]
+ """Rule is triggered if all conditions match"""
+
+ created_at: datetime
+
+ enabled: bool
+
+ name: str
+
+ priority: int
+
+ rule_id: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/email/rule_list_response.py b/src/cloudflare/types/zero_trust/dlp/email/rule_list_response.py
new file mode 100644
index 00000000000..0e5913db430
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/email/rule_list_response.py
@@ -0,0 +1,44 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ....._models import BaseModel
+
+__all__ = ["RuleListResponse", "Action", "Condition"]
+
+
+class Action(BaseModel):
+ action: Literal["Block"]
+
+ message: Optional[str] = None
+
+
+class Condition(BaseModel):
+ operator: Literal["InList", "NotInList", "MatchRegex", "NotMatchRegex"]
+
+ selector: Literal["Recipients", "Sender", "DLPProfiles"]
+
+ value: object
+
+
+class RuleListResponse(BaseModel):
+ action: Action
+
+ conditions: List[Condition]
+ """Rule is triggered if all conditions match"""
+
+ created_at: datetime
+
+ enabled: bool
+
+ name: str
+
+ priority: int
+
+ rule_id: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
diff --git a/src/cloudflare/types/zero_trust/dlp/email/rule_update_params.py b/src/cloudflare/types/zero_trust/dlp/email/rule_update_params.py
new file mode 100644
index 00000000000..1bf1e76cf2f
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/email/rule_update_params.py
@@ -0,0 +1,37 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable, Optional
+from typing_extensions import Literal, Required, TypedDict
+
+__all__ = ["RuleUpdateParams", "Action", "Condition"]
+
+
+class RuleUpdateParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ action: Required[Action]
+
+ conditions: Required[Iterable[Condition]]
+ """Rule is triggered if all conditions match"""
+
+ enabled: Required[bool]
+
+ name: Required[str]
+
+ description: Optional[str]
+
+
+class Action(TypedDict, total=False):
+ action: Required[Literal["Block"]]
+
+ message: Optional[str]
+
+
+class Condition(TypedDict, total=False):
+ operator: Required[Literal["InList", "NotInList", "MatchRegex", "NotMatchRegex"]]
+
+ selector: Required[Literal["Recipients", "Sender", "DLPProfiles"]]
+
+ value: Required[object]
diff --git a/src/cloudflare/types/zero_trust/dlp/email/rule_update_response.py b/src/cloudflare/types/zero_trust/dlp/email/rule_update_response.py
new file mode 100644
index 00000000000..c1e9f32703d
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dlp/email/rule_update_response.py
@@ -0,0 +1,44 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ....._models import BaseModel
+
+__all__ = ["RuleUpdateResponse", "Action", "Condition"]
+
+
+class Action(BaseModel):
+ action: Literal["Block"]
+
+ message: Optional[str] = None
+
+
+class Condition(BaseModel):
+ operator: Literal["InList", "NotInList", "MatchRegex", "NotMatchRegex"]
+
+ selector: Literal["Recipients", "Sender", "DLPProfiles"]
+
+ value: object
+
+
+class RuleUpdateResponse(BaseModel):
+ action: Action
+
+ conditions: List[Condition]
+ """Rule is triggered if all conditions match"""
+
+ created_at: datetime
+
+ enabled: bool
+
+ name: str
+
+ priority: int
+
+ rule_id: str
+
+ updated_at: datetime
+
+ description: Optional[str] = None
diff --git a/tests/api_resources/accounts/logs/__init__.py b/tests/api_resources/accounts/logs/__init__.py
new file mode 100644
index 00000000000..fd8019a9a1a
--- /dev/null
+++ b/tests/api_resources/accounts/logs/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/accounts/logs/test_audit.py b/tests/api_resources/accounts/logs/test_audit.py
new file mode 100644
index 00000000000..563ef94f47f
--- /dev/null
+++ b/tests/api_resources/accounts/logs/test_audit.py
@@ -0,0 +1,182 @@
+# 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._utils import parse_date
+from cloudflare.pagination import SyncCursorLimitPagination, AsyncCursorLimitPagination
+from cloudflare.types.accounts.logs import AuditListResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestAudit:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_list(self, client: Cloudflare) -> None:
+ audit = client.accounts.logs.audit.list(
+ account_id="a67e14daa5f8dceeb91fe5449ba496ef",
+ before=parse_date("2014-10-30"),
+ since=parse_date("2014-10-30"),
+ )
+ assert_matches_type(SyncCursorLimitPagination[AuditListResponse], audit, path=["response"])
+
+ @parametrize
+ def test_method_list_with_all_params(self, client: Cloudflare) -> None:
+ audit = client.accounts.logs.audit.list(
+ account_id="a67e14daa5f8dceeb91fe5449ba496ef",
+ before=parse_date("2014-10-30"),
+ since=parse_date("2014-10-30"),
+ account_name="account_name",
+ action_result="success",
+ action_type="create",
+ actor_context="api_key",
+ actor_email="alice@example.com",
+ actor_id="1d20c3afe174f18b642710cec6298a9d",
+ actor_ip_address="17.168.228.63",
+ actor_token_id="144cdb2e39c55e203cf225d8d8208647",
+ actor_token_name="Test Token",
+ actor_type="cloudflare_admin",
+ audit_log_id="f174be97-19b1-40d6-954d-70cd5fbd52db",
+ cursor="Q1buH-__DQqqig7SVYXT-SsMOTGY2Z3Y80W-fGgva7yaDdmPKveucH5ddOcHsJRhNb-xUK8agZQqkJSMAENGO8NU6g==",
+ direction="desc",
+ limit=25,
+ raw_cf_rayid="8e8dd2156ef28414",
+ raw_method="GET",
+ raw_status_code=200,
+ raw_uri="raw_uri",
+ resource_id="resource_id",
+ resource_product="Stream",
+ resource_scope="accounts",
+ resource_type="Video",
+ zone_id="zone_id",
+ zone_name="example.com",
+ )
+ assert_matches_type(SyncCursorLimitPagination[AuditListResponse], audit, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Cloudflare) -> None:
+ response = client.accounts.logs.audit.with_raw_response.list(
+ account_id="a67e14daa5f8dceeb91fe5449ba496ef",
+ before=parse_date("2014-10-30"),
+ since=parse_date("2014-10-30"),
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ audit = response.parse()
+ assert_matches_type(SyncCursorLimitPagination[AuditListResponse], audit, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Cloudflare) -> None:
+ with client.accounts.logs.audit.with_streaming_response.list(
+ account_id="a67e14daa5f8dceeb91fe5449ba496ef",
+ before=parse_date("2014-10-30"),
+ since=parse_date("2014-10-30"),
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ audit = response.parse()
+ assert_matches_type(SyncCursorLimitPagination[AuditListResponse], audit, 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.accounts.logs.audit.with_raw_response.list(
+ account_id="",
+ before=parse_date("2014-10-30"),
+ since=parse_date("2014-10-30"),
+ )
+
+
+class TestAsyncAudit:
+ parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncCloudflare) -> None:
+ audit = await async_client.accounts.logs.audit.list(
+ account_id="a67e14daa5f8dceeb91fe5449ba496ef",
+ before=parse_date("2014-10-30"),
+ since=parse_date("2014-10-30"),
+ )
+ assert_matches_type(AsyncCursorLimitPagination[AuditListResponse], audit, path=["response"])
+
+ @parametrize
+ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ audit = await async_client.accounts.logs.audit.list(
+ account_id="a67e14daa5f8dceeb91fe5449ba496ef",
+ before=parse_date("2014-10-30"),
+ since=parse_date("2014-10-30"),
+ account_name="account_name",
+ action_result="success",
+ action_type="create",
+ actor_context="api_key",
+ actor_email="alice@example.com",
+ actor_id="1d20c3afe174f18b642710cec6298a9d",
+ actor_ip_address="17.168.228.63",
+ actor_token_id="144cdb2e39c55e203cf225d8d8208647",
+ actor_token_name="Test Token",
+ actor_type="cloudflare_admin",
+ audit_log_id="f174be97-19b1-40d6-954d-70cd5fbd52db",
+ cursor="Q1buH-__DQqqig7SVYXT-SsMOTGY2Z3Y80W-fGgva7yaDdmPKveucH5ddOcHsJRhNb-xUK8agZQqkJSMAENGO8NU6g==",
+ direction="desc",
+ limit=25,
+ raw_cf_rayid="8e8dd2156ef28414",
+ raw_method="GET",
+ raw_status_code=200,
+ raw_uri="raw_uri",
+ resource_id="resource_id",
+ resource_product="Stream",
+ resource_scope="accounts",
+ resource_type="Video",
+ zone_id="zone_id",
+ zone_name="example.com",
+ )
+ assert_matches_type(AsyncCursorLimitPagination[AuditListResponse], audit, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.accounts.logs.audit.with_raw_response.list(
+ account_id="a67e14daa5f8dceeb91fe5449ba496ef",
+ before=parse_date("2014-10-30"),
+ since=parse_date("2014-10-30"),
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ audit = await response.parse()
+ assert_matches_type(AsyncCursorLimitPagination[AuditListResponse], audit, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.accounts.logs.audit.with_streaming_response.list(
+ account_id="a67e14daa5f8dceeb91fe5449ba496ef",
+ before=parse_date("2014-10-30"),
+ since=parse_date("2014-10-30"),
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ audit = await response.parse()
+ assert_matches_type(AsyncCursorLimitPagination[AuditListResponse], audit, 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.accounts.logs.audit.with_raw_response.list(
+ account_id="",
+ before=parse_date("2014-10-30"),
+ since=parse_date("2014-10-30"),
+ )
diff --git a/tests/api_resources/addressing/prefixes/bgp/test_prefixes.py b/tests/api_resources/addressing/prefixes/bgp/test_prefixes.py
index c0486fa677a..0c7f9487722 100644
--- a/tests/api_resources/addressing/prefixes/bgp/test_prefixes.py
+++ b/tests/api_resources/addressing/prefixes/bgp/test_prefixes.py
@@ -18,6 +18,63 @@
class TestPrefixes:
parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+ @parametrize
+ def test_method_create(self, client: Cloudflare) -> None:
+ prefix = client.addressing.prefixes.bgp.prefixes.create(
+ prefix_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[BGPPrefix], prefix, path=["response"])
+
+ @parametrize
+ def test_method_create_with_all_params(self, client: Cloudflare) -> None:
+ prefix = client.addressing.prefixes.bgp.prefixes.create(
+ prefix_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ cidr="192.0.2.0/24",
+ )
+ assert_matches_type(Optional[BGPPrefix], prefix, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Cloudflare) -> None:
+ response = client.addressing.prefixes.bgp.prefixes.with_raw_response.create(
+ prefix_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ prefix = response.parse()
+ assert_matches_type(Optional[BGPPrefix], prefix, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: Cloudflare) -> None:
+ with client.addressing.prefixes.bgp.prefixes.with_streaming_response.create(
+ prefix_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ prefix = response.parse()
+ assert_matches_type(Optional[BGPPrefix], prefix, 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.addressing.prefixes.bgp.prefixes.with_raw_response.create(
+ prefix_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `prefix_id` but received ''"):
+ client.addressing.prefixes.bgp.prefixes.with_raw_response.create(
+ prefix_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
@parametrize
def test_method_list(self, client: Cloudflare) -> None:
prefix = client.addressing.prefixes.bgp.prefixes.list(
@@ -200,6 +257,63 @@ def test_path_params_get(self, client: Cloudflare) -> None:
class TestAsyncPrefixes:
parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
+ @parametrize
+ async def test_method_create(self, async_client: AsyncCloudflare) -> None:
+ prefix = await async_client.addressing.prefixes.bgp.prefixes.create(
+ prefix_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[BGPPrefix], prefix, path=["response"])
+
+ @parametrize
+ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ prefix = await async_client.addressing.prefixes.bgp.prefixes.create(
+ prefix_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ cidr="192.0.2.0/24",
+ )
+ assert_matches_type(Optional[BGPPrefix], prefix, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.addressing.prefixes.bgp.prefixes.with_raw_response.create(
+ prefix_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ prefix = await response.parse()
+ assert_matches_type(Optional[BGPPrefix], prefix, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.addressing.prefixes.bgp.prefixes.with_streaming_response.create(
+ prefix_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ prefix = await response.parse()
+ assert_matches_type(Optional[BGPPrefix], prefix, 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.addressing.prefixes.bgp.prefixes.with_raw_response.create(
+ prefix_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `prefix_id` but received ''"):
+ await async_client.addressing.prefixes.bgp.prefixes.with_raw_response.create(
+ prefix_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
@parametrize
async def test_method_list(self, async_client: AsyncCloudflare) -> None:
prefix = await async_client.addressing.prefixes.bgp.prefixes.list(
diff --git a/tests/api_resources/zero_trust/access/test_gateway_ca.py b/tests/api_resources/zero_trust/access/test_gateway_ca.py
new file mode 100644
index 00000000000..723be698029
--- /dev/null
+++ b/tests/api_resources/zero_trust/access/test_gateway_ca.py
@@ -0,0 +1,271 @@
+# 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.access import GatewayCAListResponse, GatewayCACreateResponse, GatewayCADeleteResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestGatewayCA:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: Cloudflare) -> None:
+ gateway_ca = client.zero_trust.access.gateway_ca.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[GatewayCACreateResponse], gateway_ca, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Cloudflare) -> None:
+ response = client.zero_trust.access.gateway_ca.with_raw_response.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ gateway_ca = response.parse()
+ assert_matches_type(Optional[GatewayCACreateResponse], gateway_ca, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: Cloudflare) -> None:
+ with client.zero_trust.access.gateway_ca.with_streaming_response.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ gateway_ca = response.parse()
+ assert_matches_type(Optional[GatewayCACreateResponse], gateway_ca, 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.access.gateway_ca.with_raw_response.create(
+ account_id="",
+ )
+
+ @parametrize
+ def test_method_list(self, client: Cloudflare) -> None:
+ gateway_ca = client.zero_trust.access.gateway_ca.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(SyncSinglePage[GatewayCAListResponse], gateway_ca, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Cloudflare) -> None:
+ response = client.zero_trust.access.gateway_ca.with_raw_response.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ gateway_ca = response.parse()
+ assert_matches_type(SyncSinglePage[GatewayCAListResponse], gateway_ca, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Cloudflare) -> None:
+ with client.zero_trust.access.gateway_ca.with_streaming_response.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ gateway_ca = response.parse()
+ assert_matches_type(SyncSinglePage[GatewayCAListResponse], gateway_ca, 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.access.gateway_ca.with_raw_response.list(
+ account_id="",
+ )
+
+ @parametrize
+ def test_method_delete(self, client: Cloudflare) -> None:
+ gateway_ca = client.zero_trust.access.gateway_ca.delete(
+ certificate_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[GatewayCADeleteResponse], gateway_ca, path=["response"])
+
+ @parametrize
+ def test_raw_response_delete(self, client: Cloudflare) -> None:
+ response = client.zero_trust.access.gateway_ca.with_raw_response.delete(
+ certificate_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ gateway_ca = response.parse()
+ assert_matches_type(Optional[GatewayCADeleteResponse], gateway_ca, path=["response"])
+
+ @parametrize
+ def test_streaming_response_delete(self, client: Cloudflare) -> None:
+ with client.zero_trust.access.gateway_ca.with_streaming_response.delete(
+ certificate_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ gateway_ca = response.parse()
+ assert_matches_type(Optional[GatewayCADeleteResponse], gateway_ca, 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.access.gateway_ca.with_raw_response.delete(
+ certificate_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `certificate_id` but received ''"):
+ client.zero_trust.access.gateway_ca.with_raw_response.delete(
+ certificate_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+
+class TestAsyncGatewayCA:
+ parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ async def test_method_create(self, async_client: AsyncCloudflare) -> None:
+ gateway_ca = await async_client.zero_trust.access.gateway_ca.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[GatewayCACreateResponse], gateway_ca, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.access.gateway_ca.with_raw_response.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ gateway_ca = await response.parse()
+ assert_matches_type(Optional[GatewayCACreateResponse], gateway_ca, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.access.gateway_ca.with_streaming_response.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ gateway_ca = await response.parse()
+ assert_matches_type(Optional[GatewayCACreateResponse], gateway_ca, 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.access.gateway_ca.with_raw_response.create(
+ account_id="",
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncCloudflare) -> None:
+ gateway_ca = await async_client.zero_trust.access.gateway_ca.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(AsyncSinglePage[GatewayCAListResponse], gateway_ca, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.access.gateway_ca.with_raw_response.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ gateway_ca = await response.parse()
+ assert_matches_type(AsyncSinglePage[GatewayCAListResponse], gateway_ca, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.access.gateway_ca.with_streaming_response.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ gateway_ca = await response.parse()
+ assert_matches_type(AsyncSinglePage[GatewayCAListResponse], gateway_ca, 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.access.gateway_ca.with_raw_response.list(
+ account_id="",
+ )
+
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncCloudflare) -> None:
+ gateway_ca = await async_client.zero_trust.access.gateway_ca.delete(
+ certificate_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[GatewayCADeleteResponse], gateway_ca, path=["response"])
+
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.access.gateway_ca.with_raw_response.delete(
+ certificate_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ gateway_ca = await response.parse()
+ assert_matches_type(Optional[GatewayCADeleteResponse], gateway_ca, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.access.gateway_ca.with_streaming_response.delete(
+ certificate_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ gateway_ca = await response.parse()
+ assert_matches_type(Optional[GatewayCADeleteResponse], gateway_ca, 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.access.gateway_ca.with_raw_response.delete(
+ certificate_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `certificate_id` but received ''"):
+ await async_client.zero_trust.access.gateway_ca.with_raw_response.delete(
+ certificate_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
diff --git a/tests/api_resources/zero_trust/dlp/email/__init__.py b/tests/api_resources/zero_trust/dlp/email/__init__.py
new file mode 100644
index 00000000000..fd8019a9a1a
--- /dev/null
+++ b/tests/api_resources/zero_trust/dlp/email/__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/email/test_account_mapping.py b/tests/api_resources/zero_trust/dlp/email/test_account_mapping.py
new file mode 100644
index 00000000000..3b8a84fb07d
--- /dev/null
+++ b/tests/api_resources/zero_trust/dlp/email/test_account_mapping.py
@@ -0,0 +1,209 @@
+# 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.email import (
+ AccountMappingGetResponse,
+ AccountMappingCreateResponse,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestAccountMapping:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: Cloudflare) -> None:
+ account_mapping = client.zero_trust.dlp.email.account_mapping.create(
+ account_id="account_id",
+ auth_requirements={
+ "allowed_microsoft_organizations": ["string"],
+ "type": "Org",
+ },
+ )
+ assert_matches_type(Optional[AccountMappingCreateResponse], account_mapping, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Cloudflare) -> None:
+ response = client.zero_trust.dlp.email.account_mapping.with_raw_response.create(
+ account_id="account_id",
+ auth_requirements={
+ "allowed_microsoft_organizations": ["string"],
+ "type": "Org",
+ },
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ account_mapping = response.parse()
+ assert_matches_type(Optional[AccountMappingCreateResponse], account_mapping, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: Cloudflare) -> None:
+ with client.zero_trust.dlp.email.account_mapping.with_streaming_response.create(
+ account_id="account_id",
+ auth_requirements={
+ "allowed_microsoft_organizations": ["string"],
+ "type": "Org",
+ },
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ account_mapping = response.parse()
+ assert_matches_type(Optional[AccountMappingCreateResponse], account_mapping, 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.email.account_mapping.with_raw_response.create(
+ account_id="",
+ auth_requirements={
+ "allowed_microsoft_organizations": ["string"],
+ "type": "Org",
+ },
+ )
+
+ @parametrize
+ def test_method_get(self, client: Cloudflare) -> None:
+ account_mapping = client.zero_trust.dlp.email.account_mapping.get(
+ account_id="account_id",
+ )
+ assert_matches_type(Optional[AccountMappingGetResponse], account_mapping, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Cloudflare) -> None:
+ response = client.zero_trust.dlp.email.account_mapping.with_raw_response.get(
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ account_mapping = response.parse()
+ assert_matches_type(Optional[AccountMappingGetResponse], account_mapping, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Cloudflare) -> None:
+ with client.zero_trust.dlp.email.account_mapping.with_streaming_response.get(
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ account_mapping = response.parse()
+ assert_matches_type(Optional[AccountMappingGetResponse], account_mapping, 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.email.account_mapping.with_raw_response.get(
+ account_id="",
+ )
+
+
+class TestAsyncAccountMapping:
+ parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ async def test_method_create(self, async_client: AsyncCloudflare) -> None:
+ account_mapping = await async_client.zero_trust.dlp.email.account_mapping.create(
+ account_id="account_id",
+ auth_requirements={
+ "allowed_microsoft_organizations": ["string"],
+ "type": "Org",
+ },
+ )
+ assert_matches_type(Optional[AccountMappingCreateResponse], account_mapping, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.dlp.email.account_mapping.with_raw_response.create(
+ account_id="account_id",
+ auth_requirements={
+ "allowed_microsoft_organizations": ["string"],
+ "type": "Org",
+ },
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ account_mapping = await response.parse()
+ assert_matches_type(Optional[AccountMappingCreateResponse], account_mapping, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.dlp.email.account_mapping.with_streaming_response.create(
+ account_id="account_id",
+ auth_requirements={
+ "allowed_microsoft_organizations": ["string"],
+ "type": "Org",
+ },
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ account_mapping = await response.parse()
+ assert_matches_type(Optional[AccountMappingCreateResponse], account_mapping, 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.email.account_mapping.with_raw_response.create(
+ account_id="",
+ auth_requirements={
+ "allowed_microsoft_organizations": ["string"],
+ "type": "Org",
+ },
+ )
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncCloudflare) -> None:
+ account_mapping = await async_client.zero_trust.dlp.email.account_mapping.get(
+ account_id="account_id",
+ )
+ assert_matches_type(Optional[AccountMappingGetResponse], account_mapping, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.dlp.email.account_mapping.with_raw_response.get(
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ account_mapping = await response.parse()
+ assert_matches_type(Optional[AccountMappingGetResponse], account_mapping, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.dlp.email.account_mapping.with_streaming_response.get(
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ account_mapping = await response.parse()
+ assert_matches_type(Optional[AccountMappingGetResponse], account_mapping, 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.email.account_mapping.with_raw_response.get(
+ account_id="",
+ )
diff --git a/tests/api_resources/zero_trust/dlp/email/test_rules.py b/tests/api_resources/zero_trust/dlp/email/test_rules.py
new file mode 100644
index 00000000000..f64c4040aa6
--- /dev/null
+++ b/tests/api_resources/zero_trust/dlp/email/test_rules.py
@@ -0,0 +1,820 @@
+# 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.email import (
+ RuleGetResponse,
+ RuleListResponse,
+ RuleCreateResponse,
+ RuleDeleteResponse,
+ RuleUpdateResponse,
+ RuleBulkEditResponse,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestRules:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: Cloudflare) -> None:
+ rule = client.zero_trust.dlp.email.rules.create(
+ account_id="account_id",
+ action={"action": "Block"},
+ conditions=[
+ {
+ "operator": "InList",
+ "selector": "Recipients",
+ "value": {},
+ }
+ ],
+ enabled=True,
+ name="name",
+ )
+ assert_matches_type(Optional[RuleCreateResponse], rule, path=["response"])
+
+ @parametrize
+ def test_method_create_with_all_params(self, client: Cloudflare) -> None:
+ rule = client.zero_trust.dlp.email.rules.create(
+ account_id="account_id",
+ action={
+ "action": "Block",
+ "message": "message",
+ },
+ conditions=[
+ {
+ "operator": "InList",
+ "selector": "Recipients",
+ "value": {},
+ }
+ ],
+ enabled=True,
+ name="name",
+ description="description",
+ )
+ assert_matches_type(Optional[RuleCreateResponse], rule, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Cloudflare) -> None:
+ response = client.zero_trust.dlp.email.rules.with_raw_response.create(
+ account_id="account_id",
+ action={"action": "Block"},
+ conditions=[
+ {
+ "operator": "InList",
+ "selector": "Recipients",
+ "value": {},
+ }
+ ],
+ enabled=True,
+ name="name",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ rule = response.parse()
+ assert_matches_type(Optional[RuleCreateResponse], rule, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: Cloudflare) -> None:
+ with client.zero_trust.dlp.email.rules.with_streaming_response.create(
+ account_id="account_id",
+ action={"action": "Block"},
+ conditions=[
+ {
+ "operator": "InList",
+ "selector": "Recipients",
+ "value": {},
+ }
+ ],
+ enabled=True,
+ name="name",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ rule = response.parse()
+ assert_matches_type(Optional[RuleCreateResponse], rule, 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.email.rules.with_raw_response.create(
+ account_id="",
+ action={"action": "Block"},
+ conditions=[
+ {
+ "operator": "InList",
+ "selector": "Recipients",
+ "value": {},
+ }
+ ],
+ enabled=True,
+ name="name",
+ )
+
+ @parametrize
+ def test_method_update(self, client: Cloudflare) -> None:
+ rule = client.zero_trust.dlp.email.rules.update(
+ rule_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="account_id",
+ action={"action": "Block"},
+ conditions=[
+ {
+ "operator": "InList",
+ "selector": "Recipients",
+ "value": {},
+ }
+ ],
+ enabled=True,
+ name="name",
+ )
+ assert_matches_type(Optional[RuleUpdateResponse], rule, path=["response"])
+
+ @parametrize
+ def test_method_update_with_all_params(self, client: Cloudflare) -> None:
+ rule = client.zero_trust.dlp.email.rules.update(
+ rule_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="account_id",
+ action={
+ "action": "Block",
+ "message": "message",
+ },
+ conditions=[
+ {
+ "operator": "InList",
+ "selector": "Recipients",
+ "value": {},
+ }
+ ],
+ enabled=True,
+ name="name",
+ description="description",
+ )
+ assert_matches_type(Optional[RuleUpdateResponse], rule, path=["response"])
+
+ @parametrize
+ def test_raw_response_update(self, client: Cloudflare) -> None:
+ response = client.zero_trust.dlp.email.rules.with_raw_response.update(
+ rule_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="account_id",
+ action={"action": "Block"},
+ conditions=[
+ {
+ "operator": "InList",
+ "selector": "Recipients",
+ "value": {},
+ }
+ ],
+ enabled=True,
+ name="name",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ rule = response.parse()
+ assert_matches_type(Optional[RuleUpdateResponse], rule, path=["response"])
+
+ @parametrize
+ def test_streaming_response_update(self, client: Cloudflare) -> None:
+ with client.zero_trust.dlp.email.rules.with_streaming_response.update(
+ rule_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="account_id",
+ action={"action": "Block"},
+ conditions=[
+ {
+ "operator": "InList",
+ "selector": "Recipients",
+ "value": {},
+ }
+ ],
+ enabled=True,
+ name="name",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ rule = response.parse()
+ assert_matches_type(Optional[RuleUpdateResponse], rule, 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.email.rules.with_raw_response.update(
+ rule_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="",
+ action={"action": "Block"},
+ conditions=[
+ {
+ "operator": "InList",
+ "selector": "Recipients",
+ "value": {},
+ }
+ ],
+ enabled=True,
+ name="name",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"):
+ client.zero_trust.dlp.email.rules.with_raw_response.update(
+ rule_id="",
+ account_id="account_id",
+ action={"action": "Block"},
+ conditions=[
+ {
+ "operator": "InList",
+ "selector": "Recipients",
+ "value": {},
+ }
+ ],
+ enabled=True,
+ name="name",
+ )
+
+ @parametrize
+ def test_method_list(self, client: Cloudflare) -> None:
+ rule = client.zero_trust.dlp.email.rules.list(
+ account_id="account_id",
+ )
+ assert_matches_type(SyncSinglePage[RuleListResponse], rule, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Cloudflare) -> None:
+ response = client.zero_trust.dlp.email.rules.with_raw_response.list(
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ rule = response.parse()
+ assert_matches_type(SyncSinglePage[RuleListResponse], rule, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Cloudflare) -> None:
+ with client.zero_trust.dlp.email.rules.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"
+
+ rule = response.parse()
+ assert_matches_type(SyncSinglePage[RuleListResponse], rule, 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.email.rules.with_raw_response.list(
+ account_id="",
+ )
+
+ @parametrize
+ def test_method_delete(self, client: Cloudflare) -> None:
+ rule = client.zero_trust.dlp.email.rules.delete(
+ rule_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="account_id",
+ )
+ assert_matches_type(Optional[RuleDeleteResponse], rule, path=["response"])
+
+ @parametrize
+ def test_raw_response_delete(self, client: Cloudflare) -> None:
+ response = client.zero_trust.dlp.email.rules.with_raw_response.delete(
+ rule_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"
+ rule = response.parse()
+ assert_matches_type(Optional[RuleDeleteResponse], rule, path=["response"])
+
+ @parametrize
+ def test_streaming_response_delete(self, client: Cloudflare) -> None:
+ with client.zero_trust.dlp.email.rules.with_streaming_response.delete(
+ rule_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"
+
+ rule = response.parse()
+ assert_matches_type(Optional[RuleDeleteResponse], rule, 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.email.rules.with_raw_response.delete(
+ rule_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"):
+ client.zero_trust.dlp.email.rules.with_raw_response.delete(
+ rule_id="",
+ account_id="account_id",
+ )
+
+ @parametrize
+ def test_method_bulk_edit(self, client: Cloudflare) -> None:
+ rule = client.zero_trust.dlp.email.rules.bulk_edit(
+ account_id="account_id",
+ new_priorities={"foo": 0},
+ )
+ assert_matches_type(Optional[RuleBulkEditResponse], rule, path=["response"])
+
+ @parametrize
+ def test_raw_response_bulk_edit(self, client: Cloudflare) -> None:
+ response = client.zero_trust.dlp.email.rules.with_raw_response.bulk_edit(
+ account_id="account_id",
+ new_priorities={"foo": 0},
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ rule = response.parse()
+ assert_matches_type(Optional[RuleBulkEditResponse], rule, path=["response"])
+
+ @parametrize
+ def test_streaming_response_bulk_edit(self, client: Cloudflare) -> None:
+ with client.zero_trust.dlp.email.rules.with_streaming_response.bulk_edit(
+ account_id="account_id",
+ new_priorities={"foo": 0},
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ rule = response.parse()
+ assert_matches_type(Optional[RuleBulkEditResponse], rule, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_bulk_edit(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.zero_trust.dlp.email.rules.with_raw_response.bulk_edit(
+ account_id="",
+ new_priorities={"foo": 0},
+ )
+
+ @parametrize
+ def test_method_get(self, client: Cloudflare) -> None:
+ rule = client.zero_trust.dlp.email.rules.get(
+ rule_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="account_id",
+ )
+ assert_matches_type(Optional[RuleGetResponse], rule, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Cloudflare) -> None:
+ response = client.zero_trust.dlp.email.rules.with_raw_response.get(
+ rule_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"
+ rule = response.parse()
+ assert_matches_type(Optional[RuleGetResponse], rule, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Cloudflare) -> None:
+ with client.zero_trust.dlp.email.rules.with_streaming_response.get(
+ rule_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"
+
+ rule = response.parse()
+ assert_matches_type(Optional[RuleGetResponse], rule, 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.email.rules.with_raw_response.get(
+ rule_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"):
+ client.zero_trust.dlp.email.rules.with_raw_response.get(
+ rule_id="",
+ account_id="account_id",
+ )
+
+
+class TestAsyncRules:
+ parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ async def test_method_create(self, async_client: AsyncCloudflare) -> None:
+ rule = await async_client.zero_trust.dlp.email.rules.create(
+ account_id="account_id",
+ action={"action": "Block"},
+ conditions=[
+ {
+ "operator": "InList",
+ "selector": "Recipients",
+ "value": {},
+ }
+ ],
+ enabled=True,
+ name="name",
+ )
+ assert_matches_type(Optional[RuleCreateResponse], rule, path=["response"])
+
+ @parametrize
+ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ rule = await async_client.zero_trust.dlp.email.rules.create(
+ account_id="account_id",
+ action={
+ "action": "Block",
+ "message": "message",
+ },
+ conditions=[
+ {
+ "operator": "InList",
+ "selector": "Recipients",
+ "value": {},
+ }
+ ],
+ enabled=True,
+ name="name",
+ description="description",
+ )
+ assert_matches_type(Optional[RuleCreateResponse], rule, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.dlp.email.rules.with_raw_response.create(
+ account_id="account_id",
+ action={"action": "Block"},
+ conditions=[
+ {
+ "operator": "InList",
+ "selector": "Recipients",
+ "value": {},
+ }
+ ],
+ enabled=True,
+ name="name",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ rule = await response.parse()
+ assert_matches_type(Optional[RuleCreateResponse], rule, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.dlp.email.rules.with_streaming_response.create(
+ account_id="account_id",
+ action={"action": "Block"},
+ conditions=[
+ {
+ "operator": "InList",
+ "selector": "Recipients",
+ "value": {},
+ }
+ ],
+ enabled=True,
+ name="name",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ rule = await response.parse()
+ assert_matches_type(Optional[RuleCreateResponse], rule, 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.email.rules.with_raw_response.create(
+ account_id="",
+ action={"action": "Block"},
+ conditions=[
+ {
+ "operator": "InList",
+ "selector": "Recipients",
+ "value": {},
+ }
+ ],
+ enabled=True,
+ name="name",
+ )
+
+ @parametrize
+ async def test_method_update(self, async_client: AsyncCloudflare) -> None:
+ rule = await async_client.zero_trust.dlp.email.rules.update(
+ rule_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="account_id",
+ action={"action": "Block"},
+ conditions=[
+ {
+ "operator": "InList",
+ "selector": "Recipients",
+ "value": {},
+ }
+ ],
+ enabled=True,
+ name="name",
+ )
+ assert_matches_type(Optional[RuleUpdateResponse], rule, path=["response"])
+
+ @parametrize
+ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ rule = await async_client.zero_trust.dlp.email.rules.update(
+ rule_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="account_id",
+ action={
+ "action": "Block",
+ "message": "message",
+ },
+ conditions=[
+ {
+ "operator": "InList",
+ "selector": "Recipients",
+ "value": {},
+ }
+ ],
+ enabled=True,
+ name="name",
+ description="description",
+ )
+ assert_matches_type(Optional[RuleUpdateResponse], rule, path=["response"])
+
+ @parametrize
+ async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.dlp.email.rules.with_raw_response.update(
+ rule_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="account_id",
+ action={"action": "Block"},
+ conditions=[
+ {
+ "operator": "InList",
+ "selector": "Recipients",
+ "value": {},
+ }
+ ],
+ enabled=True,
+ name="name",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ rule = await response.parse()
+ assert_matches_type(Optional[RuleUpdateResponse], rule, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.dlp.email.rules.with_streaming_response.update(
+ rule_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="account_id",
+ action={"action": "Block"},
+ conditions=[
+ {
+ "operator": "InList",
+ "selector": "Recipients",
+ "value": {},
+ }
+ ],
+ enabled=True,
+ name="name",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ rule = await response.parse()
+ assert_matches_type(Optional[RuleUpdateResponse], rule, 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.email.rules.with_raw_response.update(
+ rule_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="",
+ action={"action": "Block"},
+ conditions=[
+ {
+ "operator": "InList",
+ "selector": "Recipients",
+ "value": {},
+ }
+ ],
+ enabled=True,
+ name="name",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"):
+ await async_client.zero_trust.dlp.email.rules.with_raw_response.update(
+ rule_id="",
+ account_id="account_id",
+ action={"action": "Block"},
+ conditions=[
+ {
+ "operator": "InList",
+ "selector": "Recipients",
+ "value": {},
+ }
+ ],
+ enabled=True,
+ name="name",
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncCloudflare) -> None:
+ rule = await async_client.zero_trust.dlp.email.rules.list(
+ account_id="account_id",
+ )
+ assert_matches_type(AsyncSinglePage[RuleListResponse], rule, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.dlp.email.rules.with_raw_response.list(
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ rule = await response.parse()
+ assert_matches_type(AsyncSinglePage[RuleListResponse], rule, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.dlp.email.rules.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"
+
+ rule = await response.parse()
+ assert_matches_type(AsyncSinglePage[RuleListResponse], rule, 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.email.rules.with_raw_response.list(
+ account_id="",
+ )
+
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncCloudflare) -> None:
+ rule = await async_client.zero_trust.dlp.email.rules.delete(
+ rule_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="account_id",
+ )
+ assert_matches_type(Optional[RuleDeleteResponse], rule, path=["response"])
+
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.dlp.email.rules.with_raw_response.delete(
+ rule_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"
+ rule = await response.parse()
+ assert_matches_type(Optional[RuleDeleteResponse], rule, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.dlp.email.rules.with_streaming_response.delete(
+ rule_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"
+
+ rule = await response.parse()
+ assert_matches_type(Optional[RuleDeleteResponse], rule, 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.email.rules.with_raw_response.delete(
+ rule_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"):
+ await async_client.zero_trust.dlp.email.rules.with_raw_response.delete(
+ rule_id="",
+ account_id="account_id",
+ )
+
+ @parametrize
+ async def test_method_bulk_edit(self, async_client: AsyncCloudflare) -> None:
+ rule = await async_client.zero_trust.dlp.email.rules.bulk_edit(
+ account_id="account_id",
+ new_priorities={"foo": 0},
+ )
+ assert_matches_type(Optional[RuleBulkEditResponse], rule, path=["response"])
+
+ @parametrize
+ async def test_raw_response_bulk_edit(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.dlp.email.rules.with_raw_response.bulk_edit(
+ account_id="account_id",
+ new_priorities={"foo": 0},
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ rule = await response.parse()
+ assert_matches_type(Optional[RuleBulkEditResponse], rule, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_bulk_edit(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.dlp.email.rules.with_streaming_response.bulk_edit(
+ account_id="account_id",
+ new_priorities={"foo": 0},
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ rule = await response.parse()
+ assert_matches_type(Optional[RuleBulkEditResponse], rule, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_bulk_edit(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.zero_trust.dlp.email.rules.with_raw_response.bulk_edit(
+ account_id="",
+ new_priorities={"foo": 0},
+ )
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncCloudflare) -> None:
+ rule = await async_client.zero_trust.dlp.email.rules.get(
+ rule_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="account_id",
+ )
+ assert_matches_type(Optional[RuleGetResponse], rule, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.dlp.email.rules.with_raw_response.get(
+ rule_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"
+ rule = await response.parse()
+ assert_matches_type(Optional[RuleGetResponse], rule, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.dlp.email.rules.with_streaming_response.get(
+ rule_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"
+
+ rule = await response.parse()
+ assert_matches_type(Optional[RuleGetResponse], rule, 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.email.rules.with_raw_response.get(
+ rule_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `rule_id` but received ''"):
+ await async_client.zero_trust.dlp.email.rules.with_raw_response.get(
+ rule_id="",
+ account_id="account_id",
+ )