From 8c548f7bb0b4447f013db23642bfaff5357d5244 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 6 Jun 2024 23:21:30 +0000
Subject: [PATCH] feat(api): update via SDK Studio (#862)
---
.stats.yml | 2 +-
api.md | 43 +-
src/cloudflare/resources/dns/__init__.py | 14 +
src/cloudflare/resources/dns/dns.py | 32 +
src/cloudflare/resources/dns/settings.py | 311 +++++++
.../resources/zero_trust/access/__init__.py | 14 +
.../resources/zero_trust/access/access.py | 32 +
.../resources/zero_trust/access/policies.py | 784 ++++++++++++++++++
src/cloudflare/types/dns/__init__.py | 7 +
src/cloudflare/types/dns/dns_setting.py | 76 ++
src/cloudflare/types/dns/dns_setting_param.py | 76 ++
src/cloudflare/types/dns/nameserver.py | 12 +
src/cloudflare/types/dns/nameserver_param.py | 12 +
.../types/dns/setting_edit_params.py | 19 +
.../types/dns/setting_edit_response.py | 12 +
.../types/dns/setting_get_response.py | 12 +
.../types/zero_trust/access/__init__.py | 7 +
.../zero_trust/access/policy_create_params.py | 70 ++
.../access/policy_create_response.py | 79 ++
.../access/policy_delete_response.py | 12 +
.../zero_trust/access/policy_get_response.py | 79 ++
.../zero_trust/access/policy_list_response.py | 79 ++
.../zero_trust/access/policy_update_params.py | 70 ++
.../access/policy_update_response.py | 79 ++
tests/api_resources/dns/test_settings.py | 256 ++++++
.../zero_trust/access/test_policies.py | 761 +++++++++++++++++
26 files changed, 2941 insertions(+), 9 deletions(-)
create mode 100644 src/cloudflare/resources/dns/settings.py
create mode 100644 src/cloudflare/resources/zero_trust/access/policies.py
create mode 100644 src/cloudflare/types/dns/dns_setting.py
create mode 100644 src/cloudflare/types/dns/dns_setting_param.py
create mode 100644 src/cloudflare/types/dns/nameserver.py
create mode 100644 src/cloudflare/types/dns/nameserver_param.py
create mode 100644 src/cloudflare/types/dns/setting_edit_params.py
create mode 100644 src/cloudflare/types/dns/setting_edit_response.py
create mode 100644 src/cloudflare/types/dns/setting_get_response.py
create mode 100644 src/cloudflare/types/zero_trust/access/policy_create_params.py
create mode 100644 src/cloudflare/types/zero_trust/access/policy_create_response.py
create mode 100644 src/cloudflare/types/zero_trust/access/policy_delete_response.py
create mode 100644 src/cloudflare/types/zero_trust/access/policy_get_response.py
create mode 100644 src/cloudflare/types/zero_trust/access/policy_list_response.py
create mode 100644 src/cloudflare/types/zero_trust/access/policy_update_params.py
create mode 100644 src/cloudflare/types/zero_trust/access/policy_update_response.py
create mode 100644 tests/api_resources/dns/test_settings.py
create mode 100644 tests/api_resources/zero_trust/access/test_policies.py
diff --git a/.stats.yml b/.stats.yml
index 5cc013e4dcc..563ec8b4af0 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,2 +1,2 @@
-configured_endpoints: 1336
+configured_endpoints: 1343
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare%2Fcloudflare-efdb1c15faba015f2904e7db0946e71b5bd84a6e4b96256aed210e7e0113cf17.yml
diff --git a/api.md b/api.md
index 81d0684fe74..c59b31a84a1 100644
--- a/api.md
+++ b/api.md
@@ -303,14 +303,6 @@ Methods:
- client.zones.activation_check.trigger(\*, zone_id) -> Optional
-## DNSSettings
-
-Types:
-
-```python
-from cloudflare.types.zones import DNSSetting, Nameserver
-```
-
## Settings
### ZeroRTT
@@ -1650,6 +1642,19 @@ Methods:
- client.dns.records.import\_(\*, zone_id, \*\*params) -> Optional
- client.dns.records.scan(\*, zone_id, \*\*params) -> Optional
+## Settings
+
+Types:
+
+```python
+from cloudflare.types.dns import DNSSetting, Nameserver, SettingEditResponse, SettingGetResponse
+```
+
+Methods:
+
+- client.dns.settings.edit(\*, account_id, zone_id, \*\*params) -> Optional
+- client.dns.settings.get(\*, account_id, zone_id) -> Optional
+
## Analytics
### Reports
@@ -5635,6 +5640,28 @@ Methods:
- client.zero_trust.access.tags.delete(tag_name, \*, account_id) -> Optional
- client.zero_trust.access.tags.get(tag_name, \*, account_id) -> Optional
+### Policies
+
+Types:
+
+```python
+from cloudflare.types.zero_trust.access import (
+ PolicyCreateResponse,
+ PolicyUpdateResponse,
+ PolicyListResponse,
+ PolicyDeleteResponse,
+ PolicyGetResponse,
+)
+```
+
+Methods:
+
+- client.zero_trust.access.policies.create(\*, account_id, \*\*params) -> Optional
+- client.zero_trust.access.policies.update(policy_id, \*, account_id, \*\*params) -> Optional
+- client.zero_trust.access.policies.list(\*, account_id) -> SyncSinglePage[PolicyListResponse]
+- client.zero_trust.access.policies.delete(policy_id, \*, account_id) -> Optional
+- client.zero_trust.access.policies.get(policy_id, \*, account_id) -> Optional
+
## DEX
Types:
diff --git a/src/cloudflare/resources/dns/__init__.py b/src/cloudflare/resources/dns/__init__.py
index 6f835256c8d..7e394f00159 100644
--- a/src/cloudflare/resources/dns/__init__.py
+++ b/src/cloudflare/resources/dns/__init__.py
@@ -24,6 +24,14 @@
FirewallResourceWithStreamingResponse,
AsyncFirewallResourceWithStreamingResponse,
)
+from .settings import (
+ SettingsResource,
+ AsyncSettingsResource,
+ SettingsResourceWithRawResponse,
+ AsyncSettingsResourceWithRawResponse,
+ SettingsResourceWithStreamingResponse,
+ AsyncSettingsResourceWithStreamingResponse,
+)
from .analytics import (
AnalyticsResource,
AsyncAnalyticsResource,
@@ -40,6 +48,12 @@
"AsyncRecordsResourceWithRawResponse",
"RecordsResourceWithStreamingResponse",
"AsyncRecordsResourceWithStreamingResponse",
+ "SettingsResource",
+ "AsyncSettingsResource",
+ "SettingsResourceWithRawResponse",
+ "AsyncSettingsResourceWithRawResponse",
+ "SettingsResourceWithStreamingResponse",
+ "AsyncSettingsResourceWithStreamingResponse",
"AnalyticsResource",
"AsyncAnalyticsResource",
"AnalyticsResourceWithRawResponse",
diff --git a/src/cloudflare/resources/dns/dns.py b/src/cloudflare/resources/dns/dns.py
index 2f71f123a84..7f758f9e906 100644
--- a/src/cloudflare/resources/dns/dns.py
+++ b/src/cloudflare/resources/dns/dns.py
@@ -18,6 +18,14 @@
FirewallResourceWithStreamingResponse,
AsyncFirewallResourceWithStreamingResponse,
)
+from .settings import (
+ SettingsResource,
+ AsyncSettingsResource,
+ SettingsResourceWithRawResponse,
+ AsyncSettingsResourceWithRawResponse,
+ SettingsResourceWithStreamingResponse,
+ AsyncSettingsResourceWithStreamingResponse,
+)
from ..._compat import cached_property
from .analytics import (
AnalyticsResource,
@@ -39,6 +47,10 @@ class DNSResource(SyncAPIResource):
def records(self) -> RecordsResource:
return RecordsResource(self._client)
+ @cached_property
+ def settings(self) -> SettingsResource:
+ return SettingsResource(self._client)
+
@cached_property
def analytics(self) -> AnalyticsResource:
return AnalyticsResource(self._client)
@@ -61,6 +73,10 @@ class AsyncDNSResource(AsyncAPIResource):
def records(self) -> AsyncRecordsResource:
return AsyncRecordsResource(self._client)
+ @cached_property
+ def settings(self) -> AsyncSettingsResource:
+ return AsyncSettingsResource(self._client)
+
@cached_property
def analytics(self) -> AsyncAnalyticsResource:
return AsyncAnalyticsResource(self._client)
@@ -86,6 +102,10 @@ def __init__(self, dns: DNSResource) -> None:
def records(self) -> RecordsResourceWithRawResponse:
return RecordsResourceWithRawResponse(self._dns.records)
+ @cached_property
+ def settings(self) -> SettingsResourceWithRawResponse:
+ return SettingsResourceWithRawResponse(self._dns.settings)
+
@cached_property
def analytics(self) -> AnalyticsResourceWithRawResponse:
return AnalyticsResourceWithRawResponse(self._dns.analytics)
@@ -103,6 +123,10 @@ def __init__(self, dns: AsyncDNSResource) -> None:
def records(self) -> AsyncRecordsResourceWithRawResponse:
return AsyncRecordsResourceWithRawResponse(self._dns.records)
+ @cached_property
+ def settings(self) -> AsyncSettingsResourceWithRawResponse:
+ return AsyncSettingsResourceWithRawResponse(self._dns.settings)
+
@cached_property
def analytics(self) -> AsyncAnalyticsResourceWithRawResponse:
return AsyncAnalyticsResourceWithRawResponse(self._dns.analytics)
@@ -120,6 +144,10 @@ def __init__(self, dns: DNSResource) -> None:
def records(self) -> RecordsResourceWithStreamingResponse:
return RecordsResourceWithStreamingResponse(self._dns.records)
+ @cached_property
+ def settings(self) -> SettingsResourceWithStreamingResponse:
+ return SettingsResourceWithStreamingResponse(self._dns.settings)
+
@cached_property
def analytics(self) -> AnalyticsResourceWithStreamingResponse:
return AnalyticsResourceWithStreamingResponse(self._dns.analytics)
@@ -137,6 +165,10 @@ def __init__(self, dns: AsyncDNSResource) -> None:
def records(self) -> AsyncRecordsResourceWithStreamingResponse:
return AsyncRecordsResourceWithStreamingResponse(self._dns.records)
+ @cached_property
+ def settings(self) -> AsyncSettingsResourceWithStreamingResponse:
+ return AsyncSettingsResourceWithStreamingResponse(self._dns.settings)
+
@cached_property
def analytics(self) -> AsyncAnalyticsResourceWithStreamingResponse:
return AsyncAnalyticsResourceWithStreamingResponse(self._dns.analytics)
diff --git a/src/cloudflare/resources/dns/settings.py b/src/cloudflare/resources/dns/settings.py
new file mode 100644
index 00000000000..635b4b77250
--- /dev/null
+++ b/src/cloudflare/resources/dns/settings.py
@@ -0,0 +1,311 @@
+# 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 ...types.dns import setting_edit_params
+from ..._base_client import (
+ make_request_options,
+)
+from ...types.dns.dns_setting_param import DNSSettingParam
+from ...types.dns.setting_get_response import SettingGetResponse
+from ...types.dns.setting_edit_response import SettingEditResponse
+
+__all__ = ["SettingsResource", "AsyncSettingsResource"]
+
+
+class SettingsResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> SettingsResourceWithRawResponse:
+ return SettingsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> SettingsResourceWithStreamingResponse:
+ return SettingsResourceWithStreamingResponse(self)
+
+ def edit(
+ self,
+ *,
+ account_id: str | NotGiven = NOT_GIVEN,
+ zone_id: str | NotGiven = NOT_GIVEN,
+ zone_defaults: DNSSettingParam | 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[SettingEditResponse]:
+ """
+ Update DNS settings for an account or zone
+
+ Args:
+ account_id: The Account ID to use for this endpoint. Mutually exclusive with the Zone ID.
+
+ zone_id: The Zone ID to use for this endpoint. Mutually exclusive with the Account ID.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if account_id and zone_id:
+ raise ValueError("You cannot provide both account_id and zone_id")
+
+ if account_id:
+ account_or_zone = "accounts"
+ account_or_zone_id = account_id
+ else:
+ if not zone_id:
+ raise ValueError("You must provide either account_id or zone_id")
+
+ account_or_zone = "zones"
+ account_or_zone_id = zone_id
+ return self._patch(
+ f"/{account_or_zone}/{account_or_zone_id}/dns_settings",
+ body=maybe_transform({"zone_defaults": zone_defaults}, setting_edit_params.SettingEditParams),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[SettingEditResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[SettingEditResponse]], ResultWrapper[SettingEditResponse]),
+ )
+
+ def get(
+ self,
+ *,
+ account_id: str | NotGiven = NOT_GIVEN,
+ zone_id: 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[SettingGetResponse]:
+ """
+ Show DNS settings for an account or zone
+
+ Args:
+ account_id: The Account ID to use for this endpoint. Mutually exclusive with the Zone ID.
+
+ zone_id: The Zone ID to use for this endpoint. Mutually exclusive with the Account ID.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if account_id and zone_id:
+ raise ValueError("You cannot provide both account_id and zone_id")
+
+ if account_id:
+ account_or_zone = "accounts"
+ account_or_zone_id = account_id
+ else:
+ if not zone_id:
+ raise ValueError("You must provide either account_id or zone_id")
+
+ account_or_zone = "zones"
+ account_or_zone_id = zone_id
+ return self._get(
+ f"/{account_or_zone}/{account_or_zone_id}/dns_settings",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[SettingGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[SettingGetResponse]], ResultWrapper[SettingGetResponse]),
+ )
+
+
+class AsyncSettingsResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncSettingsResourceWithRawResponse:
+ return AsyncSettingsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncSettingsResourceWithStreamingResponse:
+ return AsyncSettingsResourceWithStreamingResponse(self)
+
+ async def edit(
+ self,
+ *,
+ account_id: str | NotGiven = NOT_GIVEN,
+ zone_id: str | NotGiven = NOT_GIVEN,
+ zone_defaults: DNSSettingParam | 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[SettingEditResponse]:
+ """
+ Update DNS settings for an account or zone
+
+ Args:
+ account_id: The Account ID to use for this endpoint. Mutually exclusive with the Zone ID.
+
+ zone_id: The Zone ID to use for this endpoint. Mutually exclusive with the Account ID.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if account_id and zone_id:
+ raise ValueError("You cannot provide both account_id and zone_id")
+
+ if account_id:
+ account_or_zone = "accounts"
+ account_or_zone_id = account_id
+ else:
+ if not zone_id:
+ raise ValueError("You must provide either account_id or zone_id")
+
+ account_or_zone = "zones"
+ account_or_zone_id = zone_id
+ return await self._patch(
+ f"/{account_or_zone}/{account_or_zone_id}/dns_settings",
+ body=await async_maybe_transform({"zone_defaults": zone_defaults}, setting_edit_params.SettingEditParams),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[SettingEditResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[SettingEditResponse]], ResultWrapper[SettingEditResponse]),
+ )
+
+ async def get(
+ self,
+ *,
+ account_id: str | NotGiven = NOT_GIVEN,
+ zone_id: 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[SettingGetResponse]:
+ """
+ Show DNS settings for an account or zone
+
+ Args:
+ account_id: The Account ID to use for this endpoint. Mutually exclusive with the Zone ID.
+
+ zone_id: The Zone ID to use for this endpoint. Mutually exclusive with the Account ID.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if account_id and zone_id:
+ raise ValueError("You cannot provide both account_id and zone_id")
+
+ if account_id:
+ account_or_zone = "accounts"
+ account_or_zone_id = account_id
+ else:
+ if not zone_id:
+ raise ValueError("You must provide either account_id or zone_id")
+
+ account_or_zone = "zones"
+ account_or_zone_id = zone_id
+ return await self._get(
+ f"/{account_or_zone}/{account_or_zone_id}/dns_settings",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[SettingGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[SettingGetResponse]], ResultWrapper[SettingGetResponse]),
+ )
+
+
+class SettingsResourceWithRawResponse:
+ def __init__(self, settings: SettingsResource) -> None:
+ self._settings = settings
+
+ self.edit = to_raw_response_wrapper(
+ settings.edit,
+ )
+ self.get = to_raw_response_wrapper(
+ settings.get,
+ )
+
+
+class AsyncSettingsResourceWithRawResponse:
+ def __init__(self, settings: AsyncSettingsResource) -> None:
+ self._settings = settings
+
+ self.edit = async_to_raw_response_wrapper(
+ settings.edit,
+ )
+ self.get = async_to_raw_response_wrapper(
+ settings.get,
+ )
+
+
+class SettingsResourceWithStreamingResponse:
+ def __init__(self, settings: SettingsResource) -> None:
+ self._settings = settings
+
+ self.edit = to_streamed_response_wrapper(
+ settings.edit,
+ )
+ self.get = to_streamed_response_wrapper(
+ settings.get,
+ )
+
+
+class AsyncSettingsResourceWithStreamingResponse:
+ def __init__(self, settings: AsyncSettingsResource) -> None:
+ self._settings = settings
+
+ self.edit = async_to_streamed_response_wrapper(
+ settings.edit,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ settings.get,
+ )
diff --git a/src/cloudflare/resources/zero_trust/access/__init__.py b/src/cloudflare/resources/zero_trust/access/__init__.py
index b34af407a86..d3fe1996f9d 100644
--- a/src/cloudflare/resources/zero_trust/access/__init__.py
+++ b/src/cloudflare/resources/zero_trust/access/__init__.py
@@ -48,6 +48,14 @@
GroupsResourceWithStreamingResponse,
AsyncGroupsResourceWithStreamingResponse,
)
+from .policies import (
+ PoliciesResource,
+ AsyncPoliciesResource,
+ PoliciesResourceWithRawResponse,
+ AsyncPoliciesResourceWithRawResponse,
+ PoliciesResourceWithStreamingResponse,
+ AsyncPoliciesResourceWithStreamingResponse,
+)
from .bookmarks import (
BookmarksResource,
AsyncBookmarksResource,
@@ -150,6 +158,12 @@
"AsyncTagsResourceWithRawResponse",
"TagsResourceWithStreamingResponse",
"AsyncTagsResourceWithStreamingResponse",
+ "PoliciesResource",
+ "AsyncPoliciesResource",
+ "PoliciesResourceWithRawResponse",
+ "AsyncPoliciesResourceWithRawResponse",
+ "PoliciesResourceWithStreamingResponse",
+ "AsyncPoliciesResourceWithStreamingResponse",
"AccessResource",
"AsyncAccessResource",
"AccessResourceWithRawResponse",
diff --git a/src/cloudflare/resources/zero_trust/access/access.py b/src/cloudflare/resources/zero_trust/access/access.py
index 6707c0f7745..b0be13c5cb8 100644
--- a/src/cloudflare/resources/zero_trust/access/access.py
+++ b/src/cloudflare/resources/zero_trust/access/access.py
@@ -42,6 +42,14 @@
GroupsResourceWithStreamingResponse,
AsyncGroupsResourceWithStreamingResponse,
)
+from .policies import (
+ PoliciesResource,
+ AsyncPoliciesResource,
+ PoliciesResourceWithRawResponse,
+ AsyncPoliciesResourceWithRawResponse,
+ PoliciesResourceWithStreamingResponse,
+ AsyncPoliciesResourceWithStreamingResponse,
+)
from .bookmarks import (
BookmarksResource,
AsyncBookmarksResource,
@@ -133,6 +141,10 @@ def custom_pages(self) -> CustomPagesResource:
def tags(self) -> TagsResource:
return TagsResource(self._client)
+ @cached_property
+ def policies(self) -> PoliciesResource:
+ return PoliciesResource(self._client)
+
@cached_property
def with_raw_response(self) -> AccessResourceWithRawResponse:
return AccessResourceWithRawResponse(self)
@@ -183,6 +195,10 @@ def custom_pages(self) -> AsyncCustomPagesResource:
def tags(self) -> AsyncTagsResource:
return AsyncTagsResource(self._client)
+ @cached_property
+ def policies(self) -> AsyncPoliciesResource:
+ return AsyncPoliciesResource(self._client)
+
@cached_property
def with_raw_response(self) -> AsyncAccessResourceWithRawResponse:
return AsyncAccessResourceWithRawResponse(self)
@@ -236,6 +252,10 @@ def custom_pages(self) -> CustomPagesResourceWithRawResponse:
def tags(self) -> TagsResourceWithRawResponse:
return TagsResourceWithRawResponse(self._access.tags)
+ @cached_property
+ def policies(self) -> PoliciesResourceWithRawResponse:
+ return PoliciesResourceWithRawResponse(self._access.policies)
+
class AsyncAccessResourceWithRawResponse:
def __init__(self, access: AsyncAccessResource) -> None:
@@ -281,6 +301,10 @@ def custom_pages(self) -> AsyncCustomPagesResourceWithRawResponse:
def tags(self) -> AsyncTagsResourceWithRawResponse:
return AsyncTagsResourceWithRawResponse(self._access.tags)
+ @cached_property
+ def policies(self) -> AsyncPoliciesResourceWithRawResponse:
+ return AsyncPoliciesResourceWithRawResponse(self._access.policies)
+
class AccessResourceWithStreamingResponse:
def __init__(self, access: AccessResource) -> None:
@@ -326,6 +350,10 @@ def custom_pages(self) -> CustomPagesResourceWithStreamingResponse:
def tags(self) -> TagsResourceWithStreamingResponse:
return TagsResourceWithStreamingResponse(self._access.tags)
+ @cached_property
+ def policies(self) -> PoliciesResourceWithStreamingResponse:
+ return PoliciesResourceWithStreamingResponse(self._access.policies)
+
class AsyncAccessResourceWithStreamingResponse:
def __init__(self, access: AsyncAccessResource) -> None:
@@ -370,3 +398,7 @@ def custom_pages(self) -> AsyncCustomPagesResourceWithStreamingResponse:
@cached_property
def tags(self) -> AsyncTagsResourceWithStreamingResponse:
return AsyncTagsResourceWithStreamingResponse(self._access.tags)
+
+ @cached_property
+ def policies(self) -> AsyncPoliciesResourceWithStreamingResponse:
+ return AsyncPoliciesResourceWithStreamingResponse(self._access.policies)
diff --git a/src/cloudflare/resources/zero_trust/access/policies.py b/src/cloudflare/resources/zero_trust/access/policies.py
new file mode 100644
index 00000000000..6cddea86c29
--- /dev/null
+++ b/src/cloudflare/resources/zero_trust/access/policies.py
@@ -0,0 +1,784 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Type, Iterable, Optional, cast
+
+import httpx
+
+from ...._types import 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.access import Decision, policy_create_params, policy_update_params
+from ....types.zero_trust.access.decision import Decision
+from ....types.zero_trust.access_rule_param import AccessRuleParam
+from ....types.zero_trust.access.policy_get_response import PolicyGetResponse
+from ....types.zero_trust.access.policy_list_response import PolicyListResponse
+from ....types.zero_trust.access.policy_create_response import PolicyCreateResponse
+from ....types.zero_trust.access.policy_delete_response import PolicyDeleteResponse
+from ....types.zero_trust.access.policy_update_response import PolicyUpdateResponse
+from ....types.zero_trust.access.applications.approval_group_param import ApprovalGroupParam
+
+__all__ = ["PoliciesResource", "AsyncPoliciesResource"]
+
+
+class PoliciesResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> PoliciesResourceWithRawResponse:
+ return PoliciesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> PoliciesResourceWithStreamingResponse:
+ return PoliciesResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ *,
+ account_id: str,
+ decision: Decision,
+ include: Iterable[AccessRuleParam],
+ name: str,
+ approval_groups: Iterable[ApprovalGroupParam] | NotGiven = NOT_GIVEN,
+ approval_required: bool | NotGiven = NOT_GIVEN,
+ exclude: Iterable[AccessRuleParam] | NotGiven = NOT_GIVEN,
+ isolation_required: bool | NotGiven = NOT_GIVEN,
+ purpose_justification_prompt: str | NotGiven = NOT_GIVEN,
+ purpose_justification_required: bool | NotGiven = NOT_GIVEN,
+ require: Iterable[AccessRuleParam] | NotGiven = NOT_GIVEN,
+ session_duration: 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[PolicyCreateResponse]:
+ """
+ Creates a new Access reusable policy.
+
+ Args:
+ account_id: Identifier
+
+ decision: The action Access will take if a user matches this policy.
+
+ include: Rules evaluated with an OR logical operator. A user needs to meet only one of
+ the Include rules.
+
+ name: The name of the Access policy.
+
+ approval_groups: Administrators who can approve a temporary authentication request.
+
+ approval_required: Requires the user to request access from an administrator at the start of each
+ session.
+
+ exclude: Rules evaluated with a NOT logical operator. To match the policy, a user cannot
+ meet any of the Exclude rules.
+
+ isolation_required: Require this application to be served in an isolated browser for users matching
+ this policy. 'Client Web Isolation' must be on for the account in order to use
+ this feature.
+
+ purpose_justification_prompt: A custom message that will appear on the purpose justification screen.
+
+ purpose_justification_required: Require users to enter a justification when they log in to the application.
+
+ require: Rules evaluated with an AND logical operator. To match the policy, a user must
+ meet all of the Require rules.
+
+ session_duration: The amount of time that tokens issued for the application will be valid. Must be
+ in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, s,
+ m, h.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for 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/policies",
+ body=maybe_transform(
+ {
+ "decision": decision,
+ "include": include,
+ "name": name,
+ "approval_groups": approval_groups,
+ "approval_required": approval_required,
+ "exclude": exclude,
+ "isolation_required": isolation_required,
+ "purpose_justification_prompt": purpose_justification_prompt,
+ "purpose_justification_required": purpose_justification_required,
+ "require": require,
+ "session_duration": session_duration,
+ },
+ policy_create_params.PolicyCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[PolicyCreateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[PolicyCreateResponse]], ResultWrapper[PolicyCreateResponse]),
+ )
+
+ def update(
+ self,
+ policy_id: str,
+ *,
+ account_id: str,
+ decision: Decision,
+ include: Iterable[AccessRuleParam],
+ name: str,
+ approval_groups: Iterable[ApprovalGroupParam] | NotGiven = NOT_GIVEN,
+ approval_required: bool | NotGiven = NOT_GIVEN,
+ exclude: Iterable[AccessRuleParam] | NotGiven = NOT_GIVEN,
+ isolation_required: bool | NotGiven = NOT_GIVEN,
+ purpose_justification_prompt: str | NotGiven = NOT_GIVEN,
+ purpose_justification_required: bool | NotGiven = NOT_GIVEN,
+ require: Iterable[AccessRuleParam] | NotGiven = NOT_GIVEN,
+ session_duration: 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[PolicyUpdateResponse]:
+ """
+ Updates a Access reusable policy.
+
+ Args:
+ account_id: Identifier
+
+ policy_id: The UUID of the policy
+
+ decision: The action Access will take if a user matches this policy.
+
+ include: Rules evaluated with an OR logical operator. A user needs to meet only one of
+ the Include rules.
+
+ name: The name of the Access policy.
+
+ approval_groups: Administrators who can approve a temporary authentication request.
+
+ approval_required: Requires the user to request access from an administrator at the start of each
+ session.
+
+ exclude: Rules evaluated with a NOT logical operator. To match the policy, a user cannot
+ meet any of the Exclude rules.
+
+ isolation_required: Require this application to be served in an isolated browser for users matching
+ this policy. 'Client Web Isolation' must be on for the account in order to use
+ this feature.
+
+ purpose_justification_prompt: A custom message that will appear on the purpose justification screen.
+
+ purpose_justification_required: Require users to enter a justification when they log in to the application.
+
+ require: Rules evaluated with an AND logical operator. To match the policy, a user must
+ meet all of the Require rules.
+
+ session_duration: The amount of time that tokens issued for the application will be valid. Must be
+ in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, s,
+ m, h.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for 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 policy_id:
+ raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}")
+ return self._put(
+ f"/accounts/{account_id}/access/policies/{policy_id}",
+ body=maybe_transform(
+ {
+ "decision": decision,
+ "include": include,
+ "name": name,
+ "approval_groups": approval_groups,
+ "approval_required": approval_required,
+ "exclude": exclude,
+ "isolation_required": isolation_required,
+ "purpose_justification_prompt": purpose_justification_prompt,
+ "purpose_justification_required": purpose_justification_required,
+ "require": require,
+ "session_duration": session_duration,
+ },
+ policy_update_params.PolicyUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[PolicyUpdateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[PolicyUpdateResponse]], ResultWrapper[PolicyUpdateResponse]),
+ )
+
+ 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[PolicyListResponse]:
+ """
+ Lists Access reusable policies.
+
+ 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/policies",
+ page=SyncSinglePage[PolicyListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=PolicyListResponse,
+ )
+
+ def delete(
+ self,
+ policy_id: str,
+ *,
+ account_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this 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[PolicyDeleteResponse]:
+ """
+ Deletes an Access reusable policy.
+
+ Args:
+ account_id: Identifier
+
+ policy_id: The UUID of the policy
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for 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 policy_id:
+ raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}")
+ return self._delete(
+ f"/accounts/{account_id}/access/policies/{policy_id}",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[PolicyDeleteResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[PolicyDeleteResponse]], ResultWrapper[PolicyDeleteResponse]),
+ )
+
+ def get(
+ self,
+ policy_id: str,
+ *,
+ account_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this 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[PolicyGetResponse]:
+ """
+ Fetches a single Access reusable policy.
+
+ Args:
+ account_id: Identifier
+
+ policy_id: The UUID of the policy
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for 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 policy_id:
+ raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}")
+ return self._get(
+ f"/accounts/{account_id}/access/policies/{policy_id}",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[PolicyGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[PolicyGetResponse]], ResultWrapper[PolicyGetResponse]),
+ )
+
+
+class AsyncPoliciesResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncPoliciesResourceWithRawResponse:
+ return AsyncPoliciesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncPoliciesResourceWithStreamingResponse:
+ return AsyncPoliciesResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ *,
+ account_id: str,
+ decision: Decision,
+ include: Iterable[AccessRuleParam],
+ name: str,
+ approval_groups: Iterable[ApprovalGroupParam] | NotGiven = NOT_GIVEN,
+ approval_required: bool | NotGiven = NOT_GIVEN,
+ exclude: Iterable[AccessRuleParam] | NotGiven = NOT_GIVEN,
+ isolation_required: bool | NotGiven = NOT_GIVEN,
+ purpose_justification_prompt: str | NotGiven = NOT_GIVEN,
+ purpose_justification_required: bool | NotGiven = NOT_GIVEN,
+ require: Iterable[AccessRuleParam] | NotGiven = NOT_GIVEN,
+ session_duration: 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[PolicyCreateResponse]:
+ """
+ Creates a new Access reusable policy.
+
+ Args:
+ account_id: Identifier
+
+ decision: The action Access will take if a user matches this policy.
+
+ include: Rules evaluated with an OR logical operator. A user needs to meet only one of
+ the Include rules.
+
+ name: The name of the Access policy.
+
+ approval_groups: Administrators who can approve a temporary authentication request.
+
+ approval_required: Requires the user to request access from an administrator at the start of each
+ session.
+
+ exclude: Rules evaluated with a NOT logical operator. To match the policy, a user cannot
+ meet any of the Exclude rules.
+
+ isolation_required: Require this application to be served in an isolated browser for users matching
+ this policy. 'Client Web Isolation' must be on for the account in order to use
+ this feature.
+
+ purpose_justification_prompt: A custom message that will appear on the purpose justification screen.
+
+ purpose_justification_required: Require users to enter a justification when they log in to the application.
+
+ require: Rules evaluated with an AND logical operator. To match the policy, a user must
+ meet all of the Require rules.
+
+ session_duration: The amount of time that tokens issued for the application will be valid. Must be
+ in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, s,
+ m, h.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for 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/policies",
+ body=await async_maybe_transform(
+ {
+ "decision": decision,
+ "include": include,
+ "name": name,
+ "approval_groups": approval_groups,
+ "approval_required": approval_required,
+ "exclude": exclude,
+ "isolation_required": isolation_required,
+ "purpose_justification_prompt": purpose_justification_prompt,
+ "purpose_justification_required": purpose_justification_required,
+ "require": require,
+ "session_duration": session_duration,
+ },
+ policy_create_params.PolicyCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[PolicyCreateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[PolicyCreateResponse]], ResultWrapper[PolicyCreateResponse]),
+ )
+
+ async def update(
+ self,
+ policy_id: str,
+ *,
+ account_id: str,
+ decision: Decision,
+ include: Iterable[AccessRuleParam],
+ name: str,
+ approval_groups: Iterable[ApprovalGroupParam] | NotGiven = NOT_GIVEN,
+ approval_required: bool | NotGiven = NOT_GIVEN,
+ exclude: Iterable[AccessRuleParam] | NotGiven = NOT_GIVEN,
+ isolation_required: bool | NotGiven = NOT_GIVEN,
+ purpose_justification_prompt: str | NotGiven = NOT_GIVEN,
+ purpose_justification_required: bool | NotGiven = NOT_GIVEN,
+ require: Iterable[AccessRuleParam] | NotGiven = NOT_GIVEN,
+ session_duration: 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[PolicyUpdateResponse]:
+ """
+ Updates a Access reusable policy.
+
+ Args:
+ account_id: Identifier
+
+ policy_id: The UUID of the policy
+
+ decision: The action Access will take if a user matches this policy.
+
+ include: Rules evaluated with an OR logical operator. A user needs to meet only one of
+ the Include rules.
+
+ name: The name of the Access policy.
+
+ approval_groups: Administrators who can approve a temporary authentication request.
+
+ approval_required: Requires the user to request access from an administrator at the start of each
+ session.
+
+ exclude: Rules evaluated with a NOT logical operator. To match the policy, a user cannot
+ meet any of the Exclude rules.
+
+ isolation_required: Require this application to be served in an isolated browser for users matching
+ this policy. 'Client Web Isolation' must be on for the account in order to use
+ this feature.
+
+ purpose_justification_prompt: A custom message that will appear on the purpose justification screen.
+
+ purpose_justification_required: Require users to enter a justification when they log in to the application.
+
+ require: Rules evaluated with an AND logical operator. To match the policy, a user must
+ meet all of the Require rules.
+
+ session_duration: The amount of time that tokens issued for the application will be valid. Must be
+ in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, s,
+ m, h.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for 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 policy_id:
+ raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}")
+ return await self._put(
+ f"/accounts/{account_id}/access/policies/{policy_id}",
+ body=await async_maybe_transform(
+ {
+ "decision": decision,
+ "include": include,
+ "name": name,
+ "approval_groups": approval_groups,
+ "approval_required": approval_required,
+ "exclude": exclude,
+ "isolation_required": isolation_required,
+ "purpose_justification_prompt": purpose_justification_prompt,
+ "purpose_justification_required": purpose_justification_required,
+ "require": require,
+ "session_duration": session_duration,
+ },
+ policy_update_params.PolicyUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[PolicyUpdateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[PolicyUpdateResponse]], ResultWrapper[PolicyUpdateResponse]),
+ )
+
+ 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[PolicyListResponse, AsyncSinglePage[PolicyListResponse]]:
+ """
+ Lists Access reusable policies.
+
+ 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/policies",
+ page=AsyncSinglePage[PolicyListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=PolicyListResponse,
+ )
+
+ async def delete(
+ self,
+ policy_id: str,
+ *,
+ account_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this 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[PolicyDeleteResponse]:
+ """
+ Deletes an Access reusable policy.
+
+ Args:
+ account_id: Identifier
+
+ policy_id: The UUID of the policy
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for 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 policy_id:
+ raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}")
+ return await self._delete(
+ f"/accounts/{account_id}/access/policies/{policy_id}",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[PolicyDeleteResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[PolicyDeleteResponse]], ResultWrapper[PolicyDeleteResponse]),
+ )
+
+ async def get(
+ self,
+ policy_id: str,
+ *,
+ account_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this 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[PolicyGetResponse]:
+ """
+ Fetches a single Access reusable policy.
+
+ Args:
+ account_id: Identifier
+
+ policy_id: The UUID of the policy
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for 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 policy_id:
+ raise ValueError(f"Expected a non-empty value for `policy_id` but received {policy_id!r}")
+ return await self._get(
+ f"/accounts/{account_id}/access/policies/{policy_id}",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[PolicyGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[PolicyGetResponse]], ResultWrapper[PolicyGetResponse]),
+ )
+
+
+class PoliciesResourceWithRawResponse:
+ def __init__(self, policies: PoliciesResource) -> None:
+ self._policies = policies
+
+ self.create = to_raw_response_wrapper(
+ policies.create,
+ )
+ self.update = to_raw_response_wrapper(
+ policies.update,
+ )
+ self.list = to_raw_response_wrapper(
+ policies.list,
+ )
+ self.delete = to_raw_response_wrapper(
+ policies.delete,
+ )
+ self.get = to_raw_response_wrapper(
+ policies.get,
+ )
+
+
+class AsyncPoliciesResourceWithRawResponse:
+ def __init__(self, policies: AsyncPoliciesResource) -> None:
+ self._policies = policies
+
+ self.create = async_to_raw_response_wrapper(
+ policies.create,
+ )
+ self.update = async_to_raw_response_wrapper(
+ policies.update,
+ )
+ self.list = async_to_raw_response_wrapper(
+ policies.list,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ policies.delete,
+ )
+ self.get = async_to_raw_response_wrapper(
+ policies.get,
+ )
+
+
+class PoliciesResourceWithStreamingResponse:
+ def __init__(self, policies: PoliciesResource) -> None:
+ self._policies = policies
+
+ self.create = to_streamed_response_wrapper(
+ policies.create,
+ )
+ self.update = to_streamed_response_wrapper(
+ policies.update,
+ )
+ self.list = to_streamed_response_wrapper(
+ policies.list,
+ )
+ self.delete = to_streamed_response_wrapper(
+ policies.delete,
+ )
+ self.get = to_streamed_response_wrapper(
+ policies.get,
+ )
+
+
+class AsyncPoliciesResourceWithStreamingResponse:
+ def __init__(self, policies: AsyncPoliciesResource) -> None:
+ self._policies = policies
+
+ self.create = async_to_streamed_response_wrapper(
+ policies.create,
+ )
+ self.update = async_to_streamed_response_wrapper(
+ policies.update,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ policies.list,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ policies.delete,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ policies.get,
+ )
diff --git a/src/cloudflare/types/dns/__init__.py b/src/cloudflare/types/dns/__init__.py
index 5966582d8bf..3b3aa6dfb0b 100644
--- a/src/cloudflare/types/dns/__init__.py
+++ b/src/cloudflare/types/dns/__init__.py
@@ -12,12 +12,14 @@
from .ttl_param import TTLParam as TTLParam
from .caa_record import CAARecord as CAARecord
from .loc_record import LOCRecord as LOCRecord
+from .nameserver import Nameserver as Nameserver
from .ptr_record import PTRRecord as PTRRecord
from .srv_record import SRVRecord as SRVRecord
from .txt_record import TXTRecord as TXTRecord
from .uri_record import URIRecord as URIRecord
from .aaaa_record import AAAARecord as AAAARecord
from .cert_record import CERTRecord as CERTRecord
+from .dns_setting import DNSSetting as DNSSetting
from .record_tags import RecordTags as RecordTags
from .svcb_record import SVCBRecord as SVCBRecord
from .tlsa_record import TLSARecord as TLSARecord
@@ -30,20 +32,25 @@
from .dnskey_record import DNSKEYRecord as DNSKEYRecord
from .smimea_record import SMIMEARecord as SMIMEARecord
from .record_metadata import RecordMetadata as RecordMetadata
+from .nameserver_param import NameserverParam as NameserverParam
from .attack_mitigation import AttackMitigation as AttackMitigation
+from .dns_setting_param import DNSSettingParam as DNSSettingParam
from .firewall_ips_param import FirewallIPsParam as FirewallIPsParam
from .record_edit_params import RecordEditParams as RecordEditParams
from .record_list_params import RecordListParams as RecordListParams
from .record_scan_params import RecordScanParams as RecordScanParams
from .upstream_ips_param import UpstreamIPsParam as UpstreamIPsParam
from .dns_analytics_query import DNSAnalyticsQuery as DNSAnalyticsQuery
+from .setting_edit_params import SettingEditParams as SettingEditParams
from .firewall_edit_params import FirewallEditParams as FirewallEditParams
from .firewall_list_params import FirewallListParams as FirewallListParams
from .record_create_params import RecordCreateParams as RecordCreateParams
from .record_import_params import RecordImportParams as RecordImportParams
from .record_scan_response import RecordScanResponse as RecordScanResponse
from .record_update_params import RecordUpdateParams as RecordUpdateParams
+from .setting_get_response import SettingGetResponse as SettingGetResponse
from .record_process_timing import RecordProcessTiming as RecordProcessTiming
+from .setting_edit_response import SettingEditResponse as SettingEditResponse
from .firewall_create_params import FirewallCreateParams as FirewallCreateParams
from .record_delete_response import RecordDeleteResponse as RecordDeleteResponse
from .record_export_response import RecordExportResponse as RecordExportResponse
diff --git a/src/cloudflare/types/dns/dns_setting.py b/src/cloudflare/types/dns/dns_setting.py
new file mode 100644
index 00000000000..c96b14afb67
--- /dev/null
+++ b/src/cloudflare/types/dns/dns_setting.py
@@ -0,0 +1,76 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+from .nameserver import Nameserver
+
+__all__ = ["DNSSetting", "SOA"]
+
+
+class SOA(BaseModel):
+ expire: float
+ """
+ Time in seconds of being unable to query the primary server after which
+ secondary servers should stop serving the zone.
+ """
+
+ min_ttl: float
+ """The time to live (TTL) for negative caching of records within the zone."""
+
+ mname: str
+ """The primary nameserver, which may be used for outbound zone transfers."""
+
+ refresh: float
+ """
+ Time in seconds after which secondary servers should re-check the SOA record to
+ see if the zone has been updated.
+ """
+
+ retry: float
+ """
+ Time in seconds after which secondary servers should retry queries after the
+ primary server was unresponsive.
+ """
+
+ rname: str
+ """
+ The email address of the zone administrator, with the first label representing
+ the local part of the email address.
+ """
+
+ ttl: float
+ """The time to live (TTL) of the SOA record itself."""
+
+
+class DNSSetting(BaseModel):
+ foundation_dns: Optional[bool] = None
+ """Whether to enable Foundation DNS Advanced Nameservers on the zone."""
+
+ multi_provider: Optional[bool] = None
+ """
+ Whether to enable multi-provider DNS, which causes Cloudflare to activate the
+ zone even when non-Cloudflare NS records exist, and to respect NS records at the
+ zone apex during outbound zone transfers.
+ """
+
+ nameservers: Optional[Nameserver] = None
+ """
+ Settings determining the nameservers through which the zone should be available.
+ """
+
+ ns_ttl: Optional[float] = None
+ """The time to live (TTL) of the zone's nameserver (NS) records."""
+
+ secondary_overrides: Optional[bool] = None
+ """
+ Allows a Secondary DNS zone to use (proxied) override records and CNAME
+ flattening at the zone apex.
+ """
+
+ soa: Optional[SOA] = None
+ """Components of the zone's SOA record."""
+
+ zone_mode: Optional[Literal["standard", "cdn_only", "dns_only"]] = None
+ """Whether the zone mode is a regular or CDN/DNS only zone."""
diff --git a/src/cloudflare/types/dns/dns_setting_param.py b/src/cloudflare/types/dns/dns_setting_param.py
new file mode 100644
index 00000000000..127be3c6a83
--- /dev/null
+++ b/src/cloudflare/types/dns/dns_setting_param.py
@@ -0,0 +1,76 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, Required, TypedDict
+
+from .nameserver_param import NameserverParam
+
+__all__ = ["DNSSettingParam", "SOA"]
+
+
+class SOA(TypedDict, total=False):
+ expire: Required[float]
+ """
+ Time in seconds of being unable to query the primary server after which
+ secondary servers should stop serving the zone.
+ """
+
+ min_ttl: Required[float]
+ """The time to live (TTL) for negative caching of records within the zone."""
+
+ mname: Required[str]
+ """The primary nameserver, which may be used for outbound zone transfers."""
+
+ refresh: Required[float]
+ """
+ Time in seconds after which secondary servers should re-check the SOA record to
+ see if the zone has been updated.
+ """
+
+ retry: Required[float]
+ """
+ Time in seconds after which secondary servers should retry queries after the
+ primary server was unresponsive.
+ """
+
+ rname: Required[str]
+ """
+ The email address of the zone administrator, with the first label representing
+ the local part of the email address.
+ """
+
+ ttl: Required[float]
+ """The time to live (TTL) of the SOA record itself."""
+
+
+class DNSSettingParam(TypedDict, total=False):
+ foundation_dns: bool
+ """Whether to enable Foundation DNS Advanced Nameservers on the zone."""
+
+ multi_provider: bool
+ """
+ Whether to enable multi-provider DNS, which causes Cloudflare to activate the
+ zone even when non-Cloudflare NS records exist, and to respect NS records at the
+ zone apex during outbound zone transfers.
+ """
+
+ nameservers: NameserverParam
+ """
+ Settings determining the nameservers through which the zone should be available.
+ """
+
+ ns_ttl: float
+ """The time to live (TTL) of the zone's nameserver (NS) records."""
+
+ secondary_overrides: bool
+ """
+ Allows a Secondary DNS zone to use (proxied) override records and CNAME
+ flattening at the zone apex.
+ """
+
+ soa: SOA
+ """Components of the zone's SOA record."""
+
+ zone_mode: Literal["standard", "cdn_only", "dns_only"]
+ """Whether the zone mode is a regular or CDN/DNS only zone."""
diff --git a/src/cloudflare/types/dns/nameserver.py b/src/cloudflare/types/dns/nameserver.py
new file mode 100644
index 00000000000..3076da16fbd
--- /dev/null
+++ b/src/cloudflare/types/dns/nameserver.py
@@ -0,0 +1,12 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["Nameserver"]
+
+
+class Nameserver(BaseModel):
+ type: Literal["cloudflare.standard"]
+ """Nameserver type"""
diff --git a/src/cloudflare/types/dns/nameserver_param.py b/src/cloudflare/types/dns/nameserver_param.py
new file mode 100644
index 00000000000..6d73075a2ae
--- /dev/null
+++ b/src/cloudflare/types/dns/nameserver_param.py
@@ -0,0 +1,12 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, Required, TypedDict
+
+__all__ = ["NameserverParam"]
+
+
+class NameserverParam(TypedDict, total=False):
+ type: Required[Literal["cloudflare.standard"]]
+ """Nameserver type"""
diff --git a/src/cloudflare/types/dns/setting_edit_params.py b/src/cloudflare/types/dns/setting_edit_params.py
new file mode 100644
index 00000000000..1ac1ba3eeae
--- /dev/null
+++ b/src/cloudflare/types/dns/setting_edit_params.py
@@ -0,0 +1,19 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypedDict
+
+from .dns_setting_param import DNSSettingParam
+
+__all__ = ["SettingEditParams"]
+
+
+class SettingEditParams(TypedDict, total=False):
+ account_id: str
+ """The Account ID to use for this endpoint. Mutually exclusive with the Zone ID."""
+
+ zone_id: str
+ """The Zone ID to use for this endpoint. Mutually exclusive with the Account ID."""
+
+ zone_defaults: DNSSettingParam
diff --git a/src/cloudflare/types/dns/setting_edit_response.py b/src/cloudflare/types/dns/setting_edit_response.py
new file mode 100644
index 00000000000..87a73a5356f
--- /dev/null
+++ b/src/cloudflare/types/dns/setting_edit_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
+from .dns_setting import DNSSetting
+
+__all__ = ["SettingEditResponse"]
+
+
+class SettingEditResponse(BaseModel):
+ zone_defaults: Optional[DNSSetting] = None
diff --git a/src/cloudflare/types/dns/setting_get_response.py b/src/cloudflare/types/dns/setting_get_response.py
new file mode 100644
index 00000000000..42c33600842
--- /dev/null
+++ b/src/cloudflare/types/dns/setting_get_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
+from .dns_setting import DNSSetting
+
+__all__ = ["SettingGetResponse"]
+
+
+class SettingGetResponse(BaseModel):
+ zone_defaults: Optional[DNSSetting] = None
diff --git a/src/cloudflare/types/zero_trust/access/__init__.py b/src/cloudflare/types/zero_trust/access/__init__.py
index 8b8d5c829cf..16436e0e937 100644
--- a/src/cloudflare/types/zero_trust/access/__init__.py
+++ b/src/cloudflare/types/zero_trust/access/__init__.py
@@ -28,15 +28,22 @@
from .group_update_params import GroupUpdateParams as GroupUpdateParams
from .key_rotate_response import KeyRotateResponse as KeyRotateResponse
from .key_update_response import KeyUpdateResponse as KeyUpdateResponse
+from .policy_get_response import PolicyGetResponse as PolicyGetResponse
from .saml_saas_app_param import SAMLSaaSAppParam as SAMLSaaSAppParam
from .self_hosted_domains import SelfHostedDomains as SelfHostedDomains
from .tag_delete_response import TagDeleteResponse as TagDeleteResponse
from .associated_hostnames import AssociatedHostnames as AssociatedHostnames
+from .policy_create_params import PolicyCreateParams as PolicyCreateParams
+from .policy_list_response import PolicyListResponse as PolicyListResponse
+from .policy_update_params import PolicyUpdateParams as PolicyUpdateParams
from .saas_app_name_format import SaaSAppNameFormat as SaaSAppNameFormat
from .group_delete_response import GroupDeleteResponse as GroupDeleteResponse
from .saas_app_source_param import SaaSAppSourceParam as SaaSAppSourceParam
from .bookmark_create_params import BookmarkCreateParams as BookmarkCreateParams
from .bookmark_update_params import BookmarkUpdateParams as BookmarkUpdateParams
+from .policy_create_response import PolicyCreateResponse as PolicyCreateResponse
+from .policy_delete_response import PolicyDeleteResponse as PolicyDeleteResponse
+from .policy_update_response import PolicyUpdateResponse as PolicyUpdateResponse
from .saas_app_name_id_format import SaaSAppNameIDFormat as SaaSAppNameIDFormat
from .application_get_response import ApplicationGetResponse as ApplicationGetResponse
from .bookmark_delete_response import BookmarkDeleteResponse as BookmarkDeleteResponse
diff --git a/src/cloudflare/types/zero_trust/access/policy_create_params.py b/src/cloudflare/types/zero_trust/access/policy_create_params.py
new file mode 100644
index 00000000000..a575b5e16a6
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/access/policy_create_params.py
@@ -0,0 +1,70 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable
+from typing_extensions import Required, TypedDict
+
+from .decision import Decision
+from ..access_rule_param import AccessRuleParam
+from .applications.approval_group_param import ApprovalGroupParam
+
+__all__ = ["PolicyCreateParams"]
+
+
+class PolicyCreateParams(TypedDict, total=False):
+ account_id: Required[str]
+ """Identifier"""
+
+ decision: Required[Decision]
+ """The action Access will take if a user matches this policy."""
+
+ include: Required[Iterable[AccessRuleParam]]
+ """Rules evaluated with an OR logical operator.
+
+ A user needs to meet only one of the Include rules.
+ """
+
+ name: Required[str]
+ """The name of the Access policy."""
+
+ approval_groups: Iterable[ApprovalGroupParam]
+ """Administrators who can approve a temporary authentication request."""
+
+ approval_required: bool
+ """
+ Requires the user to request access from an administrator at the start of each
+ session.
+ """
+
+ exclude: Iterable[AccessRuleParam]
+ """Rules evaluated with a NOT logical operator.
+
+ To match the policy, a user cannot meet any of the Exclude rules.
+ """
+
+ isolation_required: bool
+ """
+ Require this application to be served in an isolated browser for users matching
+ this policy. 'Client Web Isolation' must be on for the account in order to use
+ this feature.
+ """
+
+ purpose_justification_prompt: str
+ """A custom message that will appear on the purpose justification screen."""
+
+ purpose_justification_required: bool
+ """Require users to enter a justification when they log in to the application."""
+
+ require: Iterable[AccessRuleParam]
+ """Rules evaluated with an AND logical operator.
+
+ To match the policy, a user must meet all of the Require rules.
+ """
+
+ session_duration: str
+ """The amount of time that tokens issued for the application will be valid.
+
+ Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs),
+ ms, s, m, h.
+ """
diff --git a/src/cloudflare/types/zero_trust/access/policy_create_response.py b/src/cloudflare/types/zero_trust/access/policy_create_response.py
new file mode 100644
index 00000000000..767b4f9bc18
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/access/policy_create_response.py
@@ -0,0 +1,79 @@
+# 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 .decision import Decision
+from ...._models import BaseModel
+from ..access_rule import AccessRule
+from .applications.approval_group import ApprovalGroup
+
+__all__ = ["PolicyCreateResponse"]
+
+
+class PolicyCreateResponse(BaseModel):
+ id: Optional[str] = None
+ """The UUID of the policy"""
+
+ app_count: Optional[int] = None
+ """Number of access applications currently using this policy."""
+
+ approval_groups: Optional[List[ApprovalGroup]] = None
+ """Administrators who can approve a temporary authentication request."""
+
+ approval_required: Optional[bool] = None
+ """
+ Requires the user to request access from an administrator at the start of each
+ session.
+ """
+
+ created_at: Optional[datetime] = None
+
+ decision: Optional[Decision] = None
+ """The action Access will take if a user matches this policy."""
+
+ exclude: Optional[List[AccessRule]] = None
+ """Rules evaluated with a NOT logical operator.
+
+ To match the policy, a user cannot meet any of the Exclude rules.
+ """
+
+ include: Optional[List[AccessRule]] = None
+ """Rules evaluated with an OR logical operator.
+
+ A user needs to meet only one of the Include rules.
+ """
+
+ isolation_required: Optional[bool] = None
+ """
+ Require this application to be served in an isolated browser for users matching
+ this policy. 'Client Web Isolation' must be on for the account in order to use
+ this feature.
+ """
+
+ name: Optional[str] = None
+ """The name of the Access policy."""
+
+ purpose_justification_prompt: Optional[str] = None
+ """A custom message that will appear on the purpose justification screen."""
+
+ purpose_justification_required: Optional[bool] = None
+ """Require users to enter a justification when they log in to the application."""
+
+ require: Optional[List[AccessRule]] = None
+ """Rules evaluated with an AND logical operator.
+
+ To match the policy, a user must meet all of the Require rules.
+ """
+
+ reusable: Optional[Literal[True]] = None
+
+ session_duration: Optional[str] = None
+ """The amount of time that tokens issued for the application will be valid.
+
+ Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs),
+ ms, s, m, h.
+ """
+
+ updated_at: Optional[datetime] = None
diff --git a/src/cloudflare/types/zero_trust/access/policy_delete_response.py b/src/cloudflare/types/zero_trust/access/policy_delete_response.py
new file mode 100644
index 00000000000..638056e64fd
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/access/policy_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__ = ["PolicyDeleteResponse"]
+
+
+class PolicyDeleteResponse(BaseModel):
+ id: Optional[str] = None
+ """The UUID of the policy"""
diff --git a/src/cloudflare/types/zero_trust/access/policy_get_response.py b/src/cloudflare/types/zero_trust/access/policy_get_response.py
new file mode 100644
index 00000000000..b4476baf1d0
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/access/policy_get_response.py
@@ -0,0 +1,79 @@
+# 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 .decision import Decision
+from ...._models import BaseModel
+from ..access_rule import AccessRule
+from .applications.approval_group import ApprovalGroup
+
+__all__ = ["PolicyGetResponse"]
+
+
+class PolicyGetResponse(BaseModel):
+ id: Optional[str] = None
+ """The UUID of the policy"""
+
+ app_count: Optional[int] = None
+ """Number of access applications currently using this policy."""
+
+ approval_groups: Optional[List[ApprovalGroup]] = None
+ """Administrators who can approve a temporary authentication request."""
+
+ approval_required: Optional[bool] = None
+ """
+ Requires the user to request access from an administrator at the start of each
+ session.
+ """
+
+ created_at: Optional[datetime] = None
+
+ decision: Optional[Decision] = None
+ """The action Access will take if a user matches this policy."""
+
+ exclude: Optional[List[AccessRule]] = None
+ """Rules evaluated with a NOT logical operator.
+
+ To match the policy, a user cannot meet any of the Exclude rules.
+ """
+
+ include: Optional[List[AccessRule]] = None
+ """Rules evaluated with an OR logical operator.
+
+ A user needs to meet only one of the Include rules.
+ """
+
+ isolation_required: Optional[bool] = None
+ """
+ Require this application to be served in an isolated browser for users matching
+ this policy. 'Client Web Isolation' must be on for the account in order to use
+ this feature.
+ """
+
+ name: Optional[str] = None
+ """The name of the Access policy."""
+
+ purpose_justification_prompt: Optional[str] = None
+ """A custom message that will appear on the purpose justification screen."""
+
+ purpose_justification_required: Optional[bool] = None
+ """Require users to enter a justification when they log in to the application."""
+
+ require: Optional[List[AccessRule]] = None
+ """Rules evaluated with an AND logical operator.
+
+ To match the policy, a user must meet all of the Require rules.
+ """
+
+ reusable: Optional[Literal[True]] = None
+
+ session_duration: Optional[str] = None
+ """The amount of time that tokens issued for the application will be valid.
+
+ Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs),
+ ms, s, m, h.
+ """
+
+ updated_at: Optional[datetime] = None
diff --git a/src/cloudflare/types/zero_trust/access/policy_list_response.py b/src/cloudflare/types/zero_trust/access/policy_list_response.py
new file mode 100644
index 00000000000..2a2272663c7
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/access/policy_list_response.py
@@ -0,0 +1,79 @@
+# 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 .decision import Decision
+from ...._models import BaseModel
+from ..access_rule import AccessRule
+from .applications.approval_group import ApprovalGroup
+
+__all__ = ["PolicyListResponse"]
+
+
+class PolicyListResponse(BaseModel):
+ id: Optional[str] = None
+ """The UUID of the policy"""
+
+ app_count: Optional[int] = None
+ """Number of access applications currently using this policy."""
+
+ approval_groups: Optional[List[ApprovalGroup]] = None
+ """Administrators who can approve a temporary authentication request."""
+
+ approval_required: Optional[bool] = None
+ """
+ Requires the user to request access from an administrator at the start of each
+ session.
+ """
+
+ created_at: Optional[datetime] = None
+
+ decision: Optional[Decision] = None
+ """The action Access will take if a user matches this policy."""
+
+ exclude: Optional[List[AccessRule]] = None
+ """Rules evaluated with a NOT logical operator.
+
+ To match the policy, a user cannot meet any of the Exclude rules.
+ """
+
+ include: Optional[List[AccessRule]] = None
+ """Rules evaluated with an OR logical operator.
+
+ A user needs to meet only one of the Include rules.
+ """
+
+ isolation_required: Optional[bool] = None
+ """
+ Require this application to be served in an isolated browser for users matching
+ this policy. 'Client Web Isolation' must be on for the account in order to use
+ this feature.
+ """
+
+ name: Optional[str] = None
+ """The name of the Access policy."""
+
+ purpose_justification_prompt: Optional[str] = None
+ """A custom message that will appear on the purpose justification screen."""
+
+ purpose_justification_required: Optional[bool] = None
+ """Require users to enter a justification when they log in to the application."""
+
+ require: Optional[List[AccessRule]] = None
+ """Rules evaluated with an AND logical operator.
+
+ To match the policy, a user must meet all of the Require rules.
+ """
+
+ reusable: Optional[Literal[True]] = None
+
+ session_duration: Optional[str] = None
+ """The amount of time that tokens issued for the application will be valid.
+
+ Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs),
+ ms, s, m, h.
+ """
+
+ updated_at: Optional[datetime] = None
diff --git a/src/cloudflare/types/zero_trust/access/policy_update_params.py b/src/cloudflare/types/zero_trust/access/policy_update_params.py
new file mode 100644
index 00000000000..7ac64eebe4c
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/access/policy_update_params.py
@@ -0,0 +1,70 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable
+from typing_extensions import Required, TypedDict
+
+from .decision import Decision
+from ..access_rule_param import AccessRuleParam
+from .applications.approval_group_param import ApprovalGroupParam
+
+__all__ = ["PolicyUpdateParams"]
+
+
+class PolicyUpdateParams(TypedDict, total=False):
+ account_id: Required[str]
+ """Identifier"""
+
+ decision: Required[Decision]
+ """The action Access will take if a user matches this policy."""
+
+ include: Required[Iterable[AccessRuleParam]]
+ """Rules evaluated with an OR logical operator.
+
+ A user needs to meet only one of the Include rules.
+ """
+
+ name: Required[str]
+ """The name of the Access policy."""
+
+ approval_groups: Iterable[ApprovalGroupParam]
+ """Administrators who can approve a temporary authentication request."""
+
+ approval_required: bool
+ """
+ Requires the user to request access from an administrator at the start of each
+ session.
+ """
+
+ exclude: Iterable[AccessRuleParam]
+ """Rules evaluated with a NOT logical operator.
+
+ To match the policy, a user cannot meet any of the Exclude rules.
+ """
+
+ isolation_required: bool
+ """
+ Require this application to be served in an isolated browser for users matching
+ this policy. 'Client Web Isolation' must be on for the account in order to use
+ this feature.
+ """
+
+ purpose_justification_prompt: str
+ """A custom message that will appear on the purpose justification screen."""
+
+ purpose_justification_required: bool
+ """Require users to enter a justification when they log in to the application."""
+
+ require: Iterable[AccessRuleParam]
+ """Rules evaluated with an AND logical operator.
+
+ To match the policy, a user must meet all of the Require rules.
+ """
+
+ session_duration: str
+ """The amount of time that tokens issued for the application will be valid.
+
+ Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs),
+ ms, s, m, h.
+ """
diff --git a/src/cloudflare/types/zero_trust/access/policy_update_response.py b/src/cloudflare/types/zero_trust/access/policy_update_response.py
new file mode 100644
index 00000000000..8582785d404
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/access/policy_update_response.py
@@ -0,0 +1,79 @@
+# 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 .decision import Decision
+from ...._models import BaseModel
+from ..access_rule import AccessRule
+from .applications.approval_group import ApprovalGroup
+
+__all__ = ["PolicyUpdateResponse"]
+
+
+class PolicyUpdateResponse(BaseModel):
+ id: Optional[str] = None
+ """The UUID of the policy"""
+
+ app_count: Optional[int] = None
+ """Number of access applications currently using this policy."""
+
+ approval_groups: Optional[List[ApprovalGroup]] = None
+ """Administrators who can approve a temporary authentication request."""
+
+ approval_required: Optional[bool] = None
+ """
+ Requires the user to request access from an administrator at the start of each
+ session.
+ """
+
+ created_at: Optional[datetime] = None
+
+ decision: Optional[Decision] = None
+ """The action Access will take if a user matches this policy."""
+
+ exclude: Optional[List[AccessRule]] = None
+ """Rules evaluated with a NOT logical operator.
+
+ To match the policy, a user cannot meet any of the Exclude rules.
+ """
+
+ include: Optional[List[AccessRule]] = None
+ """Rules evaluated with an OR logical operator.
+
+ A user needs to meet only one of the Include rules.
+ """
+
+ isolation_required: Optional[bool] = None
+ """
+ Require this application to be served in an isolated browser for users matching
+ this policy. 'Client Web Isolation' must be on for the account in order to use
+ this feature.
+ """
+
+ name: Optional[str] = None
+ """The name of the Access policy."""
+
+ purpose_justification_prompt: Optional[str] = None
+ """A custom message that will appear on the purpose justification screen."""
+
+ purpose_justification_required: Optional[bool] = None
+ """Require users to enter a justification when they log in to the application."""
+
+ require: Optional[List[AccessRule]] = None
+ """Rules evaluated with an AND logical operator.
+
+ To match the policy, a user must meet all of the Require rules.
+ """
+
+ reusable: Optional[Literal[True]] = None
+
+ session_duration: Optional[str] = None
+ """The amount of time that tokens issued for the application will be valid.
+
+ Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs),
+ ms, s, m, h.
+ """
+
+ updated_at: Optional[datetime] = None
diff --git a/tests/api_resources/dns/test_settings.py b/tests/api_resources/dns/test_settings.py
new file mode 100644
index 00000000000..955b284427b
--- /dev/null
+++ b/tests/api_resources/dns/test_settings.py
@@ -0,0 +1,256 @@
+# 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.dns import SettingGetResponse, SettingEditResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestSettings:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_edit(self, client: Cloudflare) -> None:
+ setting = client.dns.settings.edit(
+ account_id="string",
+ )
+ assert_matches_type(Optional[SettingEditResponse], setting, path=["response"])
+
+ @parametrize
+ def test_method_edit_with_all_params(self, client: Cloudflare) -> None:
+ setting = client.dns.settings.edit(
+ account_id="string",
+ zone_defaults={
+ "foundation_dns": False,
+ "multi_provider": False,
+ "nameservers": {"type": "cloudflare.standard"},
+ "ns_ttl": 86400,
+ "secondary_overrides": False,
+ "soa": {
+ "expire": 604800,
+ "min_ttl": 1800,
+ "mname": "kristina.ns.cloudflare.com",
+ "refresh": 10000,
+ "retry": 2400,
+ "rname": "admin.example.com",
+ "ttl": 3600,
+ },
+ "zone_mode": "dns_only",
+ },
+ )
+ assert_matches_type(Optional[SettingEditResponse], setting, path=["response"])
+
+ @parametrize
+ def test_raw_response_edit(self, client: Cloudflare) -> None:
+ response = client.dns.settings.with_raw_response.edit(
+ account_id="string",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ setting = response.parse()
+ assert_matches_type(Optional[SettingEditResponse], setting, path=["response"])
+
+ @parametrize
+ def test_streaming_response_edit(self, client: Cloudflare) -> None:
+ with client.dns.settings.with_streaming_response.edit(
+ account_id="string",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ setting = response.parse()
+ assert_matches_type(Optional[SettingEditResponse], setting, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_edit(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.dns.settings.with_raw_response.edit(
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
+ client.dns.settings.with_raw_response.edit(
+ account_id="string",
+ )
+
+ @parametrize
+ def test_method_get(self, client: Cloudflare) -> None:
+ setting = client.dns.settings.get(
+ account_id="string",
+ )
+ assert_matches_type(Optional[SettingGetResponse], setting, path=["response"])
+
+ @parametrize
+ def test_method_get_with_all_params(self, client: Cloudflare) -> None:
+ setting = client.dns.settings.get(
+ account_id="string",
+ )
+ assert_matches_type(Optional[SettingGetResponse], setting, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Cloudflare) -> None:
+ response = client.dns.settings.with_raw_response.get(
+ account_id="string",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ setting = response.parse()
+ assert_matches_type(Optional[SettingGetResponse], setting, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Cloudflare) -> None:
+ with client.dns.settings.with_streaming_response.get(
+ account_id="string",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ setting = response.parse()
+ assert_matches_type(Optional[SettingGetResponse], setting, 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.dns.settings.with_raw_response.get(
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
+ client.dns.settings.with_raw_response.get(
+ account_id="string",
+ )
+
+
+class TestAsyncSettings:
+ parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ async def test_method_edit(self, async_client: AsyncCloudflare) -> None:
+ setting = await async_client.dns.settings.edit(
+ account_id="string",
+ )
+ assert_matches_type(Optional[SettingEditResponse], setting, path=["response"])
+
+ @parametrize
+ async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ setting = await async_client.dns.settings.edit(
+ account_id="string",
+ zone_defaults={
+ "foundation_dns": False,
+ "multi_provider": False,
+ "nameservers": {"type": "cloudflare.standard"},
+ "ns_ttl": 86400,
+ "secondary_overrides": False,
+ "soa": {
+ "expire": 604800,
+ "min_ttl": 1800,
+ "mname": "kristina.ns.cloudflare.com",
+ "refresh": 10000,
+ "retry": 2400,
+ "rname": "admin.example.com",
+ "ttl": 3600,
+ },
+ "zone_mode": "dns_only",
+ },
+ )
+ assert_matches_type(Optional[SettingEditResponse], setting, path=["response"])
+
+ @parametrize
+ async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.dns.settings.with_raw_response.edit(
+ account_id="string",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ setting = await response.parse()
+ assert_matches_type(Optional[SettingEditResponse], setting, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.dns.settings.with_streaming_response.edit(
+ account_id="string",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ setting = await response.parse()
+ assert_matches_type(Optional[SettingEditResponse], setting, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_edit(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.dns.settings.with_raw_response.edit(
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
+ await async_client.dns.settings.with_raw_response.edit(
+ account_id="string",
+ )
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncCloudflare) -> None:
+ setting = await async_client.dns.settings.get(
+ account_id="string",
+ )
+ assert_matches_type(Optional[SettingGetResponse], setting, path=["response"])
+
+ @parametrize
+ async def test_method_get_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ setting = await async_client.dns.settings.get(
+ account_id="string",
+ )
+ assert_matches_type(Optional[SettingGetResponse], setting, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.dns.settings.with_raw_response.get(
+ account_id="string",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ setting = await response.parse()
+ assert_matches_type(Optional[SettingGetResponse], setting, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.dns.settings.with_streaming_response.get(
+ account_id="string",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ setting = await response.parse()
+ assert_matches_type(Optional[SettingGetResponse], setting, 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.dns.settings.with_raw_response.get(
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
+ await async_client.dns.settings.with_raw_response.get(
+ account_id="string",
+ )
diff --git a/tests/api_resources/zero_trust/access/test_policies.py b/tests/api_resources/zero_trust/access/test_policies.py
new file mode 100644
index 00000000000..dd11538c159
--- /dev/null
+++ b/tests/api_resources/zero_trust/access/test_policies.py
@@ -0,0 +1,761 @@
+# 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 (
+ PolicyGetResponse,
+ PolicyListResponse,
+ PolicyCreateResponse,
+ PolicyDeleteResponse,
+ PolicyUpdateResponse,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestPolicies:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: Cloudflare) -> None:
+ policy = client.zero_trust.access.policies.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ decision="allow",
+ include=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ name="Allow devs",
+ )
+ assert_matches_type(Optional[PolicyCreateResponse], policy, path=["response"])
+
+ @parametrize
+ def test_method_create_with_all_params(self, client: Cloudflare) -> None:
+ policy = client.zero_trust.access.policies.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ decision="allow",
+ include=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ name="Allow devs",
+ approval_groups=[
+ {
+ "approvals_needed": 1,
+ "email_addresses": ["test1@cloudflare.com", "test2@cloudflare.com"],
+ "email_list_uuid": "string",
+ },
+ {
+ "approvals_needed": 3,
+ "email_addresses": ["test@cloudflare.com", "test2@cloudflare.com"],
+ "email_list_uuid": "597147a1-976b-4ef2-9af0-81d5d007fc34",
+ },
+ ],
+ approval_required=True,
+ exclude=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ isolation_required=False,
+ purpose_justification_prompt="Please enter a justification for entering this protected domain.",
+ purpose_justification_required=True,
+ require=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ session_duration="24h",
+ )
+ assert_matches_type(Optional[PolicyCreateResponse], policy, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Cloudflare) -> None:
+ response = client.zero_trust.access.policies.with_raw_response.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ decision="allow",
+ include=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ name="Allow devs",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ policy = response.parse()
+ assert_matches_type(Optional[PolicyCreateResponse], policy, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: Cloudflare) -> None:
+ with client.zero_trust.access.policies.with_streaming_response.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ decision="allow",
+ include=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ name="Allow devs",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ policy = response.parse()
+ assert_matches_type(Optional[PolicyCreateResponse], policy, 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.policies.with_raw_response.create(
+ account_id="",
+ decision="allow",
+ include=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ name="Allow devs",
+ )
+
+ @parametrize
+ def test_method_update(self, client: Cloudflare) -> None:
+ policy = client.zero_trust.access.policies.update(
+ "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ decision="allow",
+ include=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ name="Allow devs",
+ )
+ assert_matches_type(Optional[PolicyUpdateResponse], policy, path=["response"])
+
+ @parametrize
+ def test_method_update_with_all_params(self, client: Cloudflare) -> None:
+ policy = client.zero_trust.access.policies.update(
+ "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ decision="allow",
+ include=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ name="Allow devs",
+ approval_groups=[
+ {
+ "approvals_needed": 1,
+ "email_addresses": ["test1@cloudflare.com", "test2@cloudflare.com"],
+ "email_list_uuid": "string",
+ },
+ {
+ "approvals_needed": 3,
+ "email_addresses": ["test@cloudflare.com", "test2@cloudflare.com"],
+ "email_list_uuid": "597147a1-976b-4ef2-9af0-81d5d007fc34",
+ },
+ ],
+ approval_required=True,
+ exclude=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ isolation_required=False,
+ purpose_justification_prompt="Please enter a justification for entering this protected domain.",
+ purpose_justification_required=True,
+ require=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ session_duration="24h",
+ )
+ assert_matches_type(Optional[PolicyUpdateResponse], policy, path=["response"])
+
+ @parametrize
+ def test_raw_response_update(self, client: Cloudflare) -> None:
+ response = client.zero_trust.access.policies.with_raw_response.update(
+ "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ decision="allow",
+ include=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ name="Allow devs",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ policy = response.parse()
+ assert_matches_type(Optional[PolicyUpdateResponse], policy, path=["response"])
+
+ @parametrize
+ def test_streaming_response_update(self, client: Cloudflare) -> None:
+ with client.zero_trust.access.policies.with_streaming_response.update(
+ "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ decision="allow",
+ include=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ name="Allow devs",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ policy = response.parse()
+ assert_matches_type(Optional[PolicyUpdateResponse], policy, 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.access.policies.with_raw_response.update(
+ "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="",
+ decision="allow",
+ include=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ name="Allow devs",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"):
+ client.zero_trust.access.policies.with_raw_response.update(
+ "",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ decision="allow",
+ include=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ name="Allow devs",
+ )
+
+ @parametrize
+ def test_method_list(self, client: Cloudflare) -> None:
+ policy = client.zero_trust.access.policies.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(SyncSinglePage[PolicyListResponse], policy, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Cloudflare) -> None:
+ response = client.zero_trust.access.policies.with_raw_response.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ policy = response.parse()
+ assert_matches_type(SyncSinglePage[PolicyListResponse], policy, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Cloudflare) -> None:
+ with client.zero_trust.access.policies.with_streaming_response.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ policy = response.parse()
+ assert_matches_type(SyncSinglePage[PolicyListResponse], policy, 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.policies.with_raw_response.list(
+ account_id="",
+ )
+
+ @parametrize
+ def test_method_delete(self, client: Cloudflare) -> None:
+ policy = client.zero_trust.access.policies.delete(
+ "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[PolicyDeleteResponse], policy, path=["response"])
+
+ @parametrize
+ def test_raw_response_delete(self, client: Cloudflare) -> None:
+ response = client.zero_trust.access.policies.with_raw_response.delete(
+ "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ policy = response.parse()
+ assert_matches_type(Optional[PolicyDeleteResponse], policy, path=["response"])
+
+ @parametrize
+ def test_streaming_response_delete(self, client: Cloudflare) -> None:
+ with client.zero_trust.access.policies.with_streaming_response.delete(
+ "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"
+
+ policy = response.parse()
+ assert_matches_type(Optional[PolicyDeleteResponse], policy, 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.policies.with_raw_response.delete(
+ "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"):
+ client.zero_trust.access.policies.with_raw_response.delete(
+ "",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ @parametrize
+ def test_method_get(self, client: Cloudflare) -> None:
+ policy = client.zero_trust.access.policies.get(
+ "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[PolicyGetResponse], policy, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Cloudflare) -> None:
+ response = client.zero_trust.access.policies.with_raw_response.get(
+ "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ policy = response.parse()
+ assert_matches_type(Optional[PolicyGetResponse], policy, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Cloudflare) -> None:
+ with client.zero_trust.access.policies.with_streaming_response.get(
+ "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"
+
+ policy = response.parse()
+ assert_matches_type(Optional[PolicyGetResponse], policy, 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.access.policies.with_raw_response.get(
+ "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"):
+ client.zero_trust.access.policies.with_raw_response.get(
+ "",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+
+class TestAsyncPolicies:
+ parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ async def test_method_create(self, async_client: AsyncCloudflare) -> None:
+ policy = await async_client.zero_trust.access.policies.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ decision="allow",
+ include=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ name="Allow devs",
+ )
+ assert_matches_type(Optional[PolicyCreateResponse], policy, path=["response"])
+
+ @parametrize
+ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ policy = await async_client.zero_trust.access.policies.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ decision="allow",
+ include=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ name="Allow devs",
+ approval_groups=[
+ {
+ "approvals_needed": 1,
+ "email_addresses": ["test1@cloudflare.com", "test2@cloudflare.com"],
+ "email_list_uuid": "string",
+ },
+ {
+ "approvals_needed": 3,
+ "email_addresses": ["test@cloudflare.com", "test2@cloudflare.com"],
+ "email_list_uuid": "597147a1-976b-4ef2-9af0-81d5d007fc34",
+ },
+ ],
+ approval_required=True,
+ exclude=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ isolation_required=False,
+ purpose_justification_prompt="Please enter a justification for entering this protected domain.",
+ purpose_justification_required=True,
+ require=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ session_duration="24h",
+ )
+ assert_matches_type(Optional[PolicyCreateResponse], policy, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.access.policies.with_raw_response.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ decision="allow",
+ include=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ name="Allow devs",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ policy = await response.parse()
+ assert_matches_type(Optional[PolicyCreateResponse], policy, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.access.policies.with_streaming_response.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ decision="allow",
+ include=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ name="Allow devs",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ policy = await response.parse()
+ assert_matches_type(Optional[PolicyCreateResponse], policy, 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.policies.with_raw_response.create(
+ account_id="",
+ decision="allow",
+ include=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ name="Allow devs",
+ )
+
+ @parametrize
+ async def test_method_update(self, async_client: AsyncCloudflare) -> None:
+ policy = await async_client.zero_trust.access.policies.update(
+ "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ decision="allow",
+ include=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ name="Allow devs",
+ )
+ assert_matches_type(Optional[PolicyUpdateResponse], policy, path=["response"])
+
+ @parametrize
+ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ policy = await async_client.zero_trust.access.policies.update(
+ "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ decision="allow",
+ include=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ name="Allow devs",
+ approval_groups=[
+ {
+ "approvals_needed": 1,
+ "email_addresses": ["test1@cloudflare.com", "test2@cloudflare.com"],
+ "email_list_uuid": "string",
+ },
+ {
+ "approvals_needed": 3,
+ "email_addresses": ["test@cloudflare.com", "test2@cloudflare.com"],
+ "email_list_uuid": "597147a1-976b-4ef2-9af0-81d5d007fc34",
+ },
+ ],
+ approval_required=True,
+ exclude=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ isolation_required=False,
+ purpose_justification_prompt="Please enter a justification for entering this protected domain.",
+ purpose_justification_required=True,
+ require=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ session_duration="24h",
+ )
+ assert_matches_type(Optional[PolicyUpdateResponse], policy, path=["response"])
+
+ @parametrize
+ async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.access.policies.with_raw_response.update(
+ "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ decision="allow",
+ include=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ name="Allow devs",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ policy = await response.parse()
+ assert_matches_type(Optional[PolicyUpdateResponse], policy, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.access.policies.with_streaming_response.update(
+ "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ decision="allow",
+ include=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ name="Allow devs",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ policy = await response.parse()
+ assert_matches_type(Optional[PolicyUpdateResponse], policy, 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.access.policies.with_raw_response.update(
+ "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="",
+ decision="allow",
+ include=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ name="Allow devs",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"):
+ await async_client.zero_trust.access.policies.with_raw_response.update(
+ "",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ decision="allow",
+ include=[
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ {"email": {"email": "test@example.com"}},
+ ],
+ name="Allow devs",
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncCloudflare) -> None:
+ policy = await async_client.zero_trust.access.policies.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(AsyncSinglePage[PolicyListResponse], policy, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.access.policies.with_raw_response.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ policy = await response.parse()
+ assert_matches_type(AsyncSinglePage[PolicyListResponse], policy, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.access.policies.with_streaming_response.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ policy = await response.parse()
+ assert_matches_type(AsyncSinglePage[PolicyListResponse], policy, 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.policies.with_raw_response.list(
+ account_id="",
+ )
+
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncCloudflare) -> None:
+ policy = await async_client.zero_trust.access.policies.delete(
+ "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[PolicyDeleteResponse], policy, path=["response"])
+
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.access.policies.with_raw_response.delete(
+ "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ policy = await response.parse()
+ assert_matches_type(Optional[PolicyDeleteResponse], policy, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.access.policies.with_streaming_response.delete(
+ "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"
+
+ policy = await response.parse()
+ assert_matches_type(Optional[PolicyDeleteResponse], policy, 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.policies.with_raw_response.delete(
+ "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"):
+ await async_client.zero_trust.access.policies.with_raw_response.delete(
+ "",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncCloudflare) -> None:
+ policy = await async_client.zero_trust.access.policies.get(
+ "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[PolicyGetResponse], policy, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.access.policies.with_raw_response.get(
+ "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ policy = await response.parse()
+ assert_matches_type(Optional[PolicyGetResponse], policy, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.access.policies.with_streaming_response.get(
+ "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"
+
+ policy = await response.parse()
+ assert_matches_type(Optional[PolicyGetResponse], policy, 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.access.policies.with_raw_response.get(
+ "f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `policy_id` but received ''"):
+ await async_client.zero_trust.access.policies.with_raw_response.get(
+ "",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )