diff --git a/.stats.yml b/.stats.yml
index c60c6d5cbc3..41b5b15dd67 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 2317
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-6c72aaee26a255cefb59365441066a292ee06cff650529eb8b95d9ffb73ec13a.yml
-openapi_spec_hash: 393731844a065cd2de4b422825007b70
-config_hash: fb00b1d45d83236f53f8ef08adb2db5c
+configured_endpoints: 2329
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-884b4b7d2d826afd303115f717021363d35e76d0819f4822e9faf6c577ea66ca.yml
+openapi_spec_hash: 4fc7ac1b97d37c76f38db408ab2ed0cd
+config_hash: 1fe0cc702fafe448e633d379a5633326
diff --git a/src/cloudflare/resources/abuse_reports/mitigations.py b/src/cloudflare/resources/abuse_reports/mitigations.py
index 7286fe6009b..ba7dfc2d728 100644
--- a/src/cloudflare/resources/abuse_reports/mitigations.py
+++ b/src/cloudflare/resources/abuse_reports/mitigations.py
@@ -69,13 +69,25 @@ def list(
| Omit = omit,
status: Literal["pending", "active", "in_review", "cancelled", "removed"] | Omit = omit,
type: Literal[
+ "account_suspend",
+ "copyright_interstitial",
+ "geo_block",
"legal_block",
+ "malware_interstitial",
"misleading_interstitial",
- "phishing_interstitial",
"network_block",
+ "phishing_interstitial",
+ "playfairite_enforce",
+ "r2_takedown_account",
+ "r2_takedown_bucket",
+ "r2_takedown_object",
"rate_limit_cache",
- "account_suspend",
"redirect_video_stream",
+ "registrar_freeze",
+ "registrar_parking",
+ "stream_block_account",
+ "user_suspend",
+ "workers_takedown_by_zone_id",
]
| Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -238,13 +250,25 @@ def list(
| Omit = omit,
status: Literal["pending", "active", "in_review", "cancelled", "removed"] | Omit = omit,
type: Literal[
+ "account_suspend",
+ "copyright_interstitial",
+ "geo_block",
"legal_block",
+ "malware_interstitial",
"misleading_interstitial",
- "phishing_interstitial",
"network_block",
+ "phishing_interstitial",
+ "playfairite_enforce",
+ "r2_takedown_account",
+ "r2_takedown_bucket",
+ "r2_takedown_object",
"rate_limit_cache",
- "account_suspend",
"redirect_video_stream",
+ "registrar_freeze",
+ "registrar_parking",
+ "stream_block_account",
+ "user_suspend",
+ "workers_takedown_by_zone_id",
]
| Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
diff --git a/src/cloudflare/resources/ai_gateway/ai_gateway.py b/src/cloudflare/resources/ai_gateway/ai_gateway.py
index fac8e0b1718..a2b415a26b5 100644
--- a/src/cloudflare/resources/ai_gateway/ai_gateway.py
+++ b/src/cloudflare/resources/ai_gateway/ai_gateway.py
@@ -255,6 +255,7 @@ def update(
retry_backoff: Optional[Literal["constant", "linear", "exponential"]] | Omit = omit,
retry_delay: Optional[int] | Omit = omit,
retry_max_attempts: Optional[int] | Omit = omit,
+ spend_limits: Optional[ai_gateway_update_params.SpendLimits] | Omit = omit,
store_id: Optional[str] | Omit = omit,
stripe: Optional[ai_gateway_update_params.Stripe] | Omit = omit,
workers_ai_billing_mode: Literal["postpaid"] | Omit = omit,
@@ -314,6 +315,7 @@ def update(
"retry_backoff": retry_backoff,
"retry_delay": retry_delay,
"retry_max_attempts": retry_max_attempts,
+ "spend_limits": spend_limits,
"store_id": store_id,
"stripe": stripe,
"workers_ai_billing_mode": workers_ai_billing_mode,
@@ -627,6 +629,7 @@ async def update(
retry_backoff: Optional[Literal["constant", "linear", "exponential"]] | Omit = omit,
retry_delay: Optional[int] | Omit = omit,
retry_max_attempts: Optional[int] | Omit = omit,
+ spend_limits: Optional[ai_gateway_update_params.SpendLimits] | Omit = omit,
store_id: Optional[str] | Omit = omit,
stripe: Optional[ai_gateway_update_params.Stripe] | Omit = omit,
workers_ai_billing_mode: Literal["postpaid"] | Omit = omit,
@@ -686,6 +689,7 @@ async def update(
"retry_backoff": retry_backoff,
"retry_delay": retry_delay,
"retry_max_attempts": retry_max_attempts,
+ "spend_limits": spend_limits,
"store_id": store_id,
"stripe": stripe,
"workers_ai_billing_mode": workers_ai_billing_mode,
diff --git a/src/cloudflare/resources/dns/__init__.py b/src/cloudflare/resources/dns/__init__.py
index 58768dba906..7d175c52cab 100644
--- a/src/cloudflare/resources/dns/__init__.py
+++ b/src/cloudflare/resources/dns/__init__.py
@@ -8,6 +8,14 @@
DNSResourceWithStreamingResponse,
AsyncDNSResourceWithStreamingResponse,
)
+from .usage import (
+ UsageResource,
+ AsyncUsageResource,
+ UsageResourceWithRawResponse,
+ AsyncUsageResourceWithRawResponse,
+ UsageResourceWithStreamingResponse,
+ AsyncUsageResourceWithStreamingResponse,
+)
from .dnssec import (
DNSSECResource,
AsyncDNSSECResource,
@@ -62,6 +70,12 @@
"AsyncRecordsResourceWithRawResponse",
"RecordsResourceWithStreamingResponse",
"AsyncRecordsResourceWithStreamingResponse",
+ "UsageResource",
+ "AsyncUsageResource",
+ "UsageResourceWithRawResponse",
+ "AsyncUsageResourceWithRawResponse",
+ "UsageResourceWithStreamingResponse",
+ "AsyncUsageResourceWithStreamingResponse",
"SettingsResource",
"AsyncSettingsResource",
"SettingsResourceWithRawResponse",
diff --git a/src/cloudflare/resources/dns/api.md b/src/cloudflare/resources/dns/api.md
index 73fb955aeed..8695bc1b784 100644
--- a/src/cloudflare/resources/dns/api.md
+++ b/src/cloudflare/resources/dns/api.md
@@ -72,6 +72,32 @@ Methods:
- client.dns.records.scan_review(\*, zone_id, \*\*params) -> Optional[RecordScanReviewResponse]
- client.dns.records.scan_trigger(\*, zone_id) -> RecordScanTriggerResponse
+## Usage
+
+### Zone
+
+Types:
+
+```python
+from cloudflare.types.dns.usage import ZoneGetResponse
+```
+
+Methods:
+
+- client.dns.usage.zone.get(\*, zone_id) -> Optional[ZoneGetResponse]
+
+### Account
+
+Types:
+
+```python
+from cloudflare.types.dns.usage import AccountGetResponse
+```
+
+Methods:
+
+- client.dns.usage.account.get(\*, account_id) -> Optional[AccountGetResponse]
+
## Settings
### Zone
diff --git a/src/cloudflare/resources/dns/dns.py b/src/cloudflare/resources/dns/dns.py
index a4c4157a412..badc953563b 100644
--- a/src/cloudflare/resources/dns/dns.py
+++ b/src/cloudflare/resources/dns/dns.py
@@ -20,6 +20,14 @@
)
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
+from .usage.usage import (
+ UsageResource,
+ AsyncUsageResource,
+ UsageResourceWithRawResponse,
+ AsyncUsageResourceWithRawResponse,
+ UsageResourceWithStreamingResponse,
+ AsyncUsageResourceWithStreamingResponse,
+)
from .settings.settings import (
SettingsResource,
AsyncSettingsResource,
@@ -57,6 +65,10 @@ def dnssec(self) -> DNSSECResource:
def records(self) -> RecordsResource:
return RecordsResource(self._client)
+ @cached_property
+ def usage(self) -> UsageResource:
+ return UsageResource(self._client)
+
@cached_property
def settings(self) -> SettingsResource:
return SettingsResource(self._client)
@@ -98,6 +110,10 @@ def dnssec(self) -> AsyncDNSSECResource:
def records(self) -> AsyncRecordsResource:
return AsyncRecordsResource(self._client)
+ @cached_property
+ def usage(self) -> AsyncUsageResource:
+ return AsyncUsageResource(self._client)
+
@cached_property
def settings(self) -> AsyncSettingsResource:
return AsyncSettingsResource(self._client)
@@ -142,6 +158,10 @@ def dnssec(self) -> DNSSECResourceWithRawResponse:
def records(self) -> RecordsResourceWithRawResponse:
return RecordsResourceWithRawResponse(self._dns.records)
+ @cached_property
+ def usage(self) -> UsageResourceWithRawResponse:
+ return UsageResourceWithRawResponse(self._dns.usage)
+
@cached_property
def settings(self) -> SettingsResourceWithRawResponse:
return SettingsResourceWithRawResponse(self._dns.settings)
@@ -167,6 +187,10 @@ def dnssec(self) -> AsyncDNSSECResourceWithRawResponse:
def records(self) -> AsyncRecordsResourceWithRawResponse:
return AsyncRecordsResourceWithRawResponse(self._dns.records)
+ @cached_property
+ def usage(self) -> AsyncUsageResourceWithRawResponse:
+ return AsyncUsageResourceWithRawResponse(self._dns.usage)
+
@cached_property
def settings(self) -> AsyncSettingsResourceWithRawResponse:
return AsyncSettingsResourceWithRawResponse(self._dns.settings)
@@ -192,6 +216,10 @@ def dnssec(self) -> DNSSECResourceWithStreamingResponse:
def records(self) -> RecordsResourceWithStreamingResponse:
return RecordsResourceWithStreamingResponse(self._dns.records)
+ @cached_property
+ def usage(self) -> UsageResourceWithStreamingResponse:
+ return UsageResourceWithStreamingResponse(self._dns.usage)
+
@cached_property
def settings(self) -> SettingsResourceWithStreamingResponse:
return SettingsResourceWithStreamingResponse(self._dns.settings)
@@ -217,6 +245,10 @@ def dnssec(self) -> AsyncDNSSECResourceWithStreamingResponse:
def records(self) -> AsyncRecordsResourceWithStreamingResponse:
return AsyncRecordsResourceWithStreamingResponse(self._dns.records)
+ @cached_property
+ def usage(self) -> AsyncUsageResourceWithStreamingResponse:
+ return AsyncUsageResourceWithStreamingResponse(self._dns.usage)
+
@cached_property
def settings(self) -> AsyncSettingsResourceWithStreamingResponse:
return AsyncSettingsResourceWithStreamingResponse(self._dns.settings)
diff --git a/src/cloudflare/resources/dns/usage/__init__.py b/src/cloudflare/resources/dns/usage/__init__.py
new file mode 100644
index 00000000000..84f2ba47257
--- /dev/null
+++ b/src/cloudflare/resources/dns/usage/__init__.py
@@ -0,0 +1,47 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .zone import (
+ ZoneResource,
+ AsyncZoneResource,
+ ZoneResourceWithRawResponse,
+ AsyncZoneResourceWithRawResponse,
+ ZoneResourceWithStreamingResponse,
+ AsyncZoneResourceWithStreamingResponse,
+)
+from .usage import (
+ UsageResource,
+ AsyncUsageResource,
+ UsageResourceWithRawResponse,
+ AsyncUsageResourceWithRawResponse,
+ UsageResourceWithStreamingResponse,
+ AsyncUsageResourceWithStreamingResponse,
+)
+from .account import (
+ AccountResource,
+ AsyncAccountResource,
+ AccountResourceWithRawResponse,
+ AsyncAccountResourceWithRawResponse,
+ AccountResourceWithStreamingResponse,
+ AsyncAccountResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "ZoneResource",
+ "AsyncZoneResource",
+ "ZoneResourceWithRawResponse",
+ "AsyncZoneResourceWithRawResponse",
+ "ZoneResourceWithStreamingResponse",
+ "AsyncZoneResourceWithStreamingResponse",
+ "AccountResource",
+ "AsyncAccountResource",
+ "AccountResourceWithRawResponse",
+ "AsyncAccountResourceWithRawResponse",
+ "AccountResourceWithStreamingResponse",
+ "AsyncAccountResourceWithStreamingResponse",
+ "UsageResource",
+ "AsyncUsageResource",
+ "UsageResourceWithRawResponse",
+ "AsyncUsageResourceWithRawResponse",
+ "UsageResourceWithStreamingResponse",
+ "AsyncUsageResourceWithStreamingResponse",
+]
diff --git a/src/cloudflare/resources/dns/usage/account.py b/src/cloudflare/resources/dns/usage/account.py
new file mode 100644
index 00000000000..b53b9e4109d
--- /dev/null
+++ b/src/cloudflare/resources/dns/usage/account.py
@@ -0,0 +1,183 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Type, Optional, cast
+
+import httpx
+
+from ...._types import Body, Query, Headers, NotGiven, not_given
+from ...._utils import path_template
+from ...._compat import cached_property
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from ...._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ...._wrappers import ResultWrapper
+from ...._base_client import make_request_options
+from ....types.dns.usage.account_get_response import AccountGetResponse
+
+__all__ = ["AccountResource", "AsyncAccountResource"]
+
+
+class AccountResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AccountResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return AccountResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AccountResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response
+ """
+ return AccountResourceWithStreamingResponse(self)
+
+ def get(
+ self,
+ *,
+ account_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[AccountGetResponse]:
+ """Get the current DNS record usage and quota for an account.
+
+ May include internal
+ DNS usage and quota.
+
+ 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(
+ path_template("/accounts/{account_id}/dns_records/usage", account_id=account_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[AccountGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[AccountGetResponse]], ResultWrapper[AccountGetResponse]),
+ )
+
+
+class AsyncAccountResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncAccountResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncAccountResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncAccountResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response
+ """
+ return AsyncAccountResourceWithStreamingResponse(self)
+
+ async def get(
+ self,
+ *,
+ account_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[AccountGetResponse]:
+ """Get the current DNS record usage and quota for an account.
+
+ May include internal
+ DNS usage and quota.
+
+ Args:
+ account_id: Identifier.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return await self._get(
+ path_template("/accounts/{account_id}/dns_records/usage", account_id=account_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[AccountGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[AccountGetResponse]], ResultWrapper[AccountGetResponse]),
+ )
+
+
+class AccountResourceWithRawResponse:
+ def __init__(self, account: AccountResource) -> None:
+ self._account = account
+
+ self.get = to_raw_response_wrapper(
+ account.get,
+ )
+
+
+class AsyncAccountResourceWithRawResponse:
+ def __init__(self, account: AsyncAccountResource) -> None:
+ self._account = account
+
+ self.get = async_to_raw_response_wrapper(
+ account.get,
+ )
+
+
+class AccountResourceWithStreamingResponse:
+ def __init__(self, account: AccountResource) -> None:
+ self._account = account
+
+ self.get = to_streamed_response_wrapper(
+ account.get,
+ )
+
+
+class AsyncAccountResourceWithStreamingResponse:
+ def __init__(self, account: AsyncAccountResource) -> None:
+ self._account = account
+
+ self.get = async_to_streamed_response_wrapper(
+ account.get,
+ )
diff --git a/src/cloudflare/resources/dns/usage/usage.py b/src/cloudflare/resources/dns/usage/usage.py
new file mode 100644
index 00000000000..43dd5daf595
--- /dev/null
+++ b/src/cloudflare/resources/dns/usage/usage.py
@@ -0,0 +1,134 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .zone import (
+ ZoneResource,
+ AsyncZoneResource,
+ ZoneResourceWithRawResponse,
+ AsyncZoneResourceWithRawResponse,
+ ZoneResourceWithStreamingResponse,
+ AsyncZoneResourceWithStreamingResponse,
+)
+from .account import (
+ AccountResource,
+ AsyncAccountResource,
+ AccountResourceWithRawResponse,
+ AsyncAccountResourceWithRawResponse,
+ AccountResourceWithStreamingResponse,
+ AsyncAccountResourceWithStreamingResponse,
+)
+from ...._compat import cached_property
+from ...._resource import SyncAPIResource, AsyncAPIResource
+
+__all__ = ["UsageResource", "AsyncUsageResource"]
+
+
+class UsageResource(SyncAPIResource):
+ @cached_property
+ def zone(self) -> ZoneResource:
+ return ZoneResource(self._client)
+
+ @cached_property
+ def account(self) -> AccountResource:
+ return AccountResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> UsageResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return UsageResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> UsageResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response
+ """
+ return UsageResourceWithStreamingResponse(self)
+
+
+class AsyncUsageResource(AsyncAPIResource):
+ @cached_property
+ def zone(self) -> AsyncZoneResource:
+ return AsyncZoneResource(self._client)
+
+ @cached_property
+ def account(self) -> AsyncAccountResource:
+ return AsyncAccountResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncUsageResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncUsageResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncUsageResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response
+ """
+ return AsyncUsageResourceWithStreamingResponse(self)
+
+
+class UsageResourceWithRawResponse:
+ def __init__(self, usage: UsageResource) -> None:
+ self._usage = usage
+
+ @cached_property
+ def zone(self) -> ZoneResourceWithRawResponse:
+ return ZoneResourceWithRawResponse(self._usage.zone)
+
+ @cached_property
+ def account(self) -> AccountResourceWithRawResponse:
+ return AccountResourceWithRawResponse(self._usage.account)
+
+
+class AsyncUsageResourceWithRawResponse:
+ def __init__(self, usage: AsyncUsageResource) -> None:
+ self._usage = usage
+
+ @cached_property
+ def zone(self) -> AsyncZoneResourceWithRawResponse:
+ return AsyncZoneResourceWithRawResponse(self._usage.zone)
+
+ @cached_property
+ def account(self) -> AsyncAccountResourceWithRawResponse:
+ return AsyncAccountResourceWithRawResponse(self._usage.account)
+
+
+class UsageResourceWithStreamingResponse:
+ def __init__(self, usage: UsageResource) -> None:
+ self._usage = usage
+
+ @cached_property
+ def zone(self) -> ZoneResourceWithStreamingResponse:
+ return ZoneResourceWithStreamingResponse(self._usage.zone)
+
+ @cached_property
+ def account(self) -> AccountResourceWithStreamingResponse:
+ return AccountResourceWithStreamingResponse(self._usage.account)
+
+
+class AsyncUsageResourceWithStreamingResponse:
+ def __init__(self, usage: AsyncUsageResource) -> None:
+ self._usage = usage
+
+ @cached_property
+ def zone(self) -> AsyncZoneResourceWithStreamingResponse:
+ return AsyncZoneResourceWithStreamingResponse(self._usage.zone)
+
+ @cached_property
+ def account(self) -> AsyncAccountResourceWithStreamingResponse:
+ return AsyncAccountResourceWithStreamingResponse(self._usage.account)
diff --git a/src/cloudflare/resources/dns/usage/zone.py b/src/cloudflare/resources/dns/usage/zone.py
new file mode 100644
index 00000000000..1fd9151910f
--- /dev/null
+++ b/src/cloudflare/resources/dns/usage/zone.py
@@ -0,0 +1,181 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Type, Optional, cast
+
+import httpx
+
+from ...._types import Body, Query, Headers, NotGiven, not_given
+from ...._utils import path_template
+from ...._compat import cached_property
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from ...._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ...._wrappers import ResultWrapper
+from ...._base_client import make_request_options
+from ....types.dns.usage.zone_get_response import ZoneGetResponse
+
+__all__ = ["ZoneResource", "AsyncZoneResource"]
+
+
+class ZoneResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> ZoneResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return ZoneResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> ZoneResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response
+ """
+ return ZoneResourceWithStreamingResponse(self)
+
+ def get(
+ self,
+ *,
+ zone_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[ZoneGetResponse]:
+ """
+ Get the current DNS record usage for a zone, including the number of records and
+ the quota limit.
+
+ Args:
+ zone_id: Identifier.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not zone_id:
+ raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
+ return self._get(
+ path_template("/zones/{zone_id}/dns_records/usage", zone_id=zone_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[ZoneGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[ZoneGetResponse]], ResultWrapper[ZoneGetResponse]),
+ )
+
+
+class AsyncZoneResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncZoneResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncZoneResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncZoneResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response
+ """
+ return AsyncZoneResourceWithStreamingResponse(self)
+
+ async def get(
+ self,
+ *,
+ zone_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[ZoneGetResponse]:
+ """
+ Get the current DNS record usage for a zone, including the number of records and
+ the quota limit.
+
+ Args:
+ zone_id: Identifier.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not zone_id:
+ raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
+ return await self._get(
+ path_template("/zones/{zone_id}/dns_records/usage", zone_id=zone_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[ZoneGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[ZoneGetResponse]], ResultWrapper[ZoneGetResponse]),
+ )
+
+
+class ZoneResourceWithRawResponse:
+ def __init__(self, zone: ZoneResource) -> None:
+ self._zone = zone
+
+ self.get = to_raw_response_wrapper(
+ zone.get,
+ )
+
+
+class AsyncZoneResourceWithRawResponse:
+ def __init__(self, zone: AsyncZoneResource) -> None:
+ self._zone = zone
+
+ self.get = async_to_raw_response_wrapper(
+ zone.get,
+ )
+
+
+class ZoneResourceWithStreamingResponse:
+ def __init__(self, zone: ZoneResource) -> None:
+ self._zone = zone
+
+ self.get = to_streamed_response_wrapper(
+ zone.get,
+ )
+
+
+class AsyncZoneResourceWithStreamingResponse:
+ def __init__(self, zone: AsyncZoneResource) -> None:
+ self._zone = zone
+
+ self.get = async_to_streamed_response_wrapper(
+ zone.get,
+ )
diff --git a/src/cloudflare/resources/logpush/datasets/fields.py b/src/cloudflare/resources/logpush/datasets/fields.py
index b833e0cd1fc..905b3f0fcb0 100644
--- a/src/cloudflare/resources/logpush/datasets/fields.py
+++ b/src/cloudflare/resources/logpush/datasets/fields.py
@@ -74,6 +74,7 @@ def get(
"sinkhole_http_logs",
"spectrum_events",
"ssh_logs",
+ "turnstile_events",
"warp_config_changes",
"warp_toggle_changes",
"workers_trace_events",
@@ -194,6 +195,7 @@ async def get(
"sinkhole_http_logs",
"spectrum_events",
"ssh_logs",
+ "turnstile_events",
"warp_config_changes",
"warp_toggle_changes",
"workers_trace_events",
diff --git a/src/cloudflare/resources/logpush/datasets/jobs.py b/src/cloudflare/resources/logpush/datasets/jobs.py
index ece4498669f..d229ba4c636 100644
--- a/src/cloudflare/resources/logpush/datasets/jobs.py
+++ b/src/cloudflare/resources/logpush/datasets/jobs.py
@@ -75,6 +75,7 @@ def get(
"sinkhole_http_logs",
"spectrum_events",
"ssh_logs",
+ "turnstile_events",
"warp_config_changes",
"warp_toggle_changes",
"workers_trace_events",
@@ -190,6 +191,7 @@ def get(
"sinkhole_http_logs",
"spectrum_events",
"ssh_logs",
+ "turnstile_events",
"warp_config_changes",
"warp_toggle_changes",
"workers_trace_events",
diff --git a/src/cloudflare/resources/logpush/jobs.py b/src/cloudflare/resources/logpush/jobs.py
index 67ed788882f..8c62a706d68 100644
--- a/src/cloudflare/resources/logpush/jobs.py
+++ b/src/cloudflare/resources/logpush/jobs.py
@@ -84,6 +84,7 @@ def create(
"sinkhole_http_logs",
"spectrum_events",
"ssh_logs",
+ "turnstile_events",
"warp_config_changes",
"warp_toggle_changes",
"workers_trace_events",
@@ -590,6 +591,7 @@ async def create(
"sinkhole_http_logs",
"spectrum_events",
"ssh_logs",
+ "turnstile_events",
"warp_config_changes",
"warp_toggle_changes",
"workers_trace_events",
diff --git a/src/cloudflare/resources/realtime_kit/sessions.py b/src/cloudflare/resources/realtime_kit/sessions.py
index 5c575c80543..749342eb2ed 100644
--- a/src/cloudflare/resources/realtime_kit/sessions.py
+++ b/src/cloudflare/resources/realtime_kit/sessions.py
@@ -131,16 +131,14 @@ def get_participant_data_from_peer_id(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> SessionGetParticipantDataFromPeerIDResponse:
"""
- Returns details of the given peer ID along with call statistics for the given
- session ID.
+ Returns participant details for the given peer ID along with call statistics.
Args:
account_id: The account identifier tag.
app_id: The app identifier tag.
- filters: Comma separated list of filters to apply. Note that there must be no spaces
- between the filters.
+ filters: Filter to apply to the peer report.
include_peer_events: if true, response includes all the peer events of participant.
@@ -718,16 +716,14 @@ async def get_participant_data_from_peer_id(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> SessionGetParticipantDataFromPeerIDResponse:
"""
- Returns details of the given peer ID along with call statistics for the given
- session ID.
+ Returns participant details for the given peer ID along with call statistics.
Args:
account_id: The account identifier tag.
app_id: The app identifier tag.
- filters: Comma separated list of filters to apply. Note that there must be no spaces
- between the filters.
+ filters: Filter to apply to the peer report.
include_peer_events: if true, response includes all the peer events of participant.
diff --git a/src/cloudflare/resources/resource_sharing/api.md b/src/cloudflare/resources/resource_sharing/api.md
index 7fec9dc27db..00b2d014706 100644
--- a/src/cloudflare/resources/resource_sharing/api.md
+++ b/src/cloudflare/resources/resource_sharing/api.md
@@ -45,10 +45,19 @@ Methods:
Types:
```python
-from cloudflare.types.resource_sharing import ResourceCreateResponse, ResourceListResponse
+from cloudflare.types.resource_sharing import (
+ ResourceCreateResponse,
+ ResourceUpdateResponse,
+ ResourceListResponse,
+ ResourceDeleteResponse,
+ ResourceGetResponse,
+)
```
Methods:
- client.resource_sharing.resources.create(share_id, \*, account_id, \*\*params) -> Optional[ResourceCreateResponse]
+- client.resource_sharing.resources.update(share_resource_id, \*, account_id, share_id, \*\*params) -> Optional[ResourceUpdateResponse]
- client.resource_sharing.resources.list(share_id, \*, account_id, \*\*params) -> SyncV4PagePaginationArray[ResourceListResponse]
+- client.resource_sharing.resources.delete(share_resource_id, \*, account_id, share_id) -> Optional[ResourceDeleteResponse]
+- client.resource_sharing.resources.get(share_resource_id, \*, account_id, share_id) -> Optional[ResourceGetResponse]
diff --git a/src/cloudflare/resources/resource_sharing/resources.py b/src/cloudflare/resources/resource_sharing/resources.py
index 84a136aabe7..1016063f44c 100644
--- a/src/cloudflare/resources/resource_sharing/resources.py
+++ b/src/cloudflare/resources/resource_sharing/resources.py
@@ -20,9 +20,12 @@
from ..._wrappers import ResultWrapper
from ...pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray
from ..._base_client import AsyncPaginator, make_request_options
-from ...types.resource_sharing import resource_list_params, resource_create_params
+from ...types.resource_sharing import resource_list_params, resource_create_params, resource_update_params
+from ...types.resource_sharing.resource_get_response import ResourceGetResponse
from ...types.resource_sharing.resource_list_response import ResourceListResponse
from ...types.resource_sharing.resource_create_response import ResourceCreateResponse
+from ...types.resource_sharing.resource_delete_response import ResourceDeleteResponse
+from ...types.resource_sharing.resource_update_response import ResourceUpdateResponse
__all__ = ["ResourcesResource", "AsyncResourcesResource"]
@@ -121,6 +124,65 @@ def create(
cast_to=cast(Type[Optional[ResourceCreateResponse]], ResultWrapper[ResourceCreateResponse]),
)
+ def update(
+ self,
+ share_resource_id: str,
+ *,
+ account_id: str,
+ share_id: str,
+ meta: object,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this 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[ResourceUpdateResponse]:
+ """
+ Update is not immediate, an updated share resource object with a new status will
+ be returned.
+
+ Args:
+ account_id: Account identifier.
+
+ share_id: Share identifier tag.
+
+ share_resource_id: Share Resource identifier.
+
+ meta: Resource Metadata.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the 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 share_id:
+ raise ValueError(f"Expected a non-empty value for `share_id` but received {share_id!r}")
+ if not share_resource_id:
+ raise ValueError(f"Expected a non-empty value for `share_resource_id` but received {share_resource_id!r}")
+ return self._put(
+ path_template(
+ "/accounts/{account_id}/shares/{share_id}/resources/{share_resource_id}",
+ account_id=account_id,
+ share_id=share_id,
+ share_resource_id=share_resource_id,
+ ),
+ body=maybe_transform({"meta": meta}, resource_update_params.ResourceUpdateParams),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[ResourceUpdateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[ResourceUpdateResponse]], ResultWrapper[ResourceUpdateResponse]),
+ )
+
def list(
self,
share_id: str,
@@ -199,6 +261,115 @@ def list(
model=ResourceListResponse,
)
+ def delete(
+ self,
+ share_resource_id: str,
+ *,
+ account_id: str,
+ share_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[ResourceDeleteResponse]:
+ """
+ Deletion is not immediate, an updated share resource object with a new status
+ will be returned.
+
+ Args:
+ account_id: Account identifier.
+
+ share_id: Share identifier tag.
+
+ share_resource_id: Share Resource identifier.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not share_id:
+ raise ValueError(f"Expected a non-empty value for `share_id` but received {share_id!r}")
+ if not share_resource_id:
+ raise ValueError(f"Expected a non-empty value for `share_resource_id` but received {share_resource_id!r}")
+ return self._delete(
+ path_template(
+ "/accounts/{account_id}/shares/{share_id}/resources/{share_resource_id}",
+ account_id=account_id,
+ share_id=share_id,
+ share_resource_id=share_resource_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[ResourceDeleteResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[ResourceDeleteResponse]], ResultWrapper[ResourceDeleteResponse]),
+ )
+
+ def get(
+ self,
+ share_resource_id: str,
+ *,
+ account_id: str,
+ share_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[ResourceGetResponse]:
+ """
+ Get share resource by ID.
+
+ Args:
+ account_id: Account identifier.
+
+ share_id: Share identifier tag.
+
+ share_resource_id: Share Resource identifier.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not share_id:
+ raise ValueError(f"Expected a non-empty value for `share_id` but received {share_id!r}")
+ if not share_resource_id:
+ raise ValueError(f"Expected a non-empty value for `share_resource_id` but received {share_resource_id!r}")
+ return self._get(
+ path_template(
+ "/accounts/{account_id}/shares/{share_id}/resources/{share_resource_id}",
+ account_id=account_id,
+ share_id=share_id,
+ share_resource_id=share_resource_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[ResourceGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[ResourceGetResponse]], ResultWrapper[ResourceGetResponse]),
+ )
+
class AsyncResourcesResource(AsyncAPIResource):
@cached_property
@@ -294,6 +465,65 @@ async def create(
cast_to=cast(Type[Optional[ResourceCreateResponse]], ResultWrapper[ResourceCreateResponse]),
)
+ async def update(
+ self,
+ share_resource_id: str,
+ *,
+ account_id: str,
+ share_id: str,
+ meta: object,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this 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[ResourceUpdateResponse]:
+ """
+ Update is not immediate, an updated share resource object with a new status will
+ be returned.
+
+ Args:
+ account_id: Account identifier.
+
+ share_id: Share identifier tag.
+
+ share_resource_id: Share Resource identifier.
+
+ meta: Resource Metadata.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the 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 share_id:
+ raise ValueError(f"Expected a non-empty value for `share_id` but received {share_id!r}")
+ if not share_resource_id:
+ raise ValueError(f"Expected a non-empty value for `share_resource_id` but received {share_resource_id!r}")
+ return await self._put(
+ path_template(
+ "/accounts/{account_id}/shares/{share_id}/resources/{share_resource_id}",
+ account_id=account_id,
+ share_id=share_id,
+ share_resource_id=share_resource_id,
+ ),
+ body=await async_maybe_transform({"meta": meta}, resource_update_params.ResourceUpdateParams),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[ResourceUpdateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[ResourceUpdateResponse]], ResultWrapper[ResourceUpdateResponse]),
+ )
+
def list(
self,
share_id: str,
@@ -372,6 +602,115 @@ def list(
model=ResourceListResponse,
)
+ async def delete(
+ self,
+ share_resource_id: str,
+ *,
+ account_id: str,
+ share_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[ResourceDeleteResponse]:
+ """
+ Deletion is not immediate, an updated share resource object with a new status
+ will be returned.
+
+ Args:
+ account_id: Account identifier.
+
+ share_id: Share identifier tag.
+
+ share_resource_id: Share Resource identifier.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not share_id:
+ raise ValueError(f"Expected a non-empty value for `share_id` but received {share_id!r}")
+ if not share_resource_id:
+ raise ValueError(f"Expected a non-empty value for `share_resource_id` but received {share_resource_id!r}")
+ return await self._delete(
+ path_template(
+ "/accounts/{account_id}/shares/{share_id}/resources/{share_resource_id}",
+ account_id=account_id,
+ share_id=share_id,
+ share_resource_id=share_resource_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[ResourceDeleteResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[ResourceDeleteResponse]], ResultWrapper[ResourceDeleteResponse]),
+ )
+
+ async def get(
+ self,
+ share_resource_id: str,
+ *,
+ account_id: str,
+ share_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[ResourceGetResponse]:
+ """
+ Get share resource by ID.
+
+ Args:
+ account_id: Account identifier.
+
+ share_id: Share identifier tag.
+
+ share_resource_id: Share Resource identifier.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not share_id:
+ raise ValueError(f"Expected a non-empty value for `share_id` but received {share_id!r}")
+ if not share_resource_id:
+ raise ValueError(f"Expected a non-empty value for `share_resource_id` but received {share_resource_id!r}")
+ return await self._get(
+ path_template(
+ "/accounts/{account_id}/shares/{share_id}/resources/{share_resource_id}",
+ account_id=account_id,
+ share_id=share_id,
+ share_resource_id=share_resource_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[ResourceGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[ResourceGetResponse]], ResultWrapper[ResourceGetResponse]),
+ )
+
class ResourcesResourceWithRawResponse:
def __init__(self, resources: ResourcesResource) -> None:
@@ -380,9 +719,18 @@ def __init__(self, resources: ResourcesResource) -> None:
self.create = to_raw_response_wrapper(
resources.create,
)
+ self.update = to_raw_response_wrapper(
+ resources.update,
+ )
self.list = to_raw_response_wrapper(
resources.list,
)
+ self.delete = to_raw_response_wrapper(
+ resources.delete,
+ )
+ self.get = to_raw_response_wrapper(
+ resources.get,
+ )
class AsyncResourcesResourceWithRawResponse:
@@ -392,9 +740,18 @@ def __init__(self, resources: AsyncResourcesResource) -> None:
self.create = async_to_raw_response_wrapper(
resources.create,
)
+ self.update = async_to_raw_response_wrapper(
+ resources.update,
+ )
self.list = async_to_raw_response_wrapper(
resources.list,
)
+ self.delete = async_to_raw_response_wrapper(
+ resources.delete,
+ )
+ self.get = async_to_raw_response_wrapper(
+ resources.get,
+ )
class ResourcesResourceWithStreamingResponse:
@@ -404,9 +761,18 @@ def __init__(self, resources: ResourcesResource) -> None:
self.create = to_streamed_response_wrapper(
resources.create,
)
+ self.update = to_streamed_response_wrapper(
+ resources.update,
+ )
self.list = to_streamed_response_wrapper(
resources.list,
)
+ self.delete = to_streamed_response_wrapper(
+ resources.delete,
+ )
+ self.get = to_streamed_response_wrapper(
+ resources.get,
+ )
class AsyncResourcesResourceWithStreamingResponse:
@@ -416,6 +782,15 @@ def __init__(self, resources: AsyncResourcesResource) -> None:
self.create = async_to_streamed_response_wrapper(
resources.create,
)
+ self.update = async_to_streamed_response_wrapper(
+ resources.update,
+ )
self.list = async_to_streamed_response_wrapper(
resources.list,
)
+ self.delete = async_to_streamed_response_wrapper(
+ resources.delete,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ resources.get,
+ )
diff --git a/src/cloudflare/resources/workflows/api.md b/src/cloudflare/resources/workflows/api.md
index a90bde50ec2..9b6d98404ce 100644
--- a/src/cloudflare/resources/workflows/api.md
+++ b/src/cloudflare/resources/workflows/api.md
@@ -28,6 +28,7 @@ from cloudflare.types.workflows import (
InstanceListResponse,
InstanceBulkResponse,
InstanceGetResponse,
+ InstanceStepResponse,
)
```
@@ -37,6 +38,7 @@ Methods:
- client.workflows.instances.list(workflow_name, \*, account_id, \*\*params) -> SyncV4PagePaginationArray[InstanceListResponse]
- client.workflows.instances.bulk(workflow_name, \*, account_id, \*\*params) -> SyncSinglePage[InstanceBulkResponse]
- client.workflows.instances.get(instance_id, \*, account_id, workflow_name, \*\*params) -> InstanceGetResponse
+- client.workflows.instances.step(instance_id, \*, account_id, workflow_name, \*\*params) -> InstanceStepResponse
### Status
@@ -61,10 +63,11 @@ Methods:
Types:
```python
-from cloudflare.types.workflows import VersionListResponse, VersionGetResponse
+from cloudflare.types.workflows import VersionListResponse, VersionGetResponse, VersionGraphResponse
```
Methods:
- client.workflows.versions.list(workflow_name, \*, account_id, \*\*params) -> SyncV4PagePaginationArray[VersionListResponse]
- client.workflows.versions.get(version_id, \*, account_id, workflow_name) -> VersionGetResponse
+- client.workflows.versions.graph(version_id, \*, account_id, workflow_name) -> VersionGraphResponse
diff --git a/src/cloudflare/resources/workflows/instances/instances.py b/src/cloudflare/resources/workflows/instances/instances.py
index c0a88c923a9..fe90af5e81b 100644
--- a/src/cloudflare/resources/workflows/instances/instances.py
+++ b/src/cloudflare/resources/workflows/instances/instances.py
@@ -37,10 +37,17 @@
from ...._wrappers import ResultWrapper
from ....pagination import SyncSinglePage, AsyncSinglePage, SyncV4PagePaginationArray, AsyncV4PagePaginationArray
from ...._base_client import AsyncPaginator, make_request_options
-from ....types.workflows import instance_get_params, instance_bulk_params, instance_list_params, instance_create_params
+from ....types.workflows import (
+ instance_get_params,
+ instance_bulk_params,
+ instance_list_params,
+ instance_step_params,
+ instance_create_params,
+)
from ....types.workflows.instance_get_response import InstanceGetResponse
from ....types.workflows.instance_bulk_response import InstanceBulkResponse
from ....types.workflows.instance_list_response import InstanceListResponse
+from ....types.workflows.instance_step_response import InstanceStepResponse
from ....types.workflows.instance_create_response import InstanceCreateResponse
__all__ = ["InstancesResource", "AsyncInstancesResource"]
@@ -318,6 +325,80 @@ def get(
cast_to=cast(Type[InstanceGetResponse], ResultWrapper[InstanceGetResponse]),
)
+ def step(
+ self,
+ instance_id: str,
+ *,
+ account_id: str,
+ workflow_name: str,
+ name: str,
+ type: Literal["step", "waitForEvent"],
+ attempt: int | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> InstanceStepResponse:
+ """
+ Retrieves the full, untruncated output for a specific step on a workflow
+ instance. Returns a flat status-shaped JSON body with step `status` ('running' |
+ 'waiting' | 'complete' | 'errored'), `error` (nullable), and `output` (the step
+ value, or null while running/waiting/errored). When the step returned a
+ ReadableStream from step.do, the response is served as
+ 'application/octet-stream' with the raw bytes as the body instead of JSON. A
+ `status='running'` response with non-null `error` indicates the step is
+ currently retrying after a prior attempt failed.
+
+ Args:
+ name: Exact step name from the instance logs response, including the generated counter
+ suffix.
+
+ type: Step type to disambiguate step.do and waitForEvent entries that share the same
+ name.
+
+ attempt: Specific attempt number to retrieve output or error for.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the 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 workflow_name:
+ raise ValueError(f"Expected a non-empty value for `workflow_name` but received {workflow_name!r}")
+ if not instance_id:
+ raise ValueError(f"Expected a non-empty value for `instance_id` but received {instance_id!r}")
+ return self._get(
+ path_template(
+ "/accounts/{account_id}/workflows/{workflow_name}/instances/{instance_id}/step",
+ account_id=account_id,
+ workflow_name=workflow_name,
+ instance_id=instance_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "name": name,
+ "type": type,
+ "attempt": attempt,
+ },
+ instance_step_params.InstanceStepParams,
+ ),
+ post_parser=ResultWrapper[InstanceStepResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[InstanceStepResponse], ResultWrapper[InstanceStepResponse]),
+ )
+
class AsyncInstancesResource(AsyncAPIResource):
@cached_property
@@ -591,6 +672,80 @@ async def get(
cast_to=cast(Type[InstanceGetResponse], ResultWrapper[InstanceGetResponse]),
)
+ async def step(
+ self,
+ instance_id: str,
+ *,
+ account_id: str,
+ workflow_name: str,
+ name: str,
+ type: Literal["step", "waitForEvent"],
+ attempt: int | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> InstanceStepResponse:
+ """
+ Retrieves the full, untruncated output for a specific step on a workflow
+ instance. Returns a flat status-shaped JSON body with step `status` ('running' |
+ 'waiting' | 'complete' | 'errored'), `error` (nullable), and `output` (the step
+ value, or null while running/waiting/errored). When the step returned a
+ ReadableStream from step.do, the response is served as
+ 'application/octet-stream' with the raw bytes as the body instead of JSON. A
+ `status='running'` response with non-null `error` indicates the step is
+ currently retrying after a prior attempt failed.
+
+ Args:
+ name: Exact step name from the instance logs response, including the generated counter
+ suffix.
+
+ type: Step type to disambiguate step.do and waitForEvent entries that share the same
+ name.
+
+ attempt: Specific attempt number to retrieve output or error for.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the 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 workflow_name:
+ raise ValueError(f"Expected a non-empty value for `workflow_name` but received {workflow_name!r}")
+ if not instance_id:
+ raise ValueError(f"Expected a non-empty value for `instance_id` but received {instance_id!r}")
+ return await self._get(
+ path_template(
+ "/accounts/{account_id}/workflows/{workflow_name}/instances/{instance_id}/step",
+ account_id=account_id,
+ workflow_name=workflow_name,
+ instance_id=instance_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "name": name,
+ "type": type,
+ "attempt": attempt,
+ },
+ instance_step_params.InstanceStepParams,
+ ),
+ post_parser=ResultWrapper[InstanceStepResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[InstanceStepResponse], ResultWrapper[InstanceStepResponse]),
+ )
+
class InstancesResourceWithRawResponse:
def __init__(self, instances: InstancesResource) -> None:
@@ -608,6 +763,9 @@ def __init__(self, instances: InstancesResource) -> None:
self.get = to_raw_response_wrapper(
instances.get,
)
+ self.step = to_raw_response_wrapper(
+ instances.step,
+ )
@cached_property
def status(self) -> StatusResourceWithRawResponse:
@@ -634,6 +792,9 @@ def __init__(self, instances: AsyncInstancesResource) -> None:
self.get = async_to_raw_response_wrapper(
instances.get,
)
+ self.step = async_to_raw_response_wrapper(
+ instances.step,
+ )
@cached_property
def status(self) -> AsyncStatusResourceWithRawResponse:
@@ -660,6 +821,9 @@ def __init__(self, instances: InstancesResource) -> None:
self.get = to_streamed_response_wrapper(
instances.get,
)
+ self.step = to_streamed_response_wrapper(
+ instances.step,
+ )
@cached_property
def status(self) -> StatusResourceWithStreamingResponse:
@@ -686,6 +850,9 @@ def __init__(self, instances: AsyncInstancesResource) -> None:
self.get = async_to_streamed_response_wrapper(
instances.get,
)
+ self.step = async_to_streamed_response_wrapper(
+ instances.step,
+ )
@cached_property
def status(self) -> AsyncStatusResourceWithStreamingResponse:
diff --git a/src/cloudflare/resources/workflows/versions.py b/src/cloudflare/resources/workflows/versions.py
index b702774c237..51002d88919 100644
--- a/src/cloudflare/resources/workflows/versions.py
+++ b/src/cloudflare/resources/workflows/versions.py
@@ -22,6 +22,7 @@
from ...types.workflows import version_list_params
from ...types.workflows.version_get_response import VersionGetResponse
from ...types.workflows.version_list_response import VersionListResponse
+from ...types.workflows.version_graph_response import VersionGraphResponse
__all__ = ["VersionsResource", "AsyncVersionsResource"]
@@ -147,6 +148,54 @@ def get(
cast_to=cast(Type[VersionGetResponse], ResultWrapper[VersionGetResponse]),
)
+ def graph(
+ self,
+ version_id: str,
+ *,
+ account_id: str,
+ workflow_name: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> VersionGraphResponse:
+ """
+ Retrieves the graph visualization of a workflow version.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not workflow_name:
+ raise ValueError(f"Expected a non-empty value for `workflow_name` but received {workflow_name!r}")
+ if not version_id:
+ raise ValueError(f"Expected a non-empty value for `version_id` but received {version_id!r}")
+ return self._get(
+ path_template(
+ "/accounts/{account_id}/workflows/{workflow_name}/versions/{version_id}/graph",
+ account_id=account_id,
+ workflow_name=workflow_name,
+ version_id=version_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[VersionGraphResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[VersionGraphResponse], ResultWrapper[VersionGraphResponse]),
+ )
+
class AsyncVersionsResource(AsyncAPIResource):
@cached_property
@@ -269,6 +318,54 @@ async def get(
cast_to=cast(Type[VersionGetResponse], ResultWrapper[VersionGetResponse]),
)
+ async def graph(
+ self,
+ version_id: str,
+ *,
+ account_id: str,
+ workflow_name: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> VersionGraphResponse:
+ """
+ Retrieves the graph visualization of a workflow version.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not workflow_name:
+ raise ValueError(f"Expected a non-empty value for `workflow_name` but received {workflow_name!r}")
+ if not version_id:
+ raise ValueError(f"Expected a non-empty value for `version_id` but received {version_id!r}")
+ return await self._get(
+ path_template(
+ "/accounts/{account_id}/workflows/{workflow_name}/versions/{version_id}/graph",
+ account_id=account_id,
+ workflow_name=workflow_name,
+ version_id=version_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[VersionGraphResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[VersionGraphResponse], ResultWrapper[VersionGraphResponse]),
+ )
+
class VersionsResourceWithRawResponse:
def __init__(self, versions: VersionsResource) -> None:
@@ -280,6 +377,9 @@ def __init__(self, versions: VersionsResource) -> None:
self.get = to_raw_response_wrapper(
versions.get,
)
+ self.graph = to_raw_response_wrapper(
+ versions.graph,
+ )
class AsyncVersionsResourceWithRawResponse:
@@ -292,6 +392,9 @@ def __init__(self, versions: AsyncVersionsResource) -> None:
self.get = async_to_raw_response_wrapper(
versions.get,
)
+ self.graph = async_to_raw_response_wrapper(
+ versions.graph,
+ )
class VersionsResourceWithStreamingResponse:
@@ -304,6 +407,9 @@ def __init__(self, versions: VersionsResource) -> None:
self.get = to_streamed_response_wrapper(
versions.get,
)
+ self.graph = to_streamed_response_wrapper(
+ versions.graph,
+ )
class AsyncVersionsResourceWithStreamingResponse:
@@ -316,3 +422,6 @@ def __init__(self, versions: AsyncVersionsResource) -> None:
self.get = async_to_streamed_response_wrapper(
versions.get,
)
+ self.graph = async_to_streamed_response_wrapper(
+ versions.graph,
+ )
diff --git a/src/cloudflare/resources/workflows/workflows.py b/src/cloudflare/resources/workflows/workflows.py
index 803e81f301d..e8a57121959 100644
--- a/src/cloudflare/resources/workflows/workflows.py
+++ b/src/cloudflare/resources/workflows/workflows.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import Type, cast
+from typing import Type, Iterable, cast
import httpx
@@ -80,6 +80,7 @@ def update(
class_name: str,
script_name: str,
limits: workflow_update_params.Limits | Omit = omit,
+ schedules: Iterable[workflow_update_params.Schedule] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -112,6 +113,7 @@ def update(
"class_name": class_name,
"script_name": script_name,
"limits": limits,
+ "schedules": schedules,
},
workflow_update_params.WorkflowUpdateParams,
),
@@ -298,6 +300,7 @@ async def update(
class_name: str,
script_name: str,
limits: workflow_update_params.Limits | Omit = omit,
+ schedules: Iterable[workflow_update_params.Schedule] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -330,6 +333,7 @@ async def update(
"class_name": class_name,
"script_name": script_name,
"limits": limits,
+ "schedules": schedules,
},
workflow_update_params.WorkflowUpdateParams,
),
diff --git a/src/cloudflare/resources/zero_trust/access/__init__.py b/src/cloudflare/resources/zero_trust/access/__init__.py
index ac8d0a9fa77..f8e1684a27b 100644
--- a/src/cloudflare/resources/zero_trust/access/__init__.py
+++ b/src/cloudflare/resources/zero_trust/access/__init__.py
@@ -128,6 +128,14 @@
SAMLCertificatesResourceWithStreamingResponse,
AsyncSAMLCertificatesResourceWithStreamingResponse,
)
+from .idp_federation_grants import (
+ IdPFederationGrantsResource,
+ AsyncIdPFederationGrantsResource,
+ IdPFederationGrantsResourceWithRawResponse,
+ AsyncIdPFederationGrantsResourceWithRawResponse,
+ IdPFederationGrantsResourceWithStreamingResponse,
+ AsyncIdPFederationGrantsResourceWithStreamingResponse,
+)
__all__ = [
"AIControlsResource",
@@ -142,6 +150,12 @@
"AsyncGatewayCAResourceWithRawResponse",
"GatewayCAResourceWithStreamingResponse",
"AsyncGatewayCAResourceWithStreamingResponse",
+ "IdPFederationGrantsResource",
+ "AsyncIdPFederationGrantsResource",
+ "IdPFederationGrantsResourceWithRawResponse",
+ "AsyncIdPFederationGrantsResourceWithRawResponse",
+ "IdPFederationGrantsResourceWithStreamingResponse",
+ "AsyncIdPFederationGrantsResourceWithStreamingResponse",
"SAMLCertificatesResource",
"AsyncSAMLCertificatesResource",
"SAMLCertificatesResourceWithRawResponse",
diff --git a/src/cloudflare/resources/zero_trust/access/access.py b/src/cloudflare/resources/zero_trust/access/access.py
index f9f363b3313..9efd000a88a 100644
--- a/src/cloudflare/resources/zero_trust/access/access.py
+++ b/src/cloudflare/resources/zero_trust/access/access.py
@@ -92,6 +92,14 @@
SAMLCertificatesResourceWithStreamingResponse,
AsyncSAMLCertificatesResourceWithStreamingResponse,
)
+from .idp_federation_grants import (
+ IdPFederationGrantsResource,
+ AsyncIdPFederationGrantsResource,
+ IdPFederationGrantsResourceWithRawResponse,
+ AsyncIdPFederationGrantsResourceWithRawResponse,
+ IdPFederationGrantsResourceWithStreamingResponse,
+ AsyncIdPFederationGrantsResourceWithStreamingResponse,
+)
from .ai_controls.ai_controls import (
AIControlsResource,
AsyncAIControlsResource,
@@ -137,6 +145,10 @@ def ai_controls(self) -> AIControlsResource:
def gateway_ca(self) -> GatewayCAResource:
return GatewayCAResource(self._client)
+ @cached_property
+ def idp_federation_grants(self) -> IdPFederationGrantsResource:
+ return IdPFederationGrantsResource(self._client)
+
@cached_property
def saml_certificates(self) -> SAMLCertificatesResource:
return SAMLCertificatesResource(self._client)
@@ -218,6 +230,10 @@ def ai_controls(self) -> AsyncAIControlsResource:
def gateway_ca(self) -> AsyncGatewayCAResource:
return AsyncGatewayCAResource(self._client)
+ @cached_property
+ def idp_federation_grants(self) -> AsyncIdPFederationGrantsResource:
+ return AsyncIdPFederationGrantsResource(self._client)
+
@cached_property
def saml_certificates(self) -> AsyncSAMLCertificatesResource:
return AsyncSAMLCertificatesResource(self._client)
@@ -302,6 +318,10 @@ def ai_controls(self) -> AIControlsResourceWithRawResponse:
def gateway_ca(self) -> GatewayCAResourceWithRawResponse:
return GatewayCAResourceWithRawResponse(self._access.gateway_ca)
+ @cached_property
+ def idp_federation_grants(self) -> IdPFederationGrantsResourceWithRawResponse:
+ return IdPFederationGrantsResourceWithRawResponse(self._access.idp_federation_grants)
+
@cached_property
def saml_certificates(self) -> SAMLCertificatesResourceWithRawResponse:
return SAMLCertificatesResourceWithRawResponse(self._access.saml_certificates)
@@ -367,6 +387,10 @@ def ai_controls(self) -> AsyncAIControlsResourceWithRawResponse:
def gateway_ca(self) -> AsyncGatewayCAResourceWithRawResponse:
return AsyncGatewayCAResourceWithRawResponse(self._access.gateway_ca)
+ @cached_property
+ def idp_federation_grants(self) -> AsyncIdPFederationGrantsResourceWithRawResponse:
+ return AsyncIdPFederationGrantsResourceWithRawResponse(self._access.idp_federation_grants)
+
@cached_property
def saml_certificates(self) -> AsyncSAMLCertificatesResourceWithRawResponse:
return AsyncSAMLCertificatesResourceWithRawResponse(self._access.saml_certificates)
@@ -432,6 +456,10 @@ def ai_controls(self) -> AIControlsResourceWithStreamingResponse:
def gateway_ca(self) -> GatewayCAResourceWithStreamingResponse:
return GatewayCAResourceWithStreamingResponse(self._access.gateway_ca)
+ @cached_property
+ def idp_federation_grants(self) -> IdPFederationGrantsResourceWithStreamingResponse:
+ return IdPFederationGrantsResourceWithStreamingResponse(self._access.idp_federation_grants)
+
@cached_property
def saml_certificates(self) -> SAMLCertificatesResourceWithStreamingResponse:
return SAMLCertificatesResourceWithStreamingResponse(self._access.saml_certificates)
@@ -497,6 +525,10 @@ def ai_controls(self) -> AsyncAIControlsResourceWithStreamingResponse:
def gateway_ca(self) -> AsyncGatewayCAResourceWithStreamingResponse:
return AsyncGatewayCAResourceWithStreamingResponse(self._access.gateway_ca)
+ @cached_property
+ def idp_federation_grants(self) -> AsyncIdPFederationGrantsResourceWithStreamingResponse:
+ return AsyncIdPFederationGrantsResourceWithStreamingResponse(self._access.idp_federation_grants)
+
@cached_property
def saml_certificates(self) -> AsyncSAMLCertificatesResourceWithStreamingResponse:
return AsyncSAMLCertificatesResourceWithStreamingResponse(self._access.saml_certificates)
diff --git a/src/cloudflare/resources/zero_trust/access/ai_controls/mcp/servers.py b/src/cloudflare/resources/zero_trust/access/ai_controls/mcp/servers.py
index b855f84cbdc..3c874c8e772 100644
--- a/src/cloudflare/resources/zero_trust/access/ai_controls/mcp/servers.py
+++ b/src/cloudflare/resources/zero_trust/access/ai_controls/mcp/servers.py
@@ -61,6 +61,7 @@ def create(
name: str,
auth_credentials: str | Omit = omit,
description: Optional[str] | Omit = omit,
+ is_shared_oauth_callback_enabled: bool | Omit = omit,
updated_prompts: Iterable[server_create_params.UpdatedPrompt] | Omit = omit,
updated_tools: Iterable[server_create_params.UpdatedTool] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -76,6 +77,12 @@ def create(
Args:
id: server id
+ is_shared_oauth_callback_enabled: When true, the gateway worker uses the shared Cloudflare-owned OAuth callback
+ endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the
+ customer portal hostname. New public server creates default to true; existing
+ servers default to false from migration until explicitly updated. Effective
+ behavior is gated by the gateway worker's per-env rollout mode KV key.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -96,6 +103,7 @@ def create(
"name": name,
"auth_credentials": auth_credentials,
"description": description,
+ "is_shared_oauth_callback_enabled": is_shared_oauth_callback_enabled,
"updated_prompts": updated_prompts,
"updated_tools": updated_tools,
},
@@ -118,6 +126,7 @@ def update(
account_id: str,
auth_credentials: str | Omit = omit,
description: Optional[str] | Omit = omit,
+ is_shared_oauth_callback_enabled: bool | Omit = omit,
name: str | Omit = omit,
updated_prompts: Iterable[server_update_params.UpdatedPrompt] | Omit = omit,
updated_tools: Iterable[server_update_params.UpdatedTool] | Omit = omit,
@@ -134,6 +143,12 @@ def update(
Args:
id: server id
+ is_shared_oauth_callback_enabled: When true, the gateway worker uses the shared Cloudflare-owned OAuth callback
+ endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the
+ customer portal hostname. New public server creates default to true; existing
+ servers default to false from migration until explicitly updated. Effective
+ behavior is gated by the gateway worker's per-env rollout mode KV key.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -152,6 +167,7 @@ def update(
{
"auth_credentials": auth_credentials,
"description": description,
+ "is_shared_oauth_callback_enabled": is_shared_oauth_callback_enabled,
"name": name,
"updated_prompts": updated_prompts,
"updated_tools": updated_tools,
@@ -378,6 +394,7 @@ async def create(
name: str,
auth_credentials: str | Omit = omit,
description: Optional[str] | Omit = omit,
+ is_shared_oauth_callback_enabled: bool | Omit = omit,
updated_prompts: Iterable[server_create_params.UpdatedPrompt] | Omit = omit,
updated_tools: Iterable[server_create_params.UpdatedTool] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -393,6 +410,12 @@ async def create(
Args:
id: server id
+ is_shared_oauth_callback_enabled: When true, the gateway worker uses the shared Cloudflare-owned OAuth callback
+ endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the
+ customer portal hostname. New public server creates default to true; existing
+ servers default to false from migration until explicitly updated. Effective
+ behavior is gated by the gateway worker's per-env rollout mode KV key.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -413,6 +436,7 @@ async def create(
"name": name,
"auth_credentials": auth_credentials,
"description": description,
+ "is_shared_oauth_callback_enabled": is_shared_oauth_callback_enabled,
"updated_prompts": updated_prompts,
"updated_tools": updated_tools,
},
@@ -435,6 +459,7 @@ async def update(
account_id: str,
auth_credentials: str | Omit = omit,
description: Optional[str] | Omit = omit,
+ is_shared_oauth_callback_enabled: bool | Omit = omit,
name: str | Omit = omit,
updated_prompts: Iterable[server_update_params.UpdatedPrompt] | Omit = omit,
updated_tools: Iterable[server_update_params.UpdatedTool] | Omit = omit,
@@ -451,6 +476,12 @@ async def update(
Args:
id: server id
+ is_shared_oauth_callback_enabled: When true, the gateway worker uses the shared Cloudflare-owned OAuth callback
+ endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the
+ customer portal hostname. New public server creates default to true; existing
+ servers default to false from migration until explicitly updated. Effective
+ behavior is gated by the gateway worker's per-env rollout mode KV key.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -469,6 +500,7 @@ async def update(
{
"auth_credentials": auth_credentials,
"description": description,
+ "is_shared_oauth_callback_enabled": is_shared_oauth_callback_enabled,
"name": name,
"updated_prompts": updated_prompts,
"updated_tools": updated_tools,
diff --git a/src/cloudflare/resources/zero_trust/access/idp_federation_grants.py b/src/cloudflare/resources/zero_trust/access/idp_federation_grants.py
new file mode 100644
index 00000000000..89da448503a
--- /dev/null
+++ b/src/cloudflare/resources/zero_trust/access/idp_federation_grants.py
@@ -0,0 +1,520 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Type, Optional, cast
+
+import httpx
+
+from ...._types import Body, Query, Headers, NotGiven, not_given
+from ...._utils import path_template, maybe_transform, async_maybe_transform
+from ...._compat import cached_property
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from ...._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ...._wrappers import ResultWrapper
+from ...._base_client import make_request_options
+from ....types.zero_trust.access import idp_federation_grant_create_params
+from ....types.zero_trust.access.idp_federation_grant import IdPFederationGrant
+from ....types.zero_trust.access.idp_federation_grant_list_response import IdPFederationGrantListResponse
+from ....types.zero_trust.access.idp_federation_grant_delete_response import IdPFederationGrantDeleteResponse
+
+__all__ = ["IdPFederationGrantsResource", "AsyncIdPFederationGrantsResource"]
+
+
+class IdPFederationGrantsResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> IdPFederationGrantsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return IdPFederationGrantsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> IdPFederationGrantsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response
+ """
+ return IdPFederationGrantsResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ *,
+ account_id: str,
+ idp_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[IdPFederationGrant]:
+ """
+ Creates an IdP federation grant for the specified identity provider, making it
+ available for federation to other accounts in the same Cloudflare organization.
+
+ The account must belong to a Cloudflare organization. One-time pin and
+ Cloudflare-managed identity providers cannot be federated. An identity provider
+ may only have one active grant at a time.
+
+ Args:
+ account_id: Identifier.
+
+ idp_id: UID of the identity provider to federate. Must be an existing identity provider
+ in this account. One-time pin and Cloudflare-managed identity providers cannot
+ be federated.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._post(
+ path_template("/accounts/{account_id}/access/idp_federation_grants", account_id=account_id),
+ body=maybe_transform({"idp_id": idp_id}, idp_federation_grant_create_params.IdPFederationGrantCreateParams),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[IdPFederationGrant]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[IdPFederationGrant]], ResultWrapper[IdPFederationGrant]),
+ )
+
+ 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,
+ ) -> Optional[IdPFederationGrantListResponse]:
+ """
+ Lists the IdP federation grants owned by the account.
+
+ Args:
+ account_id: Identifier.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._get(
+ path_template("/accounts/{account_id}/access/idp_federation_grants", account_id=account_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[IdPFederationGrantListResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[IdPFederationGrantListResponse]], ResultWrapper[IdPFederationGrantListResponse]),
+ )
+
+ def delete(
+ self,
+ grant_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[IdPFederationGrantDeleteResponse]:
+ """Deletes an IdP federation grant.
+
+ The identity provider remains in the account,
+ but it is no longer available for federation to other accounts.
+
+ Args:
+ account_id: Identifier.
+
+ grant_id: Identifier.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not grant_id:
+ raise ValueError(f"Expected a non-empty value for `grant_id` but received {grant_id!r}")
+ return self._delete(
+ path_template(
+ "/accounts/{account_id}/access/idp_federation_grants/{grant_id}",
+ account_id=account_id,
+ grant_id=grant_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[IdPFederationGrantDeleteResponse]]._unwrapper,
+ ),
+ cast_to=cast(
+ Type[Optional[IdPFederationGrantDeleteResponse]], ResultWrapper[IdPFederationGrantDeleteResponse]
+ ),
+ )
+
+ def get(
+ self,
+ grant_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[IdPFederationGrant]:
+ """
+ Retrieves a single IdP federation grant by its UID.
+
+ Args:
+ account_id: Identifier.
+
+ grant_id: Identifier.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not grant_id:
+ raise ValueError(f"Expected a non-empty value for `grant_id` but received {grant_id!r}")
+ return self._get(
+ path_template(
+ "/accounts/{account_id}/access/idp_federation_grants/{grant_id}",
+ account_id=account_id,
+ grant_id=grant_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[IdPFederationGrant]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[IdPFederationGrant]], ResultWrapper[IdPFederationGrant]),
+ )
+
+
+class AsyncIdPFederationGrantsResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncIdPFederationGrantsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncIdPFederationGrantsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncIdPFederationGrantsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response
+ """
+ return AsyncIdPFederationGrantsResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ *,
+ account_id: str,
+ idp_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[IdPFederationGrant]:
+ """
+ Creates an IdP federation grant for the specified identity provider, making it
+ available for federation to other accounts in the same Cloudflare organization.
+
+ The account must belong to a Cloudflare organization. One-time pin and
+ Cloudflare-managed identity providers cannot be federated. An identity provider
+ may only have one active grant at a time.
+
+ Args:
+ account_id: Identifier.
+
+ idp_id: UID of the identity provider to federate. Must be an existing identity provider
+ in this account. One-time pin and Cloudflare-managed identity providers cannot
+ be federated.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return await self._post(
+ path_template("/accounts/{account_id}/access/idp_federation_grants", account_id=account_id),
+ body=await async_maybe_transform(
+ {"idp_id": idp_id}, idp_federation_grant_create_params.IdPFederationGrantCreateParams
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[IdPFederationGrant]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[IdPFederationGrant]], ResultWrapper[IdPFederationGrant]),
+ )
+
+ async 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,
+ ) -> Optional[IdPFederationGrantListResponse]:
+ """
+ Lists the IdP federation grants owned by the account.
+
+ Args:
+ account_id: Identifier.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return await self._get(
+ path_template("/accounts/{account_id}/access/idp_federation_grants", account_id=account_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[IdPFederationGrantListResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[IdPFederationGrantListResponse]], ResultWrapper[IdPFederationGrantListResponse]),
+ )
+
+ async def delete(
+ self,
+ grant_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[IdPFederationGrantDeleteResponse]:
+ """Deletes an IdP federation grant.
+
+ The identity provider remains in the account,
+ but it is no longer available for federation to other accounts.
+
+ Args:
+ account_id: Identifier.
+
+ grant_id: Identifier.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not grant_id:
+ raise ValueError(f"Expected a non-empty value for `grant_id` but received {grant_id!r}")
+ return await self._delete(
+ path_template(
+ "/accounts/{account_id}/access/idp_federation_grants/{grant_id}",
+ account_id=account_id,
+ grant_id=grant_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[IdPFederationGrantDeleteResponse]]._unwrapper,
+ ),
+ cast_to=cast(
+ Type[Optional[IdPFederationGrantDeleteResponse]], ResultWrapper[IdPFederationGrantDeleteResponse]
+ ),
+ )
+
+ async def get(
+ self,
+ grant_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[IdPFederationGrant]:
+ """
+ Retrieves a single IdP federation grant by its UID.
+
+ Args:
+ account_id: Identifier.
+
+ grant_id: Identifier.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not grant_id:
+ raise ValueError(f"Expected a non-empty value for `grant_id` but received {grant_id!r}")
+ return await self._get(
+ path_template(
+ "/accounts/{account_id}/access/idp_federation_grants/{grant_id}",
+ account_id=account_id,
+ grant_id=grant_id,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[IdPFederationGrant]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[IdPFederationGrant]], ResultWrapper[IdPFederationGrant]),
+ )
+
+
+class IdPFederationGrantsResourceWithRawResponse:
+ def __init__(self, idp_federation_grants: IdPFederationGrantsResource) -> None:
+ self._idp_federation_grants = idp_federation_grants
+
+ self.create = to_raw_response_wrapper(
+ idp_federation_grants.create,
+ )
+ self.list = to_raw_response_wrapper(
+ idp_federation_grants.list,
+ )
+ self.delete = to_raw_response_wrapper(
+ idp_federation_grants.delete,
+ )
+ self.get = to_raw_response_wrapper(
+ idp_federation_grants.get,
+ )
+
+
+class AsyncIdPFederationGrantsResourceWithRawResponse:
+ def __init__(self, idp_federation_grants: AsyncIdPFederationGrantsResource) -> None:
+ self._idp_federation_grants = idp_federation_grants
+
+ self.create = async_to_raw_response_wrapper(
+ idp_federation_grants.create,
+ )
+ self.list = async_to_raw_response_wrapper(
+ idp_federation_grants.list,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ idp_federation_grants.delete,
+ )
+ self.get = async_to_raw_response_wrapper(
+ idp_federation_grants.get,
+ )
+
+
+class IdPFederationGrantsResourceWithStreamingResponse:
+ def __init__(self, idp_federation_grants: IdPFederationGrantsResource) -> None:
+ self._idp_federation_grants = idp_federation_grants
+
+ self.create = to_streamed_response_wrapper(
+ idp_federation_grants.create,
+ )
+ self.list = to_streamed_response_wrapper(
+ idp_federation_grants.list,
+ )
+ self.delete = to_streamed_response_wrapper(
+ idp_federation_grants.delete,
+ )
+ self.get = to_streamed_response_wrapper(
+ idp_federation_grants.get,
+ )
+
+
+class AsyncIdPFederationGrantsResourceWithStreamingResponse:
+ def __init__(self, idp_federation_grants: AsyncIdPFederationGrantsResource) -> None:
+ self._idp_federation_grants = idp_federation_grants
+
+ self.create = async_to_streamed_response_wrapper(
+ idp_federation_grants.create,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ idp_federation_grants.list,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ idp_federation_grants.delete,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ idp_federation_grants.get,
+ )
diff --git a/src/cloudflare/resources/zero_trust/api.md b/src/cloudflare/resources/zero_trust/api.md
index fae9fa9e7dc..14f6d3f5e57 100644
--- a/src/cloudflare/resources/zero_trust/api.md
+++ b/src/cloudflare/resources/zero_trust/api.md
@@ -498,6 +498,25 @@ Methods:
- client.zero_trust.access.gateway_ca.list(\*, account_id) -> SyncSinglePage[GatewayCAListResponse]
- client.zero_trust.access.gateway_ca.delete(certificate_id, \*, account_id) -> Optional[GatewayCADeleteResponse]
+### IdPFederationGrants
+
+Types:
+
+```python
+from cloudflare.types.zero_trust.access import (
+ IdPFederationGrant,
+ IdPFederationGrantListResponse,
+ IdPFederationGrantDeleteResponse,
+)
+```
+
+Methods:
+
+- client.zero_trust.access.idp_federation_grants.create(\*, account_id, \*\*params) -> Optional[IdPFederationGrant]
+- client.zero_trust.access.idp_federation_grants.list(\*, account_id) -> Optional[IdPFederationGrantListResponse]
+- client.zero_trust.access.idp_federation_grants.delete(grant_id, \*, account_id) -> Optional[IdPFederationGrantDeleteResponse]
+- client.zero_trust.access.idp_federation_grants.get(grant_id, \*, account_id) -> Optional[IdPFederationGrant]
+
### SAMLCertificates
Types:
@@ -1173,6 +1192,20 @@ Methods:
- client.zero_trust.dex.rules.delete(rule_id, \*, account_id) -> Optional[RuleDeleteResponse]
- client.zero_trust.dex.rules.get(rule_id, \*, account_id) -> Optional[RuleGetResponse]
+### Devices
+
+#### ISPs
+
+Types:
+
+```python
+from cloudflare.types.zero_trust.dex.devices import ISPs
+```
+
+Methods:
+
+- client.zero_trust.dex.devices.isps.list(device_id, \*, account_id, \*\*params) -> SyncV4PagePagination[Optional[ISPs]]
+
## Tunnels
Types:
diff --git a/src/cloudflare/resources/zero_trust/dex/__init__.py b/src/cloudflare/resources/zero_trust/dex/__init__.py
index b4e5b64def8..076ef18e863 100644
--- a/src/cloudflare/resources/zero_trust/dex/__init__.py
+++ b/src/cloudflare/resources/zero_trust/dex/__init__.py
@@ -32,6 +32,14 @@
TestsResourceWithStreamingResponse,
AsyncTestsResourceWithStreamingResponse,
)
+from .devices import (
+ DevicesResource,
+ AsyncDevicesResource,
+ DevicesResourceWithRawResponse,
+ AsyncDevicesResourceWithRawResponse,
+ DevicesResourceWithStreamingResponse,
+ AsyncDevicesResourceWithStreamingResponse,
+)
from .commands import (
CommandsResource,
AsyncCommandsResource,
@@ -136,6 +144,12 @@
"AsyncRulesResourceWithRawResponse",
"RulesResourceWithStreamingResponse",
"AsyncRulesResourceWithStreamingResponse",
+ "DevicesResource",
+ "AsyncDevicesResource",
+ "DevicesResourceWithRawResponse",
+ "AsyncDevicesResourceWithRawResponse",
+ "DevicesResourceWithStreamingResponse",
+ "AsyncDevicesResourceWithStreamingResponse",
"DEXResource",
"AsyncDEXResource",
"DEXResourceWithRawResponse",
diff --git a/src/cloudflare/resources/zero_trust/dex/devices/__init__.py b/src/cloudflare/resources/zero_trust/dex/devices/__init__.py
new file mode 100644
index 00000000000..c38aac84a8b
--- /dev/null
+++ b/src/cloudflare/resources/zero_trust/dex/devices/__init__.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .isps import (
+ ISPsResource,
+ AsyncISPsResource,
+ ISPsResourceWithRawResponse,
+ AsyncISPsResourceWithRawResponse,
+ ISPsResourceWithStreamingResponse,
+ AsyncISPsResourceWithStreamingResponse,
+)
+from .devices import (
+ DevicesResource,
+ AsyncDevicesResource,
+ DevicesResourceWithRawResponse,
+ AsyncDevicesResourceWithRawResponse,
+ DevicesResourceWithStreamingResponse,
+ AsyncDevicesResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "ISPsResource",
+ "AsyncISPsResource",
+ "ISPsResourceWithRawResponse",
+ "AsyncISPsResourceWithRawResponse",
+ "ISPsResourceWithStreamingResponse",
+ "AsyncISPsResourceWithStreamingResponse",
+ "DevicesResource",
+ "AsyncDevicesResource",
+ "DevicesResourceWithRawResponse",
+ "AsyncDevicesResourceWithRawResponse",
+ "DevicesResourceWithStreamingResponse",
+ "AsyncDevicesResourceWithStreamingResponse",
+]
diff --git a/src/cloudflare/resources/zero_trust/dex/devices/devices.py b/src/cloudflare/resources/zero_trust/dex/devices/devices.py
new file mode 100644
index 00000000000..6af9a2a3313
--- /dev/null
+++ b/src/cloudflare/resources/zero_trust/dex/devices/devices.py
@@ -0,0 +1,102 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .isps import (
+ ISPsResource,
+ AsyncISPsResource,
+ ISPsResourceWithRawResponse,
+ AsyncISPsResourceWithRawResponse,
+ ISPsResourceWithStreamingResponse,
+ AsyncISPsResourceWithStreamingResponse,
+)
+from ....._compat import cached_property
+from ....._resource import SyncAPIResource, AsyncAPIResource
+
+__all__ = ["DevicesResource", "AsyncDevicesResource"]
+
+
+class DevicesResource(SyncAPIResource):
+ @cached_property
+ def isps(self) -> ISPsResource:
+ return ISPsResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> DevicesResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return DevicesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> DevicesResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response
+ """
+ return DevicesResourceWithStreamingResponse(self)
+
+
+class AsyncDevicesResource(AsyncAPIResource):
+ @cached_property
+ def isps(self) -> AsyncISPsResource:
+ return AsyncISPsResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncDevicesResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncDevicesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncDevicesResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response
+ """
+ return AsyncDevicesResourceWithStreamingResponse(self)
+
+
+class DevicesResourceWithRawResponse:
+ def __init__(self, devices: DevicesResource) -> None:
+ self._devices = devices
+
+ @cached_property
+ def isps(self) -> ISPsResourceWithRawResponse:
+ return ISPsResourceWithRawResponse(self._devices.isps)
+
+
+class AsyncDevicesResourceWithRawResponse:
+ def __init__(self, devices: AsyncDevicesResource) -> None:
+ self._devices = devices
+
+ @cached_property
+ def isps(self) -> AsyncISPsResourceWithRawResponse:
+ return AsyncISPsResourceWithRawResponse(self._devices.isps)
+
+
+class DevicesResourceWithStreamingResponse:
+ def __init__(self, devices: DevicesResource) -> None:
+ self._devices = devices
+
+ @cached_property
+ def isps(self) -> ISPsResourceWithStreamingResponse:
+ return ISPsResourceWithStreamingResponse(self._devices.isps)
+
+
+class AsyncDevicesResourceWithStreamingResponse:
+ def __init__(self, devices: AsyncDevicesResource) -> None:
+ self._devices = devices
+
+ @cached_property
+ def isps(self) -> AsyncISPsResourceWithStreamingResponse:
+ return AsyncISPsResourceWithStreamingResponse(self._devices.isps)
diff --git a/src/cloudflare/resources/zero_trust/dex/devices/isps.py b/src/cloudflare/resources/zero_trust/dex/devices/isps.py
new file mode 100644
index 00000000000..4e3675de167
--- /dev/null
+++ b/src/cloudflare/resources/zero_trust/dex/devices/isps.py
@@ -0,0 +1,258 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+import httpx
+
+from ....._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ....._utils import path_template, maybe_transform
+from ....._compat import cached_property
+from ....._resource import SyncAPIResource, AsyncAPIResource
+from ....._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from .....pagination import SyncV4PagePagination, AsyncV4PagePagination
+from ....._base_client import AsyncPaginator, make_request_options
+from .....types.zero_trust.dex.devices import isp_list_params
+from .....types.zero_trust.dex.devices.isps import ISPs
+
+__all__ = ["ISPsResource", "AsyncISPsResource"]
+
+
+class ISPsResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> ISPsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return ISPsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> ISPsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response
+ """
+ return ISPsResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ device_id: str,
+ *,
+ account_id: str,
+ per_page: int,
+ cursor: str | Omit = omit,
+ from_: Union[str, datetime] | Omit = omit,
+ page: int | Omit = omit,
+ sort_by: Literal["time_start"] | Omit = omit,
+ sort_order: Literal["ASC", "DESC"] | Omit = omit,
+ to: Union[str, datetime] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> SyncV4PagePagination[Optional[ISPs]]:
+ """
+ List ISP information observed for a specific device during traceroute tests.
+
+ Args:
+ device_id: API Resource UUID tag.
+
+ per_page: Number of items per page
+
+ cursor: Cursor for cursor-based pagination. Mutually exclusive with page.
+
+ from_: Start time for the query in ISO 8601 format
+
+ page: Page number of paginated results. Mutually exclusive with cursor.
+
+ sort_by: The field to sort results by
+
+ sort_order: The order to sort results
+
+ to: End time for the query in ISO 8601 format
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not device_id:
+ raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}")
+ return self._get_api_list(
+ path_template(
+ "/accounts/{account_id}/dex/devices/{device_id}/isps", account_id=account_id, device_id=device_id
+ ),
+ page=SyncV4PagePagination[Optional[ISPs]],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "per_page": per_page,
+ "cursor": cursor,
+ "from_": from_,
+ "page": page,
+ "sort_by": sort_by,
+ "sort_order": sort_order,
+ "to": to,
+ },
+ isp_list_params.ISPListParams,
+ ),
+ ),
+ model=ISPs,
+ )
+
+
+class AsyncISPsResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncISPsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncISPsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncISPsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response
+ """
+ return AsyncISPsResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ device_id: str,
+ *,
+ account_id: str,
+ per_page: int,
+ cursor: str | Omit = omit,
+ from_: Union[str, datetime] | Omit = omit,
+ page: int | Omit = omit,
+ sort_by: Literal["time_start"] | Omit = omit,
+ sort_order: Literal["ASC", "DESC"] | Omit = omit,
+ to: Union[str, datetime] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> AsyncPaginator[Optional[ISPs], AsyncV4PagePagination[Optional[ISPs]]]:
+ """
+ List ISP information observed for a specific device during traceroute tests.
+
+ Args:
+ device_id: API Resource UUID tag.
+
+ per_page: Number of items per page
+
+ cursor: Cursor for cursor-based pagination. Mutually exclusive with page.
+
+ from_: Start time for the query in ISO 8601 format
+
+ page: Page number of paginated results. Mutually exclusive with cursor.
+
+ sort_by: The field to sort results by
+
+ sort_order: The order to sort results
+
+ to: End time for the query in ISO 8601 format
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not device_id:
+ raise ValueError(f"Expected a non-empty value for `device_id` but received {device_id!r}")
+ return self._get_api_list(
+ path_template(
+ "/accounts/{account_id}/dex/devices/{device_id}/isps", account_id=account_id, device_id=device_id
+ ),
+ page=AsyncV4PagePagination[Optional[ISPs]],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "per_page": per_page,
+ "cursor": cursor,
+ "from_": from_,
+ "page": page,
+ "sort_by": sort_by,
+ "sort_order": sort_order,
+ "to": to,
+ },
+ isp_list_params.ISPListParams,
+ ),
+ ),
+ model=ISPs,
+ )
+
+
+class ISPsResourceWithRawResponse:
+ def __init__(self, isps: ISPsResource) -> None:
+ self._isps = isps
+
+ self.list = to_raw_response_wrapper(
+ isps.list,
+ )
+
+
+class AsyncISPsResourceWithRawResponse:
+ def __init__(self, isps: AsyncISPsResource) -> None:
+ self._isps = isps
+
+ self.list = async_to_raw_response_wrapper(
+ isps.list,
+ )
+
+
+class ISPsResourceWithStreamingResponse:
+ def __init__(self, isps: ISPsResource) -> None:
+ self._isps = isps
+
+ self.list = to_streamed_response_wrapper(
+ isps.list,
+ )
+
+
+class AsyncISPsResourceWithStreamingResponse:
+ def __init__(self, isps: AsyncISPsResource) -> None:
+ self._isps = isps
+
+ self.list = async_to_streamed_response_wrapper(
+ isps.list,
+ )
diff --git a/src/cloudflare/resources/zero_trust/dex/dex.py b/src/cloudflare/resources/zero_trust/dex/dex.py
index 82bd1271b6f..7239e291764 100644
--- a/src/cloudflare/resources/zero_trust/dex/dex.py
+++ b/src/cloudflare/resources/zero_trust/dex/dex.py
@@ -28,6 +28,14 @@
AsyncTestsResourceWithStreamingResponse,
)
from ...._resource import SyncAPIResource, AsyncAPIResource
+from .devices.devices import (
+ DevicesResource,
+ AsyncDevicesResource,
+ DevicesResourceWithRawResponse,
+ AsyncDevicesResourceWithRawResponse,
+ DevicesResourceWithStreamingResponse,
+ AsyncDevicesResourceWithStreamingResponse,
+)
from .traceroute_tests import (
TracerouteTestsResource,
AsyncTracerouteTestsResource,
@@ -117,6 +125,10 @@ def traceroute_tests(self) -> TracerouteTestsResource:
def rules(self) -> RulesResource:
return RulesResource(self._client)
+ @cached_property
+ def devices(self) -> DevicesResource:
+ return DevicesResource(self._client)
+
@cached_property
def with_raw_response(self) -> DEXResourceWithRawResponse:
"""
@@ -174,6 +186,10 @@ def traceroute_tests(self) -> AsyncTracerouteTestsResource:
def rules(self) -> AsyncRulesResource:
return AsyncRulesResource(self._client)
+ @cached_property
+ def devices(self) -> AsyncDevicesResource:
+ return AsyncDevicesResource(self._client)
+
@cached_property
def with_raw_response(self) -> AsyncDEXResourceWithRawResponse:
"""
@@ -234,6 +250,10 @@ def traceroute_tests(self) -> TracerouteTestsResourceWithRawResponse:
def rules(self) -> RulesResourceWithRawResponse:
return RulesResourceWithRawResponse(self._dex.rules)
+ @cached_property
+ def devices(self) -> DevicesResourceWithRawResponse:
+ return DevicesResourceWithRawResponse(self._dex.devices)
+
class AsyncDEXResourceWithRawResponse:
def __init__(self, dex: AsyncDEXResource) -> None:
@@ -275,6 +295,10 @@ def traceroute_tests(self) -> AsyncTracerouteTestsResourceWithRawResponse:
def rules(self) -> AsyncRulesResourceWithRawResponse:
return AsyncRulesResourceWithRawResponse(self._dex.rules)
+ @cached_property
+ def devices(self) -> AsyncDevicesResourceWithRawResponse:
+ return AsyncDevicesResourceWithRawResponse(self._dex.devices)
+
class DEXResourceWithStreamingResponse:
def __init__(self, dex: DEXResource) -> None:
@@ -316,6 +340,10 @@ def traceroute_tests(self) -> TracerouteTestsResourceWithStreamingResponse:
def rules(self) -> RulesResourceWithStreamingResponse:
return RulesResourceWithStreamingResponse(self._dex.rules)
+ @cached_property
+ def devices(self) -> DevicesResourceWithStreamingResponse:
+ return DevicesResourceWithStreamingResponse(self._dex.devices)
+
class AsyncDEXResourceWithStreamingResponse:
def __init__(self, dex: AsyncDEXResource) -> None:
@@ -356,3 +384,7 @@ def traceroute_tests(self) -> AsyncTracerouteTestsResourceWithStreamingResponse:
@cached_property
def rules(self) -> AsyncRulesResourceWithStreamingResponse:
return AsyncRulesResourceWithStreamingResponse(self._dex.rules)
+
+ @cached_property
+ def devices(self) -> AsyncDevicesResourceWithStreamingResponse:
+ return AsyncDevicesResourceWithStreamingResponse(self._dex.devices)
diff --git a/src/cloudflare/types/abuse_reports/mitigation_list_params.py b/src/cloudflare/types/abuse_reports/mitigation_list_params.py
index 4093a07c4fb..6e0e1472123 100644
--- a/src/cloudflare/types/abuse_reports/mitigation_list_params.py
+++ b/src/cloudflare/types/abuse_reports/mitigation_list_params.py
@@ -41,13 +41,25 @@ class MitigationListParams(TypedDict, total=False):
"""Filter by the status of the mitigation."""
type: Literal[
+ "account_suspend",
+ "copyright_interstitial",
+ "geo_block",
"legal_block",
+ "malware_interstitial",
"misleading_interstitial",
- "phishing_interstitial",
"network_block",
+ "phishing_interstitial",
+ "playfairite_enforce",
+ "r2_takedown_account",
+ "r2_takedown_bucket",
+ "r2_takedown_object",
"rate_limit_cache",
- "account_suspend",
"redirect_video_stream",
+ "registrar_freeze",
+ "registrar_parking",
+ "stream_block_account",
+ "user_suspend",
+ "workers_takedown_by_zone_id",
]
"""Filter by the type of mitigation.
diff --git a/src/cloudflare/types/abuse_reports/mitigation_list_response.py b/src/cloudflare/types/abuse_reports/mitigation_list_response.py
index 3e0f9fd8075..6f2f5983a70 100644
--- a/src/cloudflare/types/abuse_reports/mitigation_list_response.py
+++ b/src/cloudflare/types/abuse_reports/mitigation_list_response.py
@@ -21,20 +21,33 @@ class Mitigation(BaseModel):
entity_id: str
entity_type: Literal["url_pattern", "account", "zone"]
+ """The type of entity targeted by a mitigation."""
status: Literal["pending", "active", "in_review", "cancelled", "removed"]
"""The status of a mitigation"""
type: Literal[
+ "account_suspend",
+ "copyright_interstitial",
+ "geo_block",
"legal_block",
+ "malware_interstitial",
"misleading_interstitial",
- "phishing_interstitial",
"network_block",
+ "phishing_interstitial",
+ "playfairite_enforce",
+ "r2_takedown_account",
+ "r2_takedown_bucket",
+ "r2_takedown_object",
"rate_limit_cache",
- "account_suspend",
"redirect_video_stream",
+ "registrar_freeze",
+ "registrar_parking",
+ "stream_block_account",
+ "user_suspend",
+ "workers_takedown_by_zone_id",
]
- """The type of mitigation"""
+ """The type of mitigation applied to a reported entity."""
class MitigationListResponse(BaseModel):
diff --git a/src/cloudflare/types/abuse_reports/mitigation_review_response.py b/src/cloudflare/types/abuse_reports/mitigation_review_response.py
index 6e83c1f4ad3..7d5cf2e61ae 100644
--- a/src/cloudflare/types/abuse_reports/mitigation_review_response.py
+++ b/src/cloudflare/types/abuse_reports/mitigation_review_response.py
@@ -20,17 +20,30 @@ class MitigationReviewResponse(BaseModel):
entity_id: str
entity_type: Literal["url_pattern", "account", "zone"]
+ """The type of entity targeted by a mitigation."""
status: Literal["pending", "active", "in_review", "cancelled", "removed"]
"""The status of a mitigation"""
type: Literal[
+ "account_suspend",
+ "copyright_interstitial",
+ "geo_block",
"legal_block",
+ "malware_interstitial",
"misleading_interstitial",
- "phishing_interstitial",
"network_block",
+ "phishing_interstitial",
+ "playfairite_enforce",
+ "r2_takedown_account",
+ "r2_takedown_bucket",
+ "r2_takedown_object",
"rate_limit_cache",
- "account_suspend",
"redirect_video_stream",
+ "registrar_freeze",
+ "registrar_parking",
+ "stream_block_account",
+ "user_suspend",
+ "workers_takedown_by_zone_id",
]
- """The type of mitigation"""
+ """The type of mitigation applied to a reported entity."""
diff --git a/src/cloudflare/types/ai_gateway/ai_gateway_create_response.py b/src/cloudflare/types/ai_gateway/ai_gateway_create_response.py
index 753c5704050..4d5c36e42ec 100644
--- a/src/cloudflare/types/ai_gateway/ai_gateway_create_response.py
+++ b/src/cloudflare/types/ai_gateway/ai_gateway_create_response.py
@@ -18,6 +18,13 @@
"GuardrailsPrompt",
"GuardrailsResponse",
"Otel",
+ "SpendLimits",
+ "SpendLimitsRule",
+ "SpendLimitsRuleMetadata",
+ "SpendLimitsRuleMetadataMode",
+ "SpendLimitsRuleMetadataUnionMember1",
+ "SpendLimitsRuleModel",
+ "SpendLimitsRuleProvider",
"Stripe",
"StripeUsageEvent",
]
@@ -128,6 +135,57 @@ class Otel(BaseModel):
content_type: Optional[Literal["json", "protobuf"]] = None
+class SpendLimitsRuleMetadataMode(BaseModel):
+ mode: Literal["partition"]
+
+
+class SpendLimitsRuleMetadataUnionMember1(BaseModel):
+ mode: Literal["filter"]
+
+ values: List[str]
+
+
+SpendLimitsRuleMetadata: TypeAlias = Union[SpendLimitsRuleMetadataMode, SpendLimitsRuleMetadataUnionMember1]
+
+
+class SpendLimitsRuleModel(BaseModel):
+ mode: Literal["filter"]
+
+ values: List[str]
+
+
+class SpendLimitsRuleProvider(BaseModel):
+ mode: Literal["filter"]
+
+ values: List[str]
+
+
+class SpendLimitsRule(BaseModel):
+ limit: float
+
+ limit_type: Literal["cost"] = FieldInfo(alias="limitType")
+
+ window: int
+
+ id: Optional[str] = None
+
+ enabled: Optional[bool] = None
+
+ metadata: Optional[Dict[str, SpendLimitsRuleMetadata]] = None
+
+ model: Optional[SpendLimitsRuleModel] = None
+
+ provider: Optional[SpendLimitsRuleProvider] = None
+
+ technique: Optional[Literal["fixed", "sliding"]] = None
+
+
+class SpendLimits(BaseModel):
+ enabled: Optional[bool] = None
+
+ rules: Optional[List[SpendLimitsRule]] = None
+
+
class StripeUsageEvent(BaseModel):
payload: str
@@ -185,6 +243,8 @@ class AIGatewayCreateResponse(BaseModel):
retry_max_attempts: Optional[int] = None
"""Maximum number of retry attempts for failed requests (1-5)"""
+ spend_limits: Optional[SpendLimits] = None
+
store_id: Optional[str] = None
stripe: Optional[Stripe] = None
diff --git a/src/cloudflare/types/ai_gateway/ai_gateway_delete_response.py b/src/cloudflare/types/ai_gateway/ai_gateway_delete_response.py
index bf676c3ea83..3fa277ec5af 100644
--- a/src/cloudflare/types/ai_gateway/ai_gateway_delete_response.py
+++ b/src/cloudflare/types/ai_gateway/ai_gateway_delete_response.py
@@ -18,6 +18,13 @@
"GuardrailsPrompt",
"GuardrailsResponse",
"Otel",
+ "SpendLimits",
+ "SpendLimitsRule",
+ "SpendLimitsRuleMetadata",
+ "SpendLimitsRuleMetadataMode",
+ "SpendLimitsRuleMetadataUnionMember1",
+ "SpendLimitsRuleModel",
+ "SpendLimitsRuleProvider",
"Stripe",
"StripeUsageEvent",
]
@@ -128,6 +135,57 @@ class Otel(BaseModel):
content_type: Optional[Literal["json", "protobuf"]] = None
+class SpendLimitsRuleMetadataMode(BaseModel):
+ mode: Literal["partition"]
+
+
+class SpendLimitsRuleMetadataUnionMember1(BaseModel):
+ mode: Literal["filter"]
+
+ values: List[str]
+
+
+SpendLimitsRuleMetadata: TypeAlias = Union[SpendLimitsRuleMetadataMode, SpendLimitsRuleMetadataUnionMember1]
+
+
+class SpendLimitsRuleModel(BaseModel):
+ mode: Literal["filter"]
+
+ values: List[str]
+
+
+class SpendLimitsRuleProvider(BaseModel):
+ mode: Literal["filter"]
+
+ values: List[str]
+
+
+class SpendLimitsRule(BaseModel):
+ limit: float
+
+ limit_type: Literal["cost"] = FieldInfo(alias="limitType")
+
+ window: int
+
+ id: Optional[str] = None
+
+ enabled: Optional[bool] = None
+
+ metadata: Optional[Dict[str, SpendLimitsRuleMetadata]] = None
+
+ model: Optional[SpendLimitsRuleModel] = None
+
+ provider: Optional[SpendLimitsRuleProvider] = None
+
+ technique: Optional[Literal["fixed", "sliding"]] = None
+
+
+class SpendLimits(BaseModel):
+ enabled: Optional[bool] = None
+
+ rules: Optional[List[SpendLimitsRule]] = None
+
+
class StripeUsageEvent(BaseModel):
payload: str
@@ -185,6 +243,8 @@ class AIGatewayDeleteResponse(BaseModel):
retry_max_attempts: Optional[int] = None
"""Maximum number of retry attempts for failed requests (1-5)"""
+ spend_limits: Optional[SpendLimits] = None
+
store_id: Optional[str] = None
stripe: Optional[Stripe] = None
diff --git a/src/cloudflare/types/ai_gateway/ai_gateway_get_response.py b/src/cloudflare/types/ai_gateway/ai_gateway_get_response.py
index 642f2530597..8baedb39786 100644
--- a/src/cloudflare/types/ai_gateway/ai_gateway_get_response.py
+++ b/src/cloudflare/types/ai_gateway/ai_gateway_get_response.py
@@ -18,6 +18,13 @@
"GuardrailsPrompt",
"GuardrailsResponse",
"Otel",
+ "SpendLimits",
+ "SpendLimitsRule",
+ "SpendLimitsRuleMetadata",
+ "SpendLimitsRuleMetadataMode",
+ "SpendLimitsRuleMetadataUnionMember1",
+ "SpendLimitsRuleModel",
+ "SpendLimitsRuleProvider",
"Stripe",
"StripeUsageEvent",
]
@@ -128,6 +135,57 @@ class Otel(BaseModel):
content_type: Optional[Literal["json", "protobuf"]] = None
+class SpendLimitsRuleMetadataMode(BaseModel):
+ mode: Literal["partition"]
+
+
+class SpendLimitsRuleMetadataUnionMember1(BaseModel):
+ mode: Literal["filter"]
+
+ values: List[str]
+
+
+SpendLimitsRuleMetadata: TypeAlias = Union[SpendLimitsRuleMetadataMode, SpendLimitsRuleMetadataUnionMember1]
+
+
+class SpendLimitsRuleModel(BaseModel):
+ mode: Literal["filter"]
+
+ values: List[str]
+
+
+class SpendLimitsRuleProvider(BaseModel):
+ mode: Literal["filter"]
+
+ values: List[str]
+
+
+class SpendLimitsRule(BaseModel):
+ limit: float
+
+ limit_type: Literal["cost"] = FieldInfo(alias="limitType")
+
+ window: int
+
+ id: Optional[str] = None
+
+ enabled: Optional[bool] = None
+
+ metadata: Optional[Dict[str, SpendLimitsRuleMetadata]] = None
+
+ model: Optional[SpendLimitsRuleModel] = None
+
+ provider: Optional[SpendLimitsRuleProvider] = None
+
+ technique: Optional[Literal["fixed", "sliding"]] = None
+
+
+class SpendLimits(BaseModel):
+ enabled: Optional[bool] = None
+
+ rules: Optional[List[SpendLimitsRule]] = None
+
+
class StripeUsageEvent(BaseModel):
payload: str
@@ -185,6 +243,8 @@ class AIGatewayGetResponse(BaseModel):
retry_max_attempts: Optional[int] = None
"""Maximum number of retry attempts for failed requests (1-5)"""
+ spend_limits: Optional[SpendLimits] = None
+
store_id: Optional[str] = None
stripe: Optional[Stripe] = None
diff --git a/src/cloudflare/types/ai_gateway/ai_gateway_list_response.py b/src/cloudflare/types/ai_gateway/ai_gateway_list_response.py
index 06720a66689..90b0d287777 100644
--- a/src/cloudflare/types/ai_gateway/ai_gateway_list_response.py
+++ b/src/cloudflare/types/ai_gateway/ai_gateway_list_response.py
@@ -18,6 +18,13 @@
"GuardrailsPrompt",
"GuardrailsResponse",
"Otel",
+ "SpendLimits",
+ "SpendLimitsRule",
+ "SpendLimitsRuleMetadata",
+ "SpendLimitsRuleMetadataMode",
+ "SpendLimitsRuleMetadataUnionMember1",
+ "SpendLimitsRuleModel",
+ "SpendLimitsRuleProvider",
"Stripe",
"StripeUsageEvent",
]
@@ -128,6 +135,57 @@ class Otel(BaseModel):
content_type: Optional[Literal["json", "protobuf"]] = None
+class SpendLimitsRuleMetadataMode(BaseModel):
+ mode: Literal["partition"]
+
+
+class SpendLimitsRuleMetadataUnionMember1(BaseModel):
+ mode: Literal["filter"]
+
+ values: List[str]
+
+
+SpendLimitsRuleMetadata: TypeAlias = Union[SpendLimitsRuleMetadataMode, SpendLimitsRuleMetadataUnionMember1]
+
+
+class SpendLimitsRuleModel(BaseModel):
+ mode: Literal["filter"]
+
+ values: List[str]
+
+
+class SpendLimitsRuleProvider(BaseModel):
+ mode: Literal["filter"]
+
+ values: List[str]
+
+
+class SpendLimitsRule(BaseModel):
+ limit: float
+
+ limit_type: Literal["cost"] = FieldInfo(alias="limitType")
+
+ window: int
+
+ id: Optional[str] = None
+
+ enabled: Optional[bool] = None
+
+ metadata: Optional[Dict[str, SpendLimitsRuleMetadata]] = None
+
+ model: Optional[SpendLimitsRuleModel] = None
+
+ provider: Optional[SpendLimitsRuleProvider] = None
+
+ technique: Optional[Literal["fixed", "sliding"]] = None
+
+
+class SpendLimits(BaseModel):
+ enabled: Optional[bool] = None
+
+ rules: Optional[List[SpendLimitsRule]] = None
+
+
class StripeUsageEvent(BaseModel):
payload: str
@@ -185,6 +243,8 @@ class AIGatewayListResponse(BaseModel):
retry_max_attempts: Optional[int] = None
"""Maximum number of retry attempts for failed requests (1-5)"""
+ spend_limits: Optional[SpendLimits] = None
+
store_id: Optional[str] = None
stripe: Optional[Stripe] = None
diff --git a/src/cloudflare/types/ai_gateway/ai_gateway_update_params.py b/src/cloudflare/types/ai_gateway/ai_gateway_update_params.py
index 798b0082c6d..de45bb4501c 100644
--- a/src/cloudflare/types/ai_gateway/ai_gateway_update_params.py
+++ b/src/cloudflare/types/ai_gateway/ai_gateway_update_params.py
@@ -18,6 +18,13 @@
"GuardrailsPrompt",
"GuardrailsResponse",
"Otel",
+ "SpendLimits",
+ "SpendLimitsRule",
+ "SpendLimitsRuleMetadata",
+ "SpendLimitsRuleMetadataMode",
+ "SpendLimitsRuleMetadataUnionMember1",
+ "SpendLimitsRuleModel",
+ "SpendLimitsRuleProvider",
"Stripe",
"StripeUsageEvent",
]
@@ -63,6 +70,8 @@ class AIGatewayUpdateParams(TypedDict, total=False):
retry_max_attempts: Optional[int]
"""Maximum number of retry attempts for failed requests (1-5)"""
+ spend_limits: Optional[SpendLimits]
+
store_id: Optional[str]
stripe: Optional[Stripe]
@@ -181,6 +190,57 @@ class Otel(TypedDict, total=False):
content_type: Literal["json", "protobuf"]
+class SpendLimitsRuleMetadataMode(TypedDict, total=False):
+ mode: Required[Literal["partition"]]
+
+
+class SpendLimitsRuleMetadataUnionMember1(TypedDict, total=False):
+ mode: Required[Literal["filter"]]
+
+ values: Required[SequenceNotStr[str]]
+
+
+SpendLimitsRuleMetadata: TypeAlias = Union[SpendLimitsRuleMetadataMode, SpendLimitsRuleMetadataUnionMember1]
+
+
+class SpendLimitsRuleModel(TypedDict, total=False):
+ mode: Required[Literal["filter"]]
+
+ values: Required[SequenceNotStr[str]]
+
+
+class SpendLimitsRuleProvider(TypedDict, total=False):
+ mode: Required[Literal["filter"]]
+
+ values: Required[SequenceNotStr[str]]
+
+
+class SpendLimitsRule(TypedDict, total=False):
+ limit: Required[float]
+
+ limit_type: Required[Annotated[Literal["cost"], PropertyInfo(alias="limitType")]]
+
+ window: Required[int]
+
+ id: str
+
+ enabled: bool
+
+ metadata: Dict[str, SpendLimitsRuleMetadata]
+
+ model: SpendLimitsRuleModel
+
+ provider: SpendLimitsRuleProvider
+
+ technique: Literal["fixed", "sliding"]
+
+
+class SpendLimits(TypedDict, total=False):
+ enabled: bool
+
+ rules: Iterable[SpendLimitsRule]
+
+
class StripeUsageEvent(TypedDict, total=False):
payload: Required[str]
diff --git a/src/cloudflare/types/ai_gateway/ai_gateway_update_response.py b/src/cloudflare/types/ai_gateway/ai_gateway_update_response.py
index 8d5d502e961..febe03efdb8 100644
--- a/src/cloudflare/types/ai_gateway/ai_gateway_update_response.py
+++ b/src/cloudflare/types/ai_gateway/ai_gateway_update_response.py
@@ -18,6 +18,13 @@
"GuardrailsPrompt",
"GuardrailsResponse",
"Otel",
+ "SpendLimits",
+ "SpendLimitsRule",
+ "SpendLimitsRuleMetadata",
+ "SpendLimitsRuleMetadataMode",
+ "SpendLimitsRuleMetadataUnionMember1",
+ "SpendLimitsRuleModel",
+ "SpendLimitsRuleProvider",
"Stripe",
"StripeUsageEvent",
]
@@ -128,6 +135,57 @@ class Otel(BaseModel):
content_type: Optional[Literal["json", "protobuf"]] = None
+class SpendLimitsRuleMetadataMode(BaseModel):
+ mode: Literal["partition"]
+
+
+class SpendLimitsRuleMetadataUnionMember1(BaseModel):
+ mode: Literal["filter"]
+
+ values: List[str]
+
+
+SpendLimitsRuleMetadata: TypeAlias = Union[SpendLimitsRuleMetadataMode, SpendLimitsRuleMetadataUnionMember1]
+
+
+class SpendLimitsRuleModel(BaseModel):
+ mode: Literal["filter"]
+
+ values: List[str]
+
+
+class SpendLimitsRuleProvider(BaseModel):
+ mode: Literal["filter"]
+
+ values: List[str]
+
+
+class SpendLimitsRule(BaseModel):
+ limit: float
+
+ limit_type: Literal["cost"] = FieldInfo(alias="limitType")
+
+ window: int
+
+ id: Optional[str] = None
+
+ enabled: Optional[bool] = None
+
+ metadata: Optional[Dict[str, SpendLimitsRuleMetadata]] = None
+
+ model: Optional[SpendLimitsRuleModel] = None
+
+ provider: Optional[SpendLimitsRuleProvider] = None
+
+ technique: Optional[Literal["fixed", "sliding"]] = None
+
+
+class SpendLimits(BaseModel):
+ enabled: Optional[bool] = None
+
+ rules: Optional[List[SpendLimitsRule]] = None
+
+
class StripeUsageEvent(BaseModel):
payload: str
@@ -185,6 +243,8 @@ class AIGatewayUpdateResponse(BaseModel):
retry_max_attempts: Optional[int] = None
"""Maximum number of retry attempts for failed requests (1-5)"""
+ spend_limits: Optional[SpendLimits] = None
+
store_id: Optional[str] = None
stripe: Optional[Stripe] = None
diff --git a/src/cloudflare/types/dns/usage/__init__.py b/src/cloudflare/types/dns/usage/__init__.py
index f8ee8b14b1c..4e413a5b08f 100644
--- a/src/cloudflare/types/dns/usage/__init__.py
+++ b/src/cloudflare/types/dns/usage/__init__.py
@@ -1,3 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from __future__ import annotations
+
+from .zone_get_response import ZoneGetResponse as ZoneGetResponse
+from .account_get_response import AccountGetResponse as AccountGetResponse
diff --git a/src/cloudflare/types/dns/usage/account_get_response.py b/src/cloudflare/types/dns/usage/account_get_response.py
new file mode 100644
index 00000000000..86a020719ac
--- /dev/null
+++ b/src/cloudflare/types/dns/usage/account_get_response.py
@@ -0,0 +1,30 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from ...._models import BaseModel
+
+__all__ = ["AccountGetResponse"]
+
+
+class AccountGetResponse(BaseModel):
+ record_quota: Optional[int] = None
+ """Maximum number of DNS records allowed across all public zones in the account.
+
+ Null if using zone-level quota.
+ """
+
+ record_usage: int
+ """Current number of DNS records across all public zones in the account."""
+
+ internal_record_quota: Optional[int] = None
+ """Maximum number of DNS records allowed across all internal zones in the account.
+
+ Only present if internal DNS is enabled.
+ """
+
+ internal_record_usage: Optional[int] = None
+ """Current number of DNS records across all internal zones in the account.
+
+ Only present if internal DNS is enabled.
+ """
diff --git a/src/cloudflare/types/dns/usage/zone_get_response.py b/src/cloudflare/types/dns/usage/zone_get_response.py
new file mode 100644
index 00000000000..3c939e08972
--- /dev/null
+++ b/src/cloudflare/types/dns/usage/zone_get_response.py
@@ -0,0 +1,18 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from ...._models import BaseModel
+
+__all__ = ["ZoneGetResponse"]
+
+
+class ZoneGetResponse(BaseModel):
+ record_quota: Optional[int] = None
+ """Maximum number of DNS records allowed for the zone.
+
+ Null if using account-level quota.
+ """
+
+ record_usage: int
+ """Current number of DNS records in the zone."""
diff --git a/src/cloudflare/types/intel/sinkhole.py b/src/cloudflare/types/intel/sinkhole.py
index 9895bde4bc0..8e404467050 100644
--- a/src/cloudflare/types/intel/sinkhole.py
+++ b/src/cloudflare/types/intel/sinkhole.py
@@ -9,7 +9,7 @@
class Sinkhole(BaseModel):
- id: Optional[int] = None
+ id: Optional[str] = None
"""The unique identifier for the sinkhole."""
account_tag: Optional[str] = None
diff --git a/src/cloudflare/types/logpush/job_create_params.py b/src/cloudflare/types/logpush/job_create_params.py
index ca59411a9df..61d6089a4d6 100644
--- a/src/cloudflare/types/logpush/job_create_params.py
+++ b/src/cloudflare/types/logpush/job_create_params.py
@@ -54,6 +54,7 @@ class JobCreateParams(TypedDict, total=False):
"sinkhole_http_logs",
"spectrum_events",
"ssh_logs",
+ "turnstile_events",
"warp_config_changes",
"warp_toggle_changes",
"workers_trace_events",
diff --git a/src/cloudflare/types/logpush/logpush_job.py b/src/cloudflare/types/logpush/logpush_job.py
index e20ceeab1cb..fbe866558cc 100644
--- a/src/cloudflare/types/logpush/logpush_job.py
+++ b/src/cloudflare/types/logpush/logpush_job.py
@@ -44,6 +44,7 @@ class LogpushJob(BaseModel):
"sinkhole_http_logs",
"spectrum_events",
"ssh_logs",
+ "turnstile_events",
"warp_config_changes",
"warp_toggle_changes",
"workers_trace_events",
diff --git a/src/cloudflare/types/realtime_kit/session_get_participant_data_from_peer_id_params.py b/src/cloudflare/types/realtime_kit/session_get_participant_data_from_peer_id_params.py
index 95288d3835c..d36ef09e63c 100644
--- a/src/cloudflare/types/realtime_kit/session_get_participant_data_from_peer_id_params.py
+++ b/src/cloudflare/types/realtime_kit/session_get_participant_data_from_peer_id_params.py
@@ -15,10 +15,7 @@ class SessionGetParticipantDataFromPeerIDParams(TypedDict, total=False):
"""The app identifier tag."""
filters: Literal["device_info", "ip_information", "precall_network_information", "events", "quality_stats"]
- """Comma separated list of filters to apply.
-
- Note that there must be no spaces between the filters.
- """
+ """Filter to apply to the peer report."""
include_peer_events: bool
"""if true, response includes all the peer events of participant."""
diff --git a/src/cloudflare/types/realtime_kit/session_get_participant_data_from_peer_id_response.py b/src/cloudflare/types/realtime_kit/session_get_participant_data_from_peer_id_response.py
index 1ac3743888b..763cd63ba8b 100644
--- a/src/cloudflare/types/realtime_kit/session_get_participant_data_from_peer_id_response.py
+++ b/src/cloudflare/types/realtime_kit/session_get_participant_data_from_peer_id_response.py
@@ -6,10 +6,10 @@
from ..._models import BaseModel
-__all__ = ["SessionGetParticipantDataFromPeerIDResponse", "Data", "DataPeerReport"]
+__all__ = ["SessionGetParticipantDataFromPeerIDResponse", "Data", "DataParticipant", "DataParticipantPeerReport"]
-class DataPeerReport(BaseModel):
+class DataParticipantPeerReport(BaseModel):
"""Peer call statistics report."""
metadata: Optional[Dict[str, object]] = None
@@ -29,9 +29,9 @@ def __getattr__(self, attr: str) -> object: ...
__pydantic_extra__: Dict[str, object]
-class Data(BaseModel):
+class DataParticipant(BaseModel):
id: Optional[str] = None
- """Participant ID. This maps to the corresponding peerId."""
+ """ID of the participant."""
created_at: Optional[str] = None
"""timestamp when this participant was created."""
@@ -53,10 +53,10 @@ class Data(BaseModel):
peer_events: Optional[List[Dict[str, object]]] = None
- peer_report: Optional[DataPeerReport] = None
+ peer_report: Optional[DataParticipantPeerReport] = None
"""Peer call statistics report."""
- preset_name: Optional[str] = None
+ role: Optional[str] = None
"""Name of the preset associated with the participant."""
session_id: Optional[str] = None
@@ -68,6 +68,10 @@ class Data(BaseModel):
"""User id for this participant."""
+class Data(BaseModel):
+ participant: Optional[DataParticipant] = None
+
+
class SessionGetParticipantDataFromPeerIDResponse(BaseModel):
data: Optional[Data] = None
diff --git a/src/cloudflare/types/resource_sharing/__init__.py b/src/cloudflare/types/resource_sharing/__init__.py
index c38cd309a1e..7655008fc78 100644
--- a/src/cloudflare/types/resource_sharing/__init__.py
+++ b/src/cloudflare/types/resource_sharing/__init__.py
@@ -5,12 +5,16 @@
from .recipient_get_params import RecipientGetParams as RecipientGetParams
from .resource_list_params import ResourceListParams as ResourceListParams
from .recipient_list_params import RecipientListParams as RecipientListParams
+from .resource_get_response import ResourceGetResponse as ResourceGetResponse
from .recipient_get_response import RecipientGetResponse as RecipientGetResponse
from .resource_create_params import ResourceCreateParams as ResourceCreateParams
from .resource_list_response import ResourceListResponse as ResourceListResponse
+from .resource_update_params import ResourceUpdateParams as ResourceUpdateParams
from .recipient_create_params import RecipientCreateParams as RecipientCreateParams
from .recipient_list_response import RecipientListResponse as RecipientListResponse
from .resource_create_response import ResourceCreateResponse as ResourceCreateResponse
+from .resource_delete_response import ResourceDeleteResponse as ResourceDeleteResponse
+from .resource_update_response import ResourceUpdateResponse as ResourceUpdateResponse
from .recipient_create_response import RecipientCreateResponse as RecipientCreateResponse
from .recipient_delete_response import RecipientDeleteResponse as RecipientDeleteResponse
from .resource_sharing_get_params import ResourceSharingGetParams as ResourceSharingGetParams
diff --git a/src/cloudflare/types/resource_sharing/resource_delete_response.py b/src/cloudflare/types/resource_sharing/resource_delete_response.py
new file mode 100644
index 00000000000..deff33152bc
--- /dev/null
+++ b/src/cloudflare/types/resource_sharing/resource_delete_response.py
@@ -0,0 +1,44 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from datetime import datetime
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["ResourceDeleteResponse"]
+
+
+class ResourceDeleteResponse(BaseModel):
+ id: str
+ """Share Resource identifier."""
+
+ created: datetime
+ """When the share was created."""
+
+ meta: object
+ """Resource Metadata."""
+
+ modified: datetime
+ """When the share was modified."""
+
+ resource_account_id: str
+ """Account identifier."""
+
+ resource_id: str
+ """Share Resource identifier."""
+
+ resource_type: Literal[
+ "custom-ruleset",
+ "gateway-policy",
+ "gateway-destination-ip",
+ "gateway-block-page-settings",
+ "gateway-extended-email-matching",
+ "idp-federation-grant",
+ ]
+ """Resource Type."""
+
+ resource_version: int
+ """Resource Version."""
+
+ status: Literal["active", "deleting", "deleted"]
+ """Resource Status."""
diff --git a/src/cloudflare/types/resource_sharing/resource_get_response.py b/src/cloudflare/types/resource_sharing/resource_get_response.py
new file mode 100644
index 00000000000..a357bb5074f
--- /dev/null
+++ b/src/cloudflare/types/resource_sharing/resource_get_response.py
@@ -0,0 +1,44 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from datetime import datetime
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["ResourceGetResponse"]
+
+
+class ResourceGetResponse(BaseModel):
+ id: str
+ """Share Resource identifier."""
+
+ created: datetime
+ """When the share was created."""
+
+ meta: object
+ """Resource Metadata."""
+
+ modified: datetime
+ """When the share was modified."""
+
+ resource_account_id: str
+ """Account identifier."""
+
+ resource_id: str
+ """Share Resource identifier."""
+
+ resource_type: Literal[
+ "custom-ruleset",
+ "gateway-policy",
+ "gateway-destination-ip",
+ "gateway-block-page-settings",
+ "gateway-extended-email-matching",
+ "idp-federation-grant",
+ ]
+ """Resource Type."""
+
+ resource_version: int
+ """Resource Version."""
+
+ status: Literal["active", "deleting", "deleted"]
+ """Resource Status."""
diff --git a/src/cloudflare/types/resource_sharing/resource_update_params.py b/src/cloudflare/types/resource_sharing/resource_update_params.py
new file mode 100644
index 00000000000..d69bbdc0eb0
--- /dev/null
+++ b/src/cloudflare/types/resource_sharing/resource_update_params.py
@@ -0,0 +1,18 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["ResourceUpdateParams"]
+
+
+class ResourceUpdateParams(TypedDict, total=False):
+ account_id: Required[str]
+ """Account identifier."""
+
+ share_id: Required[str]
+ """Share identifier tag."""
+
+ meta: Required[object]
+ """Resource Metadata."""
diff --git a/src/cloudflare/types/resource_sharing/resource_update_response.py b/src/cloudflare/types/resource_sharing/resource_update_response.py
new file mode 100644
index 00000000000..f207220bf2d
--- /dev/null
+++ b/src/cloudflare/types/resource_sharing/resource_update_response.py
@@ -0,0 +1,44 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from datetime import datetime
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["ResourceUpdateResponse"]
+
+
+class ResourceUpdateResponse(BaseModel):
+ id: str
+ """Share Resource identifier."""
+
+ created: datetime
+ """When the share was created."""
+
+ meta: object
+ """Resource Metadata."""
+
+ modified: datetime
+ """When the share was modified."""
+
+ resource_account_id: str
+ """Account identifier."""
+
+ resource_id: str
+ """Share Resource identifier."""
+
+ resource_type: Literal[
+ "custom-ruleset",
+ "gateway-policy",
+ "gateway-destination-ip",
+ "gateway-block-page-settings",
+ "gateway-extended-email-matching",
+ "idp-federation-grant",
+ ]
+ """Resource Type."""
+
+ resource_version: int
+ """Resource Version."""
+
+ status: Literal["active", "deleting", "deleted"]
+ """Resource Status."""
diff --git a/src/cloudflare/types/workflows/__init__.py b/src/cloudflare/types/workflows/__init__.py
index 385d8fff853..7bcec65237c 100644
--- a/src/cloudflare/types/workflows/__init__.py
+++ b/src/cloudflare/types/workflows/__init__.py
@@ -6,6 +6,7 @@
from .version_list_params import VersionListParams as VersionListParams
from .instance_bulk_params import InstanceBulkParams as InstanceBulkParams
from .instance_list_params import InstanceListParams as InstanceListParams
+from .instance_step_params import InstanceStepParams as InstanceStepParams
from .version_get_response import VersionGetResponse as VersionGetResponse
from .workflow_list_params import WorkflowListParams as WorkflowListParams
from .instance_get_response import InstanceGetResponse as InstanceGetResponse
@@ -14,6 +15,8 @@
from .instance_bulk_response import InstanceBulkResponse as InstanceBulkResponse
from .instance_create_params import InstanceCreateParams as InstanceCreateParams
from .instance_list_response import InstanceListResponse as InstanceListResponse
+from .instance_step_response import InstanceStepResponse as InstanceStepResponse
+from .version_graph_response import VersionGraphResponse as VersionGraphResponse
from .workflow_list_response import WorkflowListResponse as WorkflowListResponse
from .workflow_update_params import WorkflowUpdateParams as WorkflowUpdateParams
from .instance_create_response import InstanceCreateResponse as InstanceCreateResponse
diff --git a/src/cloudflare/types/workflows/instance_bulk_response.py b/src/cloudflare/types/workflows/instance_bulk_response.py
index d941e320187..18348034307 100644
--- a/src/cloudflare/types/workflows/instance_bulk_response.py
+++ b/src/cloudflare/types/workflows/instance_bulk_response.py
@@ -1,5 +1,6 @@
# 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
@@ -17,3 +18,5 @@ class InstanceBulkResponse(BaseModel):
version_id: str
workflow_id: str
+
+ trigger_source: Optional[Literal["unknown", "api", "binding", "event", "cron"]] = None
diff --git a/src/cloudflare/types/workflows/instance_create_response.py b/src/cloudflare/types/workflows/instance_create_response.py
index 76df532ca4c..12496c29da1 100644
--- a/src/cloudflare/types/workflows/instance_create_response.py
+++ b/src/cloudflare/types/workflows/instance_create_response.py
@@ -1,5 +1,6 @@
# 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
@@ -17,3 +18,5 @@ class InstanceCreateResponse(BaseModel):
version_id: str
workflow_id: str
+
+ trigger_source: Optional[Literal["unknown", "api", "binding", "event", "cron"]] = None
diff --git a/src/cloudflare/types/workflows/instance_get_response.py b/src/cloudflare/types/workflows/instance_get_response.py
index 90f743706f3..f9e0ddad80f 100644
--- a/src/cloudflare/types/workflows/instance_get_response.py
+++ b/src/cloudflare/types/workflows/instance_get_response.py
@@ -26,6 +26,7 @@
"StepUnionMember3",
"StepUnionMember3Error",
"Trigger",
+ "Schedule",
]
@@ -162,6 +163,12 @@ class Trigger(BaseModel):
source: Literal["unknown", "api", "binding", "event", "cron"]
+class Schedule(BaseModel):
+ cron: str
+
+ scheduled_time: float = FieldInfo(alias="scheduledTime")
+
+
class InstanceGetResponse(BaseModel):
end: Optional[datetime] = None
@@ -190,3 +197,5 @@ class InstanceGetResponse(BaseModel):
trigger: Trigger
version_id: str = FieldInfo(alias="versionId")
+
+ schedule: Optional[Schedule] = None
diff --git a/src/cloudflare/types/workflows/instance_list_response.py b/src/cloudflare/types/workflows/instance_list_response.py
index 7a266896551..ea6f15bb284 100644
--- a/src/cloudflare/types/workflows/instance_list_response.py
+++ b/src/cloudflare/types/workflows/instance_list_response.py
@@ -27,3 +27,5 @@ class InstanceListResponse(BaseModel):
version_id: str
workflow_id: str
+
+ trigger_source: Optional[Literal["unknown", "api", "binding", "event", "cron"]] = None
diff --git a/src/cloudflare/types/workflows/instance_step_params.py b/src/cloudflare/types/workflows/instance_step_params.py
new file mode 100644
index 00000000000..e1eafb3acf5
--- /dev/null
+++ b/src/cloudflare/types/workflows/instance_step_params.py
@@ -0,0 +1,28 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, Required, TypedDict
+
+__all__ = ["InstanceStepParams"]
+
+
+class InstanceStepParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ workflow_name: Required[str]
+
+ name: Required[str]
+ """
+ Exact step name from the instance logs response, including the generated counter
+ suffix.
+ """
+
+ type: Required[Literal["step", "waitForEvent"]]
+ """
+ Step type to disambiguate step.do and waitForEvent entries that share the same
+ name.
+ """
+
+ attempt: int
+ """Specific attempt number to retrieve output or error for."""
diff --git a/src/cloudflare/types/workflows/instance_step_response.py b/src/cloudflare/types/workflows/instance_step_response.py
new file mode 100644
index 00000000000..d91e7202d14
--- /dev/null
+++ b/src/cloudflare/types/workflows/instance_step_response.py
@@ -0,0 +1,33 @@
+# 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
+
+__all__ = ["InstanceStepResponse", "Error"]
+
+
+class Error(BaseModel):
+ """Error details when status='errored'; null otherwise."""
+
+ message: str
+
+ name: str
+
+
+class InstanceStepResponse(BaseModel):
+ error: Optional[Error] = None
+ """Error details when status='errored'; null otherwise."""
+
+ status: Literal[
+ "queued", "running", "paused", "errored", "terminated", "complete", "waitingForPause", "waiting", "rollingBack"
+ ]
+
+ output: Optional[object] = None
+ """Full step output or waitForEvent payload without truncation.
+
+ Sensitive outputs are returned as '[REDACTED]'. Populated when
+ status='complete'. May be a ReadableStream when the step returned one from
+ step.do; stream outputs are served as application/octet-stream rather than JSON.
+ """
diff --git a/src/cloudflare/types/workflows/version_graph_response.py b/src/cloudflare/types/workflows/version_graph_response.py
new file mode 100644
index 00000000000..71070ac4789
--- /dev/null
+++ b/src/cloudflare/types/workflows/version_graph_response.py
@@ -0,0 +1,377 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Dict, List, Union, Optional
+from datetime import datetime
+from typing_extensions import Literal, TypeAlias
+
+from ..._models import BaseModel
+
+__all__ = [
+ "VersionGraphResponse",
+ "Graph",
+ "GraphWorkflow",
+ "GraphWorkflowFunctions",
+ "GraphWorkflowNode",
+ "GraphWorkflowNodeUnionMember0",
+ "GraphWorkflowNodeUnionMember1",
+ "GraphWorkflowNodeUnionMember1Config",
+ "GraphWorkflowNodeUnionMember1ConfigRetries",
+ "GraphWorkflowNodeUnionMember2",
+ "GraphWorkflowNodeUnionMember2Options",
+ "GraphWorkflowNodeUnionMember2Payload",
+ "GraphWorkflowNodeUnionMember2PayloadType",
+ "GraphWorkflowNodeUnionMember2PayloadUnionMember1",
+ "GraphWorkflowNodeUnionMember3",
+ "GraphWorkflowNodeUnionMember4",
+ "GraphWorkflowNodeUnionMember5",
+ "GraphWorkflowNodeUnionMember6",
+ "GraphWorkflowNodeUnionMember6CatchBlock",
+ "GraphWorkflowNodeUnionMember6FinallyBlock",
+ "GraphWorkflowNodeUnionMember6TryBlock",
+ "GraphWorkflowNodeUnionMember7",
+ "GraphWorkflowNodeUnionMember8",
+ "GraphWorkflowNodeUnionMember8Branch",
+ "GraphWorkflowNodeUnionMember9",
+ "GraphWorkflowNodeUnionMember9Branch",
+ "GraphWorkflowNodeUnionMember10",
+ "GraphWorkflowNodeUnionMember10Functions",
+ "GraphWorkflowNodeUnionMember10Payload",
+ "GraphWorkflowNodeUnionMember10PayloadType",
+ "GraphWorkflowNodeUnionMember10PayloadUnionMember1",
+ "GraphWorkflowNodeUnionMember11",
+ "GraphWorkflowNodeUnionMember12",
+ "GraphWorkflowNodeUnionMember13",
+ "GraphWorkflowPayload",
+ "GraphWorkflowPayloadType",
+ "GraphWorkflowPayloadUnionMember1",
+]
+
+
+class GraphWorkflowFunctions(BaseModel):
+ name: str
+
+ nodes: List[object]
+ """Child nodes (recursive)."""
+
+ type: Literal["function_def"]
+
+
+class GraphWorkflowNodeUnionMember0(BaseModel):
+ duration: Union[float, str]
+ """Duration as milliseconds (number) or human-readable string."""
+
+ name: str
+
+ type: Literal["step_sleep"]
+
+ resolves: Optional[float] = None
+
+ starts: Optional[float] = None
+
+
+class GraphWorkflowNodeUnionMember1ConfigRetries(BaseModel):
+ """Retry policy for a step."""
+
+ backoff: Literal["constant", "linear", "exponential"]
+ """Backoff strategy for step retries."""
+
+ delay: Union[float, str]
+ """Duration as milliseconds (number) or human-readable string."""
+
+ limit: float
+
+
+class GraphWorkflowNodeUnionMember1Config(BaseModel):
+ """Configuration for a step (retries and timeout)."""
+
+ retries: GraphWorkflowNodeUnionMember1ConfigRetries
+ """Retry policy for a step."""
+
+ timeout: Union[float, str]
+ """Duration as milliseconds (number) or human-readable string."""
+
+
+class GraphWorkflowNodeUnionMember1(BaseModel):
+ config: GraphWorkflowNodeUnionMember1Config
+ """Configuration for a step (retries and timeout)."""
+
+ name: str
+
+ nodes: List[object]
+ """Child nodes (recursive)."""
+
+ type: Literal["step_do"]
+
+ resolves: Optional[float] = None
+
+ starts: Optional[float] = None
+
+
+class GraphWorkflowNodeUnionMember2Options(BaseModel):
+ """Options for a waitForEvent step."""
+
+ event_type: str
+
+ timeout: Union[float, str]
+ """Duration as milliseconds (number) or human-readable string."""
+
+
+class GraphWorkflowNodeUnionMember2PayloadType(BaseModel):
+ type: Literal["unknown"]
+
+
+class GraphWorkflowNodeUnionMember2PayloadUnionMember1(BaseModel):
+ fields: Dict[str, object]
+ """Nested JsonShape fields (recursive structure)."""
+
+ type: Literal["object"]
+
+
+GraphWorkflowNodeUnionMember2Payload: TypeAlias = Union[
+ GraphWorkflowNodeUnionMember2PayloadType, GraphWorkflowNodeUnionMember2PayloadUnionMember1
+]
+
+
+class GraphWorkflowNodeUnionMember2(BaseModel):
+ name: str
+
+ options: Optional[GraphWorkflowNodeUnionMember2Options] = None
+ """Options for a waitForEvent step."""
+
+ type: Literal["step_wait_for_event"]
+
+ payload: Optional[GraphWorkflowNodeUnionMember2Payload] = None
+ """Shape descriptor for JSON payloads."""
+
+ resolves: Optional[float] = None
+
+ starts: Optional[float] = None
+
+
+class GraphWorkflowNodeUnionMember3(BaseModel):
+ name: str
+
+ timestamp: str
+
+ type: Literal["step_sleep_until"]
+
+ resolves: Optional[float] = None
+
+ starts: Optional[float] = None
+
+
+class GraphWorkflowNodeUnionMember4(BaseModel):
+ nodes: List[object]
+ """Child nodes (recursive)."""
+
+ type: Literal["loop"]
+
+
+class GraphWorkflowNodeUnionMember5(BaseModel):
+ kind: Literal["all", "any", "all_settled", "race"]
+ """Parallel execution strategy."""
+
+ nodes: List[object]
+ """Child nodes (recursive)."""
+
+ type: Literal["parallel"]
+
+
+class GraphWorkflowNodeUnionMember6CatchBlock(BaseModel):
+ nodes: List[object]
+ """Child nodes (recursive)."""
+
+ type: Literal["block"]
+
+
+class GraphWorkflowNodeUnionMember6FinallyBlock(BaseModel):
+ nodes: List[object]
+ """Child nodes (recursive)."""
+
+ type: Literal["block"]
+
+
+class GraphWorkflowNodeUnionMember6TryBlock(BaseModel):
+ nodes: List[object]
+ """Child nodes (recursive)."""
+
+ type: Literal["block"]
+
+
+class GraphWorkflowNodeUnionMember6(BaseModel):
+ catch_block: Optional[GraphWorkflowNodeUnionMember6CatchBlock] = None
+
+ finally_block: Optional[GraphWorkflowNodeUnionMember6FinallyBlock] = None
+
+ try_block: Optional[GraphWorkflowNodeUnionMember6TryBlock] = None
+
+ type: Literal["try"]
+
+
+class GraphWorkflowNodeUnionMember7(BaseModel):
+ nodes: List[object]
+ """Child nodes (recursive)."""
+
+ type: Literal["block"]
+
+
+class GraphWorkflowNodeUnionMember8Branch(BaseModel):
+ condition: Optional[str] = None
+
+ nodes: List[object]
+ """Child nodes (recursive)."""
+
+
+class GraphWorkflowNodeUnionMember8(BaseModel):
+ branches: List[GraphWorkflowNodeUnionMember8Branch]
+
+ type: Literal["if"]
+
+
+class GraphWorkflowNodeUnionMember9Branch(BaseModel):
+ condition: Optional[str] = None
+
+ nodes: List[object]
+ """Child nodes (recursive)."""
+
+
+class GraphWorkflowNodeUnionMember9(BaseModel):
+ branches: List[GraphWorkflowNodeUnionMember9Branch]
+
+ discriminant: str
+
+ type: Literal["switch"]
+
+
+class GraphWorkflowNodeUnionMember10Functions(BaseModel):
+ name: str
+
+ nodes: List[object]
+ """Child nodes (recursive)."""
+
+ type: Literal["function_def"]
+
+
+class GraphWorkflowNodeUnionMember10PayloadType(BaseModel):
+ type: Literal["unknown"]
+
+
+class GraphWorkflowNodeUnionMember10PayloadUnionMember1(BaseModel):
+ fields: Dict[str, object]
+ """Nested JsonShape fields (recursive structure)."""
+
+ type: Literal["object"]
+
+
+GraphWorkflowNodeUnionMember10Payload: TypeAlias = Union[
+ GraphWorkflowNodeUnionMember10PayloadType, GraphWorkflowNodeUnionMember10PayloadUnionMember1
+]
+
+
+class GraphWorkflowNodeUnionMember10(BaseModel):
+ class_name: str
+
+ functions: Dict[str, GraphWorkflowNodeUnionMember10Functions]
+
+ nodes: List[object]
+ """Child nodes (recursive)."""
+
+ type: Literal["start"]
+
+ payload: Optional[GraphWorkflowNodeUnionMember10Payload] = None
+ """Shape descriptor for JSON payloads."""
+
+
+class GraphWorkflowNodeUnionMember11(BaseModel):
+ name: str
+
+ type: Literal["function_call"]
+
+ resolves: Optional[float] = None
+
+ starts: Optional[float] = None
+
+
+class GraphWorkflowNodeUnionMember12(BaseModel):
+ name: str
+
+ nodes: List[object]
+ """Child nodes (recursive)."""
+
+ type: Literal["function_def"]
+
+
+class GraphWorkflowNodeUnionMember13(BaseModel):
+ kind: Literal["break", "return"]
+ """Break or return from a loop."""
+
+ type: Literal["break"]
+
+
+GraphWorkflowNode: TypeAlias = Union[
+ GraphWorkflowNodeUnionMember0,
+ GraphWorkflowNodeUnionMember1,
+ GraphWorkflowNodeUnionMember2,
+ GraphWorkflowNodeUnionMember3,
+ GraphWorkflowNodeUnionMember4,
+ GraphWorkflowNodeUnionMember5,
+ GraphWorkflowNodeUnionMember6,
+ GraphWorkflowNodeUnionMember7,
+ GraphWorkflowNodeUnionMember8,
+ GraphWorkflowNodeUnionMember9,
+ GraphWorkflowNodeUnionMember10,
+ GraphWorkflowNodeUnionMember11,
+ GraphWorkflowNodeUnionMember12,
+ GraphWorkflowNodeUnionMember13,
+]
+
+
+class GraphWorkflowPayloadType(BaseModel):
+ type: Literal["unknown"]
+
+
+class GraphWorkflowPayloadUnionMember1(BaseModel):
+ fields: Dict[str, object]
+ """Nested JsonShape fields (recursive structure)."""
+
+ type: Literal["object"]
+
+
+GraphWorkflowPayload: TypeAlias = Union[GraphWorkflowPayloadType, GraphWorkflowPayloadUnionMember1]
+
+
+class GraphWorkflow(BaseModel):
+ """A parsed workflow entrypoint with its step graph."""
+
+ class_name: str
+
+ functions: Dict[str, GraphWorkflowFunctions]
+
+ nodes: List[GraphWorkflowNode]
+
+ payload: Optional[GraphWorkflowPayload] = None
+ """Shape descriptor for JSON payloads."""
+
+
+class Graph(BaseModel):
+ """Versioned workflow graph payload."""
+
+ version: float
+
+ workflow: GraphWorkflow
+ """A parsed workflow entrypoint with its step graph."""
+
+
+class VersionGraphResponse(BaseModel):
+ id: str
+
+ class_name: str
+
+ created_on: datetime
+
+ graph: Optional[Graph] = None
+ """Versioned workflow graph payload."""
+
+ modified_on: datetime
+
+ workflow_id: str
diff --git a/src/cloudflare/types/workflows/workflow_get_response.py b/src/cloudflare/types/workflows/workflow_get_response.py
index 7698baaaa17..0553291d9f0 100644
--- a/src/cloudflare/types/workflows/workflow_get_response.py
+++ b/src/cloudflare/types/workflows/workflow_get_response.py
@@ -1,13 +1,13 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Optional
+from typing import List, Optional
from datetime import datetime
from pydantic import Field as FieldInfo
from ..._models import BaseModel
-__all__ = ["WorkflowGetResponse", "Instances"]
+__all__ = ["WorkflowGetResponse", "Instances", "Schedule"]
class Instances(BaseModel):
@@ -30,6 +30,12 @@ class Instances(BaseModel):
waiting_for_pause: Optional[float] = FieldInfo(alias="waitingForPause", default=None)
+class Schedule(BaseModel):
+ cron: str
+
+ next_instance: str
+
+
class WorkflowGetResponse(BaseModel):
id: str
@@ -46,3 +52,5 @@ class WorkflowGetResponse(BaseModel):
script_name: str
triggered_on: Optional[datetime] = None
+
+ schedules: Optional[List[Schedule]] = None
diff --git a/src/cloudflare/types/workflows/workflow_list_response.py b/src/cloudflare/types/workflows/workflow_list_response.py
index bde9d7dd38c..a05251d55ce 100644
--- a/src/cloudflare/types/workflows/workflow_list_response.py
+++ b/src/cloudflare/types/workflows/workflow_list_response.py
@@ -1,13 +1,13 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Optional
+from typing import List, Optional
from datetime import datetime
from pydantic import Field as FieldInfo
from ..._models import BaseModel
-__all__ = ["WorkflowListResponse", "Instances"]
+__all__ = ["WorkflowListResponse", "Instances", "Schedule"]
class Instances(BaseModel):
@@ -30,6 +30,12 @@ class Instances(BaseModel):
waiting_for_pause: Optional[float] = FieldInfo(alias="waitingForPause", default=None)
+class Schedule(BaseModel):
+ cron: str
+
+ next_instance: str
+
+
class WorkflowListResponse(BaseModel):
id: str
@@ -46,3 +52,5 @@ class WorkflowListResponse(BaseModel):
script_name: str
triggered_on: Optional[datetime] = None
+
+ schedules: Optional[List[Schedule]] = None
diff --git a/src/cloudflare/types/workflows/workflow_update_params.py b/src/cloudflare/types/workflows/workflow_update_params.py
index 2ff781a484d..045b90afdf6 100644
--- a/src/cloudflare/types/workflows/workflow_update_params.py
+++ b/src/cloudflare/types/workflows/workflow_update_params.py
@@ -2,9 +2,10 @@
from __future__ import annotations
+from typing import Iterable
from typing_extensions import Required, TypedDict
-__all__ = ["WorkflowUpdateParams", "Limits"]
+__all__ = ["WorkflowUpdateParams", "Limits", "Schedule"]
class WorkflowUpdateParams(TypedDict, total=False):
@@ -16,6 +17,12 @@ class WorkflowUpdateParams(TypedDict, total=False):
limits: Limits
+ schedules: Iterable[Schedule]
+
class Limits(TypedDict, total=False):
steps: int
+
+
+class Schedule(TypedDict, total=False):
+ cron: Required[str]
diff --git a/src/cloudflare/types/zero_trust/access/__init__.py b/src/cloudflare/types/zero_trust/access/__init__.py
index cb7d98a5425..f1db601942e 100644
--- a/src/cloudflare/types/zero_trust/access/__init__.py
+++ b/src/cloudflare/types/zero_trust/access/__init__.py
@@ -47,6 +47,7 @@
from .tag_delete_response import TagDeleteResponse as TagDeleteResponse
from .approval_group_param import ApprovalGroupParam as ApprovalGroupParam
from .associated_hostnames import AssociatedHostnames as AssociatedHostnames
+from .idp_federation_grant import IdPFederationGrant as IdPFederationGrant
from .policy_create_params import PolicyCreateParams as PolicyCreateParams
from .policy_list_response import PolicyListResponse as PolicyListResponse
from .policy_update_params import PolicyUpdateParams as PolicyUpdateParams
@@ -94,6 +95,9 @@
from .saml_certificate_list_response import SAMLCertificateListResponse as SAMLCertificateListResponse
from .saml_certificate_rotate_response import SAMLCertificateRotateResponse as SAMLCertificateRotateResponse
from .scim_config_authentication_oauth2 import SCIMConfigAuthenticationOauth2 as SCIMConfigAuthenticationOauth2
+from .idp_federation_grant_create_params import IdPFederationGrantCreateParams as IdPFederationGrantCreateParams
+from .idp_federation_grant_list_response import IdPFederationGrantListResponse as IdPFederationGrantListResponse
+from .idp_federation_grant_delete_response import IdPFederationGrantDeleteResponse as IdPFederationGrantDeleteResponse
from .scim_config_authentication_http_basic import (
SCIMConfigAuthenticationHTTPBasic as SCIMConfigAuthenticationHTTPBasic,
)
diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_create_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_create_response.py
index 7dc526be769..61c6e6f7223 100644
--- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_create_response.py
+++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_create_response.py
@@ -84,9 +84,9 @@ class Server(BaseModel):
"""
When true, the gateway worker uses the shared Cloudflare-owned OAuth callback
endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the
- customer portal hostname. Operators manage this internal rollout flag through
- admin endpoints. Effective behavior is gated by the gateway worker's per-env
- rollout mode KV key.
+ customer portal hostname. New public server creates default to true; existing
+ servers default to false from migration until explicitly updated. Effective
+ behavior is gated by the gateway worker's per-env rollout mode KV key.
"""
last_successful_sync: Optional[datetime] = None
diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_list_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_list_response.py
index 05017bfb676..3008b57f175 100644
--- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_list_response.py
+++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_list_response.py
@@ -84,9 +84,9 @@ class Server(BaseModel):
"""
When true, the gateway worker uses the shared Cloudflare-owned OAuth callback
endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the
- customer portal hostname. Operators manage this internal rollout flag through
- admin endpoints. Effective behavior is gated by the gateway worker's per-env
- rollout mode KV key.
+ customer portal hostname. New public server creates default to true; existing
+ servers default to false from migration until explicitly updated. Effective
+ behavior is gated by the gateway worker's per-env rollout mode KV key.
"""
last_successful_sync: Optional[datetime] = None
diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_read_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_read_response.py
index 1b65b772635..07ed7ca9071 100644
--- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_read_response.py
+++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_read_response.py
@@ -84,9 +84,9 @@ class Server(BaseModel):
"""
When true, the gateway worker uses the shared Cloudflare-owned OAuth callback
endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the
- customer portal hostname. Operators manage this internal rollout flag through
- admin endpoints. Effective behavior is gated by the gateway worker's per-env
- rollout mode KV key.
+ customer portal hostname. New public server creates default to true; existing
+ servers default to false from migration until explicitly updated. Effective
+ behavior is gated by the gateway worker's per-env rollout mode KV key.
"""
last_successful_sync: Optional[datetime] = None
diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_update_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_update_response.py
index 42790e98208..a29b140f119 100644
--- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_update_response.py
+++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/portal_update_response.py
@@ -84,9 +84,9 @@ class Server(BaseModel):
"""
When true, the gateway worker uses the shared Cloudflare-owned OAuth callback
endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the
- customer portal hostname. Operators manage this internal rollout flag through
- admin endpoints. Effective behavior is gated by the gateway worker's per-env
- rollout mode KV key.
+ customer portal hostname. New public server creates default to true; existing
+ servers default to false from migration until explicitly updated. Effective
+ behavior is gated by the gateway worker's per-env rollout mode KV key.
"""
last_successful_sync: Optional[datetime] = None
diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_create_params.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_create_params.py
index 57c26163547..598d4762a3f 100644
--- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_create_params.py
+++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_create_params.py
@@ -24,6 +24,15 @@ class ServerCreateParams(TypedDict, total=False):
description: Optional[str]
+ is_shared_oauth_callback_enabled: bool
+ """
+ When true, the gateway worker uses the shared Cloudflare-owned OAuth callback
+ endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the
+ customer portal hostname. New public server creates default to true; existing
+ servers default to false from migration until explicitly updated. Effective
+ behavior is gated by the gateway worker's per-env rollout mode KV key.
+ """
+
updated_prompts: Iterable[UpdatedPrompt]
updated_tools: Iterable[UpdatedTool]
diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_create_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_create_response.py
index df613df40b6..815b4463833 100644
--- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_create_response.py
+++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_create_response.py
@@ -74,9 +74,9 @@ class ServerCreateResponse(BaseModel):
"""
When true, the gateway worker uses the shared Cloudflare-owned OAuth callback
endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the
- customer portal hostname. Operators manage this internal rollout flag through
- admin endpoints. Effective behavior is gated by the gateway worker's per-env
- rollout mode KV key.
+ customer portal hostname. New public server creates default to true; existing
+ servers default to false from migration until explicitly updated. Effective
+ behavior is gated by the gateway worker's per-env rollout mode KV key.
"""
last_successful_sync: Optional[datetime] = None
diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_delete_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_delete_response.py
index e26d32a3331..458ed1089ac 100644
--- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_delete_response.py
+++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_delete_response.py
@@ -74,9 +74,9 @@ class ServerDeleteResponse(BaseModel):
"""
When true, the gateway worker uses the shared Cloudflare-owned OAuth callback
endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the
- customer portal hostname. Operators manage this internal rollout flag through
- admin endpoints. Effective behavior is gated by the gateway worker's per-env
- rollout mode KV key.
+ customer portal hostname. New public server creates default to true; existing
+ servers default to false from migration until explicitly updated. Effective
+ behavior is gated by the gateway worker's per-env rollout mode KV key.
"""
last_successful_sync: Optional[datetime] = None
diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_list_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_list_response.py
index fe5dffa46b6..7e12dd45fb8 100644
--- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_list_response.py
+++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_list_response.py
@@ -74,9 +74,9 @@ class ServerListResponse(BaseModel):
"""
When true, the gateway worker uses the shared Cloudflare-owned OAuth callback
endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the
- customer portal hostname. Operators manage this internal rollout flag through
- admin endpoints. Effective behavior is gated by the gateway worker's per-env
- rollout mode KV key.
+ customer portal hostname. New public server creates default to true; existing
+ servers default to false from migration until explicitly updated. Effective
+ behavior is gated by the gateway worker's per-env rollout mode KV key.
"""
last_successful_sync: Optional[datetime] = None
diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_read_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_read_response.py
index af85d6b8528..259bcd23a18 100644
--- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_read_response.py
+++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_read_response.py
@@ -74,9 +74,9 @@ class ServerReadResponse(BaseModel):
"""
When true, the gateway worker uses the shared Cloudflare-owned OAuth callback
endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the
- customer portal hostname. Operators manage this internal rollout flag through
- admin endpoints. Effective behavior is gated by the gateway worker's per-env
- rollout mode KV key.
+ customer portal hostname. New public server creates default to true; existing
+ servers default to false from migration until explicitly updated. Effective
+ behavior is gated by the gateway worker's per-env rollout mode KV key.
"""
last_successful_sync: Optional[datetime] = None
diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_update_params.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_update_params.py
index 38cf578f571..394c9e5a3f4 100644
--- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_update_params.py
+++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_update_params.py
@@ -15,6 +15,15 @@ class ServerUpdateParams(TypedDict, total=False):
description: Optional[str]
+ is_shared_oauth_callback_enabled: bool
+ """
+ When true, the gateway worker uses the shared Cloudflare-owned OAuth callback
+ endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the
+ customer portal hostname. New public server creates default to true; existing
+ servers default to false from migration until explicitly updated. Effective
+ behavior is gated by the gateway worker's per-env rollout mode KV key.
+ """
+
name: str
updated_prompts: Iterable[UpdatedPrompt]
diff --git a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_update_response.py b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_update_response.py
index 19cf816346a..af37f6b9644 100644
--- a/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_update_response.py
+++ b/src/cloudflare/types/zero_trust/access/ai_controls/mcp/server_update_response.py
@@ -74,9 +74,9 @@ class ServerUpdateResponse(BaseModel):
"""
When true, the gateway worker uses the shared Cloudflare-owned OAuth callback
endpoint as the redirect_uri for upstream on-behalf OAuth, instead of the
- customer portal hostname. Operators manage this internal rollout flag through
- admin endpoints. Effective behavior is gated by the gateway worker's per-env
- rollout mode KV key.
+ customer portal hostname. New public server creates default to true; existing
+ servers default to false from migration until explicitly updated. Effective
+ behavior is gated by the gateway worker's per-env rollout mode KV key.
"""
last_successful_sync: Optional[datetime] = None
diff --git a/src/cloudflare/types/zero_trust/access/idp_federation_grant.py b/src/cloudflare/types/zero_trust/access/idp_federation_grant.py
new file mode 100644
index 00000000000..c9bd2c2bda6
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/access/idp_federation_grant.py
@@ -0,0 +1,18 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from datetime import datetime
+
+from ...._models import BaseModel
+
+__all__ = ["IdPFederationGrant"]
+
+
+class IdPFederationGrant(BaseModel):
+ id: str
+ """UID of the IdP federation grant."""
+
+ created_at: datetime
+ """When the grant was created."""
+
+ idp_id: str
+ """UID of the identity provider being federated."""
diff --git a/src/cloudflare/types/zero_trust/access/idp_federation_grant_create_params.py b/src/cloudflare/types/zero_trust/access/idp_federation_grant_create_params.py
new file mode 100644
index 00000000000..8c305cc572b
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/access/idp_federation_grant_create_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 Required, TypedDict
+
+__all__ = ["IdPFederationGrantCreateParams"]
+
+
+class IdPFederationGrantCreateParams(TypedDict, total=False):
+ account_id: Required[str]
+ """Identifier."""
+
+ idp_id: Required[str]
+ """UID of the identity provider to federate.
+
+ Must be an existing identity provider in this account. One-time pin and
+ Cloudflare-managed identity providers cannot be federated.
+ """
diff --git a/src/cloudflare/types/zero_trust/access/idp_federation_grant_delete_response.py b/src/cloudflare/types/zero_trust/access/idp_federation_grant_delete_response.py
new file mode 100644
index 00000000000..768c2517ce1
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/access/idp_federation_grant_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__ = ["IdPFederationGrantDeleteResponse"]
+
+
+class IdPFederationGrantDeleteResponse(BaseModel):
+ id: Optional[str] = None
+ """UID of the deleted IdP federation grant."""
diff --git a/src/cloudflare/types/zero_trust/access/idp_federation_grant_list_response.py b/src/cloudflare/types/zero_trust/access/idp_federation_grant_list_response.py
new file mode 100644
index 00000000000..dfd7e168333
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/access/idp_federation_grant_list_response.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List
+from typing_extensions import TypeAlias
+
+from .idp_federation_grant import IdPFederationGrant
+
+__all__ = ["IdPFederationGrantListResponse"]
+
+IdPFederationGrantListResponse: TypeAlias = List[IdPFederationGrant]
diff --git a/src/cloudflare/types/zero_trust/dex/devices/__init__.py b/src/cloudflare/types/zero_trust/dex/devices/__init__.py
new file mode 100644
index 00000000000..a923e772912
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dex/devices/__init__.py
@@ -0,0 +1,6 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .isps import ISPs as ISPs
+from .isp_list_params import ISPListParams as ISPListParams
diff --git a/src/cloudflare/types/zero_trust/dex/devices/isp_list_params.py b/src/cloudflare/types/zero_trust/dex/devices/isp_list_params.py
new file mode 100644
index 00000000000..127afcc2b87
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dex/devices/isp_list_params.py
@@ -0,0 +1,36 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union
+from datetime import datetime
+from typing_extensions import Literal, Required, Annotated, TypedDict
+
+from ....._utils import PropertyInfo
+
+__all__ = ["ISPListParams"]
+
+
+class ISPListParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ per_page: Required[int]
+ """Number of items per page"""
+
+ cursor: str
+ """Cursor for cursor-based pagination. Mutually exclusive with page."""
+
+ from_: Annotated[Union[str, datetime], PropertyInfo(alias="from", format="iso8601")]
+ """Start time for the query in ISO 8601 format"""
+
+ page: int
+ """Page number of paginated results. Mutually exclusive with cursor."""
+
+ sort_by: Literal["time_start"]
+ """The field to sort results by"""
+
+ sort_order: Literal["ASC", "DESC"]
+ """The order to sort results"""
+
+ to: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")]
+ """End time for the query in ISO 8601 format"""
diff --git a/src/cloudflare/types/zero_trust/dex/devices/isps.py b/src/cloudflare/types/zero_trust/dex/devices/isps.py
new file mode 100644
index 00000000000..86840403985
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/dex/devices/isps.py
@@ -0,0 +1,86 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+
+from ....._models import BaseModel
+
+__all__ = ["ISPs", "ISP", "ISPIP", "ISPIPLocation"]
+
+
+class ISPIPLocation(BaseModel):
+ """Geographic location information.
+
+ All fields are returned as the literal string `"REDACTED"` for callers that do not have the PII permission.
+ """
+
+ city: Optional[str] = None
+ """City name. Returned as `"REDACTED"` without PII permission."""
+
+ country_iso: Optional[str] = None
+ """Country ISO code. Returned as `"REDACTED"` without PII permission."""
+
+ state_iso: Optional[str] = None
+ """State/province ISO code. Returned as `"REDACTED"` without PII permission."""
+
+ zip: Optional[str] = None
+ """ZIP/postal code. Returned as `"REDACTED"` without PII permission."""
+
+
+class ISPIP(BaseModel):
+ """IP address information for the ISP hop.
+
+ Fields marked as PII-gated (`name`, `address`, `netmask`, and all `location` sub-fields) will be returned as the literal string `"REDACTED"` for callers that do not have the PII permission. `asn`, `aso`, and `version` are always returned regardless of PII access.
+ """
+
+ address: Optional[str] = None
+ """IP address. Returned as `"REDACTED"` without PII permission."""
+
+ asn: Optional[int] = None
+ """Autonomous System Number"""
+
+ aso: Optional[str] = None
+ """Autonomous System Organization name"""
+
+ location: Optional[ISPIPLocation] = None
+ """Geographic location information.
+
+ All fields are returned as the literal string `"REDACTED"` for callers that do
+ not have the PII permission.
+ """
+
+ name: Optional[str] = None
+ """Named IP address (reverse DNS hostname when available).
+
+ Returned as `"REDACTED"` without PII permission.
+ """
+
+ netmask: Optional[str] = None
+ """Network mask. Returned as `"REDACTED"` without PII permission."""
+
+ version: Optional[int] = None
+ """IP version (`1` for IPv4, `2` for IPv6, `0` if unknown)"""
+
+
+class ISP(BaseModel):
+ test_id: str
+ """The test that generated this result"""
+
+ test_result_id: str
+ """The specific test result"""
+
+ time_start: datetime
+ """Timestamp of when the ISP was observed"""
+
+ ip: Optional[ISPIP] = None
+ """IP address information for the ISP hop.
+
+ Fields marked as PII-gated (`name`, `address`, `netmask`, and all `location`
+ sub-fields) will be returned as the literal string `"REDACTED"` for callers that
+ do not have the PII permission. `asn`, `aso`, and `version` are always returned
+ regardless of PII access.
+ """
+
+
+class ISPs(BaseModel):
+ isps: List[ISP]
diff --git a/tests/api_resources/abuse_reports/test_mitigations.py b/tests/api_resources/abuse_reports/test_mitigations.py
index 7975ce3809e..8fff01ce149 100644
--- a/tests/api_resources/abuse_reports/test_mitigations.py
+++ b/tests/api_resources/abuse_reports/test_mitigations.py
@@ -43,7 +43,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None:
per_page=0,
sort="type,asc",
status="pending",
- type="legal_block",
+ type="account_suspend",
)
assert_matches_type(SyncV4PagePagination[Optional[MitigationListResponse]], mitigation, path=["response"])
@@ -200,7 +200,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare)
per_page=0,
sort="type,asc",
status="pending",
- type="legal_block",
+ type="account_suspend",
)
assert_matches_type(AsyncV4PagePagination[Optional[MitigationListResponse]], mitigation, path=["response"])
diff --git a/tests/api_resources/dns/usage/__init__.py b/tests/api_resources/dns/usage/__init__.py
new file mode 100644
index 00000000000..fd8019a9a1a
--- /dev/null
+++ b/tests/api_resources/dns/usage/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/dns/usage/test_account.py b/tests/api_resources/dns/usage/test_account.py
new file mode 100644
index 00000000000..03d86dca84a
--- /dev/null
+++ b/tests/api_resources/dns/usage/test_account.py
@@ -0,0 +1,100 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, Optional, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare.types.dns.usage import AccountGetResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestAccount:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_get(self, client: Cloudflare) -> None:
+ account = client.dns.usage.account.get(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[AccountGetResponse], account, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Cloudflare) -> None:
+ response = client.dns.usage.account.with_raw_response.get(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ account = response.parse()
+ assert_matches_type(Optional[AccountGetResponse], account, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Cloudflare) -> None:
+ with client.dns.usage.account.with_streaming_response.get(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ account = response.parse()
+ assert_matches_type(Optional[AccountGetResponse], account, 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.usage.account.with_raw_response.get(
+ account_id="",
+ )
+
+
+class TestAsyncAccount:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncCloudflare) -> None:
+ account = await async_client.dns.usage.account.get(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[AccountGetResponse], account, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.dns.usage.account.with_raw_response.get(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ account = await response.parse()
+ assert_matches_type(Optional[AccountGetResponse], account, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.dns.usage.account.with_streaming_response.get(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ account = await response.parse()
+ assert_matches_type(Optional[AccountGetResponse], account, 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.usage.account.with_raw_response.get(
+ account_id="",
+ )
diff --git a/tests/api_resources/dns/usage/test_zone.py b/tests/api_resources/dns/usage/test_zone.py
new file mode 100644
index 00000000000..be5c61715f1
--- /dev/null
+++ b/tests/api_resources/dns/usage/test_zone.py
@@ -0,0 +1,100 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, Optional, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare.types.dns.usage import ZoneGetResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestZone:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_get(self, client: Cloudflare) -> None:
+ zone = client.dns.usage.zone.get(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[ZoneGetResponse], zone, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Cloudflare) -> None:
+ response = client.dns.usage.zone.with_raw_response.get(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ zone = response.parse()
+ assert_matches_type(Optional[ZoneGetResponse], zone, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Cloudflare) -> None:
+ with client.dns.usage.zone.with_streaming_response.get(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ zone = response.parse()
+ assert_matches_type(Optional[ZoneGetResponse], zone, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_get(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
+ client.dns.usage.zone.with_raw_response.get(
+ zone_id="",
+ )
+
+
+class TestAsyncZone:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncCloudflare) -> None:
+ zone = await async_client.dns.usage.zone.get(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[ZoneGetResponse], zone, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.dns.usage.zone.with_raw_response.get(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ zone = await response.parse()
+ assert_matches_type(Optional[ZoneGetResponse], zone, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.dns.usage.zone.with_streaming_response.get(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ zone = await response.parse()
+ assert_matches_type(Optional[ZoneGetResponse], zone, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_get(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
+ await async_client.dns.usage.zone.with_raw_response.get(
+ zone_id="",
+ )
diff --git a/tests/api_resources/resource_sharing/test_resources.py b/tests/api_resources/resource_sharing/test_resources.py
index ccb14582074..a07aeebdca1 100644
--- a/tests/api_resources/resource_sharing/test_resources.py
+++ b/tests/api_resources/resource_sharing/test_resources.py
@@ -11,8 +11,11 @@
from tests.utils import assert_matches_type
from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray
from cloudflare.types.resource_sharing import (
+ ResourceGetResponse,
ResourceListResponse,
ResourceCreateResponse,
+ ResourceDeleteResponse,
+ ResourceUpdateResponse,
)
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -89,6 +92,72 @@ def test_path_params_create(self, client: Cloudflare) -> None:
resource_type="custom-ruleset",
)
+ @parametrize
+ def test_method_update(self, client: Cloudflare) -> None:
+ resource = client.resource_sharing.resources.update(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ meta={},
+ )
+ assert_matches_type(Optional[ResourceUpdateResponse], resource, path=["response"])
+
+ @parametrize
+ def test_raw_response_update(self, client: Cloudflare) -> None:
+ response = client.resource_sharing.resources.with_raw_response.update(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ meta={},
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ resource = response.parse()
+ assert_matches_type(Optional[ResourceUpdateResponse], resource, path=["response"])
+
+ @parametrize
+ def test_streaming_response_update(self, client: Cloudflare) -> None:
+ with client.resource_sharing.resources.with_streaming_response.update(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ meta={},
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ resource = response.parse()
+ assert_matches_type(Optional[ResourceUpdateResponse], resource, 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.resource_sharing.resources.with_raw_response.update(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ meta={},
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `share_id` but received ''"):
+ client.resource_sharing.resources.with_raw_response.update(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="",
+ meta={},
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `share_resource_id` but received ''"):
+ client.resource_sharing.resources.with_raw_response.update(
+ share_resource_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ meta={},
+ )
+
@parametrize
def test_method_list(self, client: Cloudflare) -> None:
resource = client.resource_sharing.resources.list(
@@ -149,6 +218,126 @@ def test_path_params_list(self, client: Cloudflare) -> None:
account_id="023e105f4ecef8ad9ca31a8372d0c353",
)
+ @parametrize
+ def test_method_delete(self, client: Cloudflare) -> None:
+ resource = client.resource_sharing.resources.delete(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ )
+ assert_matches_type(Optional[ResourceDeleteResponse], resource, path=["response"])
+
+ @parametrize
+ def test_raw_response_delete(self, client: Cloudflare) -> None:
+ response = client.resource_sharing.resources.with_raw_response.delete(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ resource = response.parse()
+ assert_matches_type(Optional[ResourceDeleteResponse], resource, path=["response"])
+
+ @parametrize
+ def test_streaming_response_delete(self, client: Cloudflare) -> None:
+ with client.resource_sharing.resources.with_streaming_response.delete(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ resource = response.parse()
+ assert_matches_type(Optional[ResourceDeleteResponse], resource, 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.resource_sharing.resources.with_raw_response.delete(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `share_id` but received ''"):
+ client.resource_sharing.resources.with_raw_response.delete(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `share_resource_id` but received ''"):
+ client.resource_sharing.resources.with_raw_response.delete(
+ share_resource_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ )
+
+ @parametrize
+ def test_method_get(self, client: Cloudflare) -> None:
+ resource = client.resource_sharing.resources.get(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ )
+ assert_matches_type(Optional[ResourceGetResponse], resource, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Cloudflare) -> None:
+ response = client.resource_sharing.resources.with_raw_response.get(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ resource = response.parse()
+ assert_matches_type(Optional[ResourceGetResponse], resource, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Cloudflare) -> None:
+ with client.resource_sharing.resources.with_streaming_response.get(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ resource = response.parse()
+ assert_matches_type(Optional[ResourceGetResponse], resource, 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.resource_sharing.resources.with_raw_response.get(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `share_id` but received ''"):
+ client.resource_sharing.resources.with_raw_response.get(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `share_resource_id` but received ''"):
+ client.resource_sharing.resources.with_raw_response.get(
+ share_resource_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ )
+
class TestAsyncResources:
parametrize = pytest.mark.parametrize(
@@ -223,6 +412,72 @@ async def test_path_params_create(self, async_client: AsyncCloudflare) -> None:
resource_type="custom-ruleset",
)
+ @parametrize
+ async def test_method_update(self, async_client: AsyncCloudflare) -> None:
+ resource = await async_client.resource_sharing.resources.update(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ meta={},
+ )
+ assert_matches_type(Optional[ResourceUpdateResponse], resource, path=["response"])
+
+ @parametrize
+ async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.resource_sharing.resources.with_raw_response.update(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ meta={},
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ resource = await response.parse()
+ assert_matches_type(Optional[ResourceUpdateResponse], resource, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.resource_sharing.resources.with_streaming_response.update(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ meta={},
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ resource = await response.parse()
+ assert_matches_type(Optional[ResourceUpdateResponse], resource, 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.resource_sharing.resources.with_raw_response.update(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ meta={},
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `share_id` but received ''"):
+ await async_client.resource_sharing.resources.with_raw_response.update(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="",
+ meta={},
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `share_resource_id` but received ''"):
+ await async_client.resource_sharing.resources.with_raw_response.update(
+ share_resource_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ meta={},
+ )
+
@parametrize
async def test_method_list(self, async_client: AsyncCloudflare) -> None:
resource = await async_client.resource_sharing.resources.list(
@@ -282,3 +537,123 @@ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None:
share_id="",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
)
+
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncCloudflare) -> None:
+ resource = await async_client.resource_sharing.resources.delete(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ )
+ assert_matches_type(Optional[ResourceDeleteResponse], resource, path=["response"])
+
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.resource_sharing.resources.with_raw_response.delete(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ resource = await response.parse()
+ assert_matches_type(Optional[ResourceDeleteResponse], resource, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.resource_sharing.resources.with_streaming_response.delete(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ resource = await response.parse()
+ assert_matches_type(Optional[ResourceDeleteResponse], resource, 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.resource_sharing.resources.with_raw_response.delete(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `share_id` but received ''"):
+ await async_client.resource_sharing.resources.with_raw_response.delete(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `share_resource_id` but received ''"):
+ await async_client.resource_sharing.resources.with_raw_response.delete(
+ share_resource_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ )
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncCloudflare) -> None:
+ resource = await async_client.resource_sharing.resources.get(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ )
+ assert_matches_type(Optional[ResourceGetResponse], resource, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.resource_sharing.resources.with_raw_response.get(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ resource = await response.parse()
+ assert_matches_type(Optional[ResourceGetResponse], resource, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.resource_sharing.resources.with_streaming_response.get(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ resource = await response.parse()
+ assert_matches_type(Optional[ResourceGetResponse], resource, 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.resource_sharing.resources.with_raw_response.get(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `share_id` but received ''"):
+ await async_client.resource_sharing.resources.with_raw_response.get(
+ share_resource_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `share_resource_id` but received ''"):
+ await async_client.resource_sharing.resources.with_raw_response.get(
+ share_resource_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ share_id="3fd85f74b32742f1bff64a85009dda07",
+ )
diff --git a/tests/api_resources/test_ai_gateway.py b/tests/api_resources/test_ai_gateway.py
index 20338d953cc..33015cc2c13 100644
--- a/tests/api_resources/test_ai_gateway.py
+++ b/tests/api_resources/test_ai_gateway.py
@@ -189,6 +189,28 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None:
retry_backoff="constant",
retry_delay=0,
retry_max_attempts=1,
+ spend_limits={
+ "enabled": True,
+ "rules": [
+ {
+ "limit": 1,
+ "limit_type": "cost",
+ "window": 1,
+ "id": "x",
+ "enabled": True,
+ "metadata": {"foo": {"mode": "partition"}},
+ "model": {
+ "mode": "filter",
+ "values": ["string"],
+ },
+ "provider": {
+ "mode": "filter",
+ "values": ["string"],
+ },
+ "technique": "fixed",
+ }
+ ],
+ },
store_id="store_id",
stripe={
"authorization": "authorization",
@@ -574,6 +596,28 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare
retry_backoff="constant",
retry_delay=0,
retry_max_attempts=1,
+ spend_limits={
+ "enabled": True,
+ "rules": [
+ {
+ "limit": 1,
+ "limit_type": "cost",
+ "window": 1,
+ "id": "x",
+ "enabled": True,
+ "metadata": {"foo": {"mode": "partition"}},
+ "model": {
+ "mode": "filter",
+ "values": ["string"],
+ },
+ "provider": {
+ "mode": "filter",
+ "values": ["string"],
+ },
+ "technique": "fixed",
+ }
+ ],
+ },
store_id="store_id",
stripe={
"authorization": "authorization",
diff --git a/tests/api_resources/test_workflows.py b/tests/api_resources/test_workflows.py
index 50b603500c7..d8dc7b04888 100644
--- a/tests/api_resources/test_workflows.py
+++ b/tests/api_resources/test_workflows.py
@@ -41,6 +41,7 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None:
class_name="x",
script_name="x",
limits={"steps": 1},
+ schedules=[{"cron": "x"}],
)
assert_matches_type(WorkflowUpdateResponse, workflow, path=["response"])
@@ -260,6 +261,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare
class_name="x",
script_name="x",
limits={"steps": 1},
+ schedules=[{"cron": "x"}],
)
assert_matches_type(WorkflowUpdateResponse, workflow, path=["response"])
diff --git a/tests/api_resources/workflows/test_instances.py b/tests/api_resources/workflows/test_instances.py
index 5ffbec6aa23..b3f99e55b80 100644
--- a/tests/api_resources/workflows/test_instances.py
+++ b/tests/api_resources/workflows/test_instances.py
@@ -15,6 +15,7 @@
InstanceGetResponse,
InstanceBulkResponse,
InstanceListResponse,
+ InstanceStepResponse,
InstanceCreateResponse,
)
@@ -286,6 +287,90 @@ def test_path_params_get(self, client: Cloudflare) -> None:
workflow_name="x",
)
+ @parametrize
+ def test_method_step(self, client: Cloudflare) -> None:
+ instance = client.workflows.instances.step(
+ instance_id="x",
+ account_id="account_id",
+ workflow_name="x",
+ name="x",
+ type="step",
+ )
+ assert_matches_type(InstanceStepResponse, instance, path=["response"])
+
+ @parametrize
+ def test_method_step_with_all_params(self, client: Cloudflare) -> None:
+ instance = client.workflows.instances.step(
+ instance_id="x",
+ account_id="account_id",
+ workflow_name="x",
+ name="x",
+ type="step",
+ attempt=1,
+ )
+ assert_matches_type(InstanceStepResponse, instance, path=["response"])
+
+ @parametrize
+ def test_raw_response_step(self, client: Cloudflare) -> None:
+ response = client.workflows.instances.with_raw_response.step(
+ instance_id="x",
+ account_id="account_id",
+ workflow_name="x",
+ name="x",
+ type="step",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ instance = response.parse()
+ assert_matches_type(InstanceStepResponse, instance, path=["response"])
+
+ @parametrize
+ def test_streaming_response_step(self, client: Cloudflare) -> None:
+ with client.workflows.instances.with_streaming_response.step(
+ instance_id="x",
+ account_id="account_id",
+ workflow_name="x",
+ name="x",
+ type="step",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ instance = response.parse()
+ assert_matches_type(InstanceStepResponse, instance, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_step(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.workflows.instances.with_raw_response.step(
+ instance_id="x",
+ account_id="",
+ workflow_name="x",
+ name="x",
+ type="step",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `workflow_name` but received ''"):
+ client.workflows.instances.with_raw_response.step(
+ instance_id="x",
+ account_id="account_id",
+ workflow_name="",
+ name="x",
+ type="step",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `instance_id` but received ''"):
+ client.workflows.instances.with_raw_response.step(
+ instance_id="",
+ account_id="account_id",
+ workflow_name="x",
+ name="x",
+ type="step",
+ )
+
class TestAsyncInstances:
parametrize = pytest.mark.parametrize(
@@ -553,3 +638,87 @@ async def test_path_params_get(self, async_client: AsyncCloudflare) -> None:
account_id="account_id",
workflow_name="x",
)
+
+ @parametrize
+ async def test_method_step(self, async_client: AsyncCloudflare) -> None:
+ instance = await async_client.workflows.instances.step(
+ instance_id="x",
+ account_id="account_id",
+ workflow_name="x",
+ name="x",
+ type="step",
+ )
+ assert_matches_type(InstanceStepResponse, instance, path=["response"])
+
+ @parametrize
+ async def test_method_step_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ instance = await async_client.workflows.instances.step(
+ instance_id="x",
+ account_id="account_id",
+ workflow_name="x",
+ name="x",
+ type="step",
+ attempt=1,
+ )
+ assert_matches_type(InstanceStepResponse, instance, path=["response"])
+
+ @parametrize
+ async def test_raw_response_step(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.workflows.instances.with_raw_response.step(
+ instance_id="x",
+ account_id="account_id",
+ workflow_name="x",
+ name="x",
+ type="step",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ instance = await response.parse()
+ assert_matches_type(InstanceStepResponse, instance, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_step(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.workflows.instances.with_streaming_response.step(
+ instance_id="x",
+ account_id="account_id",
+ workflow_name="x",
+ name="x",
+ type="step",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ instance = await response.parse()
+ assert_matches_type(InstanceStepResponse, instance, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_step(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.workflows.instances.with_raw_response.step(
+ instance_id="x",
+ account_id="",
+ workflow_name="x",
+ name="x",
+ type="step",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `workflow_name` but received ''"):
+ await async_client.workflows.instances.with_raw_response.step(
+ instance_id="x",
+ account_id="account_id",
+ workflow_name="",
+ name="x",
+ type="step",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `instance_id` but received ''"):
+ await async_client.workflows.instances.with_raw_response.step(
+ instance_id="",
+ account_id="account_id",
+ workflow_name="x",
+ name="x",
+ type="step",
+ )
diff --git a/tests/api_resources/workflows/test_versions.py b/tests/api_resources/workflows/test_versions.py
index ecdc89ad65b..d1b3f39217a 100644
--- a/tests/api_resources/workflows/test_versions.py
+++ b/tests/api_resources/workflows/test_versions.py
@@ -10,7 +10,11 @@
from cloudflare import Cloudflare, AsyncCloudflare
from tests.utils import assert_matches_type
from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray
-from cloudflare.types.workflows import VersionGetResponse, VersionListResponse
+from cloudflare.types.workflows import (
+ VersionGetResponse,
+ VersionListResponse,
+ VersionGraphResponse,
+)
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -136,6 +140,66 @@ def test_path_params_get(self, client: Cloudflare) -> None:
workflow_name="x",
)
+ @parametrize
+ def test_method_graph(self, client: Cloudflare) -> None:
+ version = client.workflows.versions.graph(
+ version_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="account_id",
+ workflow_name="x",
+ )
+ assert_matches_type(VersionGraphResponse, version, path=["response"])
+
+ @parametrize
+ def test_raw_response_graph(self, client: Cloudflare) -> None:
+ response = client.workflows.versions.with_raw_response.graph(
+ version_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="account_id",
+ workflow_name="x",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ version = response.parse()
+ assert_matches_type(VersionGraphResponse, version, path=["response"])
+
+ @parametrize
+ def test_streaming_response_graph(self, client: Cloudflare) -> None:
+ with client.workflows.versions.with_streaming_response.graph(
+ version_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="account_id",
+ workflow_name="x",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ version = response.parse()
+ assert_matches_type(VersionGraphResponse, version, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_graph(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.workflows.versions.with_raw_response.graph(
+ version_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="",
+ workflow_name="x",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `workflow_name` but received ''"):
+ client.workflows.versions.with_raw_response.graph(
+ version_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="account_id",
+ workflow_name="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `version_id` but received ''"):
+ client.workflows.versions.with_raw_response.graph(
+ version_id="",
+ account_id="account_id",
+ workflow_name="x",
+ )
+
class TestAsyncVersions:
parametrize = pytest.mark.parametrize(
@@ -259,3 +323,63 @@ async def test_path_params_get(self, async_client: AsyncCloudflare) -> None:
account_id="account_id",
workflow_name="x",
)
+
+ @parametrize
+ async def test_method_graph(self, async_client: AsyncCloudflare) -> None:
+ version = await async_client.workflows.versions.graph(
+ version_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="account_id",
+ workflow_name="x",
+ )
+ assert_matches_type(VersionGraphResponse, version, path=["response"])
+
+ @parametrize
+ async def test_raw_response_graph(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.workflows.versions.with_raw_response.graph(
+ version_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="account_id",
+ workflow_name="x",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ version = await response.parse()
+ assert_matches_type(VersionGraphResponse, version, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_graph(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.workflows.versions.with_streaming_response.graph(
+ version_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="account_id",
+ workflow_name="x",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ version = await response.parse()
+ assert_matches_type(VersionGraphResponse, version, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_graph(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.workflows.versions.with_raw_response.graph(
+ version_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="",
+ workflow_name="x",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `workflow_name` but received ''"):
+ await async_client.workflows.versions.with_raw_response.graph(
+ version_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ account_id="account_id",
+ workflow_name="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `version_id` but received ''"):
+ await async_client.workflows.versions.with_raw_response.graph(
+ version_id="",
+ account_id="account_id",
+ workflow_name="x",
+ )
diff --git a/tests/api_resources/zero_trust/access/ai_controls/mcp/test_servers.py b/tests/api_resources/zero_trust/access/ai_controls/mcp/test_servers.py
index 730d3ecb17d..33145a04d0d 100644
--- a/tests/api_resources/zero_trust/access/ai_controls/mcp/test_servers.py
+++ b/tests/api_resources/zero_trust/access/ai_controls/mcp/test_servers.py
@@ -46,6 +46,7 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None:
name="My MCP Server",
auth_credentials="auth_credentials",
description="This is one remote mcp server",
+ is_shared_oauth_callback_enabled=True,
updated_prompts=[
{
"name": "name",
@@ -123,6 +124,7 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None:
account_id="a86a8f5c339544d7bdc89926de14fb8c",
auth_credentials="auth_credentials",
description="This is one remote mcp server",
+ is_shared_oauth_callback_enabled=True,
name="My MCP Server",
updated_prompts=[
{
@@ -402,6 +404,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare
name="My MCP Server",
auth_credentials="auth_credentials",
description="This is one remote mcp server",
+ is_shared_oauth_callback_enabled=True,
updated_prompts=[
{
"name": "name",
@@ -479,6 +482,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare
account_id="a86a8f5c339544d7bdc89926de14fb8c",
auth_credentials="auth_credentials",
description="This is one remote mcp server",
+ is_shared_oauth_callback_enabled=True,
name="My MCP Server",
updated_prompts=[
{
diff --git a/tests/api_resources/zero_trust/access/test_idp_federation_grants.py b/tests/api_resources/zero_trust/access/test_idp_federation_grants.py
new file mode 100644
index 00000000000..ab5896d9356
--- /dev/null
+++ b/tests/api_resources/zero_trust/access/test_idp_federation_grants.py
@@ -0,0 +1,380 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, Optional, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare.types.zero_trust.access import (
+ IdPFederationGrant,
+ IdPFederationGrantListResponse,
+ IdPFederationGrantDeleteResponse,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestIdPFederationGrants:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: Cloudflare) -> None:
+ idp_federation_grant = client.zero_trust.access.idp_federation_grants.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ idp_id="a79de439-0e7f-4ebb-8a02-222222222222",
+ )
+ assert_matches_type(Optional[IdPFederationGrant], idp_federation_grant, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Cloudflare) -> None:
+ response = client.zero_trust.access.idp_federation_grants.with_raw_response.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ idp_id="a79de439-0e7f-4ebb-8a02-222222222222",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ idp_federation_grant = response.parse()
+ assert_matches_type(Optional[IdPFederationGrant], idp_federation_grant, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: Cloudflare) -> None:
+ with client.zero_trust.access.idp_federation_grants.with_streaming_response.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ idp_id="a79de439-0e7f-4ebb-8a02-222222222222",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ idp_federation_grant = response.parse()
+ assert_matches_type(Optional[IdPFederationGrant], idp_federation_grant, 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.idp_federation_grants.with_raw_response.create(
+ account_id="",
+ idp_id="a79de439-0e7f-4ebb-8a02-222222222222",
+ )
+
+ @parametrize
+ def test_method_list(self, client: Cloudflare) -> None:
+ idp_federation_grant = client.zero_trust.access.idp_federation_grants.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[IdPFederationGrantListResponse], idp_federation_grant, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Cloudflare) -> None:
+ response = client.zero_trust.access.idp_federation_grants.with_raw_response.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ idp_federation_grant = response.parse()
+ assert_matches_type(Optional[IdPFederationGrantListResponse], idp_federation_grant, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Cloudflare) -> None:
+ with client.zero_trust.access.idp_federation_grants.with_streaming_response.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ idp_federation_grant = response.parse()
+ assert_matches_type(Optional[IdPFederationGrantListResponse], idp_federation_grant, 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.idp_federation_grants.with_raw_response.list(
+ account_id="",
+ )
+
+ @parametrize
+ def test_method_delete(self, client: Cloudflare) -> None:
+ idp_federation_grant = client.zero_trust.access.idp_federation_grants.delete(
+ grant_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[IdPFederationGrantDeleteResponse], idp_federation_grant, path=["response"])
+
+ @parametrize
+ def test_raw_response_delete(self, client: Cloudflare) -> None:
+ response = client.zero_trust.access.idp_federation_grants.with_raw_response.delete(
+ grant_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ idp_federation_grant = response.parse()
+ assert_matches_type(Optional[IdPFederationGrantDeleteResponse], idp_federation_grant, path=["response"])
+
+ @parametrize
+ def test_streaming_response_delete(self, client: Cloudflare) -> None:
+ with client.zero_trust.access.idp_federation_grants.with_streaming_response.delete(
+ grant_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ idp_federation_grant = response.parse()
+ assert_matches_type(Optional[IdPFederationGrantDeleteResponse], idp_federation_grant, 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.idp_federation_grants.with_raw_response.delete(
+ grant_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `grant_id` but received ''"):
+ client.zero_trust.access.idp_federation_grants.with_raw_response.delete(
+ grant_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ @parametrize
+ def test_method_get(self, client: Cloudflare) -> None:
+ idp_federation_grant = client.zero_trust.access.idp_federation_grants.get(
+ grant_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[IdPFederationGrant], idp_federation_grant, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Cloudflare) -> None:
+ response = client.zero_trust.access.idp_federation_grants.with_raw_response.get(
+ grant_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ idp_federation_grant = response.parse()
+ assert_matches_type(Optional[IdPFederationGrant], idp_federation_grant, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Cloudflare) -> None:
+ with client.zero_trust.access.idp_federation_grants.with_streaming_response.get(
+ grant_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ idp_federation_grant = response.parse()
+ assert_matches_type(Optional[IdPFederationGrant], idp_federation_grant, 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.idp_federation_grants.with_raw_response.get(
+ grant_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `grant_id` but received ''"):
+ client.zero_trust.access.idp_federation_grants.with_raw_response.get(
+ grant_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+
+class TestAsyncIdPFederationGrants:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_create(self, async_client: AsyncCloudflare) -> None:
+ idp_federation_grant = await async_client.zero_trust.access.idp_federation_grants.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ idp_id="a79de439-0e7f-4ebb-8a02-222222222222",
+ )
+ assert_matches_type(Optional[IdPFederationGrant], idp_federation_grant, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.access.idp_federation_grants.with_raw_response.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ idp_id="a79de439-0e7f-4ebb-8a02-222222222222",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ idp_federation_grant = await response.parse()
+ assert_matches_type(Optional[IdPFederationGrant], idp_federation_grant, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.access.idp_federation_grants.with_streaming_response.create(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ idp_id="a79de439-0e7f-4ebb-8a02-222222222222",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ idp_federation_grant = await response.parse()
+ assert_matches_type(Optional[IdPFederationGrant], idp_federation_grant, 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.idp_federation_grants.with_raw_response.create(
+ account_id="",
+ idp_id="a79de439-0e7f-4ebb-8a02-222222222222",
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncCloudflare) -> None:
+ idp_federation_grant = await async_client.zero_trust.access.idp_federation_grants.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[IdPFederationGrantListResponse], idp_federation_grant, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.access.idp_federation_grants.with_raw_response.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ idp_federation_grant = await response.parse()
+ assert_matches_type(Optional[IdPFederationGrantListResponse], idp_federation_grant, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.access.idp_federation_grants.with_streaming_response.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ idp_federation_grant = await response.parse()
+ assert_matches_type(Optional[IdPFederationGrantListResponse], idp_federation_grant, 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.idp_federation_grants.with_raw_response.list(
+ account_id="",
+ )
+
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncCloudflare) -> None:
+ idp_federation_grant = await async_client.zero_trust.access.idp_federation_grants.delete(
+ grant_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[IdPFederationGrantDeleteResponse], idp_federation_grant, path=["response"])
+
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.access.idp_federation_grants.with_raw_response.delete(
+ grant_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ idp_federation_grant = await response.parse()
+ assert_matches_type(Optional[IdPFederationGrantDeleteResponse], idp_federation_grant, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.access.idp_federation_grants.with_streaming_response.delete(
+ grant_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ idp_federation_grant = await response.parse()
+ assert_matches_type(Optional[IdPFederationGrantDeleteResponse], idp_federation_grant, 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.idp_federation_grants.with_raw_response.delete(
+ grant_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `grant_id` but received ''"):
+ await async_client.zero_trust.access.idp_federation_grants.with_raw_response.delete(
+ grant_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncCloudflare) -> None:
+ idp_federation_grant = await async_client.zero_trust.access.idp_federation_grants.get(
+ grant_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[IdPFederationGrant], idp_federation_grant, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.access.idp_federation_grants.with_raw_response.get(
+ grant_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ idp_federation_grant = await response.parse()
+ assert_matches_type(Optional[IdPFederationGrant], idp_federation_grant, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.access.idp_federation_grants.with_streaming_response.get(
+ grant_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ idp_federation_grant = await response.parse()
+ assert_matches_type(Optional[IdPFederationGrant], idp_federation_grant, 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.idp_federation_grants.with_raw_response.get(
+ grant_id="023e105f4ecef8ad9ca31a8372d0c353",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `grant_id` but received ''"):
+ await async_client.zero_trust.access.idp_federation_grants.with_raw_response.get(
+ grant_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
diff --git a/tests/api_resources/zero_trust/dex/devices/__init__.py b/tests/api_resources/zero_trust/dex/devices/__init__.py
new file mode 100644
index 00000000000..fd8019a9a1a
--- /dev/null
+++ b/tests/api_resources/zero_trust/dex/devices/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/zero_trust/dex/devices/test_isps.py b/tests/api_resources/zero_trust/dex/devices/test_isps.py
new file mode 100644
index 00000000000..85455da30ec
--- /dev/null
+++ b/tests/api_resources/zero_trust/dex/devices/test_isps.py
@@ -0,0 +1,162 @@
+# 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._utils import parse_datetime
+from cloudflare.pagination import SyncV4PagePagination, AsyncV4PagePagination
+from cloudflare.types.zero_trust.dex.devices import ISPs
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestISPs:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_list(self, client: Cloudflare) -> None:
+ isp = client.zero_trust.dex.devices.isps.list(
+ device_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="01a7362d577a6c3019a474fd6f485823",
+ per_page=1,
+ )
+ assert_matches_type(SyncV4PagePagination[Optional[ISPs]], isp, path=["response"])
+
+ @parametrize
+ def test_method_list_with_all_params(self, client: Cloudflare) -> None:
+ isp = client.zero_trust.dex.devices.isps.list(
+ device_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="01a7362d577a6c3019a474fd6f485823",
+ per_page=1,
+ cursor="cursor",
+ from_=parse_datetime("2019-12-27T18:11:19.117Z"),
+ page=1,
+ sort_by="time_start",
+ sort_order="ASC",
+ to=parse_datetime("2019-12-27T18:11:19.117Z"),
+ )
+ assert_matches_type(SyncV4PagePagination[Optional[ISPs]], isp, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Cloudflare) -> None:
+ response = client.zero_trust.dex.devices.isps.with_raw_response.list(
+ device_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="01a7362d577a6c3019a474fd6f485823",
+ per_page=1,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ isp = response.parse()
+ assert_matches_type(SyncV4PagePagination[Optional[ISPs]], isp, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Cloudflare) -> None:
+ with client.zero_trust.dex.devices.isps.with_streaming_response.list(
+ device_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="01a7362d577a6c3019a474fd6f485823",
+ per_page=1,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ isp = response.parse()
+ assert_matches_type(SyncV4PagePagination[Optional[ISPs]], isp, 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.dex.devices.isps.with_raw_response.list(
+ device_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="",
+ per_page=1,
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `device_id` but received ''"):
+ client.zero_trust.dex.devices.isps.with_raw_response.list(
+ device_id="",
+ account_id="01a7362d577a6c3019a474fd6f485823",
+ per_page=1,
+ )
+
+
+class TestAsyncISPs:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_list(self, async_client: AsyncCloudflare) -> None:
+ isp = await async_client.zero_trust.dex.devices.isps.list(
+ device_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="01a7362d577a6c3019a474fd6f485823",
+ per_page=1,
+ )
+ assert_matches_type(AsyncV4PagePagination[Optional[ISPs]], isp, path=["response"])
+
+ @parametrize
+ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ isp = await async_client.zero_trust.dex.devices.isps.list(
+ device_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="01a7362d577a6c3019a474fd6f485823",
+ per_page=1,
+ cursor="cursor",
+ from_=parse_datetime("2019-12-27T18:11:19.117Z"),
+ page=1,
+ sort_by="time_start",
+ sort_order="ASC",
+ to=parse_datetime("2019-12-27T18:11:19.117Z"),
+ )
+ assert_matches_type(AsyncV4PagePagination[Optional[ISPs]], isp, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.dex.devices.isps.with_raw_response.list(
+ device_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="01a7362d577a6c3019a474fd6f485823",
+ per_page=1,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ isp = await response.parse()
+ assert_matches_type(AsyncV4PagePagination[Optional[ISPs]], isp, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.dex.devices.isps.with_streaming_response.list(
+ device_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="01a7362d577a6c3019a474fd6f485823",
+ per_page=1,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ isp = await response.parse()
+ assert_matches_type(AsyncV4PagePagination[Optional[ISPs]], isp, 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.dex.devices.isps.with_raw_response.list(
+ device_id="f174e90a-fafe-4643-bbbc-4a0ed4fc8415",
+ account_id="",
+ per_page=1,
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `device_id` but received ''"):
+ await async_client.zero_trust.dex.devices.isps.with_raw_response.list(
+ device_id="",
+ account_id="01a7362d577a6c3019a474fd6f485823",
+ per_page=1,
+ )