diff --git a/.stats.yml b/.stats.yml
index 1ed9537b832..85278f61745 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 2204
+configured_endpoints: 2224
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare%2Fcloudflare-a6c352830d1270d0abb5bb983058ea21815e1bb7d2e163965335dcb0e706f057.yml
-openapi_spec_hash: e722ad1f58e3dfb3a928cf9890d48da4
-config_hash: ff549978909de2badc92845fea964f4b
+openapi_spec_hash: 5f7d8a96b953cef8677dacffc249761d
+config_hash: f6fa3a155508fae2904b264233641e02
diff --git a/src/cloudflare/resources/ai_gateway/__init__.py b/src/cloudflare/resources/ai_gateway/__init__.py
index d149a1d44cb..1e953d202f6 100644
--- a/src/cloudflare/resources/ai_gateway/__init__.py
+++ b/src/cloudflare/resources/ai_gateway/__init__.py
@@ -16,6 +16,14 @@
URLsResourceWithStreamingResponse,
AsyncURLsResourceWithStreamingResponse,
)
+from .billing import (
+ BillingResource,
+ AsyncBillingResource,
+ BillingResourceWithRawResponse,
+ AsyncBillingResourceWithRawResponse,
+ BillingResourceWithStreamingResponse,
+ AsyncBillingResourceWithStreamingResponse,
+)
from .datasets import (
DatasetsResource,
AsyncDatasetsResource,
@@ -108,6 +116,12 @@
"AsyncURLsResourceWithRawResponse",
"URLsResourceWithStreamingResponse",
"AsyncURLsResourceWithStreamingResponse",
+ "BillingResource",
+ "AsyncBillingResource",
+ "BillingResourceWithRawResponse",
+ "AsyncBillingResourceWithRawResponse",
+ "BillingResourceWithStreamingResponse",
+ "AsyncBillingResourceWithStreamingResponse",
"AIGatewayResource",
"AsyncAIGatewayResource",
"AIGatewayResourceWithRawResponse",
diff --git a/src/cloudflare/resources/ai_gateway/ai_gateway.py b/src/cloudflare/resources/ai_gateway/ai_gateway.py
index 0e953643619..7144e47a40d 100644
--- a/src/cloudflare/resources/ai_gateway/ai_gateway.py
+++ b/src/cloudflare/resources/ai_gateway/ai_gateway.py
@@ -52,6 +52,14 @@
)
from ...pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray
from ..._base_client import AsyncPaginator, make_request_options
+from .billing.billing import (
+ BillingResource,
+ AsyncBillingResource,
+ BillingResourceWithRawResponse,
+ AsyncBillingResourceWithRawResponse,
+ BillingResourceWithStreamingResponse,
+ AsyncBillingResourceWithStreamingResponse,
+)
from .dynamic_routing import (
DynamicRoutingResource,
AsyncDynamicRoutingResource,
@@ -115,6 +123,10 @@ def provider_configs(self) -> ProviderConfigsResource:
def urls(self) -> URLsResource:
return URLsResource(self._client)
+ @cached_property
+ def billing(self) -> BillingResource:
+ return BillingResource(self._client)
+
@cached_property
def with_raw_response(self) -> AIGatewayResourceWithRawResponse:
"""
@@ -481,6 +493,10 @@ def provider_configs(self) -> AsyncProviderConfigsResource:
def urls(self) -> AsyncURLsResource:
return AsyncURLsResource(self._client)
+ @cached_property
+ def billing(self) -> AsyncBillingResource:
+ return AsyncBillingResource(self._client)
+
@cached_property
def with_raw_response(self) -> AsyncAIGatewayResourceWithRawResponse:
"""
@@ -866,6 +882,10 @@ def provider_configs(self) -> ProviderConfigsResourceWithRawResponse:
def urls(self) -> URLsResourceWithRawResponse:
return URLsResourceWithRawResponse(self._ai_gateway.urls)
+ @cached_property
+ def billing(self) -> BillingResourceWithRawResponse:
+ return BillingResourceWithRawResponse(self._ai_gateway.billing)
+
class AsyncAIGatewayResourceWithRawResponse:
def __init__(self, ai_gateway: AsyncAIGatewayResource) -> None:
@@ -915,6 +935,10 @@ def provider_configs(self) -> AsyncProviderConfigsResourceWithRawResponse:
def urls(self) -> AsyncURLsResourceWithRawResponse:
return AsyncURLsResourceWithRawResponse(self._ai_gateway.urls)
+ @cached_property
+ def billing(self) -> AsyncBillingResourceWithRawResponse:
+ return AsyncBillingResourceWithRawResponse(self._ai_gateway.billing)
+
class AIGatewayResourceWithStreamingResponse:
def __init__(self, ai_gateway: AIGatewayResource) -> None:
@@ -964,6 +988,10 @@ def provider_configs(self) -> ProviderConfigsResourceWithStreamingResponse:
def urls(self) -> URLsResourceWithStreamingResponse:
return URLsResourceWithStreamingResponse(self._ai_gateway.urls)
+ @cached_property
+ def billing(self) -> BillingResourceWithStreamingResponse:
+ return BillingResourceWithStreamingResponse(self._ai_gateway.billing)
+
class AsyncAIGatewayResourceWithStreamingResponse:
def __init__(self, ai_gateway: AsyncAIGatewayResource) -> None:
@@ -1012,3 +1040,7 @@ def provider_configs(self) -> AsyncProviderConfigsResourceWithStreamingResponse:
@cached_property
def urls(self) -> AsyncURLsResourceWithStreamingResponse:
return AsyncURLsResourceWithStreamingResponse(self._ai_gateway.urls)
+
+ @cached_property
+ def billing(self) -> AsyncBillingResourceWithStreamingResponse:
+ return AsyncBillingResourceWithStreamingResponse(self._ai_gateway.billing)
diff --git a/src/cloudflare/resources/ai_gateway/api.md b/src/cloudflare/resources/ai_gateway/api.md
index 7202ceae450..0c50249f0c5 100644
--- a/src/cloudflare/resources/ai_gateway/api.md
+++ b/src/cloudflare/resources/ai_gateway/api.md
@@ -147,3 +147,64 @@ from cloudflare.types.ai_gateway import URLGetResponse
Methods:
- client.ai_gateway.urls.get(provider, \*, account_id, gateway_id) -> str
+
+## Billing
+
+Types:
+
+```python
+from cloudflare.types.ai_gateway import (
+ BillingCreditBalanceResponse,
+ BillingInvoiceHistoryResponse,
+ BillingInvoicePreviewResponse,
+ BillingUsageHistoryResponse,
+)
+```
+
+Methods:
+
+- client.ai_gateway.billing.credit_balance(\*, account_id) -> BillingCreditBalanceResponse
+- client.ai_gateway.billing.invoice_history(\*, account_id, \*\*params) -> BillingInvoiceHistoryResponse
+- client.ai_gateway.billing.invoice_preview(\*, account_id) -> BillingInvoicePreviewResponse
+- client.ai_gateway.billing.usage_history(\*, account_id, \*\*params) -> BillingUsageHistoryResponse
+
+### Topup
+
+Types:
+
+```python
+from cloudflare.types.ai_gateway.billing import TopupCreateResponse, TopupStatusResponse
+```
+
+Methods:
+
+- client.ai_gateway.billing.topup.create(\*, account_id, \*\*params) -> TopupCreateResponse
+- client.ai_gateway.billing.topup.status(\*, account_id, \*\*params) -> TopupStatusResponse
+
+#### Config
+
+Types:
+
+```python
+from cloudflare.types.ai_gateway.billing.topup import ConfigCreateResponse, ConfigGetResponse
+```
+
+Methods:
+
+- client.ai_gateway.billing.topup.config.create(\*, account_id, \*\*params) -> ConfigCreateResponse
+- client.ai_gateway.billing.topup.config.delete(\*, account_id) -> object
+- client.ai_gateway.billing.topup.config.get(\*, account_id) -> ConfigGetResponse
+
+### SpendingLimit
+
+Types:
+
+```python
+from cloudflare.types.ai_gateway.billing import SpendingLimitGetResponse
+```
+
+Methods:
+
+- client.ai_gateway.billing.spending_limit.create(\*, account_id, \*\*params) -> object
+- client.ai_gateway.billing.spending_limit.delete(\*, account_id) -> object
+- client.ai_gateway.billing.spending_limit.get(\*, account_id) -> SpendingLimitGetResponse
diff --git a/src/cloudflare/resources/ai_gateway/billing/__init__.py b/src/cloudflare/resources/ai_gateway/billing/__init__.py
new file mode 100644
index 00000000000..87c8c52888b
--- /dev/null
+++ b/src/cloudflare/resources/ai_gateway/billing/__init__.py
@@ -0,0 +1,47 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .topup import (
+ TopupResource,
+ AsyncTopupResource,
+ TopupResourceWithRawResponse,
+ AsyncTopupResourceWithRawResponse,
+ TopupResourceWithStreamingResponse,
+ AsyncTopupResourceWithStreamingResponse,
+)
+from .billing import (
+ BillingResource,
+ AsyncBillingResource,
+ BillingResourceWithRawResponse,
+ AsyncBillingResourceWithRawResponse,
+ BillingResourceWithStreamingResponse,
+ AsyncBillingResourceWithStreamingResponse,
+)
+from .spending_limit import (
+ SpendingLimitResource,
+ AsyncSpendingLimitResource,
+ SpendingLimitResourceWithRawResponse,
+ AsyncSpendingLimitResourceWithRawResponse,
+ SpendingLimitResourceWithStreamingResponse,
+ AsyncSpendingLimitResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "TopupResource",
+ "AsyncTopupResource",
+ "TopupResourceWithRawResponse",
+ "AsyncTopupResourceWithRawResponse",
+ "TopupResourceWithStreamingResponse",
+ "AsyncTopupResourceWithStreamingResponse",
+ "SpendingLimitResource",
+ "AsyncSpendingLimitResource",
+ "SpendingLimitResourceWithRawResponse",
+ "AsyncSpendingLimitResourceWithRawResponse",
+ "SpendingLimitResourceWithStreamingResponse",
+ "AsyncSpendingLimitResourceWithStreamingResponse",
+ "BillingResource",
+ "AsyncBillingResource",
+ "BillingResourceWithRawResponse",
+ "AsyncBillingResourceWithRawResponse",
+ "BillingResourceWithStreamingResponse",
+ "AsyncBillingResourceWithStreamingResponse",
+]
diff --git a/src/cloudflare/resources/ai_gateway/billing/billing.py b/src/cloudflare/resources/ai_gateway/billing/billing.py
new file mode 100644
index 00000000000..4229618032c
--- /dev/null
+++ b/src/cloudflare/resources/ai_gateway/billing/billing.py
@@ -0,0 +1,548 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Type, Optional, cast
+from typing_extensions import Literal
+
+import httpx
+
+from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ...._utils import path_template, maybe_transform, async_maybe_transform
+from ...._compat import cached_property
+from .topup.topup import (
+ TopupResource,
+ AsyncTopupResource,
+ TopupResourceWithRawResponse,
+ AsyncTopupResourceWithRawResponse,
+ TopupResourceWithStreamingResponse,
+ AsyncTopupResourceWithStreamingResponse,
+)
+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 .spending_limit import (
+ SpendingLimitResource,
+ AsyncSpendingLimitResource,
+ SpendingLimitResourceWithRawResponse,
+ AsyncSpendingLimitResourceWithRawResponse,
+ SpendingLimitResourceWithStreamingResponse,
+ AsyncSpendingLimitResourceWithStreamingResponse,
+)
+from ...._base_client import make_request_options
+from ....types.ai_gateway import billing_usage_history_params, billing_invoice_history_params
+from ....types.ai_gateway.billing_usage_history_response import BillingUsageHistoryResponse
+from ....types.ai_gateway.billing_credit_balance_response import BillingCreditBalanceResponse
+from ....types.ai_gateway.billing_invoice_history_response import BillingInvoiceHistoryResponse
+from ....types.ai_gateway.billing_invoice_preview_response import BillingInvoicePreviewResponse
+
+__all__ = ["BillingResource", "AsyncBillingResource"]
+
+
+class BillingResource(SyncAPIResource):
+ @cached_property
+ def topup(self) -> TopupResource:
+ return TopupResource(self._client)
+
+ @cached_property
+ def spending_limit(self) -> SpendingLimitResource:
+ return SpendingLimitResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> BillingResourceWithRawResponse:
+ """
+ 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 BillingResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> BillingResourceWithStreamingResponse:
+ """
+ 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 BillingResourceWithStreamingResponse(self)
+
+ def credit_balance(
+ 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,
+ ) -> BillingCreditBalanceResponse:
+ """
+ Retrieve the current credit balance, payment method info, and top-up
+ configuration.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._get(
+ path_template("/accounts/{account_id}/ai-gateway/billing/credit-balance", 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[BillingCreditBalanceResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[BillingCreditBalanceResponse], ResultWrapper[BillingCreditBalanceResponse]),
+ )
+
+ def invoice_history(
+ self,
+ *,
+ account_id: str,
+ type: Literal["auto", "all", "manual"] | 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,
+ ) -> BillingInvoiceHistoryResponse:
+ """
+ Retrieve a list of past invoices with pagination, optionally filtered by type.
+
+ Args:
+ type: Filter invoice type: auto, manual, or all.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the 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}/ai-gateway/billing/invoice-history", account_id=account_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform({"type": type}, billing_invoice_history_params.BillingInvoiceHistoryParams),
+ post_parser=ResultWrapper[BillingInvoiceHistoryResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[BillingInvoiceHistoryResponse], ResultWrapper[BillingInvoiceHistoryResponse]),
+ )
+
+ def invoice_preview(
+ 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,
+ ) -> BillingInvoicePreviewResponse:
+ """
+ Retrieve a preview of the upcoming invoice including line items and tax.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._get(
+ path_template("/accounts/{account_id}/ai-gateway/billing/invoice-preview", 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[BillingInvoicePreviewResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[BillingInvoicePreviewResponse], ResultWrapper[BillingInvoicePreviewResponse]),
+ )
+
+ def usage_history(
+ self,
+ *,
+ account_id: str,
+ value_grouping_window: Literal["day", "hour"],
+ end_time: Optional[float] | Omit = omit,
+ start_time: Optional[float] | 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,
+ ) -> BillingUsageHistoryResponse:
+ """
+ Retrieve aggregated usage meter event summaries for the given time range.
+
+ Args:
+ value_grouping_window: Grouping window for usage data.
+
+ end_time: End time as Unix timestamp in milliseconds.
+
+ start_time: Start time as Unix timestamp in milliseconds.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the 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}/ai-gateway/billing/usage-history", account_id=account_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "value_grouping_window": value_grouping_window,
+ "end_time": end_time,
+ "start_time": start_time,
+ },
+ billing_usage_history_params.BillingUsageHistoryParams,
+ ),
+ post_parser=ResultWrapper[BillingUsageHistoryResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[BillingUsageHistoryResponse], ResultWrapper[BillingUsageHistoryResponse]),
+ )
+
+
+class AsyncBillingResource(AsyncAPIResource):
+ @cached_property
+ def topup(self) -> AsyncTopupResource:
+ return AsyncTopupResource(self._client)
+
+ @cached_property
+ def spending_limit(self) -> AsyncSpendingLimitResource:
+ return AsyncSpendingLimitResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncBillingResourceWithRawResponse:
+ """
+ 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 AsyncBillingResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncBillingResourceWithStreamingResponse:
+ """
+ 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 AsyncBillingResourceWithStreamingResponse(self)
+
+ async def credit_balance(
+ 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,
+ ) -> BillingCreditBalanceResponse:
+ """
+ Retrieve the current credit balance, payment method info, and top-up
+ configuration.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return await self._get(
+ path_template("/accounts/{account_id}/ai-gateway/billing/credit-balance", 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[BillingCreditBalanceResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[BillingCreditBalanceResponse], ResultWrapper[BillingCreditBalanceResponse]),
+ )
+
+ async def invoice_history(
+ self,
+ *,
+ account_id: str,
+ type: Literal["auto", "all", "manual"] | 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,
+ ) -> BillingInvoiceHistoryResponse:
+ """
+ Retrieve a list of past invoices with pagination, optionally filtered by type.
+
+ Args:
+ type: Filter invoice type: auto, manual, or all.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the 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}/ai-gateway/billing/invoice-history", account_id=account_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {"type": type}, billing_invoice_history_params.BillingInvoiceHistoryParams
+ ),
+ post_parser=ResultWrapper[BillingInvoiceHistoryResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[BillingInvoiceHistoryResponse], ResultWrapper[BillingInvoiceHistoryResponse]),
+ )
+
+ async def invoice_preview(
+ 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,
+ ) -> BillingInvoicePreviewResponse:
+ """
+ Retrieve a preview of the upcoming invoice including line items and tax.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return await self._get(
+ path_template("/accounts/{account_id}/ai-gateway/billing/invoice-preview", 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[BillingInvoicePreviewResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[BillingInvoicePreviewResponse], ResultWrapper[BillingInvoicePreviewResponse]),
+ )
+
+ async def usage_history(
+ self,
+ *,
+ account_id: str,
+ value_grouping_window: Literal["day", "hour"],
+ end_time: Optional[float] | Omit = omit,
+ start_time: Optional[float] | 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,
+ ) -> BillingUsageHistoryResponse:
+ """
+ Retrieve aggregated usage meter event summaries for the given time range.
+
+ Args:
+ value_grouping_window: Grouping window for usage data.
+
+ end_time: End time as Unix timestamp in milliseconds.
+
+ start_time: Start time as Unix timestamp in milliseconds.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the 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}/ai-gateway/billing/usage-history", account_id=account_id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "value_grouping_window": value_grouping_window,
+ "end_time": end_time,
+ "start_time": start_time,
+ },
+ billing_usage_history_params.BillingUsageHistoryParams,
+ ),
+ post_parser=ResultWrapper[BillingUsageHistoryResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[BillingUsageHistoryResponse], ResultWrapper[BillingUsageHistoryResponse]),
+ )
+
+
+class BillingResourceWithRawResponse:
+ def __init__(self, billing: BillingResource) -> None:
+ self._billing = billing
+
+ self.credit_balance = to_raw_response_wrapper(
+ billing.credit_balance,
+ )
+ self.invoice_history = to_raw_response_wrapper(
+ billing.invoice_history,
+ )
+ self.invoice_preview = to_raw_response_wrapper(
+ billing.invoice_preview,
+ )
+ self.usage_history = to_raw_response_wrapper(
+ billing.usage_history,
+ )
+
+ @cached_property
+ def topup(self) -> TopupResourceWithRawResponse:
+ return TopupResourceWithRawResponse(self._billing.topup)
+
+ @cached_property
+ def spending_limit(self) -> SpendingLimitResourceWithRawResponse:
+ return SpendingLimitResourceWithRawResponse(self._billing.spending_limit)
+
+
+class AsyncBillingResourceWithRawResponse:
+ def __init__(self, billing: AsyncBillingResource) -> None:
+ self._billing = billing
+
+ self.credit_balance = async_to_raw_response_wrapper(
+ billing.credit_balance,
+ )
+ self.invoice_history = async_to_raw_response_wrapper(
+ billing.invoice_history,
+ )
+ self.invoice_preview = async_to_raw_response_wrapper(
+ billing.invoice_preview,
+ )
+ self.usage_history = async_to_raw_response_wrapper(
+ billing.usage_history,
+ )
+
+ @cached_property
+ def topup(self) -> AsyncTopupResourceWithRawResponse:
+ return AsyncTopupResourceWithRawResponse(self._billing.topup)
+
+ @cached_property
+ def spending_limit(self) -> AsyncSpendingLimitResourceWithRawResponse:
+ return AsyncSpendingLimitResourceWithRawResponse(self._billing.spending_limit)
+
+
+class BillingResourceWithStreamingResponse:
+ def __init__(self, billing: BillingResource) -> None:
+ self._billing = billing
+
+ self.credit_balance = to_streamed_response_wrapper(
+ billing.credit_balance,
+ )
+ self.invoice_history = to_streamed_response_wrapper(
+ billing.invoice_history,
+ )
+ self.invoice_preview = to_streamed_response_wrapper(
+ billing.invoice_preview,
+ )
+ self.usage_history = to_streamed_response_wrapper(
+ billing.usage_history,
+ )
+
+ @cached_property
+ def topup(self) -> TopupResourceWithStreamingResponse:
+ return TopupResourceWithStreamingResponse(self._billing.topup)
+
+ @cached_property
+ def spending_limit(self) -> SpendingLimitResourceWithStreamingResponse:
+ return SpendingLimitResourceWithStreamingResponse(self._billing.spending_limit)
+
+
+class AsyncBillingResourceWithStreamingResponse:
+ def __init__(self, billing: AsyncBillingResource) -> None:
+ self._billing = billing
+
+ self.credit_balance = async_to_streamed_response_wrapper(
+ billing.credit_balance,
+ )
+ self.invoice_history = async_to_streamed_response_wrapper(
+ billing.invoice_history,
+ )
+ self.invoice_preview = async_to_streamed_response_wrapper(
+ billing.invoice_preview,
+ )
+ self.usage_history = async_to_streamed_response_wrapper(
+ billing.usage_history,
+ )
+
+ @cached_property
+ def topup(self) -> AsyncTopupResourceWithStreamingResponse:
+ return AsyncTopupResourceWithStreamingResponse(self._billing.topup)
+
+ @cached_property
+ def spending_limit(self) -> AsyncSpendingLimitResourceWithStreamingResponse:
+ return AsyncSpendingLimitResourceWithStreamingResponse(self._billing.spending_limit)
diff --git a/src/cloudflare/resources/ai_gateway/billing/spending_limit.py b/src/cloudflare/resources/ai_gateway/billing/spending_limit.py
new file mode 100644
index 00000000000..8235d6ccb1c
--- /dev/null
+++ b/src/cloudflare/resources/ai_gateway/billing/spending_limit.py
@@ -0,0 +1,383 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Type, cast
+from typing_extensions import Literal
+
+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.ai_gateway.billing import spending_limit_create_params
+from ....types.ai_gateway.billing.spending_limit_get_response import SpendingLimitGetResponse
+
+__all__ = ["SpendingLimitResource", "AsyncSpendingLimitResource"]
+
+
+class SpendingLimitResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> SpendingLimitResourceWithRawResponse:
+ """
+ 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 SpendingLimitResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> SpendingLimitResourceWithStreamingResponse:
+ """
+ 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 SpendingLimitResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ *,
+ account_id: str,
+ amount: int,
+ duration: Literal["daily", "weekly", "monthly"],
+ strategy: Literal["fixed", "sliding"],
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> object:
+ """
+ Configure a spending limit with amount, strategy, and duration.
+
+ Args:
+ amount: Spending limit amount in cents (min 100).
+
+ duration: Spending limit duration.
+
+ strategy: Spending limit strategy.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._post(
+ path_template("/accounts/{account_id}/ai-gateway/billing/spending-limit", account_id=account_id),
+ body=maybe_transform(
+ {
+ "amount": amount,
+ "duration": duration,
+ "strategy": strategy,
+ },
+ spending_limit_create_params.SpendingLimitCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[object]._unwrapper,
+ ),
+ cast_to=cast(Type[object], ResultWrapper[object]),
+ )
+
+ def delete(
+ 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,
+ ) -> object:
+ """
+ Remove the spending limit for the account.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._delete(
+ path_template("/accounts/{account_id}/ai-gateway/billing/spending-limit", 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[object]._unwrapper,
+ ),
+ cast_to=cast(Type[object], ResultWrapper[object]),
+ )
+
+ 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,
+ ) -> SpendingLimitGetResponse:
+ """
+ Retrieve the current spending limit configuration for the account.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._get(
+ path_template("/accounts/{account_id}/ai-gateway/billing/spending-limit", 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[SpendingLimitGetResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[SpendingLimitGetResponse], ResultWrapper[SpendingLimitGetResponse]),
+ )
+
+
+class AsyncSpendingLimitResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncSpendingLimitResourceWithRawResponse:
+ """
+ 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 AsyncSpendingLimitResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncSpendingLimitResourceWithStreamingResponse:
+ """
+ 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 AsyncSpendingLimitResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ *,
+ account_id: str,
+ amount: int,
+ duration: Literal["daily", "weekly", "monthly"],
+ strategy: Literal["fixed", "sliding"],
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> object:
+ """
+ Configure a spending limit with amount, strategy, and duration.
+
+ Args:
+ amount: Spending limit amount in cents (min 100).
+
+ duration: Spending limit duration.
+
+ strategy: Spending limit strategy.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return await self._post(
+ path_template("/accounts/{account_id}/ai-gateway/billing/spending-limit", account_id=account_id),
+ body=await async_maybe_transform(
+ {
+ "amount": amount,
+ "duration": duration,
+ "strategy": strategy,
+ },
+ spending_limit_create_params.SpendingLimitCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[object]._unwrapper,
+ ),
+ cast_to=cast(Type[object], ResultWrapper[object]),
+ )
+
+ async def delete(
+ 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,
+ ) -> object:
+ """
+ Remove the spending limit for the account.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return await self._delete(
+ path_template("/accounts/{account_id}/ai-gateway/billing/spending-limit", 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[object]._unwrapper,
+ ),
+ cast_to=cast(Type[object], ResultWrapper[object]),
+ )
+
+ 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,
+ ) -> SpendingLimitGetResponse:
+ """
+ Retrieve the current spending limit configuration for the account.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return await self._get(
+ path_template("/accounts/{account_id}/ai-gateway/billing/spending-limit", 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[SpendingLimitGetResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[SpendingLimitGetResponse], ResultWrapper[SpendingLimitGetResponse]),
+ )
+
+
+class SpendingLimitResourceWithRawResponse:
+ def __init__(self, spending_limit: SpendingLimitResource) -> None:
+ self._spending_limit = spending_limit
+
+ self.create = to_raw_response_wrapper(
+ spending_limit.create,
+ )
+ self.delete = to_raw_response_wrapper(
+ spending_limit.delete,
+ )
+ self.get = to_raw_response_wrapper(
+ spending_limit.get,
+ )
+
+
+class AsyncSpendingLimitResourceWithRawResponse:
+ def __init__(self, spending_limit: AsyncSpendingLimitResource) -> None:
+ self._spending_limit = spending_limit
+
+ self.create = async_to_raw_response_wrapper(
+ spending_limit.create,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ spending_limit.delete,
+ )
+ self.get = async_to_raw_response_wrapper(
+ spending_limit.get,
+ )
+
+
+class SpendingLimitResourceWithStreamingResponse:
+ def __init__(self, spending_limit: SpendingLimitResource) -> None:
+ self._spending_limit = spending_limit
+
+ self.create = to_streamed_response_wrapper(
+ spending_limit.create,
+ )
+ self.delete = to_streamed_response_wrapper(
+ spending_limit.delete,
+ )
+ self.get = to_streamed_response_wrapper(
+ spending_limit.get,
+ )
+
+
+class AsyncSpendingLimitResourceWithStreamingResponse:
+ def __init__(self, spending_limit: AsyncSpendingLimitResource) -> None:
+ self._spending_limit = spending_limit
+
+ self.create = async_to_streamed_response_wrapper(
+ spending_limit.create,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ spending_limit.delete,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ spending_limit.get,
+ )
diff --git a/src/cloudflare/resources/ai_gateway/billing/topup/__init__.py b/src/cloudflare/resources/ai_gateway/billing/topup/__init__.py
new file mode 100644
index 00000000000..759bbfcffc6
--- /dev/null
+++ b/src/cloudflare/resources/ai_gateway/billing/topup/__init__.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .topup import (
+ TopupResource,
+ AsyncTopupResource,
+ TopupResourceWithRawResponse,
+ AsyncTopupResourceWithRawResponse,
+ TopupResourceWithStreamingResponse,
+ AsyncTopupResourceWithStreamingResponse,
+)
+from .config import (
+ ConfigResource,
+ AsyncConfigResource,
+ ConfigResourceWithRawResponse,
+ AsyncConfigResourceWithRawResponse,
+ ConfigResourceWithStreamingResponse,
+ AsyncConfigResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "ConfigResource",
+ "AsyncConfigResource",
+ "ConfigResourceWithRawResponse",
+ "AsyncConfigResourceWithRawResponse",
+ "ConfigResourceWithStreamingResponse",
+ "AsyncConfigResourceWithStreamingResponse",
+ "TopupResource",
+ "AsyncTopupResource",
+ "TopupResourceWithRawResponse",
+ "AsyncTopupResourceWithRawResponse",
+ "TopupResourceWithStreamingResponse",
+ "AsyncTopupResourceWithStreamingResponse",
+]
diff --git a/src/cloudflare/resources/ai_gateway/billing/topup/config.py b/src/cloudflare/resources/ai_gateway/billing/topup/config.py
new file mode 100644
index 00000000000..86a14fe9a8a
--- /dev/null
+++ b/src/cloudflare/resources/ai_gateway/billing/topup/config.py
@@ -0,0 +1,375 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Type, cast
+
+import httpx
+
+from ....._types import Body, Query, Headers, NotGiven, not_given
+from ....._utils import path_template, maybe_transform, async_maybe_transform
+from ....._compat import cached_property
+from ....._resource import SyncAPIResource, AsyncAPIResource
+from ....._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ....._wrappers import ResultWrapper
+from ....._base_client import make_request_options
+from .....types.ai_gateway.billing.topup import config_create_params
+from .....types.ai_gateway.billing.topup.config_get_response import ConfigGetResponse
+from .....types.ai_gateway.billing.topup.config_create_response import ConfigCreateResponse
+
+__all__ = ["ConfigResource", "AsyncConfigResource"]
+
+
+class ConfigResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> ConfigResourceWithRawResponse:
+ """
+ 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 ConfigResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> ConfigResourceWithStreamingResponse:
+ """
+ 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 ConfigResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ *,
+ account_id: str,
+ amount: int,
+ threshold: int,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ConfigCreateResponse:
+ """
+ Configure auto top-up with a balance threshold and top-up amount.
+
+ Args:
+ amount: Auto top-up amount in cents (min 1000).
+
+ threshold: Balance threshold in cents that triggers auto top-up (min 500).
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._post(
+ path_template("/accounts/{account_id}/ai-gateway/billing/topup/config", account_id=account_id),
+ body=maybe_transform(
+ {
+ "amount": amount,
+ "threshold": threshold,
+ },
+ config_create_params.ConfigCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[ConfigCreateResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[ConfigCreateResponse], ResultWrapper[ConfigCreateResponse]),
+ )
+
+ def delete(
+ 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,
+ ) -> object:
+ """
+ Remove the auto top-up configuration for the account.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._delete(
+ path_template("/accounts/{account_id}/ai-gateway/billing/topup/config", 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[object]._unwrapper,
+ ),
+ cast_to=cast(Type[object], ResultWrapper[object]),
+ )
+
+ 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,
+ ) -> ConfigGetResponse:
+ """
+ Retrieve the current auto top-up threshold, amount, and any error state.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._get(
+ path_template("/accounts/{account_id}/ai-gateway/billing/topup/config", 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[ConfigGetResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[ConfigGetResponse], ResultWrapper[ConfigGetResponse]),
+ )
+
+
+class AsyncConfigResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncConfigResourceWithRawResponse:
+ """
+ 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 AsyncConfigResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncConfigResourceWithStreamingResponse:
+ """
+ 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 AsyncConfigResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ *,
+ account_id: str,
+ amount: int,
+ threshold: int,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ConfigCreateResponse:
+ """
+ Configure auto top-up with a balance threshold and top-up amount.
+
+ Args:
+ amount: Auto top-up amount in cents (min 1000).
+
+ threshold: Balance threshold in cents that triggers auto top-up (min 500).
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return await self._post(
+ path_template("/accounts/{account_id}/ai-gateway/billing/topup/config", account_id=account_id),
+ body=await async_maybe_transform(
+ {
+ "amount": amount,
+ "threshold": threshold,
+ },
+ config_create_params.ConfigCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[ConfigCreateResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[ConfigCreateResponse], ResultWrapper[ConfigCreateResponse]),
+ )
+
+ async def delete(
+ 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,
+ ) -> object:
+ """
+ Remove the auto top-up configuration for the account.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return await self._delete(
+ path_template("/accounts/{account_id}/ai-gateway/billing/topup/config", 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[object]._unwrapper,
+ ),
+ cast_to=cast(Type[object], ResultWrapper[object]),
+ )
+
+ 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,
+ ) -> ConfigGetResponse:
+ """
+ Retrieve the current auto top-up threshold, amount, and any error state.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return await self._get(
+ path_template("/accounts/{account_id}/ai-gateway/billing/topup/config", 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[ConfigGetResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[ConfigGetResponse], ResultWrapper[ConfigGetResponse]),
+ )
+
+
+class ConfigResourceWithRawResponse:
+ def __init__(self, config: ConfigResource) -> None:
+ self._config = config
+
+ self.create = to_raw_response_wrapper(
+ config.create,
+ )
+ self.delete = to_raw_response_wrapper(
+ config.delete,
+ )
+ self.get = to_raw_response_wrapper(
+ config.get,
+ )
+
+
+class AsyncConfigResourceWithRawResponse:
+ def __init__(self, config: AsyncConfigResource) -> None:
+ self._config = config
+
+ self.create = async_to_raw_response_wrapper(
+ config.create,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ config.delete,
+ )
+ self.get = async_to_raw_response_wrapper(
+ config.get,
+ )
+
+
+class ConfigResourceWithStreamingResponse:
+ def __init__(self, config: ConfigResource) -> None:
+ self._config = config
+
+ self.create = to_streamed_response_wrapper(
+ config.create,
+ )
+ self.delete = to_streamed_response_wrapper(
+ config.delete,
+ )
+ self.get = to_streamed_response_wrapper(
+ config.get,
+ )
+
+
+class AsyncConfigResourceWithStreamingResponse:
+ def __init__(self, config: AsyncConfigResource) -> None:
+ self._config = config
+
+ self.create = async_to_streamed_response_wrapper(
+ config.create,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ config.delete,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ config.get,
+ )
diff --git a/src/cloudflare/resources/ai_gateway/billing/topup/topup.py b/src/cloudflare/resources/ai_gateway/billing/topup/topup.py
new file mode 100644
index 00000000000..c4719a7d822
--- /dev/null
+++ b/src/cloudflare/resources/ai_gateway/billing/topup/topup.py
@@ -0,0 +1,313 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Type, cast
+
+import httpx
+
+from .config import (
+ ConfigResource,
+ AsyncConfigResource,
+ ConfigResourceWithRawResponse,
+ AsyncConfigResourceWithRawResponse,
+ ConfigResourceWithStreamingResponse,
+ AsyncConfigResourceWithStreamingResponse,
+)
+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.ai_gateway.billing import topup_create_params, topup_status_params
+from .....types.ai_gateway.billing.topup_create_response import TopupCreateResponse
+from .....types.ai_gateway.billing.topup_status_response import TopupStatusResponse
+
+__all__ = ["TopupResource", "AsyncTopupResource"]
+
+
+class TopupResource(SyncAPIResource):
+ @cached_property
+ def config(self) -> ConfigResource:
+ return ConfigResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> TopupResourceWithRawResponse:
+ """
+ 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 TopupResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> TopupResourceWithStreamingResponse:
+ """
+ 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 TopupResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ *,
+ account_id: str,
+ amount: int,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> TopupCreateResponse:
+ """
+ Create a credit top-up via Stripe PaymentIntent for the given account.
+
+ Args:
+ amount: Top-up amount in cents (min 1000).
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._post(
+ path_template("/accounts/{account_id}/ai-gateway/billing/topup", account_id=account_id),
+ body=maybe_transform({"amount": amount}, topup_create_params.TopupCreateParams),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[TopupCreateResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[TopupCreateResponse], ResultWrapper[TopupCreateResponse]),
+ )
+
+ def status(
+ self,
+ *,
+ account_id: str,
+ payment_intent_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,
+ ) -> TopupStatusResponse:
+ """
+ Get the payment processing status of a top-up by its invoice ID.
+
+ Args:
+ payment_intent_id: Stripe invoice ID to check status 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}")
+ return self._post(
+ path_template("/accounts/{account_id}/ai-gateway/billing/topup/status", account_id=account_id),
+ body=maybe_transform({"payment_intent_id": payment_intent_id}, topup_status_params.TopupStatusParams),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[TopupStatusResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[TopupStatusResponse], ResultWrapper[TopupStatusResponse]),
+ )
+
+
+class AsyncTopupResource(AsyncAPIResource):
+ @cached_property
+ def config(self) -> AsyncConfigResource:
+ return AsyncConfigResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncTopupResourceWithRawResponse:
+ """
+ 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 AsyncTopupResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncTopupResourceWithStreamingResponse:
+ """
+ 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 AsyncTopupResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ *,
+ account_id: str,
+ amount: int,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> TopupCreateResponse:
+ """
+ Create a credit top-up via Stripe PaymentIntent for the given account.
+
+ Args:
+ amount: Top-up amount in cents (min 1000).
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return await self._post(
+ path_template("/accounts/{account_id}/ai-gateway/billing/topup", account_id=account_id),
+ body=await async_maybe_transform({"amount": amount}, topup_create_params.TopupCreateParams),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[TopupCreateResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[TopupCreateResponse], ResultWrapper[TopupCreateResponse]),
+ )
+
+ async def status(
+ self,
+ *,
+ account_id: str,
+ payment_intent_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,
+ ) -> TopupStatusResponse:
+ """
+ Get the payment processing status of a top-up by its invoice ID.
+
+ Args:
+ payment_intent_id: Stripe invoice ID to check status 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}")
+ return await self._post(
+ path_template("/accounts/{account_id}/ai-gateway/billing/topup/status", account_id=account_id),
+ body=await async_maybe_transform(
+ {"payment_intent_id": payment_intent_id}, topup_status_params.TopupStatusParams
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[TopupStatusResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[TopupStatusResponse], ResultWrapper[TopupStatusResponse]),
+ )
+
+
+class TopupResourceWithRawResponse:
+ def __init__(self, topup: TopupResource) -> None:
+ self._topup = topup
+
+ self.create = to_raw_response_wrapper(
+ topup.create,
+ )
+ self.status = to_raw_response_wrapper(
+ topup.status,
+ )
+
+ @cached_property
+ def config(self) -> ConfigResourceWithRawResponse:
+ return ConfigResourceWithRawResponse(self._topup.config)
+
+
+class AsyncTopupResourceWithRawResponse:
+ def __init__(self, topup: AsyncTopupResource) -> None:
+ self._topup = topup
+
+ self.create = async_to_raw_response_wrapper(
+ topup.create,
+ )
+ self.status = async_to_raw_response_wrapper(
+ topup.status,
+ )
+
+ @cached_property
+ def config(self) -> AsyncConfigResourceWithRawResponse:
+ return AsyncConfigResourceWithRawResponse(self._topup.config)
+
+
+class TopupResourceWithStreamingResponse:
+ def __init__(self, topup: TopupResource) -> None:
+ self._topup = topup
+
+ self.create = to_streamed_response_wrapper(
+ topup.create,
+ )
+ self.status = to_streamed_response_wrapper(
+ topup.status,
+ )
+
+ @cached_property
+ def config(self) -> ConfigResourceWithStreamingResponse:
+ return ConfigResourceWithStreamingResponse(self._topup.config)
+
+
+class AsyncTopupResourceWithStreamingResponse:
+ def __init__(self, topup: AsyncTopupResource) -> None:
+ self._topup = topup
+
+ self.create = async_to_streamed_response_wrapper(
+ topup.create,
+ )
+ self.status = async_to_streamed_response_wrapper(
+ topup.status,
+ )
+
+ @cached_property
+ def config(self) -> AsyncConfigResourceWithStreamingResponse:
+ return AsyncConfigResourceWithStreamingResponse(self._topup.config)
diff --git a/src/cloudflare/resources/cache/api.md b/src/cloudflare/resources/cache/api.md
index 3bbb74056ef..ddc6ee11597 100644
--- a/src/cloudflare/resources/cache/api.md
+++ b/src/cloudflare/resources/cache/api.md
@@ -3,12 +3,13 @@
Types:
```python
-from cloudflare.types.cache import CachePurgeResponse
+from cloudflare.types.cache import CachePurgeResponse, CachePurgeEnvironmentResponse
```
Methods:
- client.cache.purge(\*, zone_id, \*\*params) -> Optional[CachePurgeResponse]
+- client.cache.purge_environment(environment_id, \*, zone_id, \*\*params) -> Optional[CachePurgeEnvironmentResponse]
## CacheReserve
@@ -39,6 +40,7 @@ Types:
```python
from cloudflare.types.cache import (
+ SmartTieredCacheCreateResponse,
SmartTieredCacheDeleteResponse,
SmartTieredCacheEditResponse,
SmartTieredCacheGetResponse,
@@ -47,6 +49,7 @@ from cloudflare.types.cache import (
Methods:
+- client.cache.smart_tiered_cache.create(\*, zone_id, \*\*params) -> Optional[SmartTieredCacheCreateResponse]
- client.cache.smart_tiered_cache.delete(\*, zone_id) -> Optional[SmartTieredCacheDeleteResponse]
- client.cache.smart_tiered_cache.edit(\*, zone_id, \*\*params) -> Optional[SmartTieredCacheEditResponse]
- client.cache.smart_tiered_cache.get(\*, zone_id) -> Optional[SmartTieredCacheGetResponse]
@@ -94,24 +97,19 @@ Types:
```python
from cloudflare.types.cache import (
OriginCloudRegion,
- OriginCloudRegionCreateResponse,
- OriginCloudRegionListResponse,
OriginCloudRegionDeleteResponse,
OriginCloudRegionBulkDeleteResponse,
- OriginCloudRegionBulkEditResponse,
- OriginCloudRegionEditResponse,
- OriginCloudRegionGetResponse,
+ OriginCloudRegionBulkUpdateResponse,
OriginCloudRegionSupportedRegionsResponse,
)
```
Methods:
-- client.cache.origin_cloud_regions.create(\*, zone_id, \*\*params) -> Optional[OriginCloudRegionCreateResponse]
-- client.cache.origin_cloud_regions.list(\*, zone_id) -> Optional[OriginCloudRegionListResponse]
-- client.cache.origin_cloud_regions.delete(origin_ip, \*, zone_id) -> Optional[OriginCloudRegionDeleteResponse]
-- client.cache.origin_cloud_regions.bulk_delete(\*, zone_id) -> Optional[OriginCloudRegionBulkDeleteResponse]
-- client.cache.origin_cloud_regions.bulk_edit(\*, zone_id, \*\*params) -> Optional[OriginCloudRegionBulkEditResponse]
-- client.cache.origin_cloud_regions.edit(\*, zone_id, \*\*params) -> Optional[OriginCloudRegionEditResponse]
-- client.cache.origin_cloud_regions.get(origin_ip, \*, zone_id) -> Optional[OriginCloudRegionGetResponse]
-- client.cache.origin_cloud_regions.supported_regions(\*, zone_id) -> Optional[OriginCloudRegionSupportedRegionsResponse]
+- client.cache.origin_cloud_regions.update(path_origin_ip, \*, zone_id, \*\*params) -> Optional[OriginCloudRegion]
+- client.cache.origin_cloud_regions.list(\*, zone_id, \*\*params) -> SyncV4PagePaginationArray[OriginCloudRegion]
+- client.cache.origin_cloud_regions.delete(origin_ip, \*, zone_id) -> Optional[OriginCloudRegionDeleteResponse]
+- client.cache.origin_cloud_regions.bulk_delete(\*, zone_id) -> Optional[OriginCloudRegionBulkDeleteResponse]
+- client.cache.origin_cloud_regions.bulk_update(\*, zone_id, \*\*params) -> Optional[OriginCloudRegionBulkUpdateResponse]
+- client.cache.origin_cloud_regions.get(origin_ip, \*, zone_id) -> Optional[OriginCloudRegion]
+- client.cache.origin_cloud_regions.supported_regions(\*, zone_id) -> Optional[OriginCloudRegionSupportedRegionsResponse]
diff --git a/src/cloudflare/resources/cache/cache.py b/src/cloudflare/resources/cache/cache.py
index d6b1c0f7a0b..736c814eea0 100644
--- a/src/cloudflare/resources/cache/cache.py
+++ b/src/cloudflare/resources/cache/cache.py
@@ -26,7 +26,7 @@
async_to_streamed_response_wrapper,
)
from ..._wrappers import ResultWrapper
-from ...types.cache import cache_purge_params
+from ...types.cache import cache_purge_params, cache_purge_environment_params
from .cache_reserve import (
CacheReserveResource,
AsyncCacheReserveResource,
@@ -61,6 +61,7 @@
AsyncRegionalTieredCacheResourceWithStreamingResponse,
)
from ...types.cache.cache_purge_response import CachePurgeResponse
+from ...types.cache.cache_purge_environment_response import CachePurgeEnvironmentResponse
__all__ = ["CacheResource", "AsyncCacheResource"]
@@ -154,12 +155,12 @@ def purge(
{
"files": [
{
- url: "http://www.example.com/cat_picture.jpg",
- headers: {"CF-IPCountry": "US", "CF-Device-Type": "desktop", "Accept-Language": "zh-CN"},
+ "url": "http://www.example.com/cat_picture.jpg",
+ "headers": {"CF-IPCountry": "US", "CF-Device-Type": "desktop", "Accept-Language": "zh-CN"},
},
{
- url: "http://www.example.com/dog_picture.jpg",
- headers: {"CF-IPCountry": "EU", "CF-Device-Type": "mobile", "Accept-Language": "en-US"},
+ "url": "http://www.example.com/dog_picture.jpg",
+ "headers": {"CF-IPCountry": "EU", "CF-Device-Type": "mobile", "Accept-Language": "en-US"},
},
]
}
@@ -190,7 +191,7 @@ def purge(
### Availability and limits
- please refer to
+ Please refer to
[purge cache availability and limits documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits).
Args:
@@ -256,12 +257,12 @@ def purge(
{
"files": [
{
- url: "http://www.example.com/cat_picture.jpg",
- headers: {"CF-IPCountry": "US", "CF-Device-Type": "desktop", "Accept-Language": "zh-CN"},
+ "url": "http://www.example.com/cat_picture.jpg",
+ "headers": {"CF-IPCountry": "US", "CF-Device-Type": "desktop", "Accept-Language": "zh-CN"},
},
{
- url: "http://www.example.com/dog_picture.jpg",
- headers: {"CF-IPCountry": "EU", "CF-Device-Type": "mobile", "Accept-Language": "en-US"},
+ "url": "http://www.example.com/dog_picture.jpg",
+ "headers": {"CF-IPCountry": "EU", "CF-Device-Type": "mobile", "Accept-Language": "en-US"},
},
]
}
@@ -292,7 +293,7 @@ def purge(
### Availability and limits
- please refer to
+ Please refer to
[purge cache availability and limits documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits).
Args:
@@ -358,12 +359,12 @@ def purge(
{
"files": [
{
- url: "http://www.example.com/cat_picture.jpg",
- headers: {"CF-IPCountry": "US", "CF-Device-Type": "desktop", "Accept-Language": "zh-CN"},
+ "url": "http://www.example.com/cat_picture.jpg",
+ "headers": {"CF-IPCountry": "US", "CF-Device-Type": "desktop", "Accept-Language": "zh-CN"},
},
{
- url: "http://www.example.com/dog_picture.jpg",
- headers: {"CF-IPCountry": "EU", "CF-Device-Type": "mobile", "Accept-Language": "en-US"},
+ "url": "http://www.example.com/dog_picture.jpg",
+ "headers": {"CF-IPCountry": "EU", "CF-Device-Type": "mobile", "Accept-Language": "en-US"},
},
]
}
@@ -394,7 +395,7 @@ def purge(
### Availability and limits
- please refer to
+ Please refer to
[purge cache availability and limits documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits).
Args:
@@ -460,12 +461,12 @@ def purge(
{
"files": [
{
- url: "http://www.example.com/cat_picture.jpg",
- headers: {"CF-IPCountry": "US", "CF-Device-Type": "desktop", "Accept-Language": "zh-CN"},
+ "url": "http://www.example.com/cat_picture.jpg",
+ "headers": {"CF-IPCountry": "US", "CF-Device-Type": "desktop", "Accept-Language": "zh-CN"},
},
{
- url: "http://www.example.com/dog_picture.jpg",
- headers: {"CF-IPCountry": "EU", "CF-Device-Type": "mobile", "Accept-Language": "en-US"},
+ "url": "http://www.example.com/dog_picture.jpg",
+ "headers": {"CF-IPCountry": "EU", "CF-Device-Type": "mobile", "Accept-Language": "en-US"},
},
]
}
@@ -496,7 +497,7 @@ def purge(
### Availability and limits
- please refer to
+ Please refer to
[purge cache availability and limits documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits).
Args:
@@ -562,12 +563,12 @@ def purge(
{
"files": [
{
- url: "http://www.example.com/cat_picture.jpg",
- headers: {"CF-IPCountry": "US", "CF-Device-Type": "desktop", "Accept-Language": "zh-CN"},
+ "url": "http://www.example.com/cat_picture.jpg",
+ "headers": {"CF-IPCountry": "US", "CF-Device-Type": "desktop", "Accept-Language": "zh-CN"},
},
{
- url: "http://www.example.com/dog_picture.jpg",
- headers: {"CF-IPCountry": "EU", "CF-Device-Type": "mobile", "Accept-Language": "en-US"},
+ "url": "http://www.example.com/dog_picture.jpg",
+ "headers": {"CF-IPCountry": "EU", "CF-Device-Type": "mobile", "Accept-Language": "en-US"},
},
]
}
@@ -598,7 +599,7 @@ def purge(
### Availability and limits
- please refer to
+ Please refer to
[purge cache availability and limits documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits).
Args:
@@ -664,12 +665,12 @@ def purge(
{
"files": [
{
- url: "http://www.example.com/cat_picture.jpg",
- headers: {"CF-IPCountry": "US", "CF-Device-Type": "desktop", "Accept-Language": "zh-CN"},
+ "url": "http://www.example.com/cat_picture.jpg",
+ "headers": {"CF-IPCountry": "US", "CF-Device-Type": "desktop", "Accept-Language": "zh-CN"},
},
{
- url: "http://www.example.com/dog_picture.jpg",
- headers: {"CF-IPCountry": "EU", "CF-Device-Type": "mobile", "Accept-Language": "en-US"},
+ "url": "http://www.example.com/dog_picture.jpg",
+ "headers": {"CF-IPCountry": "EU", "CF-Device-Type": "mobile", "Accept-Language": "en-US"},
},
]
}
@@ -700,7 +701,7 @@ def purge(
### Availability and limits
- please refer to
+ Please refer to
[purge cache availability and limits documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits).
Args:
@@ -760,6 +761,290 @@ def purge(
cast_to=cast(Type[Optional[CachePurgeResponse]], ResultWrapper[CachePurgeResponse]),
)
+ @overload
+ def purge_environment(
+ self,
+ environment_id: str,
+ *,
+ zone_id: str,
+ tags: SequenceNotStr[str] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[CachePurgeEnvironmentResponse]:
+ """Purge cached content scoped to a specific environment.
+
+ Supports the same purge
+ types as the zone-level endpoint (purge everything, by URL, by tag, host, or
+ prefix).
+
+ ### Availability and limits
+
+ Please refer to
+ [purge cache availability and limits documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits).
+
+ Args:
+ tags: For more information on cache tags and purging by tags, please refer to
+ [purge by cache-tags documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-tags/).
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ ...
+
+ @overload
+ def purge_environment(
+ self,
+ environment_id: str,
+ *,
+ zone_id: str,
+ hosts: SequenceNotStr[str] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[CachePurgeEnvironmentResponse]:
+ """Purge cached content scoped to a specific environment.
+
+ Supports the same purge
+ types as the zone-level endpoint (purge everything, by URL, by tag, host, or
+ prefix).
+
+ ### Availability and limits
+
+ Please refer to
+ [purge cache availability and limits documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits).
+
+ Args:
+ hosts: For more information purging by hostnames, please refer to
+ [purge by hostname documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-hostname/).
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ ...
+
+ @overload
+ def purge_environment(
+ self,
+ environment_id: str,
+ *,
+ zone_id: str,
+ prefixes: SequenceNotStr[str] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[CachePurgeEnvironmentResponse]:
+ """Purge cached content scoped to a specific environment.
+
+ Supports the same purge
+ types as the zone-level endpoint (purge everything, by URL, by tag, host, or
+ prefix).
+
+ ### Availability and limits
+
+ Please refer to
+ [purge cache availability and limits documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits).
+
+ Args:
+ prefixes: For more information on purging by prefixes, please refer to
+ [purge by prefix documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/purge_by_prefix/).
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ ...
+
+ @overload
+ def purge_environment(
+ self,
+ environment_id: str,
+ *,
+ zone_id: str,
+ purge_everything: bool | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[CachePurgeEnvironmentResponse]:
+ """Purge cached content scoped to a specific environment.
+
+ Supports the same purge
+ types as the zone-level endpoint (purge everything, by URL, by tag, host, or
+ prefix).
+
+ ### Availability and limits
+
+ Please refer to
+ [purge cache availability and limits documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits).
+
+ Args:
+ purge_everything: For more information, please refer to
+ [purge everything documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-everything/).
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ ...
+
+ @overload
+ def purge_environment(
+ self,
+ environment_id: str,
+ *,
+ zone_id: str,
+ files: SequenceNotStr[str] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[CachePurgeEnvironmentResponse]:
+ """Purge cached content scoped to a specific environment.
+
+ Supports the same purge
+ types as the zone-level endpoint (purge everything, by URL, by tag, host, or
+ prefix).
+
+ ### Availability and limits
+
+ Please refer to
+ [purge cache availability and limits documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits).
+
+ Args:
+ files: For more information on purging files, please refer to
+ [purge by single-file documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-single-file/).
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ ...
+
+ @overload
+ def purge_environment(
+ self,
+ environment_id: str,
+ *,
+ zone_id: str,
+ files: Iterable[cache_purge_environment_params.CachePurgeSingleFileWithURLAndHeadersFile] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[CachePurgeEnvironmentResponse]:
+ """Purge cached content scoped to a specific environment.
+
+ Supports the same purge
+ types as the zone-level endpoint (purge everything, by URL, by tag, host, or
+ prefix).
+
+ ### Availability and limits
+
+ Please refer to
+ [purge cache availability and limits documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits).
+
+ Args:
+ files: For more information on purging files with URL and headers, please refer to
+ [purge by single-file documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-single-file/).
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ ...
+
+ @required_args(["zone_id"])
+ def purge_environment(
+ self,
+ environment_id: str,
+ *,
+ zone_id: str,
+ tags: SequenceNotStr[str] | Omit = omit,
+ hosts: SequenceNotStr[str] | Omit = omit,
+ prefixes: SequenceNotStr[str] | Omit = omit,
+ purge_everything: bool | Omit = omit,
+ files: SequenceNotStr[str]
+ | Iterable[cache_purge_environment_params.CachePurgeSingleFileWithURLAndHeadersFile]
+ | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[CachePurgeEnvironmentResponse]:
+ if not zone_id:
+ raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
+ if not environment_id:
+ raise ValueError(f"Expected a non-empty value for `environment_id` but received {environment_id!r}")
+ return self._post(
+ path_template(
+ "/zones/{zone_id}/environments/{environment_id}/purge_cache",
+ zone_id=zone_id,
+ environment_id=environment_id,
+ ),
+ body=maybe_transform(
+ {
+ "tags": tags,
+ "hosts": hosts,
+ "prefixes": prefixes,
+ "purge_everything": purge_everything,
+ "files": files,
+ },
+ cache_purge_environment_params.CachePurgeEnvironmentParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[CachePurgeEnvironmentResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[CachePurgeEnvironmentResponse]], ResultWrapper[CachePurgeEnvironmentResponse]),
+ )
+
class AsyncCacheResource(AsyncAPIResource):
@cached_property
@@ -850,12 +1135,12 @@ async def purge(
{
"files": [
{
- url: "http://www.example.com/cat_picture.jpg",
- headers: {"CF-IPCountry": "US", "CF-Device-Type": "desktop", "Accept-Language": "zh-CN"},
+ "url": "http://www.example.com/cat_picture.jpg",
+ "headers": {"CF-IPCountry": "US", "CF-Device-Type": "desktop", "Accept-Language": "zh-CN"},
},
{
- url: "http://www.example.com/dog_picture.jpg",
- headers: {"CF-IPCountry": "EU", "CF-Device-Type": "mobile", "Accept-Language": "en-US"},
+ "url": "http://www.example.com/dog_picture.jpg",
+ "headers": {"CF-IPCountry": "EU", "CF-Device-Type": "mobile", "Accept-Language": "en-US"},
},
]
}
@@ -886,7 +1171,7 @@ async def purge(
### Availability and limits
- please refer to
+ Please refer to
[purge cache availability and limits documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits).
Args:
@@ -952,12 +1237,12 @@ async def purge(
{
"files": [
{
- url: "http://www.example.com/cat_picture.jpg",
- headers: {"CF-IPCountry": "US", "CF-Device-Type": "desktop", "Accept-Language": "zh-CN"},
+ "url": "http://www.example.com/cat_picture.jpg",
+ "headers": {"CF-IPCountry": "US", "CF-Device-Type": "desktop", "Accept-Language": "zh-CN"},
},
{
- url: "http://www.example.com/dog_picture.jpg",
- headers: {"CF-IPCountry": "EU", "CF-Device-Type": "mobile", "Accept-Language": "en-US"},
+ "url": "http://www.example.com/dog_picture.jpg",
+ "headers": {"CF-IPCountry": "EU", "CF-Device-Type": "mobile", "Accept-Language": "en-US"},
},
]
}
@@ -988,7 +1273,7 @@ async def purge(
### Availability and limits
- please refer to
+ Please refer to
[purge cache availability and limits documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits).
Args:
@@ -1054,12 +1339,12 @@ async def purge(
{
"files": [
{
- url: "http://www.example.com/cat_picture.jpg",
- headers: {"CF-IPCountry": "US", "CF-Device-Type": "desktop", "Accept-Language": "zh-CN"},
+ "url": "http://www.example.com/cat_picture.jpg",
+ "headers": {"CF-IPCountry": "US", "CF-Device-Type": "desktop", "Accept-Language": "zh-CN"},
},
{
- url: "http://www.example.com/dog_picture.jpg",
- headers: {"CF-IPCountry": "EU", "CF-Device-Type": "mobile", "Accept-Language": "en-US"},
+ "url": "http://www.example.com/dog_picture.jpg",
+ "headers": {"CF-IPCountry": "EU", "CF-Device-Type": "mobile", "Accept-Language": "en-US"},
},
]
}
@@ -1090,7 +1375,7 @@ async def purge(
### Availability and limits
- please refer to
+ Please refer to
[purge cache availability and limits documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits).
Args:
@@ -1156,12 +1441,12 @@ async def purge(
{
"files": [
{
- url: "http://www.example.com/cat_picture.jpg",
- headers: {"CF-IPCountry": "US", "CF-Device-Type": "desktop", "Accept-Language": "zh-CN"},
+ "url": "http://www.example.com/cat_picture.jpg",
+ "headers": {"CF-IPCountry": "US", "CF-Device-Type": "desktop", "Accept-Language": "zh-CN"},
},
{
- url: "http://www.example.com/dog_picture.jpg",
- headers: {"CF-IPCountry": "EU", "CF-Device-Type": "mobile", "Accept-Language": "en-US"},
+ "url": "http://www.example.com/dog_picture.jpg",
+ "headers": {"CF-IPCountry": "EU", "CF-Device-Type": "mobile", "Accept-Language": "en-US"},
},
]
}
@@ -1192,7 +1477,7 @@ async def purge(
### Availability and limits
- please refer to
+ Please refer to
[purge cache availability and limits documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits).
Args:
@@ -1258,12 +1543,12 @@ async def purge(
{
"files": [
{
- url: "http://www.example.com/cat_picture.jpg",
- headers: {"CF-IPCountry": "US", "CF-Device-Type": "desktop", "Accept-Language": "zh-CN"},
+ "url": "http://www.example.com/cat_picture.jpg",
+ "headers": {"CF-IPCountry": "US", "CF-Device-Type": "desktop", "Accept-Language": "zh-CN"},
},
{
- url: "http://www.example.com/dog_picture.jpg",
- headers: {"CF-IPCountry": "EU", "CF-Device-Type": "mobile", "Accept-Language": "en-US"},
+ "url": "http://www.example.com/dog_picture.jpg",
+ "headers": {"CF-IPCountry": "EU", "CF-Device-Type": "mobile", "Accept-Language": "en-US"},
},
]
}
@@ -1294,7 +1579,7 @@ async def purge(
### Availability and limits
- please refer to
+ Please refer to
[purge cache availability and limits documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits).
Args:
@@ -1360,12 +1645,12 @@ async def purge(
{
"files": [
{
- url: "http://www.example.com/cat_picture.jpg",
- headers: {"CF-IPCountry": "US", "CF-Device-Type": "desktop", "Accept-Language": "zh-CN"},
+ "url": "http://www.example.com/cat_picture.jpg",
+ "headers": {"CF-IPCountry": "US", "CF-Device-Type": "desktop", "Accept-Language": "zh-CN"},
},
{
- url: "http://www.example.com/dog_picture.jpg",
- headers: {"CF-IPCountry": "EU", "CF-Device-Type": "mobile", "Accept-Language": "en-US"},
+ "url": "http://www.example.com/dog_picture.jpg",
+ "headers": {"CF-IPCountry": "EU", "CF-Device-Type": "mobile", "Accept-Language": "en-US"},
},
]
}
@@ -1396,7 +1681,7 @@ async def purge(
### Availability and limits
- please refer to
+ Please refer to
[purge cache availability and limits documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits).
Args:
@@ -1456,6 +1741,290 @@ async def purge(
cast_to=cast(Type[Optional[CachePurgeResponse]], ResultWrapper[CachePurgeResponse]),
)
+ @overload
+ async def purge_environment(
+ self,
+ environment_id: str,
+ *,
+ zone_id: str,
+ tags: SequenceNotStr[str] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[CachePurgeEnvironmentResponse]:
+ """Purge cached content scoped to a specific environment.
+
+ Supports the same purge
+ types as the zone-level endpoint (purge everything, by URL, by tag, host, or
+ prefix).
+
+ ### Availability and limits
+
+ Please refer to
+ [purge cache availability and limits documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits).
+
+ Args:
+ tags: For more information on cache tags and purging by tags, please refer to
+ [purge by cache-tags documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-tags/).
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ ...
+
+ @overload
+ async def purge_environment(
+ self,
+ environment_id: str,
+ *,
+ zone_id: str,
+ hosts: SequenceNotStr[str] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[CachePurgeEnvironmentResponse]:
+ """Purge cached content scoped to a specific environment.
+
+ Supports the same purge
+ types as the zone-level endpoint (purge everything, by URL, by tag, host, or
+ prefix).
+
+ ### Availability and limits
+
+ Please refer to
+ [purge cache availability and limits documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits).
+
+ Args:
+ hosts: For more information purging by hostnames, please refer to
+ [purge by hostname documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-hostname/).
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ ...
+
+ @overload
+ async def purge_environment(
+ self,
+ environment_id: str,
+ *,
+ zone_id: str,
+ prefixes: SequenceNotStr[str] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[CachePurgeEnvironmentResponse]:
+ """Purge cached content scoped to a specific environment.
+
+ Supports the same purge
+ types as the zone-level endpoint (purge everything, by URL, by tag, host, or
+ prefix).
+
+ ### Availability and limits
+
+ Please refer to
+ [purge cache availability and limits documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits).
+
+ Args:
+ prefixes: For more information on purging by prefixes, please refer to
+ [purge by prefix documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/purge_by_prefix/).
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ ...
+
+ @overload
+ async def purge_environment(
+ self,
+ environment_id: str,
+ *,
+ zone_id: str,
+ purge_everything: bool | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[CachePurgeEnvironmentResponse]:
+ """Purge cached content scoped to a specific environment.
+
+ Supports the same purge
+ types as the zone-level endpoint (purge everything, by URL, by tag, host, or
+ prefix).
+
+ ### Availability and limits
+
+ Please refer to
+ [purge cache availability and limits documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits).
+
+ Args:
+ purge_everything: For more information, please refer to
+ [purge everything documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-everything/).
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ ...
+
+ @overload
+ async def purge_environment(
+ self,
+ environment_id: str,
+ *,
+ zone_id: str,
+ files: SequenceNotStr[str] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[CachePurgeEnvironmentResponse]:
+ """Purge cached content scoped to a specific environment.
+
+ Supports the same purge
+ types as the zone-level endpoint (purge everything, by URL, by tag, host, or
+ prefix).
+
+ ### Availability and limits
+
+ Please refer to
+ [purge cache availability and limits documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits).
+
+ Args:
+ files: For more information on purging files, please refer to
+ [purge by single-file documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-single-file/).
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ ...
+
+ @overload
+ async def purge_environment(
+ self,
+ environment_id: str,
+ *,
+ zone_id: str,
+ files: Iterable[cache_purge_environment_params.CachePurgeSingleFileWithURLAndHeadersFile] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[CachePurgeEnvironmentResponse]:
+ """Purge cached content scoped to a specific environment.
+
+ Supports the same purge
+ types as the zone-level endpoint (purge everything, by URL, by tag, host, or
+ prefix).
+
+ ### Availability and limits
+
+ Please refer to
+ [purge cache availability and limits documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/#availability-and-limits).
+
+ Args:
+ files: For more information on purging files with URL and headers, please refer to
+ [purge by single-file documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-single-file/).
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ ...
+
+ @required_args(["zone_id"])
+ async def purge_environment(
+ self,
+ environment_id: str,
+ *,
+ zone_id: str,
+ tags: SequenceNotStr[str] | Omit = omit,
+ hosts: SequenceNotStr[str] | Omit = omit,
+ prefixes: SequenceNotStr[str] | Omit = omit,
+ purge_everything: bool | Omit = omit,
+ files: SequenceNotStr[str]
+ | Iterable[cache_purge_environment_params.CachePurgeSingleFileWithURLAndHeadersFile]
+ | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[CachePurgeEnvironmentResponse]:
+ if not zone_id:
+ raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
+ if not environment_id:
+ raise ValueError(f"Expected a non-empty value for `environment_id` but received {environment_id!r}")
+ return await self._post(
+ path_template(
+ "/zones/{zone_id}/environments/{environment_id}/purge_cache",
+ zone_id=zone_id,
+ environment_id=environment_id,
+ ),
+ body=await async_maybe_transform(
+ {
+ "tags": tags,
+ "hosts": hosts,
+ "prefixes": prefixes,
+ "purge_everything": purge_everything,
+ "files": files,
+ },
+ cache_purge_environment_params.CachePurgeEnvironmentParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[CachePurgeEnvironmentResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[CachePurgeEnvironmentResponse]], ResultWrapper[CachePurgeEnvironmentResponse]),
+ )
+
class CacheResourceWithRawResponse:
def __init__(self, cache: CacheResource) -> None:
@@ -1464,6 +2033,9 @@ def __init__(self, cache: CacheResource) -> None:
self.purge = to_raw_response_wrapper(
cache.purge,
)
+ self.purge_environment = to_raw_response_wrapper(
+ cache.purge_environment,
+ )
@cached_property
def cache_reserve(self) -> CacheReserveResourceWithRawResponse:
@@ -1493,6 +2065,9 @@ def __init__(self, cache: AsyncCacheResource) -> None:
self.purge = async_to_raw_response_wrapper(
cache.purge,
)
+ self.purge_environment = async_to_raw_response_wrapper(
+ cache.purge_environment,
+ )
@cached_property
def cache_reserve(self) -> AsyncCacheReserveResourceWithRawResponse:
@@ -1522,6 +2097,9 @@ def __init__(self, cache: CacheResource) -> None:
self.purge = to_streamed_response_wrapper(
cache.purge,
)
+ self.purge_environment = to_streamed_response_wrapper(
+ cache.purge_environment,
+ )
@cached_property
def cache_reserve(self) -> CacheReserveResourceWithStreamingResponse:
@@ -1551,6 +2129,9 @@ def __init__(self, cache: AsyncCacheResource) -> None:
self.purge = async_to_streamed_response_wrapper(
cache.purge,
)
+ self.purge_environment = async_to_streamed_response_wrapper(
+ cache.purge_environment,
+ )
@cached_property
def cache_reserve(self) -> AsyncCacheReserveResourceWithStreamingResponse:
diff --git a/src/cloudflare/resources/cache/origin_cloud_regions.py b/src/cloudflare/resources/cache/origin_cloud_regions.py
index a961eecd1d0..e56f7d4f63b 100644
--- a/src/cloudflare/resources/cache/origin_cloud_regions.py
+++ b/src/cloudflare/resources/cache/origin_cloud_regions.py
@@ -7,7 +7,7 @@
import httpx
-from ..._types import Body, Query, Headers, NotGiven, not_given
+from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
@@ -18,19 +18,17 @@
async_to_streamed_response_wrapper,
)
from ..._wrappers import ResultWrapper
+from ...pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray
from ...types.cache import (
- origin_cloud_region_edit_params,
- origin_cloud_region_create_params,
- origin_cloud_region_bulk_edit_params,
+ origin_cloud_region_list_params,
+ origin_cloud_region_update_params,
+ origin_cloud_region_bulk_update_params,
)
-from ..._base_client import make_request_options
-from ...types.cache.origin_cloud_region_get_response import OriginCloudRegionGetResponse
-from ...types.cache.origin_cloud_region_edit_response import OriginCloudRegionEditResponse
-from ...types.cache.origin_cloud_region_list_response import OriginCloudRegionListResponse
-from ...types.cache.origin_cloud_region_create_response import OriginCloudRegionCreateResponse
+from ..._base_client import AsyncPaginator, make_request_options
+from ...types.cache.origin_cloud_region import OriginCloudRegion
from ...types.cache.origin_cloud_region_delete_response import OriginCloudRegionDeleteResponse
-from ...types.cache.origin_cloud_region_bulk_edit_response import OriginCloudRegionBulkEditResponse
from ...types.cache.origin_cloud_region_bulk_delete_response import OriginCloudRegionBulkDeleteResponse
+from ...types.cache.origin_cloud_region_bulk_update_response import OriginCloudRegionBulkUpdateResponse
from ...types.cache.origin_cloud_region_supported_regions_response import OriginCloudRegionSupportedRegionsResponse
__all__ = ["OriginCloudRegionsResource", "AsyncOriginCloudRegionsResource"]
@@ -56,11 +54,12 @@ def with_streaming_response(self) -> OriginCloudRegionsResourceWithStreamingResp
"""
return OriginCloudRegionsResourceWithStreamingResponse(self)
- def create(
+ def update(
self,
+ path_origin_ip: str,
*,
zone_id: str,
- ip: str,
+ body_origin_ip: str,
region: str,
vendor: Literal["aws", "azure", "gcp", "oci"],
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -69,21 +68,24 @@ def create(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> Optional[OriginCloudRegionCreateResponse]:
- """Adds a single IP-to-cloud-region mapping for the zone.
-
- The IP must be a valid
- IPv4 or IPv6 address and is normalized to canonical form before storage (RFC
- 5952 for IPv6). Returns 400 (code 1145) if a mapping for that IP already exists
- — use PATCH to update an existing entry. The vendor and region are validated
- against the list from
- `GET /zones/{zone_id}/cache/origin_cloud_regions/supported_regions`.
+ ) -> Optional[OriginCloudRegion]:
+ """
+ Creates a new IP-to-cloud-region mapping or replaces the existing mapping for
+ the specified IP. PUT is idempotent — calling it repeatedly with the same body
+ produces the same result. The IP path parameter is normalized to canonical form
+ (RFC 5952 for IPv6) before storage. The vendor and region are validated against
+ the list from `GET /zones/{zone_id}/origin/cloud_regions/supported_regions`.
+ Returns 400 if the `origin_ip` in the body does not match the URL path
+ parameter. Returns 403 (code 1164) when the zone has reached the limit of 3,500
+ IP mappings.
Args:
zone_id: Identifier.
- ip: Origin IP address (IPv4 or IPv6). Normalized to canonical form before storage
- (RFC 5952 for IPv6).
+ body_origin_ip: Origin IP address (IPv4 or IPv6). For the single PUT endpoint
+ (`PUT /origin/cloud_regions/{origin_ip}`), this field must match the path
+ parameter or the request will be rejected with a 400 error. For the batch PUT
+ endpoint, this field identifies which mapping to upsert.
region: Cloud vendor region identifier. Must be a valid region for the specified vendor
as returned by the supported_regions endpoint.
@@ -100,49 +102,57 @@ def create(
"""
if not zone_id:
raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
- return self._post(
- path_template("/zones/{zone_id}/cache/origin_cloud_regions", zone_id=zone_id),
+ if not path_origin_ip:
+ raise ValueError(f"Expected a non-empty value for `path_origin_ip` but received {path_origin_ip!r}")
+ return self._put(
+ path_template(
+ "/zones/{zone_id}/origin/cloud_regions/{path_origin_ip}", zone_id=zone_id, path_origin_ip=path_origin_ip
+ ),
body=maybe_transform(
{
- "ip": ip,
+ "body_origin_ip": body_origin_ip,
"region": region,
"vendor": vendor,
},
- origin_cloud_region_create_params.OriginCloudRegionCreateParams,
+ origin_cloud_region_update_params.OriginCloudRegionUpdateParams,
),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
- post_parser=ResultWrapper[Optional[OriginCloudRegionCreateResponse]]._unwrapper,
- ),
- cast_to=cast(
- Type[Optional[OriginCloudRegionCreateResponse]], ResultWrapper[OriginCloudRegionCreateResponse]
+ post_parser=ResultWrapper[Optional[OriginCloudRegion]]._unwrapper,
),
+ cast_to=cast(Type[Optional[OriginCloudRegion]], ResultWrapper[OriginCloudRegion]),
)
def list(
self,
*,
zone_id: str,
+ page: int | Omit = omit,
+ per_page: 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,
- ) -> Optional[OriginCloudRegionListResponse]:
- """Returns all IP-to-cloud-region mappings configured for the zone.
-
- Each mapping
- tells Cloudflare which cloud vendor and region hosts the origin at that IP,
- enabling the edge to route via the nearest Tiered Cache upper-tier co-located
- with that cloud provider. Returns an empty array when no mappings exist.
+ ) -> SyncV4PagePaginationArray[OriginCloudRegion]:
+ """
+ Returns all IP-to-cloud-region mappings configured for the zone with pagination
+ support. Each mapping tells Cloudflare which cloud vendor and region hosts the
+ origin at that IP, enabling the edge to route via the nearest Tiered Cache
+ upper-tier co-located with that cloud provider. Returns an empty array when no
+ mappings exist.
Args:
zone_id: Identifier.
+ page: Page number of paginated results.
+
+ per_page: Number of items per page.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -153,16 +163,23 @@ def list(
"""
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}/cache/origin_cloud_regions", zone_id=zone_id),
+ return self._get_api_list(
+ path_template("/zones/{zone_id}/origin/cloud_regions", zone_id=zone_id),
+ page=SyncV4PagePaginationArray[OriginCloudRegion],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
- post_parser=ResultWrapper[Optional[OriginCloudRegionListResponse]]._unwrapper,
+ query=maybe_transform(
+ {
+ "page": page,
+ "per_page": per_page,
+ },
+ origin_cloud_region_list_params.OriginCloudRegionListParams,
+ ),
),
- cast_to=cast(Type[Optional[OriginCloudRegionListResponse]], ResultWrapper[OriginCloudRegionListResponse]),
+ model=OriginCloudRegion,
)
def delete(
@@ -180,9 +197,9 @@ def delete(
"""Removes the cloud region mapping for a single origin IP address.
The IP path
- parameter is normalized before lookup. Returns the deleted entry on success.
- Returns 404 (code 1163) if no mapping exists for the specified IP. When the last
- mapping for the zone is removed the underlying rule record is also deleted.
+ parameter is normalized before lookup. Returns the deleted IP on success.
+ Returns 404 if no mapping exists for the specified IP. When the last mapping for
+ the zone is removed the underlying rule record is also deleted.
Args:
zone_id: Identifier.
@@ -200,9 +217,7 @@ def delete(
if not origin_ip:
raise ValueError(f"Expected a non-empty value for `origin_ip` but received {origin_ip!r}")
return self._delete(
- path_template(
- "/zones/{zone_id}/cache/origin_cloud_regions/{origin_ip}", zone_id=zone_id, origin_ip=origin_ip
- ),
+ path_template("/zones/{zone_id}/origin/cloud_regions/{origin_ip}", zone_id=zone_id, origin_ip=origin_ip),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -247,7 +262,7 @@ def bulk_delete(
if not zone_id:
raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
return self._delete(
- path_template("/zones/{zone_id}/cache/origin_cloud_regions/batch", zone_id=zone_id),
+ path_template("/zones/{zone_id}/origin/cloud_regions/batch", zone_id=zone_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -260,25 +275,27 @@ def bulk_delete(
),
)
- def bulk_edit(
+ def bulk_update(
self,
*,
zone_id: str,
- body: Iterable[origin_cloud_region_bulk_edit_params.Body],
+ body: Iterable[origin_cloud_region_bulk_update_params.Body],
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> Optional[OriginCloudRegionBulkEditResponse]:
- """Adds or updates up to 100 IP-to-cloud-region mappings in a single request.
+ ) -> Optional[OriginCloudRegionBulkUpdateResponse]:
+ """Upserts up to 100 IP-to-cloud-region mappings in a single request.
- Each
- item is validated independently — valid items are applied and invalid items are
- returned in the `failed` array. The vendor and region for every item are
- validated against the list from
- `GET /zones/{zone_id}/cache/origin_cloud_regions/supported_regions`.
+ Items in the
+ request body are created or replaced; mappings not included in the request body
+ are preserved unchanged (this is a merge operation, not a full collection
+ replacement). Each item is validated independently — valid items are applied and
+ invalid items are returned in the `failed` array. The vendor and region for
+ every item are validated against the list from
+ `GET /zones/{zone_id}/origin/cloud_regions/supported_regions`.
Args:
zone_id: Identifier.
@@ -293,82 +310,19 @@ def bulk_edit(
"""
if not zone_id:
raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
- return self._patch(
- path_template("/zones/{zone_id}/cache/origin_cloud_regions/batch", zone_id=zone_id),
- body=maybe_transform(body, Iterable[origin_cloud_region_bulk_edit_params.Body]),
+ return self._put(
+ path_template("/zones/{zone_id}/origin/cloud_regions/batch", zone_id=zone_id),
+ body=maybe_transform(body, Iterable[origin_cloud_region_bulk_update_params.Body]),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
- post_parser=ResultWrapper[Optional[OriginCloudRegionBulkEditResponse]]._unwrapper,
+ post_parser=ResultWrapper[Optional[OriginCloudRegionBulkUpdateResponse]]._unwrapper,
),
cast_to=cast(
- Type[Optional[OriginCloudRegionBulkEditResponse]], ResultWrapper[OriginCloudRegionBulkEditResponse]
- ),
- )
-
- def edit(
- self,
- *,
- zone_id: str,
- ip: str,
- region: str,
- vendor: Literal["aws", "azure", "gcp", "oci"],
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this 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[OriginCloudRegionEditResponse]:
- """Adds or updates a single IP-to-cloud-region mapping for the zone.
-
- Unlike POST,
- this operation is idempotent — if a mapping for the IP already exists it is
- overwritten. Returns the complete updated list of all mappings for the zone.
- Returns 403 (code 1164) when the zone has reached the limit of 3,500 IP
- mappings.
-
- Args:
- zone_id: Identifier.
-
- ip: Origin IP address (IPv4 or IPv6). Normalized to canonical form before storage
- (RFC 5952 for IPv6).
-
- region: Cloud vendor region identifier. Must be a valid region for the specified vendor
- as returned by the supported_regions endpoint.
-
- vendor: Cloud vendor hosting the origin. Must be one of the supported vendors.
-
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not zone_id:
- raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
- return self._patch(
- path_template("/zones/{zone_id}/cache/origin_cloud_regions", zone_id=zone_id),
- body=maybe_transform(
- {
- "ip": ip,
- "region": region,
- "vendor": vendor,
- },
- origin_cloud_region_edit_params.OriginCloudRegionEditParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- post_parser=ResultWrapper[Optional[OriginCloudRegionEditResponse]]._unwrapper,
+ Type[Optional[OriginCloudRegionBulkUpdateResponse]], ResultWrapper[OriginCloudRegionBulkUpdateResponse]
),
- cast_to=cast(Type[Optional[OriginCloudRegionEditResponse]], ResultWrapper[OriginCloudRegionEditResponse]),
)
def get(
@@ -382,12 +336,12 @@ def get(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> Optional[OriginCloudRegionGetResponse]:
+ ) -> Optional[OriginCloudRegion]:
"""Returns the cloud region mapping for a single origin IP address.
The IP path
- parameter is normalized before lookup (RFC 5952 for IPv6). Returns 404
- (code 1142) if the zone has no mappings or if the specified IP has no mapping.
+ parameter is normalized before lookup (RFC 5952 for IPv6). Returns 404 if the
+ zone has no mappings or if the specified IP has no mapping.
Args:
zone_id: Identifier.
@@ -405,17 +359,15 @@ def get(
if not origin_ip:
raise ValueError(f"Expected a non-empty value for `origin_ip` but received {origin_ip!r}")
return self._get(
- path_template(
- "/zones/{zone_id}/cache/origin_cloud_regions/{origin_ip}", zone_id=zone_id, origin_ip=origin_ip
- ),
+ path_template("/zones/{zone_id}/origin/cloud_regions/{origin_ip}", zone_id=zone_id, origin_ip=origin_ip),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
- post_parser=ResultWrapper[Optional[OriginCloudRegionGetResponse]]._unwrapper,
+ post_parser=ResultWrapper[Optional[OriginCloudRegion]]._unwrapper,
),
- cast_to=cast(Type[Optional[OriginCloudRegionGetResponse]], ResultWrapper[OriginCloudRegionGetResponse]),
+ cast_to=cast(Type[Optional[OriginCloudRegion]], ResultWrapper[OriginCloudRegion]),
)
def supported_regions(
@@ -449,7 +401,7 @@ def supported_regions(
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}/cache/origin_cloud_regions/supported_regions", zone_id=zone_id),
+ path_template("/zones/{zone_id}/origin/cloud_regions/supported_regions", zone_id=zone_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -484,11 +436,12 @@ def with_streaming_response(self) -> AsyncOriginCloudRegionsResourceWithStreamin
"""
return AsyncOriginCloudRegionsResourceWithStreamingResponse(self)
- async def create(
+ async def update(
self,
+ path_origin_ip: str,
*,
zone_id: str,
- ip: str,
+ body_origin_ip: str,
region: str,
vendor: Literal["aws", "azure", "gcp", "oci"],
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -497,21 +450,24 @@ async def create(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> Optional[OriginCloudRegionCreateResponse]:
- """Adds a single IP-to-cloud-region mapping for the zone.
-
- The IP must be a valid
- IPv4 or IPv6 address and is normalized to canonical form before storage (RFC
- 5952 for IPv6). Returns 400 (code 1145) if a mapping for that IP already exists
- — use PATCH to update an existing entry. The vendor and region are validated
- against the list from
- `GET /zones/{zone_id}/cache/origin_cloud_regions/supported_regions`.
+ ) -> Optional[OriginCloudRegion]:
+ """
+ Creates a new IP-to-cloud-region mapping or replaces the existing mapping for
+ the specified IP. PUT is idempotent — calling it repeatedly with the same body
+ produces the same result. The IP path parameter is normalized to canonical form
+ (RFC 5952 for IPv6) before storage. The vendor and region are validated against
+ the list from `GET /zones/{zone_id}/origin/cloud_regions/supported_regions`.
+ Returns 400 if the `origin_ip` in the body does not match the URL path
+ parameter. Returns 403 (code 1164) when the zone has reached the limit of 3,500
+ IP mappings.
Args:
zone_id: Identifier.
- ip: Origin IP address (IPv4 or IPv6). Normalized to canonical form before storage
- (RFC 5952 for IPv6).
+ body_origin_ip: Origin IP address (IPv4 or IPv6). For the single PUT endpoint
+ (`PUT /origin/cloud_regions/{origin_ip}`), this field must match the path
+ parameter or the request will be rejected with a 400 error. For the batch PUT
+ endpoint, this field identifies which mapping to upsert.
region: Cloud vendor region identifier. Must be a valid region for the specified vendor
as returned by the supported_regions endpoint.
@@ -528,49 +484,57 @@ async def create(
"""
if not zone_id:
raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
- return await self._post(
- path_template("/zones/{zone_id}/cache/origin_cloud_regions", zone_id=zone_id),
+ if not path_origin_ip:
+ raise ValueError(f"Expected a non-empty value for `path_origin_ip` but received {path_origin_ip!r}")
+ return await self._put(
+ path_template(
+ "/zones/{zone_id}/origin/cloud_regions/{path_origin_ip}", zone_id=zone_id, path_origin_ip=path_origin_ip
+ ),
body=await async_maybe_transform(
{
- "ip": ip,
+ "body_origin_ip": body_origin_ip,
"region": region,
"vendor": vendor,
},
- origin_cloud_region_create_params.OriginCloudRegionCreateParams,
+ origin_cloud_region_update_params.OriginCloudRegionUpdateParams,
),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
- post_parser=ResultWrapper[Optional[OriginCloudRegionCreateResponse]]._unwrapper,
- ),
- cast_to=cast(
- Type[Optional[OriginCloudRegionCreateResponse]], ResultWrapper[OriginCloudRegionCreateResponse]
+ post_parser=ResultWrapper[Optional[OriginCloudRegion]]._unwrapper,
),
+ cast_to=cast(Type[Optional[OriginCloudRegion]], ResultWrapper[OriginCloudRegion]),
)
- async def list(
+ def list(
self,
*,
zone_id: str,
+ page: int | Omit = omit,
+ per_page: 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,
- ) -> Optional[OriginCloudRegionListResponse]:
- """Returns all IP-to-cloud-region mappings configured for the zone.
-
- Each mapping
- tells Cloudflare which cloud vendor and region hosts the origin at that IP,
- enabling the edge to route via the nearest Tiered Cache upper-tier co-located
- with that cloud provider. Returns an empty array when no mappings exist.
+ ) -> AsyncPaginator[OriginCloudRegion, AsyncV4PagePaginationArray[OriginCloudRegion]]:
+ """
+ Returns all IP-to-cloud-region mappings configured for the zone with pagination
+ support. Each mapping tells Cloudflare which cloud vendor and region hosts the
+ origin at that IP, enabling the edge to route via the nearest Tiered Cache
+ upper-tier co-located with that cloud provider. Returns an empty array when no
+ mappings exist.
Args:
zone_id: Identifier.
+ page: Page number of paginated results.
+
+ per_page: Number of items per page.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -581,16 +545,23 @@ async def list(
"""
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}/cache/origin_cloud_regions", zone_id=zone_id),
+ return self._get_api_list(
+ path_template("/zones/{zone_id}/origin/cloud_regions", zone_id=zone_id),
+ page=AsyncV4PagePaginationArray[OriginCloudRegion],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
- post_parser=ResultWrapper[Optional[OriginCloudRegionListResponse]]._unwrapper,
+ query=maybe_transform(
+ {
+ "page": page,
+ "per_page": per_page,
+ },
+ origin_cloud_region_list_params.OriginCloudRegionListParams,
+ ),
),
- cast_to=cast(Type[Optional[OriginCloudRegionListResponse]], ResultWrapper[OriginCloudRegionListResponse]),
+ model=OriginCloudRegion,
)
async def delete(
@@ -608,9 +579,9 @@ async def delete(
"""Removes the cloud region mapping for a single origin IP address.
The IP path
- parameter is normalized before lookup. Returns the deleted entry on success.
- Returns 404 (code 1163) if no mapping exists for the specified IP. When the last
- mapping for the zone is removed the underlying rule record is also deleted.
+ parameter is normalized before lookup. Returns the deleted IP on success.
+ Returns 404 if no mapping exists for the specified IP. When the last mapping for
+ the zone is removed the underlying rule record is also deleted.
Args:
zone_id: Identifier.
@@ -628,9 +599,7 @@ async def delete(
if not origin_ip:
raise ValueError(f"Expected a non-empty value for `origin_ip` but received {origin_ip!r}")
return await self._delete(
- path_template(
- "/zones/{zone_id}/cache/origin_cloud_regions/{origin_ip}", zone_id=zone_id, origin_ip=origin_ip
- ),
+ path_template("/zones/{zone_id}/origin/cloud_regions/{origin_ip}", zone_id=zone_id, origin_ip=origin_ip),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -675,7 +644,7 @@ async def bulk_delete(
if not zone_id:
raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
return await self._delete(
- path_template("/zones/{zone_id}/cache/origin_cloud_regions/batch", zone_id=zone_id),
+ path_template("/zones/{zone_id}/origin/cloud_regions/batch", zone_id=zone_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -688,25 +657,27 @@ async def bulk_delete(
),
)
- async def bulk_edit(
+ async def bulk_update(
self,
*,
zone_id: str,
- body: Iterable[origin_cloud_region_bulk_edit_params.Body],
+ body: Iterable[origin_cloud_region_bulk_update_params.Body],
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> Optional[OriginCloudRegionBulkEditResponse]:
- """Adds or updates up to 100 IP-to-cloud-region mappings in a single request.
+ ) -> Optional[OriginCloudRegionBulkUpdateResponse]:
+ """Upserts up to 100 IP-to-cloud-region mappings in a single request.
- Each
- item is validated independently — valid items are applied and invalid items are
- returned in the `failed` array. The vendor and region for every item are
- validated against the list from
- `GET /zones/{zone_id}/cache/origin_cloud_regions/supported_regions`.
+ Items in the
+ request body are created or replaced; mappings not included in the request body
+ are preserved unchanged (this is a merge operation, not a full collection
+ replacement). Each item is validated independently — valid items are applied and
+ invalid items are returned in the `failed` array. The vendor and region for
+ every item are validated against the list from
+ `GET /zones/{zone_id}/origin/cloud_regions/supported_regions`.
Args:
zone_id: Identifier.
@@ -721,84 +692,21 @@ async def bulk_edit(
"""
if not zone_id:
raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
- return await self._patch(
- path_template("/zones/{zone_id}/cache/origin_cloud_regions/batch", zone_id=zone_id),
- body=await async_maybe_transform(body, Iterable[origin_cloud_region_bulk_edit_params.Body]),
+ return await self._put(
+ path_template("/zones/{zone_id}/origin/cloud_regions/batch", zone_id=zone_id),
+ body=await async_maybe_transform(body, Iterable[origin_cloud_region_bulk_update_params.Body]),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
- post_parser=ResultWrapper[Optional[OriginCloudRegionBulkEditResponse]]._unwrapper,
+ post_parser=ResultWrapper[Optional[OriginCloudRegionBulkUpdateResponse]]._unwrapper,
),
cast_to=cast(
- Type[Optional[OriginCloudRegionBulkEditResponse]], ResultWrapper[OriginCloudRegionBulkEditResponse]
+ Type[Optional[OriginCloudRegionBulkUpdateResponse]], ResultWrapper[OriginCloudRegionBulkUpdateResponse]
),
)
- async def edit(
- self,
- *,
- zone_id: str,
- ip: str,
- region: str,
- vendor: Literal["aws", "azure", "gcp", "oci"],
- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
- # The extra values given here take precedence over values defined on the client or passed to this 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[OriginCloudRegionEditResponse]:
- """Adds or updates a single IP-to-cloud-region mapping for the zone.
-
- Unlike POST,
- this operation is idempotent — if a mapping for the IP already exists it is
- overwritten. Returns the complete updated list of all mappings for the zone.
- Returns 403 (code 1164) when the zone has reached the limit of 3,500 IP
- mappings.
-
- Args:
- zone_id: Identifier.
-
- ip: Origin IP address (IPv4 or IPv6). Normalized to canonical form before storage
- (RFC 5952 for IPv6).
-
- region: Cloud vendor region identifier. Must be a valid region for the specified vendor
- as returned by the supported_regions endpoint.
-
- vendor: Cloud vendor hosting the origin. Must be one of the supported vendors.
-
- extra_headers: Send extra headers
-
- extra_query: Add additional query parameters to the request
-
- extra_body: Add additional JSON properties to the request
-
- timeout: Override the client-level default timeout for this request, in seconds
- """
- if not zone_id:
- raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}")
- return await self._patch(
- path_template("/zones/{zone_id}/cache/origin_cloud_regions", zone_id=zone_id),
- body=await async_maybe_transform(
- {
- "ip": ip,
- "region": region,
- "vendor": vendor,
- },
- origin_cloud_region_edit_params.OriginCloudRegionEditParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- post_parser=ResultWrapper[Optional[OriginCloudRegionEditResponse]]._unwrapper,
- ),
- cast_to=cast(Type[Optional[OriginCloudRegionEditResponse]], ResultWrapper[OriginCloudRegionEditResponse]),
- )
-
async def get(
self,
origin_ip: str,
@@ -810,12 +718,12 @@ async def get(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> Optional[OriginCloudRegionGetResponse]:
+ ) -> Optional[OriginCloudRegion]:
"""Returns the cloud region mapping for a single origin IP address.
The IP path
- parameter is normalized before lookup (RFC 5952 for IPv6). Returns 404
- (code 1142) if the zone has no mappings or if the specified IP has no mapping.
+ parameter is normalized before lookup (RFC 5952 for IPv6). Returns 404 if the
+ zone has no mappings or if the specified IP has no mapping.
Args:
zone_id: Identifier.
@@ -833,17 +741,15 @@ async def get(
if not origin_ip:
raise ValueError(f"Expected a non-empty value for `origin_ip` but received {origin_ip!r}")
return await self._get(
- path_template(
- "/zones/{zone_id}/cache/origin_cloud_regions/{origin_ip}", zone_id=zone_id, origin_ip=origin_ip
- ),
+ path_template("/zones/{zone_id}/origin/cloud_regions/{origin_ip}", zone_id=zone_id, origin_ip=origin_ip),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
- post_parser=ResultWrapper[Optional[OriginCloudRegionGetResponse]]._unwrapper,
+ post_parser=ResultWrapper[Optional[OriginCloudRegion]]._unwrapper,
),
- cast_to=cast(Type[Optional[OriginCloudRegionGetResponse]], ResultWrapper[OriginCloudRegionGetResponse]),
+ cast_to=cast(Type[Optional[OriginCloudRegion]], ResultWrapper[OriginCloudRegion]),
)
async def supported_regions(
@@ -877,7 +783,7 @@ async def supported_regions(
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}/cache/origin_cloud_regions/supported_regions", zone_id=zone_id),
+ path_template("/zones/{zone_id}/origin/cloud_regions/supported_regions", zone_id=zone_id),
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -896,8 +802,8 @@ class OriginCloudRegionsResourceWithRawResponse:
def __init__(self, origin_cloud_regions: OriginCloudRegionsResource) -> None:
self._origin_cloud_regions = origin_cloud_regions
- self.create = to_raw_response_wrapper(
- origin_cloud_regions.create,
+ self.update = to_raw_response_wrapper(
+ origin_cloud_regions.update,
)
self.list = to_raw_response_wrapper(
origin_cloud_regions.list,
@@ -908,11 +814,8 @@ def __init__(self, origin_cloud_regions: OriginCloudRegionsResource) -> None:
self.bulk_delete = to_raw_response_wrapper(
origin_cloud_regions.bulk_delete,
)
- self.bulk_edit = to_raw_response_wrapper(
- origin_cloud_regions.bulk_edit,
- )
- self.edit = to_raw_response_wrapper(
- origin_cloud_regions.edit,
+ self.bulk_update = to_raw_response_wrapper(
+ origin_cloud_regions.bulk_update,
)
self.get = to_raw_response_wrapper(
origin_cloud_regions.get,
@@ -926,8 +829,8 @@ class AsyncOriginCloudRegionsResourceWithRawResponse:
def __init__(self, origin_cloud_regions: AsyncOriginCloudRegionsResource) -> None:
self._origin_cloud_regions = origin_cloud_regions
- self.create = async_to_raw_response_wrapper(
- origin_cloud_regions.create,
+ self.update = async_to_raw_response_wrapper(
+ origin_cloud_regions.update,
)
self.list = async_to_raw_response_wrapper(
origin_cloud_regions.list,
@@ -938,11 +841,8 @@ def __init__(self, origin_cloud_regions: AsyncOriginCloudRegionsResource) -> Non
self.bulk_delete = async_to_raw_response_wrapper(
origin_cloud_regions.bulk_delete,
)
- self.bulk_edit = async_to_raw_response_wrapper(
- origin_cloud_regions.bulk_edit,
- )
- self.edit = async_to_raw_response_wrapper(
- origin_cloud_regions.edit,
+ self.bulk_update = async_to_raw_response_wrapper(
+ origin_cloud_regions.bulk_update,
)
self.get = async_to_raw_response_wrapper(
origin_cloud_regions.get,
@@ -956,8 +856,8 @@ class OriginCloudRegionsResourceWithStreamingResponse:
def __init__(self, origin_cloud_regions: OriginCloudRegionsResource) -> None:
self._origin_cloud_regions = origin_cloud_regions
- self.create = to_streamed_response_wrapper(
- origin_cloud_regions.create,
+ self.update = to_streamed_response_wrapper(
+ origin_cloud_regions.update,
)
self.list = to_streamed_response_wrapper(
origin_cloud_regions.list,
@@ -968,11 +868,8 @@ def __init__(self, origin_cloud_regions: OriginCloudRegionsResource) -> None:
self.bulk_delete = to_streamed_response_wrapper(
origin_cloud_regions.bulk_delete,
)
- self.bulk_edit = to_streamed_response_wrapper(
- origin_cloud_regions.bulk_edit,
- )
- self.edit = to_streamed_response_wrapper(
- origin_cloud_regions.edit,
+ self.bulk_update = to_streamed_response_wrapper(
+ origin_cloud_regions.bulk_update,
)
self.get = to_streamed_response_wrapper(
origin_cloud_regions.get,
@@ -986,8 +883,8 @@ class AsyncOriginCloudRegionsResourceWithStreamingResponse:
def __init__(self, origin_cloud_regions: AsyncOriginCloudRegionsResource) -> None:
self._origin_cloud_regions = origin_cloud_regions
- self.create = async_to_streamed_response_wrapper(
- origin_cloud_regions.create,
+ self.update = async_to_streamed_response_wrapper(
+ origin_cloud_regions.update,
)
self.list = async_to_streamed_response_wrapper(
origin_cloud_regions.list,
@@ -998,11 +895,8 @@ def __init__(self, origin_cloud_regions: AsyncOriginCloudRegionsResource) -> Non
self.bulk_delete = async_to_streamed_response_wrapper(
origin_cloud_regions.bulk_delete,
)
- self.bulk_edit = async_to_streamed_response_wrapper(
- origin_cloud_regions.bulk_edit,
- )
- self.edit = async_to_streamed_response_wrapper(
- origin_cloud_regions.edit,
+ self.bulk_update = async_to_streamed_response_wrapper(
+ origin_cloud_regions.bulk_update,
)
self.get = async_to_streamed_response_wrapper(
origin_cloud_regions.get,
diff --git a/src/cloudflare/resources/cache/smart_tiered_cache.py b/src/cloudflare/resources/cache/smart_tiered_cache.py
index ce23d7d3c3e..fe272d3765b 100644
--- a/src/cloudflare/resources/cache/smart_tiered_cache.py
+++ b/src/cloudflare/resources/cache/smart_tiered_cache.py
@@ -18,10 +18,11 @@
async_to_streamed_response_wrapper,
)
from ..._wrappers import ResultWrapper
-from ...types.cache import smart_tiered_cache_edit_params
+from ...types.cache import smart_tiered_cache_edit_params, smart_tiered_cache_create_params
from ..._base_client import make_request_options
from ...types.cache.smart_tiered_cache_get_response import SmartTieredCacheGetResponse
from ...types.cache.smart_tiered_cache_edit_response import SmartTieredCacheEditResponse
+from ...types.cache.smart_tiered_cache_create_response import SmartTieredCacheCreateResponse
from ...types.cache.smart_tiered_cache_delete_response import SmartTieredCacheDeleteResponse
__all__ = ["SmartTieredCacheResource", "AsyncSmartTieredCacheResource"]
@@ -47,6 +48,54 @@ def with_streaming_response(self) -> SmartTieredCacheResourceWithStreamingRespon
"""
return SmartTieredCacheResourceWithStreamingResponse(self)
+ def create(
+ self,
+ *,
+ zone_id: str,
+ value: Literal["on", "off"],
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this 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[SmartTieredCacheCreateResponse]:
+ """
+ Smart Tiered Cache dynamically selects the single closest upper tier for each of
+ your website's origins with no configuration required, using our in-house
+ performance and routing data. Cloudflare collects latency data for each request
+ to an origin, and uses the latency data to determine how well any upper-tier
+ data center is connected with an origin. As a result, Cloudflare can select the
+ data center with the lowest latency to be the upper-tier for an origin.
+
+ Args:
+ zone_id: Identifier.
+
+ value: Enable or disable the Smart Tiered Cache.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the 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._post(
+ path_template("/zones/{zone_id}/cache/tiered_cache_smart_topology_enable", zone_id=zone_id),
+ body=maybe_transform({"value": value}, smart_tiered_cache_create_params.SmartTieredCacheCreateParams),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[SmartTieredCacheCreateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[SmartTieredCacheCreateResponse]], ResultWrapper[SmartTieredCacheCreateResponse]),
+ )
+
def delete(
self,
*,
@@ -204,6 +253,56 @@ def with_streaming_response(self) -> AsyncSmartTieredCacheResourceWithStreamingR
"""
return AsyncSmartTieredCacheResourceWithStreamingResponse(self)
+ async def create(
+ self,
+ *,
+ zone_id: str,
+ value: Literal["on", "off"],
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this 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[SmartTieredCacheCreateResponse]:
+ """
+ Smart Tiered Cache dynamically selects the single closest upper tier for each of
+ your website's origins with no configuration required, using our in-house
+ performance and routing data. Cloudflare collects latency data for each request
+ to an origin, and uses the latency data to determine how well any upper-tier
+ data center is connected with an origin. As a result, Cloudflare can select the
+ data center with the lowest latency to be the upper-tier for an origin.
+
+ Args:
+ zone_id: Identifier.
+
+ value: Enable or disable the Smart Tiered Cache.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the 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._post(
+ path_template("/zones/{zone_id}/cache/tiered_cache_smart_topology_enable", zone_id=zone_id),
+ body=await async_maybe_transform(
+ {"value": value}, smart_tiered_cache_create_params.SmartTieredCacheCreateParams
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[SmartTieredCacheCreateResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[SmartTieredCacheCreateResponse]], ResultWrapper[SmartTieredCacheCreateResponse]),
+ )
+
async def delete(
self,
*,
@@ -347,6 +446,9 @@ class SmartTieredCacheResourceWithRawResponse:
def __init__(self, smart_tiered_cache: SmartTieredCacheResource) -> None:
self._smart_tiered_cache = smart_tiered_cache
+ self.create = to_raw_response_wrapper(
+ smart_tiered_cache.create,
+ )
self.delete = to_raw_response_wrapper(
smart_tiered_cache.delete,
)
@@ -362,6 +464,9 @@ class AsyncSmartTieredCacheResourceWithRawResponse:
def __init__(self, smart_tiered_cache: AsyncSmartTieredCacheResource) -> None:
self._smart_tiered_cache = smart_tiered_cache
+ self.create = async_to_raw_response_wrapper(
+ smart_tiered_cache.create,
+ )
self.delete = async_to_raw_response_wrapper(
smart_tiered_cache.delete,
)
@@ -377,6 +482,9 @@ class SmartTieredCacheResourceWithStreamingResponse:
def __init__(self, smart_tiered_cache: SmartTieredCacheResource) -> None:
self._smart_tiered_cache = smart_tiered_cache
+ self.create = to_streamed_response_wrapper(
+ smart_tiered_cache.create,
+ )
self.delete = to_streamed_response_wrapper(
smart_tiered_cache.delete,
)
@@ -392,6 +500,9 @@ class AsyncSmartTieredCacheResourceWithStreamingResponse:
def __init__(self, smart_tiered_cache: AsyncSmartTieredCacheResource) -> None:
self._smart_tiered_cache = smart_tiered_cache
+ self.create = async_to_streamed_response_wrapper(
+ smart_tiered_cache.create,
+ )
self.delete = async_to_streamed_response_wrapper(
smart_tiered_cache.delete,
)
diff --git a/src/cloudflare/resources/cloudforce_one/threat_events/threat_events.py b/src/cloudflare/resources/cloudforce_one/threat_events/threat_events.py
index a6ce67298e5..0a85505a555 100644
--- a/src/cloudflare/resources/cloudforce_one/threat_events/threat_events.py
+++ b/src/cloudflare/resources/cloudforce_one/threat_events/threat_events.py
@@ -260,7 +260,7 @@ def list(
cursor: str | Omit = omit,
dataset_id: SequenceNotStr[str] | Omit = omit,
force_refresh: bool | Omit = omit,
- format: Literal["json", "stix2"] | Omit = omit,
+ format: Literal["json", "stix2", "taxii"] | Omit = omit,
order: Literal["asc", "desc"] | Omit = omit,
order_by: str | Omit = omit,
page: float | Omit = omit,
@@ -653,7 +653,7 @@ async def list(
cursor: str | Omit = omit,
dataset_id: SequenceNotStr[str] | Omit = omit,
force_refresh: bool | Omit = omit,
- format: Literal["json", "stix2"] | Omit = omit,
+ format: Literal["json", "stix2", "taxii"] | Omit = omit,
order: Literal["asc", "desc"] | Omit = omit,
order_by: str | Omit = omit,
page: float | Omit = omit,
diff --git a/src/cloudflare/resources/load_balancers/api.md b/src/cloudflare/resources/load_balancers/api.md
index 947746e3fe6..58bd01c5f43 100644
--- a/src/cloudflare/resources/load_balancers/api.md
+++ b/src/cloudflare/resources/load_balancers/api.md
@@ -85,12 +85,24 @@ from cloudflare.types.load_balancers import MonitorGroup
Methods:
-- client.load_balancers.monitor_groups.create(\*, account_id, \*\*params) -> MonitorGroup
-- client.load_balancers.monitor_groups.update(monitor_group_id, \*, account_id, \*\*params) -> MonitorGroup
-- client.load_balancers.monitor_groups.list(\*, account_id) -> SyncSinglePage[MonitorGroup]
-- client.load_balancers.monitor_groups.delete(monitor_group_id, \*, account_id) -> MonitorGroup
-- client.load_balancers.monitor_groups.edit(monitor_group_id, \*, account_id, \*\*params) -> MonitorGroup
-- client.load_balancers.monitor_groups.get(monitor_group_id, \*, account_id) -> MonitorGroup
+- client.load_balancers.monitor_groups.create(\*, account_id, \*\*params) -> MonitorGroup
+- client.load_balancers.monitor_groups.update(monitor_group_id, \*, account_id, \*\*params) -> MonitorGroup
+- client.load_balancers.monitor_groups.list(\*, account_id) -> SyncSinglePage[MonitorGroup]
+- client.load_balancers.monitor_groups.delete(monitor_group_id, \*, account_id) -> MonitorGroup
+- client.load_balancers.monitor_groups.edit(monitor_group_id, \*, account_id, \*\*params) -> MonitorGroup
+- client.load_balancers.monitor_groups.get(monitor_group_id, \*, account_id) -> MonitorGroup
+
+### References
+
+Types:
+
+```python
+from cloudflare.types.load_balancers.monitor_groups import ReferenceGetResponse
+```
+
+Methods:
+
+- client.load_balancers.monitor_groups.references.get(monitor_group_id, \*, account_id) -> SyncSinglePage[ReferenceGetResponse]
## Pools
diff --git a/src/cloudflare/resources/load_balancers/load_balancers.py b/src/cloudflare/resources/load_balancers/load_balancers.py
index 83f2ac5dd7c..277f7a5c7fe 100644
--- a/src/cloudflare/resources/load_balancers/load_balancers.py
+++ b/src/cloudflare/resources/load_balancers/load_balancers.py
@@ -51,14 +51,6 @@
)
from ...pagination import SyncSinglePage, AsyncSinglePage
from ..._base_client import AsyncPaginator, make_request_options
-from .monitor_groups import (
- MonitorGroupsResource,
- AsyncMonitorGroupsResource,
- MonitorGroupsResourceWithRawResponse,
- AsyncMonitorGroupsResourceWithRawResponse,
- MonitorGroupsResourceWithStreamingResponse,
- AsyncMonitorGroupsResourceWithStreamingResponse,
-)
from .monitors.monitors import (
MonitorsResource,
AsyncMonitorsResource,
@@ -74,6 +66,14 @@
load_balancer_create_params,
load_balancer_update_params,
)
+from .monitor_groups.monitor_groups import (
+ MonitorGroupsResource,
+ AsyncMonitorGroupsResource,
+ MonitorGroupsResourceWithRawResponse,
+ AsyncMonitorGroupsResourceWithRawResponse,
+ MonitorGroupsResourceWithStreamingResponse,
+ AsyncMonitorGroupsResourceWithStreamingResponse,
+)
from ...types.load_balancers.rules_param import RulesParam
from ...types.load_balancers.default_pools import DefaultPools
from ...types.load_balancers.load_balancer import LoadBalancer
diff --git a/src/cloudflare/resources/load_balancers/monitor_groups/__init__.py b/src/cloudflare/resources/load_balancers/monitor_groups/__init__.py
new file mode 100644
index 00000000000..f7790874f1c
--- /dev/null
+++ b/src/cloudflare/resources/load_balancers/monitor_groups/__init__.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .references import (
+ ReferencesResource,
+ AsyncReferencesResource,
+ ReferencesResourceWithRawResponse,
+ AsyncReferencesResourceWithRawResponse,
+ ReferencesResourceWithStreamingResponse,
+ AsyncReferencesResourceWithStreamingResponse,
+)
+from .monitor_groups import (
+ MonitorGroupsResource,
+ AsyncMonitorGroupsResource,
+ MonitorGroupsResourceWithRawResponse,
+ AsyncMonitorGroupsResourceWithRawResponse,
+ MonitorGroupsResourceWithStreamingResponse,
+ AsyncMonitorGroupsResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "ReferencesResource",
+ "AsyncReferencesResource",
+ "ReferencesResourceWithRawResponse",
+ "AsyncReferencesResourceWithRawResponse",
+ "ReferencesResourceWithStreamingResponse",
+ "AsyncReferencesResourceWithStreamingResponse",
+ "MonitorGroupsResource",
+ "AsyncMonitorGroupsResource",
+ "MonitorGroupsResourceWithRawResponse",
+ "AsyncMonitorGroupsResourceWithRawResponse",
+ "MonitorGroupsResourceWithStreamingResponse",
+ "AsyncMonitorGroupsResourceWithStreamingResponse",
+]
diff --git a/src/cloudflare/resources/load_balancers/monitor_groups.py b/src/cloudflare/resources/load_balancers/monitor_groups/monitor_groups.py
similarity index 94%
rename from src/cloudflare/resources/load_balancers/monitor_groups.py
rename to src/cloudflare/resources/load_balancers/monitor_groups/monitor_groups.py
index 97990a78f5c..af986d2cb85 100644
--- a/src/cloudflare/resources/load_balancers/monitor_groups.py
+++ b/src/cloudflare/resources/load_balancers/monitor_groups/monitor_groups.py
@@ -6,26 +6,38 @@
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 (
+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 .references import (
+ ReferencesResource,
+ AsyncReferencesResource,
+ ReferencesResourceWithRawResponse,
+ AsyncReferencesResourceWithRawResponse,
+ ReferencesResourceWithStreamingResponse,
+ AsyncReferencesResourceWithStreamingResponse,
+)
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from ...._response import (
to_raw_response_wrapper,
to_streamed_response_wrapper,
async_to_raw_response_wrapper,
async_to_streamed_response_wrapper,
)
-from ..._wrappers import ResultWrapper
-from ...pagination import SyncSinglePage, AsyncSinglePage
-from ..._base_client import AsyncPaginator, make_request_options
-from ...types.load_balancers import monitor_group_edit_params, monitor_group_create_params, monitor_group_update_params
-from ...types.load_balancers.monitor_group import MonitorGroup
+from ...._wrappers import ResultWrapper
+from ....pagination import SyncSinglePage, AsyncSinglePage
+from ...._base_client import AsyncPaginator, make_request_options
+from ....types.load_balancers import monitor_group_edit_params, monitor_group_create_params, monitor_group_update_params
+from ....types.load_balancers.monitor_group import MonitorGroup
__all__ = ["MonitorGroupsResource", "AsyncMonitorGroupsResource"]
class MonitorGroupsResource(SyncAPIResource):
+ @cached_property
+ def references(self) -> ReferencesResource:
+ return ReferencesResource(self._client)
+
@cached_property
def with_raw_response(self) -> MonitorGroupsResourceWithRawResponse:
"""
@@ -49,7 +61,6 @@ def create(
self,
*,
account_id: str,
- id: str,
description: str,
members: Iterable[monitor_group_create_params.Member],
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -65,9 +76,6 @@ def create(
Args:
account_id: Identifier.
- id: The ID of the Monitor Group to use for checking the health of origins within
- this pool.
-
description: A short description of the monitor group
members: List of monitors in this group
@@ -86,7 +94,6 @@ def create(
path_template("/accounts/{account_id}/load_balancers/monitor_groups", account_id=account_id),
body=maybe_transform(
{
- "id": id,
"description": description,
"members": members,
},
@@ -107,7 +114,6 @@ def update(
monitor_group_id: str,
*,
account_id: str,
- id: str,
description: str,
members: Iterable[monitor_group_update_params.Member],
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -123,9 +129,6 @@ def update(
Args:
account_id: Identifier.
- id: The ID of the Monitor Group to use for checking the health of origins within
- this pool.
-
description: A short description of the monitor group
members: List of monitors in this group
@@ -150,7 +153,6 @@ def update(
),
body=maybe_transform(
{
- "id": id,
"description": description,
"members": members,
},
@@ -253,7 +255,6 @@ def edit(
monitor_group_id: str,
*,
account_id: str,
- id: str,
description: str,
members: Iterable[monitor_group_edit_params.Member],
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -269,9 +270,6 @@ def edit(
Args:
account_id: Identifier.
- id: The ID of the Monitor Group to use for checking the health of origins within
- this pool.
-
description: A short description of the monitor group
members: List of monitors in this group
@@ -296,7 +294,6 @@ def edit(
),
body=maybe_transform(
{
- "id": id,
"description": description,
"members": members,
},
@@ -360,6 +357,10 @@ def get(
class AsyncMonitorGroupsResource(AsyncAPIResource):
+ @cached_property
+ def references(self) -> AsyncReferencesResource:
+ return AsyncReferencesResource(self._client)
+
@cached_property
def with_raw_response(self) -> AsyncMonitorGroupsResourceWithRawResponse:
"""
@@ -383,7 +384,6 @@ async def create(
self,
*,
account_id: str,
- id: str,
description: str,
members: Iterable[monitor_group_create_params.Member],
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -399,9 +399,6 @@ async def create(
Args:
account_id: Identifier.
- id: The ID of the Monitor Group to use for checking the health of origins within
- this pool.
-
description: A short description of the monitor group
members: List of monitors in this group
@@ -420,7 +417,6 @@ async def create(
path_template("/accounts/{account_id}/load_balancers/monitor_groups", account_id=account_id),
body=await async_maybe_transform(
{
- "id": id,
"description": description,
"members": members,
},
@@ -441,7 +437,6 @@ async def update(
monitor_group_id: str,
*,
account_id: str,
- id: str,
description: str,
members: Iterable[monitor_group_update_params.Member],
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -457,9 +452,6 @@ async def update(
Args:
account_id: Identifier.
- id: The ID of the Monitor Group to use for checking the health of origins within
- this pool.
-
description: A short description of the monitor group
members: List of monitors in this group
@@ -484,7 +476,6 @@ async def update(
),
body=await async_maybe_transform(
{
- "id": id,
"description": description,
"members": members,
},
@@ -587,7 +578,6 @@ async def edit(
monitor_group_id: str,
*,
account_id: str,
- id: str,
description: str,
members: Iterable[monitor_group_edit_params.Member],
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
@@ -603,9 +593,6 @@ async def edit(
Args:
account_id: Identifier.
- id: The ID of the Monitor Group to use for checking the health of origins within
- this pool.
-
description: A short description of the monitor group
members: List of monitors in this group
@@ -630,7 +617,6 @@ async def edit(
),
body=await async_maybe_transform(
{
- "id": id,
"description": description,
"members": members,
},
@@ -716,6 +702,10 @@ def __init__(self, monitor_groups: MonitorGroupsResource) -> None:
monitor_groups.get,
)
+ @cached_property
+ def references(self) -> ReferencesResourceWithRawResponse:
+ return ReferencesResourceWithRawResponse(self._monitor_groups.references)
+
class AsyncMonitorGroupsResourceWithRawResponse:
def __init__(self, monitor_groups: AsyncMonitorGroupsResource) -> None:
@@ -740,6 +730,10 @@ def __init__(self, monitor_groups: AsyncMonitorGroupsResource) -> None:
monitor_groups.get,
)
+ @cached_property
+ def references(self) -> AsyncReferencesResourceWithRawResponse:
+ return AsyncReferencesResourceWithRawResponse(self._monitor_groups.references)
+
class MonitorGroupsResourceWithStreamingResponse:
def __init__(self, monitor_groups: MonitorGroupsResource) -> None:
@@ -764,6 +758,10 @@ def __init__(self, monitor_groups: MonitorGroupsResource) -> None:
monitor_groups.get,
)
+ @cached_property
+ def references(self) -> ReferencesResourceWithStreamingResponse:
+ return ReferencesResourceWithStreamingResponse(self._monitor_groups.references)
+
class AsyncMonitorGroupsResourceWithStreamingResponse:
def __init__(self, monitor_groups: AsyncMonitorGroupsResource) -> None:
@@ -787,3 +785,7 @@ def __init__(self, monitor_groups: AsyncMonitorGroupsResource) -> None:
self.get = async_to_streamed_response_wrapper(
monitor_groups.get,
)
+
+ @cached_property
+ def references(self) -> AsyncReferencesResourceWithStreamingResponse:
+ return AsyncReferencesResourceWithStreamingResponse(self._monitor_groups.references)
diff --git a/src/cloudflare/resources/load_balancers/monitor_groups/references.py b/src/cloudflare/resources/load_balancers/monitor_groups/references.py
new file mode 100644
index 00000000000..8e0f97f4fef
--- /dev/null
+++ b/src/cloudflare/resources/load_balancers/monitor_groups/references.py
@@ -0,0 +1,185 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from ...._types import Body, Query, Headers, NotGiven, not_given
+from ...._utils import path_template
+from ...._compat import cached_property
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from ...._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ....pagination import SyncSinglePage, AsyncSinglePage
+from ...._base_client import AsyncPaginator, make_request_options
+from ....types.load_balancers.monitor_groups.reference_get_response import ReferenceGetResponse
+
+__all__ = ["ReferencesResource", "AsyncReferencesResource"]
+
+
+class ReferencesResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> ReferencesResourceWithRawResponse:
+ """
+ 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 ReferencesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> ReferencesResourceWithStreamingResponse:
+ """
+ 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 ReferencesResourceWithStreamingResponse(self)
+
+ def get(
+ self,
+ monitor_group_id: str,
+ *,
+ account_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> SyncSinglePage[ReferenceGetResponse]:
+ """
+ Get the list of resources that reference the provided monitor group.
+
+ 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}")
+ if not monitor_group_id:
+ raise ValueError(f"Expected a non-empty value for `monitor_group_id` but received {monitor_group_id!r}")
+ return self._get_api_list(
+ path_template(
+ "/accounts/{account_id}/load_balancers/monitor_groups/{monitor_group_id}/references",
+ account_id=account_id,
+ monitor_group_id=monitor_group_id,
+ ),
+ page=SyncSinglePage[ReferenceGetResponse],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=ReferenceGetResponse,
+ )
+
+
+class AsyncReferencesResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncReferencesResourceWithRawResponse:
+ """
+ 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 AsyncReferencesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncReferencesResourceWithStreamingResponse:
+ """
+ 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 AsyncReferencesResourceWithStreamingResponse(self)
+
+ def get(
+ self,
+ monitor_group_id: str,
+ *,
+ account_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> AsyncPaginator[ReferenceGetResponse, AsyncSinglePage[ReferenceGetResponse]]:
+ """
+ Get the list of resources that reference the provided monitor group.
+
+ 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}")
+ if not monitor_group_id:
+ raise ValueError(f"Expected a non-empty value for `monitor_group_id` but received {monitor_group_id!r}")
+ return self._get_api_list(
+ path_template(
+ "/accounts/{account_id}/load_balancers/monitor_groups/{monitor_group_id}/references",
+ account_id=account_id,
+ monitor_group_id=monitor_group_id,
+ ),
+ page=AsyncSinglePage[ReferenceGetResponse],
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ model=ReferenceGetResponse,
+ )
+
+
+class ReferencesResourceWithRawResponse:
+ def __init__(self, references: ReferencesResource) -> None:
+ self._references = references
+
+ self.get = to_raw_response_wrapper(
+ references.get,
+ )
+
+
+class AsyncReferencesResourceWithRawResponse:
+ def __init__(self, references: AsyncReferencesResource) -> None:
+ self._references = references
+
+ self.get = async_to_raw_response_wrapper(
+ references.get,
+ )
+
+
+class ReferencesResourceWithStreamingResponse:
+ def __init__(self, references: ReferencesResource) -> None:
+ self._references = references
+
+ self.get = to_streamed_response_wrapper(
+ references.get,
+ )
+
+
+class AsyncReferencesResourceWithStreamingResponse:
+ def __init__(self, references: AsyncReferencesResource) -> None:
+ self._references = references
+
+ self.get = async_to_streamed_response_wrapper(
+ references.get,
+ )
diff --git a/src/cloudflare/resources/radar/api.md b/src/cloudflare/resources/radar/api.md
index 1b322eb9563..30ab46a98ad 100644
--- a/src/cloudflare/resources/radar/api.md
+++ b/src/cloudflare/resources/radar/api.md
@@ -305,7 +305,19 @@ from cloudflare.types.radar.bgp import IPTimeseriesResponse
Methods:
-- client.radar.bgp.ips.timeseries(\*\*params) -> IPTimeseriesResponse
+- client.radar.bgp.ips.timeseries(\*\*params) -> IPTimeseriesResponse
+
+#### Top
+
+Types:
+
+```python
+from cloudflare.types.radar.bgp.ips import TopAsesResponse
+```
+
+Methods:
+
+- client.radar.bgp.ips.top.ases(\*\*params) -> TopAsesResponse
### RPKI
@@ -327,6 +339,18 @@ Methods:
- client.radar.bgp.rpki.aspa.snapshot(\*\*params) -> ASPASnapshotResponse
- client.radar.bgp.rpki.aspa.timeseries(\*\*params) -> ASPATimeseriesResponse
+#### Roas
+
+Types:
+
+```python
+from cloudflare.types.radar.bgp.rpki import RoaTimeseriesResponse
+```
+
+Methods:
+
+- client.radar.bgp.rpki.roas.timeseries(\*\*params) -> RoaTimeseriesResponse
+
## Bots
Types:
diff --git a/src/cloudflare/resources/radar/bgp/bgp.py b/src/cloudflare/resources/radar/bgp/bgp.py
index d4d93f61538..f84cb3d137f 100644
--- a/src/cloudflare/resources/radar/bgp/bgp.py
+++ b/src/cloudflare/resources/radar/bgp/bgp.py
@@ -8,14 +8,6 @@
import httpx
-from .ips import (
- IPsResource,
- AsyncIPsResource,
- IPsResourceWithRawResponse,
- AsyncIPsResourceWithRawResponse,
- IPsResourceWithStreamingResponse,
- AsyncIPsResourceWithStreamingResponse,
-)
from .routes import (
RoutesResource,
AsyncRoutesResource,
@@ -24,6 +16,14 @@
RoutesResourceWithStreamingResponse,
AsyncRoutesResourceWithStreamingResponse,
)
+from .ips.ips import (
+ IPsResource,
+ AsyncIPsResource,
+ IPsResourceWithRawResponse,
+ AsyncIPsResourceWithRawResponse,
+ IPsResourceWithStreamingResponse,
+ AsyncIPsResourceWithStreamingResponse,
+)
from .top.top import (
TopResource,
AsyncTopResource,
diff --git a/src/cloudflare/resources/radar/bgp/ips/__init__.py b/src/cloudflare/resources/radar/bgp/ips/__init__.py
new file mode 100644
index 00000000000..7fb6d08dcd8
--- /dev/null
+++ b/src/cloudflare/resources/radar/bgp/ips/__init__.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .ips import (
+ IPsResource,
+ AsyncIPsResource,
+ IPsResourceWithRawResponse,
+ AsyncIPsResourceWithRawResponse,
+ IPsResourceWithStreamingResponse,
+ AsyncIPsResourceWithStreamingResponse,
+)
+from .top import (
+ TopResource,
+ AsyncTopResource,
+ TopResourceWithRawResponse,
+ AsyncTopResourceWithRawResponse,
+ TopResourceWithStreamingResponse,
+ AsyncTopResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "TopResource",
+ "AsyncTopResource",
+ "TopResourceWithRawResponse",
+ "AsyncTopResourceWithRawResponse",
+ "TopResourceWithStreamingResponse",
+ "AsyncTopResourceWithStreamingResponse",
+ "IPsResource",
+ "AsyncIPsResource",
+ "IPsResourceWithRawResponse",
+ "AsyncIPsResourceWithRawResponse",
+ "IPsResourceWithStreamingResponse",
+ "AsyncIPsResourceWithStreamingResponse",
+]
diff --git a/src/cloudflare/resources/radar/bgp/ips.py b/src/cloudflare/resources/radar/bgp/ips/ips.py
similarity index 87%
rename from src/cloudflare/resources/radar/bgp/ips.py
rename to src/cloudflare/resources/radar/bgp/ips/ips.py
index ed5d5aa4891..1cb8186841d 100644
--- a/src/cloudflare/resources/radar/bgp/ips.py
+++ b/src/cloudflare/resources/radar/bgp/ips/ips.py
@@ -8,25 +8,37 @@
import httpx
-from ...._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from ...._utils import maybe_transform, async_maybe_transform
-from ...._compat import cached_property
-from ...._resource import SyncAPIResource, AsyncAPIResource
-from ...._response import (
+from .top import (
+ TopResource,
+ AsyncTopResource,
+ TopResourceWithRawResponse,
+ AsyncTopResourceWithRawResponse,
+ TopResourceWithStreamingResponse,
+ AsyncTopResourceWithStreamingResponse,
+)
+from ....._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
+from ....._utils import maybe_transform, async_maybe_transform
+from ....._compat import cached_property
+from ....._resource import SyncAPIResource, AsyncAPIResource
+from ....._response import (
to_raw_response_wrapper,
to_streamed_response_wrapper,
async_to_raw_response_wrapper,
async_to_streamed_response_wrapper,
)
-from ...._wrappers import ResultWrapper
-from ...._base_client import make_request_options
-from ....types.radar.bgp import ip_timeseries_params
-from ....types.radar.bgp.ip_timeseries_response import IPTimeseriesResponse
+from ....._wrappers import ResultWrapper
+from ....._base_client import make_request_options
+from .....types.radar.bgp import ip_timeseries_params
+from .....types.radar.bgp.ip_timeseries_response import IPTimeseriesResponse
__all__ = ["IPsResource", "AsyncIPsResource"]
class IPsResource(SyncAPIResource):
+ @cached_property
+ def top(self) -> TopResource:
+ return TopResource(self._client)
+
@cached_property
def with_raw_response(self) -> IPsResourceWithRawResponse:
"""
@@ -130,6 +142,10 @@ def timeseries(
class AsyncIPsResource(AsyncAPIResource):
+ @cached_property
+ def top(self) -> AsyncTopResource:
+ return AsyncTopResource(self._client)
+
@cached_property
def with_raw_response(self) -> AsyncIPsResourceWithRawResponse:
"""
@@ -240,6 +256,10 @@ def __init__(self, ips: IPsResource) -> None:
ips.timeseries,
)
+ @cached_property
+ def top(self) -> TopResourceWithRawResponse:
+ return TopResourceWithRawResponse(self._ips.top)
+
class AsyncIPsResourceWithRawResponse:
def __init__(self, ips: AsyncIPsResource) -> None:
@@ -249,6 +269,10 @@ def __init__(self, ips: AsyncIPsResource) -> None:
ips.timeseries,
)
+ @cached_property
+ def top(self) -> AsyncTopResourceWithRawResponse:
+ return AsyncTopResourceWithRawResponse(self._ips.top)
+
class IPsResourceWithStreamingResponse:
def __init__(self, ips: IPsResource) -> None:
@@ -258,6 +282,10 @@ def __init__(self, ips: IPsResource) -> None:
ips.timeseries,
)
+ @cached_property
+ def top(self) -> TopResourceWithStreamingResponse:
+ return TopResourceWithStreamingResponse(self._ips.top)
+
class AsyncIPsResourceWithStreamingResponse:
def __init__(self, ips: AsyncIPsResource) -> None:
@@ -266,3 +294,7 @@ def __init__(self, ips: AsyncIPsResource) -> None:
self.timeseries = async_to_streamed_response_wrapper(
ips.timeseries,
)
+
+ @cached_property
+ def top(self) -> AsyncTopResourceWithStreamingResponse:
+ return AsyncTopResourceWithStreamingResponse(self._ips.top)
diff --git a/src/cloudflare/resources/radar/bgp/ips/top.py b/src/cloudflare/resources/radar/bgp/ips/top.py
new file mode 100644
index 00000000000..692b17c1fc5
--- /dev/null
+++ b/src/cloudflare/resources/radar/bgp/ips/top.py
@@ -0,0 +1,226 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Type, Union, cast
+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 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.radar.bgp.ips import top_ases_params
+from .....types.radar.bgp.ips.top_ases_response import TopAsesResponse
+
+__all__ = ["TopResource", "AsyncTopResource"]
+
+
+class TopResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> TopResourceWithRawResponse:
+ """
+ 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 TopResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> TopResourceWithStreamingResponse:
+ """
+ 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 TopResourceWithStreamingResponse(self)
+
+ def ases(
+ self,
+ *,
+ country: str | Omit = omit,
+ date: Union[str, datetime] | Omit = omit,
+ format: Literal["JSON", "CSV"] | Omit = omit,
+ limit: int | Omit = omit,
+ metric: Literal["v4_24s", "v6_48s"] | 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,
+ ) -> TopAsesResponse:
+ """
+ Returns the top-N autonomous systems by announced IP space at the nearest 8-hour
+ RIB boundary at or before the requested date. The snapped boundary is returned
+ as `anchor_ts`.
+
+ Args:
+ country: Optional ISO 3166-1 alpha-2 country filter. Omit for global top-N.
+
+ date: Filters results by the specified datetime (ISO 8601).
+
+ format: Format in which results will be returned.
+
+ limit: Limits the number of objects returned in the response.
+
+ metric: Ranking metric: IPv4 /24 count or IPv6 /48 count.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._get(
+ "/radar/bgp/ips/top/ases",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "country": country,
+ "date": date,
+ "format": format,
+ "limit": limit,
+ "metric": metric,
+ },
+ top_ases_params.TopAsesParams,
+ ),
+ post_parser=ResultWrapper[TopAsesResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[TopAsesResponse], ResultWrapper[TopAsesResponse]),
+ )
+
+
+class AsyncTopResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncTopResourceWithRawResponse:
+ """
+ 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 AsyncTopResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncTopResourceWithStreamingResponse:
+ """
+ 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 AsyncTopResourceWithStreamingResponse(self)
+
+ async def ases(
+ self,
+ *,
+ country: str | Omit = omit,
+ date: Union[str, datetime] | Omit = omit,
+ format: Literal["JSON", "CSV"] | Omit = omit,
+ limit: int | Omit = omit,
+ metric: Literal["v4_24s", "v6_48s"] | 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,
+ ) -> TopAsesResponse:
+ """
+ Returns the top-N autonomous systems by announced IP space at the nearest 8-hour
+ RIB boundary at or before the requested date. The snapped boundary is returned
+ as `anchor_ts`.
+
+ Args:
+ country: Optional ISO 3166-1 alpha-2 country filter. Omit for global top-N.
+
+ date: Filters results by the specified datetime (ISO 8601).
+
+ format: Format in which results will be returned.
+
+ limit: Limits the number of objects returned in the response.
+
+ metric: Ranking metric: IPv4 /24 count or IPv6 /48 count.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._get(
+ "/radar/bgp/ips/top/ases",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "country": country,
+ "date": date,
+ "format": format,
+ "limit": limit,
+ "metric": metric,
+ },
+ top_ases_params.TopAsesParams,
+ ),
+ post_parser=ResultWrapper[TopAsesResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[TopAsesResponse], ResultWrapper[TopAsesResponse]),
+ )
+
+
+class TopResourceWithRawResponse:
+ def __init__(self, top: TopResource) -> None:
+ self._top = top
+
+ self.ases = to_raw_response_wrapper(
+ top.ases,
+ )
+
+
+class AsyncTopResourceWithRawResponse:
+ def __init__(self, top: AsyncTopResource) -> None:
+ self._top = top
+
+ self.ases = async_to_raw_response_wrapper(
+ top.ases,
+ )
+
+
+class TopResourceWithStreamingResponse:
+ def __init__(self, top: TopResource) -> None:
+ self._top = top
+
+ self.ases = to_streamed_response_wrapper(
+ top.ases,
+ )
+
+
+class AsyncTopResourceWithStreamingResponse:
+ def __init__(self, top: AsyncTopResource) -> None:
+ self._top = top
+
+ self.ases = async_to_streamed_response_wrapper(
+ top.ases,
+ )
diff --git a/src/cloudflare/resources/radar/bgp/rpki/__init__.py b/src/cloudflare/resources/radar/bgp/rpki/__init__.py
index 824bd86d5d1..c09318d6d8b 100644
--- a/src/cloudflare/resources/radar/bgp/rpki/__init__.py
+++ b/src/cloudflare/resources/radar/bgp/rpki/__init__.py
@@ -8,6 +8,14 @@
ASPAResourceWithStreamingResponse,
AsyncASPAResourceWithStreamingResponse,
)
+from .roas import (
+ RoasResource,
+ AsyncRoasResource,
+ RoasResourceWithRawResponse,
+ AsyncRoasResourceWithRawResponse,
+ RoasResourceWithStreamingResponse,
+ AsyncRoasResourceWithStreamingResponse,
+)
from .rpki import (
RPKIResource,
AsyncRPKIResource,
@@ -24,6 +32,12 @@
"AsyncASPAResourceWithRawResponse",
"ASPAResourceWithStreamingResponse",
"AsyncASPAResourceWithStreamingResponse",
+ "RoasResource",
+ "AsyncRoasResource",
+ "RoasResourceWithRawResponse",
+ "AsyncRoasResourceWithRawResponse",
+ "RoasResourceWithStreamingResponse",
+ "AsyncRoasResourceWithStreamingResponse",
"RPKIResource",
"AsyncRPKIResource",
"RPKIResourceWithRawResponse",
diff --git a/src/cloudflare/resources/radar/bgp/rpki/roas.py b/src/cloudflare/resources/radar/bgp/rpki/roas.py
new file mode 100644
index 00000000000..7e69251d192
--- /dev/null
+++ b/src/cloudflare/resources/radar/bgp/rpki/roas.py
@@ -0,0 +1,272 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Type, Union, cast
+from datetime import datetime
+from typing_extensions import Literal
+
+import httpx
+
+from ....._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
+from ....._utils import maybe_transform, async_maybe_transform
+from ....._compat import cached_property
+from ....._resource import SyncAPIResource, AsyncAPIResource
+from ....._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ....._wrappers import ResultWrapper
+from ....._base_client import make_request_options
+from .....types.radar.bgp.rpki import roa_timeseries_params
+from .....types.radar.bgp.rpki.roa_timeseries_response import RoaTimeseriesResponse
+
+__all__ = ["RoasResource", "AsyncRoasResource"]
+
+
+class RoasResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> RoasResourceWithRawResponse:
+ """
+ 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 RoasResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> RoasResourceWithStreamingResponse:
+ """
+ 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 RoasResourceWithStreamingResponse(self)
+
+ def timeseries(
+ self,
+ *,
+ asn: SequenceNotStr[str] | Omit = omit,
+ date_end: Union[str, datetime] | Omit = omit,
+ date_start: Union[str, datetime] | Omit = omit,
+ format: Literal["JSON", "CSV"] | Omit = omit,
+ location: SequenceNotStr[str] | Omit = omit,
+ metric: Literal[
+ "validPfxsRatio",
+ "validPfxsV4Ratio",
+ "validPfxsV6Ratio",
+ "validIpsRatio",
+ "validIpsV4Ratio",
+ "validIpsV6Ratio",
+ ]
+ | Omit = omit,
+ name: SequenceNotStr[str] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> RoaTimeseriesResponse:
+ """
+ Retrieves RPKI ROA (Route Origin Authorization) validation ratios over time.
+ Returns the selected metric as a time series. Supports filtering by ASN or
+ location (country code) — multiple values of the same filter type produce one
+ series per value. If no ASN or location is specified, returns the global
+ aggregate.
+
+ Args:
+ asn: Filters results by Autonomous System Number. Specify one or more ASNs. Multiple
+ values generate one series per ASN.
+
+ date_end: End of the date range (inclusive).
+
+ date_start: Start of the date range (inclusive).
+
+ format: Format in which results will be returned.
+
+ location: Filters results by location. Specify a comma-separated list of alpha-2 location
+ codes.
+
+ metric: Which RPKI ROA validation metric to return. validPfxsRatio = ratio of RPKI-valid
+ prefixes (IPv4+IPv6 combined). validPfxsV4Ratio / validPfxsV6Ratio = same, split
+ by IP version. validIpsRatio = ratio of RPKI-valid address space (IPv4 /24s +
+ IPv6 /48s). validIpsV4Ratio / validIpsV6Ratio = same, split by IP version.
+
+ name: Array of names used to label the series in the response.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._get(
+ "/radar/bgp/rpki/roas/timeseries",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "asn": asn,
+ "date_end": date_end,
+ "date_start": date_start,
+ "format": format,
+ "location": location,
+ "metric": metric,
+ "name": name,
+ },
+ roa_timeseries_params.RoaTimeseriesParams,
+ ),
+ post_parser=ResultWrapper[RoaTimeseriesResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[RoaTimeseriesResponse], ResultWrapper[RoaTimeseriesResponse]),
+ )
+
+
+class AsyncRoasResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncRoasResourceWithRawResponse:
+ """
+ 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 AsyncRoasResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncRoasResourceWithStreamingResponse:
+ """
+ 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 AsyncRoasResourceWithStreamingResponse(self)
+
+ async def timeseries(
+ self,
+ *,
+ asn: SequenceNotStr[str] | Omit = omit,
+ date_end: Union[str, datetime] | Omit = omit,
+ date_start: Union[str, datetime] | Omit = omit,
+ format: Literal["JSON", "CSV"] | Omit = omit,
+ location: SequenceNotStr[str] | Omit = omit,
+ metric: Literal[
+ "validPfxsRatio",
+ "validPfxsV4Ratio",
+ "validPfxsV6Ratio",
+ "validIpsRatio",
+ "validIpsV4Ratio",
+ "validIpsV6Ratio",
+ ]
+ | Omit = omit,
+ name: SequenceNotStr[str] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> RoaTimeseriesResponse:
+ """
+ Retrieves RPKI ROA (Route Origin Authorization) validation ratios over time.
+ Returns the selected metric as a time series. Supports filtering by ASN or
+ location (country code) — multiple values of the same filter type produce one
+ series per value. If no ASN or location is specified, returns the global
+ aggregate.
+
+ Args:
+ asn: Filters results by Autonomous System Number. Specify one or more ASNs. Multiple
+ values generate one series per ASN.
+
+ date_end: End of the date range (inclusive).
+
+ date_start: Start of the date range (inclusive).
+
+ format: Format in which results will be returned.
+
+ location: Filters results by location. Specify a comma-separated list of alpha-2 location
+ codes.
+
+ metric: Which RPKI ROA validation metric to return. validPfxsRatio = ratio of RPKI-valid
+ prefixes (IPv4+IPv6 combined). validPfxsV4Ratio / validPfxsV6Ratio = same, split
+ by IP version. validIpsRatio = ratio of RPKI-valid address space (IPv4 /24s +
+ IPv6 /48s). validIpsV4Ratio / validIpsV6Ratio = same, split by IP version.
+
+ name: Array of names used to label the series in the response.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._get(
+ "/radar/bgp/rpki/roas/timeseries",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "asn": asn,
+ "date_end": date_end,
+ "date_start": date_start,
+ "format": format,
+ "location": location,
+ "metric": metric,
+ "name": name,
+ },
+ roa_timeseries_params.RoaTimeseriesParams,
+ ),
+ post_parser=ResultWrapper[RoaTimeseriesResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[RoaTimeseriesResponse], ResultWrapper[RoaTimeseriesResponse]),
+ )
+
+
+class RoasResourceWithRawResponse:
+ def __init__(self, roas: RoasResource) -> None:
+ self._roas = roas
+
+ self.timeseries = to_raw_response_wrapper(
+ roas.timeseries,
+ )
+
+
+class AsyncRoasResourceWithRawResponse:
+ def __init__(self, roas: AsyncRoasResource) -> None:
+ self._roas = roas
+
+ self.timeseries = async_to_raw_response_wrapper(
+ roas.timeseries,
+ )
+
+
+class RoasResourceWithStreamingResponse:
+ def __init__(self, roas: RoasResource) -> None:
+ self._roas = roas
+
+ self.timeseries = to_streamed_response_wrapper(
+ roas.timeseries,
+ )
+
+
+class AsyncRoasResourceWithStreamingResponse:
+ def __init__(self, roas: AsyncRoasResource) -> None:
+ self._roas = roas
+
+ self.timeseries = async_to_streamed_response_wrapper(
+ roas.timeseries,
+ )
diff --git a/src/cloudflare/resources/radar/bgp/rpki/rpki.py b/src/cloudflare/resources/radar/bgp/rpki/rpki.py
index 9d76245de9e..0c5f82ac5cc 100644
--- a/src/cloudflare/resources/radar/bgp/rpki/rpki.py
+++ b/src/cloudflare/resources/radar/bgp/rpki/rpki.py
@@ -10,6 +10,14 @@
ASPAResourceWithStreamingResponse,
AsyncASPAResourceWithStreamingResponse,
)
+from .roas import (
+ RoasResource,
+ AsyncRoasResource,
+ RoasResourceWithRawResponse,
+ AsyncRoasResourceWithRawResponse,
+ RoasResourceWithStreamingResponse,
+ AsyncRoasResourceWithStreamingResponse,
+)
from ....._compat import cached_property
from ....._resource import SyncAPIResource, AsyncAPIResource
@@ -21,6 +29,10 @@ class RPKIResource(SyncAPIResource):
def aspa(self) -> ASPAResource:
return ASPAResource(self._client)
+ @cached_property
+ def roas(self) -> RoasResource:
+ return RoasResource(self._client)
+
@cached_property
def with_raw_response(self) -> RPKIResourceWithRawResponse:
"""
@@ -46,6 +58,10 @@ class AsyncRPKIResource(AsyncAPIResource):
def aspa(self) -> AsyncASPAResource:
return AsyncASPAResource(self._client)
+ @cached_property
+ def roas(self) -> AsyncRoasResource:
+ return AsyncRoasResource(self._client)
+
@cached_property
def with_raw_response(self) -> AsyncRPKIResourceWithRawResponse:
"""
@@ -74,6 +90,10 @@ def __init__(self, rpki: RPKIResource) -> None:
def aspa(self) -> ASPAResourceWithRawResponse:
return ASPAResourceWithRawResponse(self._rpki.aspa)
+ @cached_property
+ def roas(self) -> RoasResourceWithRawResponse:
+ return RoasResourceWithRawResponse(self._rpki.roas)
+
class AsyncRPKIResourceWithRawResponse:
def __init__(self, rpki: AsyncRPKIResource) -> None:
@@ -83,6 +103,10 @@ def __init__(self, rpki: AsyncRPKIResource) -> None:
def aspa(self) -> AsyncASPAResourceWithRawResponse:
return AsyncASPAResourceWithRawResponse(self._rpki.aspa)
+ @cached_property
+ def roas(self) -> AsyncRoasResourceWithRawResponse:
+ return AsyncRoasResourceWithRawResponse(self._rpki.roas)
+
class RPKIResourceWithStreamingResponse:
def __init__(self, rpki: RPKIResource) -> None:
@@ -92,6 +116,10 @@ def __init__(self, rpki: RPKIResource) -> None:
def aspa(self) -> ASPAResourceWithStreamingResponse:
return ASPAResourceWithStreamingResponse(self._rpki.aspa)
+ @cached_property
+ def roas(self) -> RoasResourceWithStreamingResponse:
+ return RoasResourceWithStreamingResponse(self._rpki.roas)
+
class AsyncRPKIResourceWithStreamingResponse:
def __init__(self, rpki: AsyncRPKIResource) -> None:
@@ -100,3 +128,7 @@ def __init__(self, rpki: AsyncRPKIResource) -> None:
@cached_property
def aspa(self) -> AsyncASPAResourceWithStreamingResponse:
return AsyncASPAResourceWithStreamingResponse(self._rpki.aspa)
+
+ @cached_property
+ def roas(self) -> AsyncRoasResourceWithStreamingResponse:
+ return AsyncRoasResourceWithStreamingResponse(self._rpki.roas)
diff --git a/src/cloudflare/resources/resource_sharing/resource_sharing.py b/src/cloudflare/resources/resource_sharing/resource_sharing.py
index fc3a665fd7d..fa5288fe7ba 100644
--- a/src/cloudflare/resources/resource_sharing/resource_sharing.py
+++ b/src/cloudflare/resources/resource_sharing/resource_sharing.py
@@ -7,7 +7,7 @@
import httpx
-from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
from .resources import (
@@ -199,10 +199,12 @@ def list(
"gateway-destination-ip",
"gateway-block-page-settings",
"gateway-extended-email-matching",
+ "idp-federation-grant",
]
]
| Omit = omit,
status: Literal["active", "deleting", "deleted"] | Omit = omit,
+ tag: SequenceNotStr[str] | Omit = omit,
target_type: Literal["account", "organization"] | 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.
@@ -235,6 +237,11 @@ def list(
status: Filter shares by status.
+ tag: Filter shares by tag. Each value is either `key=value` (matches shares whose
+ tags contain that key/value pair) or `key` alone (matches shares that have any
+ value for that key). May be repeated; multiple `tag` parameters are ANDed
+ together. Maximum 20 `tag` parameters per request.
+
target_type: Filter shares by target_type.
extra_headers: Send extra headers
@@ -266,6 +273,7 @@ def list(
"per_page": per_page,
"resource_types": resource_types,
"status": status,
+ "tag": tag,
"target_type": target_type,
},
resource_sharing_list_params.ResourceSharingListParams,
@@ -527,10 +535,12 @@ def list(
"gateway-destination-ip",
"gateway-block-page-settings",
"gateway-extended-email-matching",
+ "idp-federation-grant",
]
]
| Omit = omit,
status: Literal["active", "deleting", "deleted"] | Omit = omit,
+ tag: SequenceNotStr[str] | Omit = omit,
target_type: Literal["account", "organization"] | 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.
@@ -563,6 +573,11 @@ def list(
status: Filter shares by status.
+ tag: Filter shares by tag. Each value is either `key=value` (matches shares whose
+ tags contain that key/value pair) or `key` alone (matches shares that have any
+ value for that key). May be repeated; multiple `tag` parameters are ANDed
+ together. Maximum 20 `tag` parameters per request.
+
target_type: Filter shares by target_type.
extra_headers: Send extra headers
@@ -594,6 +609,7 @@ def list(
"per_page": per_page,
"resource_types": resource_types,
"status": status,
+ "tag": tag,
"target_type": target_type,
},
resource_sharing_list_params.ResourceSharingListParams,
diff --git a/src/cloudflare/resources/resource_sharing/resources.py b/src/cloudflare/resources/resource_sharing/resources.py
index ba92aa2776f..807904557ba 100644
--- a/src/cloudflare/resources/resource_sharing/resources.py
+++ b/src/cloudflare/resources/resource_sharing/resources.py
@@ -64,6 +64,7 @@ def create(
"gateway-destination-ip",
"gateway-block-page-settings",
"gateway-extended-email-matching",
+ "idp-federation-grant",
],
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -195,6 +196,7 @@ def list(
"gateway-destination-ip",
"gateway-block-page-settings",
"gateway-extended-email-matching",
+ "idp-federation-grant",
]
| Omit = omit,
status: Literal["active", "deleting", "deleted"] | Omit = omit,
@@ -400,6 +402,7 @@ async def create(
"gateway-destination-ip",
"gateway-block-page-settings",
"gateway-extended-email-matching",
+ "idp-federation-grant",
],
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
@@ -531,6 +534,7 @@ def list(
"gateway-destination-ip",
"gateway-block-page-settings",
"gateway-extended-email-matching",
+ "idp-federation-grant",
]
| Omit = omit,
status: Literal["active", "deleting", "deleted"] | Omit = omit,
diff --git a/src/cloudflare/resources/zero_trust/__init__.py b/src/cloudflare/resources/zero_trust/__init__.py
index 7703df18c9b..7a42ce26500 100644
--- a/src/cloudflare/resources/zero_trust/__init__.py
+++ b/src/cloudflare/resources/zero_trust/__init__.py
@@ -88,6 +88,14 @@
OrganizationsResourceWithStreamingResponse,
AsyncOrganizationsResourceWithStreamingResponse,
)
+from .resource_library import (
+ ResourceLibraryResource,
+ AsyncResourceLibraryResource,
+ ResourceLibraryResourceWithRawResponse,
+ AsyncResourceLibraryResourceWithRawResponse,
+ ResourceLibraryResourceWithStreamingResponse,
+ AsyncResourceLibraryResourceWithStreamingResponse,
+)
from .identity_providers import (
IdentityProvidersResource,
AsyncIdentityProvidersResource,
@@ -178,6 +186,12 @@
"AsyncRiskScoringResourceWithRawResponse",
"RiskScoringResourceWithStreamingResponse",
"AsyncRiskScoringResourceWithStreamingResponse",
+ "ResourceLibraryResource",
+ "AsyncResourceLibraryResource",
+ "ResourceLibraryResourceWithRawResponse",
+ "AsyncResourceLibraryResourceWithRawResponse",
+ "ResourceLibraryResourceWithStreamingResponse",
+ "AsyncResourceLibraryResourceWithStreamingResponse",
"ZeroTrustResource",
"AsyncZeroTrustResource",
"ZeroTrustResourceWithRawResponse",
diff --git a/src/cloudflare/resources/zero_trust/api.md b/src/cloudflare/resources/zero_trust/api.md
index 35c0c1fd0d3..ac40770aada 100644
--- a/src/cloudflare/resources/zero_trust/api.md
+++ b/src/cloudflare/resources/zero_trust/api.md
@@ -1978,3 +1978,34 @@ from cloudflare.types.zero_trust.risk_scoring.integrations import ReferenceGetRe
Methods:
- client.zero_trust.risk_scoring.integrations.references.get(reference_id, \*, account_id) -> Optional[ReferenceGetResponse]
+
+## ResourceLibrary
+
+### Applications
+
+Types:
+
+```python
+from cloudflare.types.zero_trust.resource_library import (
+ ApplicationListResponse,
+ ApplicationGetResponse,
+)
+```
+
+Methods:
+
+- client.zero_trust.resource_library.applications.list(\*, account_id, \*\*params) -> SyncSinglePage[ApplicationListResponse]
+- client.zero_trust.resource_library.applications.get(id, \*, account_id) -> Optional[ApplicationGetResponse]
+
+### Categories
+
+Types:
+
+```python
+from cloudflare.types.zero_trust.resource_library import CategoryListResponse, CategoryGetResponse
+```
+
+Methods:
+
+- client.zero_trust.resource_library.categories.list(\*, account_id, \*\*params) -> SyncSinglePage[CategoryListResponse]
+- client.zero_trust.resource_library.categories.get(id, \*, account_id) -> Optional[CategoryGetResponse]
diff --git a/src/cloudflare/resources/zero_trust/resource_library/__init__.py b/src/cloudflare/resources/zero_trust/resource_library/__init__.py
new file mode 100644
index 00000000000..d110503ebed
--- /dev/null
+++ b/src/cloudflare/resources/zero_trust/resource_library/__init__.py
@@ -0,0 +1,47 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .categories import (
+ CategoriesResource,
+ AsyncCategoriesResource,
+ CategoriesResourceWithRawResponse,
+ AsyncCategoriesResourceWithRawResponse,
+ CategoriesResourceWithStreamingResponse,
+ AsyncCategoriesResourceWithStreamingResponse,
+)
+from .applications import (
+ ApplicationsResource,
+ AsyncApplicationsResource,
+ ApplicationsResourceWithRawResponse,
+ AsyncApplicationsResourceWithRawResponse,
+ ApplicationsResourceWithStreamingResponse,
+ AsyncApplicationsResourceWithStreamingResponse,
+)
+from .resource_library import (
+ ResourceLibraryResource,
+ AsyncResourceLibraryResource,
+ ResourceLibraryResourceWithRawResponse,
+ AsyncResourceLibraryResourceWithRawResponse,
+ ResourceLibraryResourceWithStreamingResponse,
+ AsyncResourceLibraryResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "ApplicationsResource",
+ "AsyncApplicationsResource",
+ "ApplicationsResourceWithRawResponse",
+ "AsyncApplicationsResourceWithRawResponse",
+ "ApplicationsResourceWithStreamingResponse",
+ "AsyncApplicationsResourceWithStreamingResponse",
+ "CategoriesResource",
+ "AsyncCategoriesResource",
+ "CategoriesResourceWithRawResponse",
+ "AsyncCategoriesResourceWithRawResponse",
+ "CategoriesResourceWithStreamingResponse",
+ "AsyncCategoriesResourceWithStreamingResponse",
+ "ResourceLibraryResource",
+ "AsyncResourceLibraryResource",
+ "ResourceLibraryResourceWithRawResponse",
+ "AsyncResourceLibraryResourceWithRawResponse",
+ "ResourceLibraryResourceWithStreamingResponse",
+ "AsyncResourceLibraryResourceWithStreamingResponse",
+]
diff --git a/src/cloudflare/resources/zero_trust/resource_library/applications.py b/src/cloudflare/resources/zero_trust/resource_library/applications.py
new file mode 100644
index 00000000000..e6fc505388c
--- /dev/null
+++ b/src/cloudflare/resources/zero_trust/resource_library/applications.py
@@ -0,0 +1,362 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Type, Optional, cast
+
+import httpx
+
+from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ...._utils import path_template, maybe_transform
+from ...._compat import cached_property
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from ...._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ...._wrappers import ResultWrapper
+from ....pagination import SyncSinglePage, AsyncSinglePage
+from ...._base_client import AsyncPaginator, make_request_options
+from ....types.zero_trust.resource_library import application_list_params
+from ....types.zero_trust.resource_library.application_get_response import ApplicationGetResponse
+from ....types.zero_trust.resource_library.application_list_response import ApplicationListResponse
+
+__all__ = ["ApplicationsResource", "AsyncApplicationsResource"]
+
+
+class ApplicationsResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> ApplicationsResourceWithRawResponse:
+ """
+ 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 ApplicationsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> ApplicationsResourceWithStreamingResponse:
+ """
+ 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 ApplicationsResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ *,
+ account_id: str,
+ filter: str | Omit = omit,
+ limit: int | Omit = omit,
+ offset: int | Omit = omit,
+ order_by: str | Omit = omit,
+ search: str | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> SyncSinglePage[ApplicationListResponse]:
+ """
+ List applications with different filters.
+
+ Args:
+ filter:
+ Filter applications using key:value format. Supported filter keys:
+
+ - name: Filter by application name (e.g., name:HR)
+ - id: Filter by application ID (e.g., id:0b63249c-95bf-4cc0-a7cc-d7faaaf1dac0)
+ - human_id: Filter by human-readable ID (e.g., human_id:HR)
+ - hostname: Filter by hostname or support domain (e.g.,
+ hostname:portal.example.com)
+ - source: Filter by application source name (e.g., source:cloudflare)
+ - ip_subnet: Filter by IP subnet using CIDR containment — returns applications
+ where any stored subnet contains the search value (e.g., ip_subnet:10.0.1.5/32
+ matches apps with 10.0.0.0/16)
+ - intel_id: Filter by Intel API ID (e.g., intel_id:498). also supports multiple
+ values (e.g., intel_id:498,1001)
+ - category_id: Filter by category ID (e.g.,
+ category_id:37f8ec03-8766-49d4-9a15-369b044c842c).
+ - category_name: Filter by category name (e.g., category_name:HR).
+ - supported: Filter by supported Cloudflare product (e.g., supported:ACCESS).
+ Values: GATEWAY, ACCESS, CASB. .
+
+ limit: Limit of number of results to return (max 250).
+
+ offset: Offset of results to return.
+
+ order_by: Order results by field name and direction (e.g., name:asc). Ignored when search
+ is provided; results are ranked by relevance instead.
+
+ search: Fuzzy search across application name and hostnames. Results are ranked by
+ relevance. Must be between 2 and 200 characters. Can be combined with filter
+ parameters.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._get_api_list(
+ path_template("/accounts/{account_id}/resource-library/applications", account_id=account_id),
+ page=SyncSinglePage[ApplicationListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "filter": filter,
+ "limit": limit,
+ "offset": offset,
+ "order_by": order_by,
+ "search": search,
+ },
+ application_list_params.ApplicationListParams,
+ ),
+ ),
+ model=ApplicationListResponse,
+ )
+
+ def get(
+ self,
+ id: str,
+ *,
+ account_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[ApplicationGetResponse]:
+ """
+ Get application by ID.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return self._get(
+ path_template("/accounts/{account_id}/resource-library/applications/{id}", account_id=account_id, id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[ApplicationGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[ApplicationGetResponse]], ResultWrapper[ApplicationGetResponse]),
+ )
+
+
+class AsyncApplicationsResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncApplicationsResourceWithRawResponse:
+ """
+ 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 AsyncApplicationsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncApplicationsResourceWithStreamingResponse:
+ """
+ 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 AsyncApplicationsResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ *,
+ account_id: str,
+ filter: str | Omit = omit,
+ limit: int | Omit = omit,
+ offset: int | Omit = omit,
+ order_by: str | Omit = omit,
+ search: str | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> AsyncPaginator[ApplicationListResponse, AsyncSinglePage[ApplicationListResponse]]:
+ """
+ List applications with different filters.
+
+ Args:
+ filter:
+ Filter applications using key:value format. Supported filter keys:
+
+ - name: Filter by application name (e.g., name:HR)
+ - id: Filter by application ID (e.g., id:0b63249c-95bf-4cc0-a7cc-d7faaaf1dac0)
+ - human_id: Filter by human-readable ID (e.g., human_id:HR)
+ - hostname: Filter by hostname or support domain (e.g.,
+ hostname:portal.example.com)
+ - source: Filter by application source name (e.g., source:cloudflare)
+ - ip_subnet: Filter by IP subnet using CIDR containment — returns applications
+ where any stored subnet contains the search value (e.g., ip_subnet:10.0.1.5/32
+ matches apps with 10.0.0.0/16)
+ - intel_id: Filter by Intel API ID (e.g., intel_id:498). also supports multiple
+ values (e.g., intel_id:498,1001)
+ - category_id: Filter by category ID (e.g.,
+ category_id:37f8ec03-8766-49d4-9a15-369b044c842c).
+ - category_name: Filter by category name (e.g., category_name:HR).
+ - supported: Filter by supported Cloudflare product (e.g., supported:ACCESS).
+ Values: GATEWAY, ACCESS, CASB. .
+
+ limit: Limit of number of results to return (max 250).
+
+ offset: Offset of results to return.
+
+ order_by: Order results by field name and direction (e.g., name:asc). Ignored when search
+ is provided; results are ranked by relevance instead.
+
+ search: Fuzzy search across application name and hostnames. Results are ranked by
+ relevance. Must be between 2 and 200 characters. Can be combined with filter
+ parameters.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._get_api_list(
+ path_template("/accounts/{account_id}/resource-library/applications", account_id=account_id),
+ page=AsyncSinglePage[ApplicationListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "filter": filter,
+ "limit": limit,
+ "offset": offset,
+ "order_by": order_by,
+ "search": search,
+ },
+ application_list_params.ApplicationListParams,
+ ),
+ ),
+ model=ApplicationListResponse,
+ )
+
+ async def get(
+ self,
+ id: str,
+ *,
+ account_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[ApplicationGetResponse]:
+ """
+ Get application by ID.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return await self._get(
+ path_template("/accounts/{account_id}/resource-library/applications/{id}", account_id=account_id, id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[ApplicationGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[ApplicationGetResponse]], ResultWrapper[ApplicationGetResponse]),
+ )
+
+
+class ApplicationsResourceWithRawResponse:
+ def __init__(self, applications: ApplicationsResource) -> None:
+ self._applications = applications
+
+ self.list = to_raw_response_wrapper(
+ applications.list,
+ )
+ self.get = to_raw_response_wrapper(
+ applications.get,
+ )
+
+
+class AsyncApplicationsResourceWithRawResponse:
+ def __init__(self, applications: AsyncApplicationsResource) -> None:
+ self._applications = applications
+
+ self.list = async_to_raw_response_wrapper(
+ applications.list,
+ )
+ self.get = async_to_raw_response_wrapper(
+ applications.get,
+ )
+
+
+class ApplicationsResourceWithStreamingResponse:
+ def __init__(self, applications: ApplicationsResource) -> None:
+ self._applications = applications
+
+ self.list = to_streamed_response_wrapper(
+ applications.list,
+ )
+ self.get = to_streamed_response_wrapper(
+ applications.get,
+ )
+
+
+class AsyncApplicationsResourceWithStreamingResponse:
+ def __init__(self, applications: AsyncApplicationsResource) -> None:
+ self._applications = applications
+
+ self.list = async_to_streamed_response_wrapper(
+ applications.list,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ applications.get,
+ )
diff --git a/src/cloudflare/resources/zero_trust/resource_library/categories.py b/src/cloudflare/resources/zero_trust/resource_library/categories.py
new file mode 100644
index 00000000000..69101048506
--- /dev/null
+++ b/src/cloudflare/resources/zero_trust/resource_library/categories.py
@@ -0,0 +1,296 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Type, Optional, cast
+
+import httpx
+
+from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ...._utils import path_template, maybe_transform
+from ...._compat import cached_property
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from ...._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ...._wrappers import ResultWrapper
+from ....pagination import SyncSinglePage, AsyncSinglePage
+from ...._base_client import AsyncPaginator, make_request_options
+from ....types.zero_trust.resource_library import category_list_params
+from ....types.zero_trust.resource_library.category_get_response import CategoryGetResponse
+from ....types.zero_trust.resource_library.category_list_response import CategoryListResponse
+
+__all__ = ["CategoriesResource", "AsyncCategoriesResource"]
+
+
+class CategoriesResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> CategoriesResourceWithRawResponse:
+ """
+ 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 CategoriesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> CategoriesResourceWithStreamingResponse:
+ """
+ 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 CategoriesResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ *,
+ account_id: str,
+ limit: int | Omit = omit,
+ offset: 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,
+ ) -> SyncSinglePage[CategoryListResponse]:
+ """
+ List application categories.
+
+ Args:
+ limit: Limit of number of results to return.
+
+ offset: Offset of results to return.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._get_api_list(
+ path_template("/accounts/{account_id}/resource-library/categories", account_id=account_id),
+ page=SyncSinglePage[CategoryListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "limit": limit,
+ "offset": offset,
+ },
+ category_list_params.CategoryListParams,
+ ),
+ ),
+ model=CategoryListResponse,
+ )
+
+ def get(
+ self,
+ id: str,
+ *,
+ account_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[CategoryGetResponse]:
+ """
+ Get application category by ID.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return self._get(
+ path_template("/accounts/{account_id}/resource-library/categories/{id}", account_id=account_id, id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[CategoryGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[CategoryGetResponse]], ResultWrapper[CategoryGetResponse]),
+ )
+
+
+class AsyncCategoriesResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncCategoriesResourceWithRawResponse:
+ """
+ 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 AsyncCategoriesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncCategoriesResourceWithStreamingResponse:
+ """
+ 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 AsyncCategoriesResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ *,
+ account_id: str,
+ limit: int | Omit = omit,
+ offset: 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,
+ ) -> AsyncPaginator[CategoryListResponse, AsyncSinglePage[CategoryListResponse]]:
+ """
+ List application categories.
+
+ Args:
+ limit: Limit of number of results to return.
+
+ offset: Offset of results to return.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ return self._get_api_list(
+ path_template("/accounts/{account_id}/resource-library/categories", account_id=account_id),
+ page=AsyncSinglePage[CategoryListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "limit": limit,
+ "offset": offset,
+ },
+ category_list_params.CategoryListParams,
+ ),
+ ),
+ model=CategoryListResponse,
+ )
+
+ async def get(
+ self,
+ id: str,
+ *,
+ account_id: str,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> Optional[CategoryGetResponse]:
+ """
+ Get application category by ID.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return await self._get(
+ path_template("/accounts/{account_id}/resource-library/categories/{id}", account_id=account_id, id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ post_parser=ResultWrapper[Optional[CategoryGetResponse]]._unwrapper,
+ ),
+ cast_to=cast(Type[Optional[CategoryGetResponse]], ResultWrapper[CategoryGetResponse]),
+ )
+
+
+class CategoriesResourceWithRawResponse:
+ def __init__(self, categories: CategoriesResource) -> None:
+ self._categories = categories
+
+ self.list = to_raw_response_wrapper(
+ categories.list,
+ )
+ self.get = to_raw_response_wrapper(
+ categories.get,
+ )
+
+
+class AsyncCategoriesResourceWithRawResponse:
+ def __init__(self, categories: AsyncCategoriesResource) -> None:
+ self._categories = categories
+
+ self.list = async_to_raw_response_wrapper(
+ categories.list,
+ )
+ self.get = async_to_raw_response_wrapper(
+ categories.get,
+ )
+
+
+class CategoriesResourceWithStreamingResponse:
+ def __init__(self, categories: CategoriesResource) -> None:
+ self._categories = categories
+
+ self.list = to_streamed_response_wrapper(
+ categories.list,
+ )
+ self.get = to_streamed_response_wrapper(
+ categories.get,
+ )
+
+
+class AsyncCategoriesResourceWithStreamingResponse:
+ def __init__(self, categories: AsyncCategoriesResource) -> None:
+ self._categories = categories
+
+ self.list = async_to_streamed_response_wrapper(
+ categories.list,
+ )
+ self.get = async_to_streamed_response_wrapper(
+ categories.get,
+ )
diff --git a/src/cloudflare/resources/zero_trust/resource_library/resource_library.py b/src/cloudflare/resources/zero_trust/resource_library/resource_library.py
new file mode 100644
index 00000000000..45085b0e456
--- /dev/null
+++ b/src/cloudflare/resources/zero_trust/resource_library/resource_library.py
@@ -0,0 +1,134 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from ...._compat import cached_property
+from .categories import (
+ CategoriesResource,
+ AsyncCategoriesResource,
+ CategoriesResourceWithRawResponse,
+ AsyncCategoriesResourceWithRawResponse,
+ CategoriesResourceWithStreamingResponse,
+ AsyncCategoriesResourceWithStreamingResponse,
+)
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from .applications import (
+ ApplicationsResource,
+ AsyncApplicationsResource,
+ ApplicationsResourceWithRawResponse,
+ AsyncApplicationsResourceWithRawResponse,
+ ApplicationsResourceWithStreamingResponse,
+ AsyncApplicationsResourceWithStreamingResponse,
+)
+
+__all__ = ["ResourceLibraryResource", "AsyncResourceLibraryResource"]
+
+
+class ResourceLibraryResource(SyncAPIResource):
+ @cached_property
+ def applications(self) -> ApplicationsResource:
+ return ApplicationsResource(self._client)
+
+ @cached_property
+ def categories(self) -> CategoriesResource:
+ return CategoriesResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> ResourceLibraryResourceWithRawResponse:
+ """
+ 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 ResourceLibraryResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> ResourceLibraryResourceWithStreamingResponse:
+ """
+ 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 ResourceLibraryResourceWithStreamingResponse(self)
+
+
+class AsyncResourceLibraryResource(AsyncAPIResource):
+ @cached_property
+ def applications(self) -> AsyncApplicationsResource:
+ return AsyncApplicationsResource(self._client)
+
+ @cached_property
+ def categories(self) -> AsyncCategoriesResource:
+ return AsyncCategoriesResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncResourceLibraryResourceWithRawResponse:
+ """
+ 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 AsyncResourceLibraryResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncResourceLibraryResourceWithStreamingResponse:
+ """
+ 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 AsyncResourceLibraryResourceWithStreamingResponse(self)
+
+
+class ResourceLibraryResourceWithRawResponse:
+ def __init__(self, resource_library: ResourceLibraryResource) -> None:
+ self._resource_library = resource_library
+
+ @cached_property
+ def applications(self) -> ApplicationsResourceWithRawResponse:
+ return ApplicationsResourceWithRawResponse(self._resource_library.applications)
+
+ @cached_property
+ def categories(self) -> CategoriesResourceWithRawResponse:
+ return CategoriesResourceWithRawResponse(self._resource_library.categories)
+
+
+class AsyncResourceLibraryResourceWithRawResponse:
+ def __init__(self, resource_library: AsyncResourceLibraryResource) -> None:
+ self._resource_library = resource_library
+
+ @cached_property
+ def applications(self) -> AsyncApplicationsResourceWithRawResponse:
+ return AsyncApplicationsResourceWithRawResponse(self._resource_library.applications)
+
+ @cached_property
+ def categories(self) -> AsyncCategoriesResourceWithRawResponse:
+ return AsyncCategoriesResourceWithRawResponse(self._resource_library.categories)
+
+
+class ResourceLibraryResourceWithStreamingResponse:
+ def __init__(self, resource_library: ResourceLibraryResource) -> None:
+ self._resource_library = resource_library
+
+ @cached_property
+ def applications(self) -> ApplicationsResourceWithStreamingResponse:
+ return ApplicationsResourceWithStreamingResponse(self._resource_library.applications)
+
+ @cached_property
+ def categories(self) -> CategoriesResourceWithStreamingResponse:
+ return CategoriesResourceWithStreamingResponse(self._resource_library.categories)
+
+
+class AsyncResourceLibraryResourceWithStreamingResponse:
+ def __init__(self, resource_library: AsyncResourceLibraryResource) -> None:
+ self._resource_library = resource_library
+
+ @cached_property
+ def applications(self) -> AsyncApplicationsResourceWithStreamingResponse:
+ return AsyncApplicationsResourceWithStreamingResponse(self._resource_library.applications)
+
+ @cached_property
+ def categories(self) -> AsyncCategoriesResourceWithStreamingResponse:
+ return AsyncCategoriesResourceWithStreamingResponse(self._resource_library.categories)
diff --git a/src/cloudflare/resources/zero_trust/zero_trust.py b/src/cloudflare/resources/zero_trust/zero_trust.py
index a8de3d6cb8b..b144dc88569 100644
--- a/src/cloudflare/resources/zero_trust/zero_trust.py
+++ b/src/cloudflare/resources/zero_trust/zero_trust.py
@@ -92,6 +92,14 @@
OrganizationsResourceWithStreamingResponse,
AsyncOrganizationsResourceWithStreamingResponse,
)
+from .resource_library.resource_library import (
+ ResourceLibraryResource,
+ AsyncResourceLibraryResource,
+ ResourceLibraryResourceWithRawResponse,
+ AsyncResourceLibraryResourceWithRawResponse,
+ ResourceLibraryResourceWithStreamingResponse,
+ AsyncResourceLibraryResourceWithStreamingResponse,
+)
from .identity_providers.identity_providers import (
IdentityProvidersResource,
AsyncIdentityProvidersResource,
@@ -153,6 +161,10 @@ def networks(self) -> NetworksResource:
def risk_scoring(self) -> RiskScoringResource:
return RiskScoringResource(self._client)
+ @cached_property
+ def resource_library(self) -> ResourceLibraryResource:
+ return ResourceLibraryResource(self._client)
+
@cached_property
def with_raw_response(self) -> ZeroTrustResourceWithRawResponse:
"""
@@ -222,6 +234,10 @@ def networks(self) -> AsyncNetworksResource:
def risk_scoring(self) -> AsyncRiskScoringResource:
return AsyncRiskScoringResource(self._client)
+ @cached_property
+ def resource_library(self) -> AsyncResourceLibraryResource:
+ return AsyncResourceLibraryResource(self._client)
+
@cached_property
def with_raw_response(self) -> AsyncZeroTrustResourceWithRawResponse:
"""
@@ -294,6 +310,10 @@ def networks(self) -> NetworksResourceWithRawResponse:
def risk_scoring(self) -> RiskScoringResourceWithRawResponse:
return RiskScoringResourceWithRawResponse(self._zero_trust.risk_scoring)
+ @cached_property
+ def resource_library(self) -> ResourceLibraryResourceWithRawResponse:
+ return ResourceLibraryResourceWithRawResponse(self._zero_trust.resource_library)
+
class AsyncZeroTrustResourceWithRawResponse:
def __init__(self, zero_trust: AsyncZeroTrustResource) -> None:
@@ -347,6 +367,10 @@ def networks(self) -> AsyncNetworksResourceWithRawResponse:
def risk_scoring(self) -> AsyncRiskScoringResourceWithRawResponse:
return AsyncRiskScoringResourceWithRawResponse(self._zero_trust.risk_scoring)
+ @cached_property
+ def resource_library(self) -> AsyncResourceLibraryResourceWithRawResponse:
+ return AsyncResourceLibraryResourceWithRawResponse(self._zero_trust.resource_library)
+
class ZeroTrustResourceWithStreamingResponse:
def __init__(self, zero_trust: ZeroTrustResource) -> None:
@@ -400,6 +424,10 @@ def networks(self) -> NetworksResourceWithStreamingResponse:
def risk_scoring(self) -> RiskScoringResourceWithStreamingResponse:
return RiskScoringResourceWithStreamingResponse(self._zero_trust.risk_scoring)
+ @cached_property
+ def resource_library(self) -> ResourceLibraryResourceWithStreamingResponse:
+ return ResourceLibraryResourceWithStreamingResponse(self._zero_trust.resource_library)
+
class AsyncZeroTrustResourceWithStreamingResponse:
def __init__(self, zero_trust: AsyncZeroTrustResource) -> None:
@@ -452,3 +480,7 @@ def networks(self) -> AsyncNetworksResourceWithStreamingResponse:
@cached_property
def risk_scoring(self) -> AsyncRiskScoringResourceWithStreamingResponse:
return AsyncRiskScoringResourceWithStreamingResponse(self._zero_trust.risk_scoring)
+
+ @cached_property
+ def resource_library(self) -> AsyncResourceLibraryResourceWithStreamingResponse:
+ return AsyncResourceLibraryResourceWithStreamingResponse(self._zero_trust.resource_library)
diff --git a/src/cloudflare/types/ai_gateway/__init__.py b/src/cloudflare/types/ai_gateway/__init__.py
index faf6b260a5d..34182daf230 100644
--- a/src/cloudflare/types/ai_gateway/__init__.py
+++ b/src/cloudflare/types/ai_gateway/__init__.py
@@ -33,6 +33,7 @@
from .evaluation_delete_response import EvaluationDeleteResponse as EvaluationDeleteResponse
from .evaluation_type_list_params import EvaluationTypeListParams as EvaluationTypeListParams
from .provider_config_list_params import ProviderConfigListParams as ProviderConfigListParams
+from .billing_usage_history_params import BillingUsageHistoryParams as BillingUsageHistoryParams
from .dynamic_routing_get_response import DynamicRoutingGetResponse as DynamicRoutingGetResponse
from .dynamic_routing_create_params import DynamicRoutingCreateParams as DynamicRoutingCreateParams
from .dynamic_routing_list_response import DynamicRoutingListResponse as DynamicRoutingListResponse
@@ -40,10 +41,15 @@
from .evaluation_type_list_response import EvaluationTypeListResponse as EvaluationTypeListResponse
from .provider_config_create_params import ProviderConfigCreateParams as ProviderConfigCreateParams
from .provider_config_list_response import ProviderConfigListResponse as ProviderConfigListResponse
+from .billing_invoice_history_params import BillingInvoiceHistoryParams as BillingInvoiceHistoryParams
+from .billing_usage_history_response import BillingUsageHistoryResponse as BillingUsageHistoryResponse
+from .billing_credit_balance_response import BillingCreditBalanceResponse as BillingCreditBalanceResponse
from .dynamic_routing_create_response import DynamicRoutingCreateResponse as DynamicRoutingCreateResponse
from .dynamic_routing_delete_response import DynamicRoutingDeleteResponse as DynamicRoutingDeleteResponse
from .dynamic_routing_update_response import DynamicRoutingUpdateResponse as DynamicRoutingUpdateResponse
from .provider_config_create_response import ProviderConfigCreateResponse as ProviderConfigCreateResponse
+from .billing_invoice_history_response import BillingInvoiceHistoryResponse as BillingInvoiceHistoryResponse
+from .billing_invoice_preview_response import BillingInvoicePreviewResponse as BillingInvoicePreviewResponse
from .dynamic_routing_get_version_response import DynamicRoutingGetVersionResponse as DynamicRoutingGetVersionResponse
from .dynamic_routing_create_version_params import (
DynamicRoutingCreateVersionParams as DynamicRoutingCreateVersionParams,
diff --git a/src/cloudflare/types/ai_gateway/billing/__init__.py b/src/cloudflare/types/ai_gateway/billing/__init__.py
new file mode 100644
index 00000000000..9531f2bff04
--- /dev/null
+++ b/src/cloudflare/types/ai_gateway/billing/__init__.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .topup_create_params import TopupCreateParams as TopupCreateParams
+from .topup_status_params import TopupStatusParams as TopupStatusParams
+from .topup_create_response import TopupCreateResponse as TopupCreateResponse
+from .topup_status_response import TopupStatusResponse as TopupStatusResponse
+from .spending_limit_get_response import SpendingLimitGetResponse as SpendingLimitGetResponse
+from .spending_limit_create_params import SpendingLimitCreateParams as SpendingLimitCreateParams
diff --git a/src/cloudflare/types/ai_gateway/billing/spending_limit_create_params.py b/src/cloudflare/types/ai_gateway/billing/spending_limit_create_params.py
new file mode 100644
index 00000000000..316e3c1e699
--- /dev/null
+++ b/src/cloudflare/types/ai_gateway/billing/spending_limit_create_params.py
@@ -0,0 +1,20 @@
+# 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__ = ["SpendingLimitCreateParams"]
+
+
+class SpendingLimitCreateParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ amount: Required[int]
+ """Spending limit amount in cents (min 100)."""
+
+ duration: Required[Literal["daily", "weekly", "monthly"]]
+ """Spending limit duration."""
+
+ strategy: Required[Literal["fixed", "sliding"]]
+ """Spending limit strategy."""
diff --git a/src/cloudflare/types/ai_gateway/billing/spending_limit_get_response.py b/src/cloudflare/types/ai_gateway/billing/spending_limit_get_response.py
new file mode 100644
index 00000000000..2e5e2dd1b82
--- /dev/null
+++ b/src/cloudflare/types/ai_gateway/billing/spending_limit_get_response.py
@@ -0,0 +1,21 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from ...._models import BaseModel
+
+__all__ = ["SpendingLimitGetResponse", "Config"]
+
+
+class Config(BaseModel):
+ amount: Optional[float] = None
+
+ duration: Optional[str] = None
+
+ strategy: Optional[str] = None
+
+
+class SpendingLimitGetResponse(BaseModel):
+ config: Config
+
+ enabled: bool
diff --git a/src/cloudflare/types/ai_gateway/billing/topup/__init__.py b/src/cloudflare/types/ai_gateway/billing/topup/__init__.py
new file mode 100644
index 00000000000..5ed7bb71e45
--- /dev/null
+++ b/src/cloudflare/types/ai_gateway/billing/topup/__init__.py
@@ -0,0 +1,7 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .config_get_response import ConfigGetResponse as ConfigGetResponse
+from .config_create_params import ConfigCreateParams as ConfigCreateParams
+from .config_create_response import ConfigCreateResponse as ConfigCreateResponse
diff --git a/src/cloudflare/types/ai_gateway/billing/topup/config_create_params.py b/src/cloudflare/types/ai_gateway/billing/topup/config_create_params.py
new file mode 100644
index 00000000000..8ca59302fae
--- /dev/null
+++ b/src/cloudflare/types/ai_gateway/billing/topup/config_create_params.py
@@ -0,0 +1,17 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["ConfigCreateParams"]
+
+
+class ConfigCreateParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ amount: Required[int]
+ """Auto top-up amount in cents (min 1000)."""
+
+ threshold: Required[int]
+ """Balance threshold in cents that triggers auto top-up (min 500)."""
diff --git a/src/cloudflare/types/ai_gateway/billing/topup/config_create_response.py b/src/cloudflare/types/ai_gateway/billing/topup/config_create_response.py
new file mode 100644
index 00000000000..b21c7baebfb
--- /dev/null
+++ b/src/cloudflare/types/ai_gateway/billing/topup/config_create_response.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from ....._models import BaseModel
+
+__all__ = ["ConfigCreateResponse"]
+
+
+class ConfigCreateResponse(BaseModel):
+ amount: float
+
+ threshold: float
diff --git a/src/cloudflare/types/ai_gateway/billing/topup/config_get_response.py b/src/cloudflare/types/ai_gateway/billing/topup/config_get_response.py
new file mode 100644
index 00000000000..7cc5351881e
--- /dev/null
+++ b/src/cloudflare/types/ai_gateway/billing/topup/config_get_response.py
@@ -0,0 +1,21 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from pydantic import Field as FieldInfo
+
+from ....._models import BaseModel
+
+__all__ = ["ConfigGetResponse"]
+
+
+class ConfigGetResponse(BaseModel):
+ amount: Optional[float] = None
+
+ disabled_reason: Optional[str] = FieldInfo(alias="disabledReason", default=None)
+
+ error: Optional[str] = None
+
+ last_failed_at: Optional[float] = FieldInfo(alias="lastFailedAt", default=None)
+
+ threshold: Optional[float] = None
diff --git a/src/cloudflare/types/ai_gateway/billing/topup_create_params.py b/src/cloudflare/types/ai_gateway/billing/topup_create_params.py
new file mode 100644
index 00000000000..136f086c960
--- /dev/null
+++ b/src/cloudflare/types/ai_gateway/billing/topup_create_params.py
@@ -0,0 +1,14 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["TopupCreateParams"]
+
+
+class TopupCreateParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ amount: Required[int]
+ """Top-up amount in cents (min 1000)."""
diff --git a/src/cloudflare/types/ai_gateway/billing/topup_create_response.py b/src/cloudflare/types/ai_gateway/billing/topup_create_response.py
new file mode 100644
index 00000000000..61241bf6075
--- /dev/null
+++ b/src/cloudflare/types/ai_gateway/billing/topup_create_response.py
@@ -0,0 +1,24 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from ...._models import BaseModel
+
+__all__ = ["TopupCreateResponse"]
+
+
+class TopupCreateResponse(BaseModel):
+ client_secret: Optional[str] = None
+ """Stripe PaymentIntent client secret."""
+
+ onboarding: bool
+ """Whether the user was already onboarded."""
+
+ payment_intent_id: str
+ """Stripe invoice ID."""
+
+ brand: Optional[str] = None
+ """Card brand (visa, mastercard, etc.)."""
+
+ last4: Optional[str] = None
+ """Last 4 digits of card."""
diff --git a/src/cloudflare/types/ai_gateway/billing/topup_status_params.py b/src/cloudflare/types/ai_gateway/billing/topup_status_params.py
new file mode 100644
index 00000000000..12bb967898c
--- /dev/null
+++ b/src/cloudflare/types/ai_gateway/billing/topup_status_params.py
@@ -0,0 +1,14 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["TopupStatusParams"]
+
+
+class TopupStatusParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ payment_intent_id: Required[str]
+ """Stripe invoice ID to check status for."""
diff --git a/src/cloudflare/types/ai_gateway/billing/topup_status_response.py b/src/cloudflare/types/ai_gateway/billing/topup_status_response.py
new file mode 100644
index 00000000000..3803c9917e6
--- /dev/null
+++ b/src/cloudflare/types/ai_gateway/billing/topup_status_response.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import Literal
+
+from ...._models import BaseModel
+
+__all__ = ["TopupStatusResponse"]
+
+
+class TopupStatusResponse(BaseModel):
+ payment_intent_id: str
+
+ status: Literal["completed", "pending"]
diff --git a/src/cloudflare/types/ai_gateway/billing_credit_balance_response.py b/src/cloudflare/types/ai_gateway/billing_credit_balance_response.py
new file mode 100644
index 00000000000..40bff68aa01
--- /dev/null
+++ b/src/cloudflare/types/ai_gateway/billing_credit_balance_response.py
@@ -0,0 +1,39 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from pydantic import Field as FieldInfo
+
+from ..._models import BaseModel
+
+__all__ = ["BillingCreditBalanceResponse", "PaymentMethod", "TopupConfig"]
+
+
+class PaymentMethod(BaseModel):
+ brand: Optional[str] = None
+
+ last4: Optional[str] = None
+
+
+class TopupConfig(BaseModel):
+ amount: Optional[float] = None
+
+ disabled_reason: Optional[str] = FieldInfo(alias="disabledReason", default=None)
+
+ error: Optional[str] = None
+
+ last_failed_at: Optional[float] = FieldInfo(alias="lastFailedAt", default=None)
+
+ threshold: Optional[float] = None
+
+
+class BillingCreditBalanceResponse(BaseModel):
+ balance: float
+
+ has_default_payment_method: bool
+
+ payment_method: Optional[PaymentMethod] = None
+
+ topup_config: TopupConfig
+
+ first_topup_success: Optional[bool] = None
diff --git a/src/cloudflare/types/ai_gateway/billing_invoice_history_params.py b/src/cloudflare/types/ai_gateway/billing_invoice_history_params.py
new file mode 100644
index 00000000000..040695f6f96
--- /dev/null
+++ b/src/cloudflare/types/ai_gateway/billing_invoice_history_params.py
@@ -0,0 +1,14 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, Required, TypedDict
+
+__all__ = ["BillingInvoiceHistoryParams"]
+
+
+class BillingInvoiceHistoryParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ type: Literal["auto", "all", "manual"]
+ """Filter invoice type: auto, manual, or all."""
diff --git a/src/cloudflare/types/ai_gateway/billing_invoice_history_response.py b/src/cloudflare/types/ai_gateway/billing_invoice_history_response.py
new file mode 100644
index 00000000000..dfcab171f12
--- /dev/null
+++ b/src/cloudflare/types/ai_gateway/billing_invoice_history_response.py
@@ -0,0 +1,53 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+
+from ..._models import BaseModel
+
+__all__ = ["BillingInvoiceHistoryResponse", "Invoice", "Pagination"]
+
+
+class Invoice(BaseModel):
+ amount_due: float
+
+ amount_paid: float
+
+ amount_remaining: float
+
+ currency: str
+
+ id: Optional[str] = None
+
+ attempt_count: Optional[float] = None
+
+ attempted: Optional[bool] = None
+
+ auto_advance: Optional[bool] = None
+
+ created: Optional[float] = None
+
+ created_by: Optional[str] = None
+
+ description: Optional[str] = None
+
+ invoice_origin: Optional[str] = None
+
+ invoice_pdf: Optional[str] = None
+
+ status: Optional[str] = None
+
+
+class Pagination(BaseModel):
+ has_more: bool
+
+ page: float
+
+ per_page: float
+
+ total_count: float
+
+
+class BillingInvoiceHistoryResponse(BaseModel):
+ invoices: List[Invoice]
+
+ pagination: Pagination
diff --git a/src/cloudflare/types/ai_gateway/billing_invoice_preview_response.py b/src/cloudflare/types/ai_gateway/billing_invoice_preview_response.py
new file mode 100644
index 00000000000..eaff7ba8f46
--- /dev/null
+++ b/src/cloudflare/types/ai_gateway/billing_invoice_preview_response.py
@@ -0,0 +1,70 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = [
+ "BillingInvoicePreviewResponse",
+ "InvoiceLine",
+ "InvoiceLinePeriod",
+ "InvoiceLinePricing",
+ "InvoiceLinePretaxCreditAmount",
+]
+
+
+class InvoiceLinePeriod(BaseModel):
+ end: float
+
+ start: float
+
+
+class InvoiceLinePricing(BaseModel):
+ unit_amount_decimal: Optional[str] = None
+
+
+class InvoiceLinePretaxCreditAmount(BaseModel):
+ amount: float
+
+ type: str
+
+ credit_balance_transaction: Optional[str] = None
+
+ discount: Optional[str] = None
+
+
+class InvoiceLine(BaseModel):
+ amount: float
+
+ currency: str
+
+ description: Optional[str] = None
+
+ period: InvoiceLinePeriod
+
+ pricing: InvoiceLinePricing
+
+ quantity: float
+
+ pretax_credit_amounts: Optional[List[InvoiceLinePretaxCreditAmount]] = None
+
+
+class BillingInvoicePreviewResponse(BaseModel):
+ id: str
+
+ amount_due: float
+
+ amount_paid: float
+
+ amount_remaining: float
+
+ currency: str
+
+ invoice_lines: List[InvoiceLine]
+
+ period_end: float
+
+ period_start: float
+
+ status: Literal["draft", "open", "paid", "uncollectible", "void"]
diff --git a/src/cloudflare/types/ai_gateway/billing_usage_history_params.py b/src/cloudflare/types/ai_gateway/billing_usage_history_params.py
new file mode 100644
index 00000000000..ae82ec9e6e1
--- /dev/null
+++ b/src/cloudflare/types/ai_gateway/billing_usage_history_params.py
@@ -0,0 +1,21 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Optional
+from typing_extensions import Literal, Required, TypedDict
+
+__all__ = ["BillingUsageHistoryParams"]
+
+
+class BillingUsageHistoryParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ value_grouping_window: Required[Literal["day", "hour"]]
+ """Grouping window for usage data."""
+
+ end_time: Optional[float]
+ """End time as Unix timestamp in milliseconds."""
+
+ start_time: Optional[float]
+ """Start time as Unix timestamp in milliseconds."""
diff --git a/src/cloudflare/types/ai_gateway/billing_usage_history_response.py b/src/cloudflare/types/ai_gateway/billing_usage_history_response.py
new file mode 100644
index 00000000000..e54aae19e14
--- /dev/null
+++ b/src/cloudflare/types/ai_gateway/billing_usage_history_response.py
@@ -0,0 +1,21 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List
+
+from ..._models import BaseModel
+
+__all__ = ["BillingUsageHistoryResponse", "History"]
+
+
+class History(BaseModel):
+ id: str
+
+ aggregated_value: float
+
+ end_time: float
+
+ start_time: float
+
+
+class BillingUsageHistoryResponse(BaseModel):
+ history: List[History]
diff --git a/src/cloudflare/types/aisearch/instance_create_params.py b/src/cloudflare/types/aisearch/instance_create_params.py
index 66b6ae9f39b..bd94ee3086c 100644
--- a/src/cloudflare/types/aisearch/instance_create_params.py
+++ b/src/cloudflare/types/aisearch/instance_create_params.py
@@ -325,8 +325,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(TypedDict, total=False):
selector: Required[str]
"""CSS selector to extract content from pages matching the path pattern.
- Supports standard CSS selectors including class, ID, element, and attribute
- selectors.
+ Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single
+ element; if multiple elements match, the selector is ignored and the full page
+ is used.
"""
@@ -335,10 +336,16 @@ class SourceParamsWebCrawlerParseOptions(TypedDict, total=False):
"""
List of path-to-selector mappings for extracting specific content from crawled
pages. Each entry pairs a URL glob pattern with a CSS selector. The first
- matching path wins. Only the matched HTML fragment is stored and indexed.
+ matching path wins. Only the matched HTML fragment is stored and indexed. Omit
+ the field to disable content selection — empty arrays are rejected.
"""
include_headers: Dict[str, str]
+ """Up to 5 custom HTTP headers sent with each crawl request.
+
+ Names must be RFC-7230 token characters (no spaces, colons, or control
+ characters); values must be HTAB + printable ASCII (no CR/LF).
+ """
include_images: bool
diff --git a/src/cloudflare/types/aisearch/instance_create_response.py b/src/cloudflare/types/aisearch/instance_create_response.py
index 29f8aa3e5a1..46e1dbe5507 100644
--- a/src/cloudflare/types/aisearch/instance_create_response.py
+++ b/src/cloudflare/types/aisearch/instance_create_response.py
@@ -166,8 +166,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel):
selector: str
"""CSS selector to extract content from pages matching the path pattern.
- Supports standard CSS selectors including class, ID, element, and attribute
- selectors.
+ Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single
+ element; if multiple elements match, the selector is ignored and the full page
+ is used.
"""
@@ -176,10 +177,16 @@ class SourceParamsWebCrawlerParseOptions(BaseModel):
"""
List of path-to-selector mappings for extracting specific content from crawled
pages. Each entry pairs a URL glob pattern with a CSS selector. The first
- matching path wins. Only the matched HTML fragment is stored and indexed.
+ matching path wins. Only the matched HTML fragment is stored and indexed. Omit
+ the field to disable content selection — empty arrays are rejected.
"""
include_headers: Optional[Dict[str, str]] = None
+ """Up to 5 custom HTTP headers sent with each crawl request.
+
+ Names must be RFC-7230 token characters (no spaces, colons, or control
+ characters); values must be HTAB + printable ASCII (no CR/LF).
+ """
include_images: Optional[bool] = None
diff --git a/src/cloudflare/types/aisearch/instance_delete_response.py b/src/cloudflare/types/aisearch/instance_delete_response.py
index 63b7cc489f8..5fa4b6aec7b 100644
--- a/src/cloudflare/types/aisearch/instance_delete_response.py
+++ b/src/cloudflare/types/aisearch/instance_delete_response.py
@@ -166,8 +166,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel):
selector: str
"""CSS selector to extract content from pages matching the path pattern.
- Supports standard CSS selectors including class, ID, element, and attribute
- selectors.
+ Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single
+ element; if multiple elements match, the selector is ignored and the full page
+ is used.
"""
@@ -176,10 +177,16 @@ class SourceParamsWebCrawlerParseOptions(BaseModel):
"""
List of path-to-selector mappings for extracting specific content from crawled
pages. Each entry pairs a URL glob pattern with a CSS selector. The first
- matching path wins. Only the matched HTML fragment is stored and indexed.
+ matching path wins. Only the matched HTML fragment is stored and indexed. Omit
+ the field to disable content selection — empty arrays are rejected.
"""
include_headers: Optional[Dict[str, str]] = None
+ """Up to 5 custom HTTP headers sent with each crawl request.
+
+ Names must be RFC-7230 token characters (no spaces, colons, or control
+ characters); values must be HTAB + printable ASCII (no CR/LF).
+ """
include_images: Optional[bool] = None
diff --git a/src/cloudflare/types/aisearch/instance_list_response.py b/src/cloudflare/types/aisearch/instance_list_response.py
index 725f969e08d..672411cfd4a 100644
--- a/src/cloudflare/types/aisearch/instance_list_response.py
+++ b/src/cloudflare/types/aisearch/instance_list_response.py
@@ -166,8 +166,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel):
selector: str
"""CSS selector to extract content from pages matching the path pattern.
- Supports standard CSS selectors including class, ID, element, and attribute
- selectors.
+ Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single
+ element; if multiple elements match, the selector is ignored and the full page
+ is used.
"""
@@ -176,10 +177,16 @@ class SourceParamsWebCrawlerParseOptions(BaseModel):
"""
List of path-to-selector mappings for extracting specific content from crawled
pages. Each entry pairs a URL glob pattern with a CSS selector. The first
- matching path wins. Only the matched HTML fragment is stored and indexed.
+ matching path wins. Only the matched HTML fragment is stored and indexed. Omit
+ the field to disable content selection — empty arrays are rejected.
"""
include_headers: Optional[Dict[str, str]] = None
+ """Up to 5 custom HTTP headers sent with each crawl request.
+
+ Names must be RFC-7230 token characters (no spaces, colons, or control
+ characters); values must be HTAB + printable ASCII (no CR/LF).
+ """
include_images: Optional[bool] = None
diff --git a/src/cloudflare/types/aisearch/instance_read_response.py b/src/cloudflare/types/aisearch/instance_read_response.py
index dc0a8c18c72..fe5412fa35d 100644
--- a/src/cloudflare/types/aisearch/instance_read_response.py
+++ b/src/cloudflare/types/aisearch/instance_read_response.py
@@ -166,8 +166,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel):
selector: str
"""CSS selector to extract content from pages matching the path pattern.
- Supports standard CSS selectors including class, ID, element, and attribute
- selectors.
+ Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single
+ element; if multiple elements match, the selector is ignored and the full page
+ is used.
"""
@@ -176,10 +177,16 @@ class SourceParamsWebCrawlerParseOptions(BaseModel):
"""
List of path-to-selector mappings for extracting specific content from crawled
pages. Each entry pairs a URL glob pattern with a CSS selector. The first
- matching path wins. Only the matched HTML fragment is stored and indexed.
+ matching path wins. Only the matched HTML fragment is stored and indexed. Omit
+ the field to disable content selection — empty arrays are rejected.
"""
include_headers: Optional[Dict[str, str]] = None
+ """Up to 5 custom HTTP headers sent with each crawl request.
+
+ Names must be RFC-7230 token characters (no spaces, colons, or control
+ characters); values must be HTAB + printable ASCII (no CR/LF).
+ """
include_images: Optional[bool] = None
diff --git a/src/cloudflare/types/aisearch/instance_update_params.py b/src/cloudflare/types/aisearch/instance_update_params.py
index fddda6864f0..bcbf19cb3bb 100644
--- a/src/cloudflare/types/aisearch/instance_update_params.py
+++ b/src/cloudflare/types/aisearch/instance_update_params.py
@@ -360,8 +360,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(TypedDict, total=False):
selector: Required[str]
"""CSS selector to extract content from pages matching the path pattern.
- Supports standard CSS selectors including class, ID, element, and attribute
- selectors.
+ Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single
+ element; if multiple elements match, the selector is ignored and the full page
+ is used.
"""
@@ -370,10 +371,16 @@ class SourceParamsWebCrawlerParseOptions(TypedDict, total=False):
"""
List of path-to-selector mappings for extracting specific content from crawled
pages. Each entry pairs a URL glob pattern with a CSS selector. The first
- matching path wins. Only the matched HTML fragment is stored and indexed.
+ matching path wins. Only the matched HTML fragment is stored and indexed. Omit
+ the field to disable content selection — empty arrays are rejected.
"""
include_headers: Dict[str, str]
+ """Up to 5 custom HTTP headers sent with each crawl request.
+
+ Names must be RFC-7230 token characters (no spaces, colons, or control
+ characters); values must be HTAB + printable ASCII (no CR/LF).
+ """
include_images: bool
diff --git a/src/cloudflare/types/aisearch/instance_update_response.py b/src/cloudflare/types/aisearch/instance_update_response.py
index 379e9d7b207..31a820e5e8e 100644
--- a/src/cloudflare/types/aisearch/instance_update_response.py
+++ b/src/cloudflare/types/aisearch/instance_update_response.py
@@ -166,8 +166,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel):
selector: str
"""CSS selector to extract content from pages matching the path pattern.
- Supports standard CSS selectors including class, ID, element, and attribute
- selectors.
+ Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single
+ element; if multiple elements match, the selector is ignored and the full page
+ is used.
"""
@@ -176,10 +177,16 @@ class SourceParamsWebCrawlerParseOptions(BaseModel):
"""
List of path-to-selector mappings for extracting specific content from crawled
pages. Each entry pairs a URL glob pattern with a CSS selector. The first
- matching path wins. Only the matched HTML fragment is stored and indexed.
+ matching path wins. Only the matched HTML fragment is stored and indexed. Omit
+ the field to disable content selection — empty arrays are rejected.
"""
include_headers: Optional[Dict[str, str]] = None
+ """Up to 5 custom HTTP headers sent with each crawl request.
+
+ Names must be RFC-7230 token characters (no spaces, colons, or control
+ characters); values must be HTAB + printable ASCII (no CR/LF).
+ """
include_images: Optional[bool] = None
diff --git a/src/cloudflare/types/aisearch/namespaces/instance_create_params.py b/src/cloudflare/types/aisearch/namespaces/instance_create_params.py
index 10493f5da1a..81c6ac6303e 100644
--- a/src/cloudflare/types/aisearch/namespaces/instance_create_params.py
+++ b/src/cloudflare/types/aisearch/namespaces/instance_create_params.py
@@ -325,8 +325,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(TypedDict, total=False):
selector: Required[str]
"""CSS selector to extract content from pages matching the path pattern.
- Supports standard CSS selectors including class, ID, element, and attribute
- selectors.
+ Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single
+ element; if multiple elements match, the selector is ignored and the full page
+ is used.
"""
@@ -335,10 +336,16 @@ class SourceParamsWebCrawlerParseOptions(TypedDict, total=False):
"""
List of path-to-selector mappings for extracting specific content from crawled
pages. Each entry pairs a URL glob pattern with a CSS selector. The first
- matching path wins. Only the matched HTML fragment is stored and indexed.
+ matching path wins. Only the matched HTML fragment is stored and indexed. Omit
+ the field to disable content selection — empty arrays are rejected.
"""
include_headers: Dict[str, str]
+ """Up to 5 custom HTTP headers sent with each crawl request.
+
+ Names must be RFC-7230 token characters (no spaces, colons, or control
+ characters); values must be HTAB + printable ASCII (no CR/LF).
+ """
include_images: bool
diff --git a/src/cloudflare/types/aisearch/namespaces/instance_create_response.py b/src/cloudflare/types/aisearch/namespaces/instance_create_response.py
index 3e320dec61a..b25271799ea 100644
--- a/src/cloudflare/types/aisearch/namespaces/instance_create_response.py
+++ b/src/cloudflare/types/aisearch/namespaces/instance_create_response.py
@@ -166,8 +166,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel):
selector: str
"""CSS selector to extract content from pages matching the path pattern.
- Supports standard CSS selectors including class, ID, element, and attribute
- selectors.
+ Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single
+ element; if multiple elements match, the selector is ignored and the full page
+ is used.
"""
@@ -176,10 +177,16 @@ class SourceParamsWebCrawlerParseOptions(BaseModel):
"""
List of path-to-selector mappings for extracting specific content from crawled
pages. Each entry pairs a URL glob pattern with a CSS selector. The first
- matching path wins. Only the matched HTML fragment is stored and indexed.
+ matching path wins. Only the matched HTML fragment is stored and indexed. Omit
+ the field to disable content selection — empty arrays are rejected.
"""
include_headers: Optional[Dict[str, str]] = None
+ """Up to 5 custom HTTP headers sent with each crawl request.
+
+ Names must be RFC-7230 token characters (no spaces, colons, or control
+ characters); values must be HTAB + printable ASCII (no CR/LF).
+ """
include_images: Optional[bool] = None
diff --git a/src/cloudflare/types/aisearch/namespaces/instance_delete_response.py b/src/cloudflare/types/aisearch/namespaces/instance_delete_response.py
index 6caf390c7f4..31331886982 100644
--- a/src/cloudflare/types/aisearch/namespaces/instance_delete_response.py
+++ b/src/cloudflare/types/aisearch/namespaces/instance_delete_response.py
@@ -166,8 +166,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel):
selector: str
"""CSS selector to extract content from pages matching the path pattern.
- Supports standard CSS selectors including class, ID, element, and attribute
- selectors.
+ Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single
+ element; if multiple elements match, the selector is ignored and the full page
+ is used.
"""
@@ -176,10 +177,16 @@ class SourceParamsWebCrawlerParseOptions(BaseModel):
"""
List of path-to-selector mappings for extracting specific content from crawled
pages. Each entry pairs a URL glob pattern with a CSS selector. The first
- matching path wins. Only the matched HTML fragment is stored and indexed.
+ matching path wins. Only the matched HTML fragment is stored and indexed. Omit
+ the field to disable content selection — empty arrays are rejected.
"""
include_headers: Optional[Dict[str, str]] = None
+ """Up to 5 custom HTTP headers sent with each crawl request.
+
+ Names must be RFC-7230 token characters (no spaces, colons, or control
+ characters); values must be HTAB + printable ASCII (no CR/LF).
+ """
include_images: Optional[bool] = None
diff --git a/src/cloudflare/types/aisearch/namespaces/instance_list_response.py b/src/cloudflare/types/aisearch/namespaces/instance_list_response.py
index 70f2d02faf3..568d389a7ec 100644
--- a/src/cloudflare/types/aisearch/namespaces/instance_list_response.py
+++ b/src/cloudflare/types/aisearch/namespaces/instance_list_response.py
@@ -166,8 +166,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel):
selector: str
"""CSS selector to extract content from pages matching the path pattern.
- Supports standard CSS selectors including class, ID, element, and attribute
- selectors.
+ Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single
+ element; if multiple elements match, the selector is ignored and the full page
+ is used.
"""
@@ -176,10 +177,16 @@ class SourceParamsWebCrawlerParseOptions(BaseModel):
"""
List of path-to-selector mappings for extracting specific content from crawled
pages. Each entry pairs a URL glob pattern with a CSS selector. The first
- matching path wins. Only the matched HTML fragment is stored and indexed.
+ matching path wins. Only the matched HTML fragment is stored and indexed. Omit
+ the field to disable content selection — empty arrays are rejected.
"""
include_headers: Optional[Dict[str, str]] = None
+ """Up to 5 custom HTTP headers sent with each crawl request.
+
+ Names must be RFC-7230 token characters (no spaces, colons, or control
+ characters); values must be HTAB + printable ASCII (no CR/LF).
+ """
include_images: Optional[bool] = None
diff --git a/src/cloudflare/types/aisearch/namespaces/instance_read_response.py b/src/cloudflare/types/aisearch/namespaces/instance_read_response.py
index 1c2e469c282..1f0f6568691 100644
--- a/src/cloudflare/types/aisearch/namespaces/instance_read_response.py
+++ b/src/cloudflare/types/aisearch/namespaces/instance_read_response.py
@@ -166,8 +166,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel):
selector: str
"""CSS selector to extract content from pages matching the path pattern.
- Supports standard CSS selectors including class, ID, element, and attribute
- selectors.
+ Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single
+ element; if multiple elements match, the selector is ignored and the full page
+ is used.
"""
@@ -176,10 +177,16 @@ class SourceParamsWebCrawlerParseOptions(BaseModel):
"""
List of path-to-selector mappings for extracting specific content from crawled
pages. Each entry pairs a URL glob pattern with a CSS selector. The first
- matching path wins. Only the matched HTML fragment is stored and indexed.
+ matching path wins. Only the matched HTML fragment is stored and indexed. Omit
+ the field to disable content selection — empty arrays are rejected.
"""
include_headers: Optional[Dict[str, str]] = None
+ """Up to 5 custom HTTP headers sent with each crawl request.
+
+ Names must be RFC-7230 token characters (no spaces, colons, or control
+ characters); values must be HTAB + printable ASCII (no CR/LF).
+ """
include_images: Optional[bool] = None
diff --git a/src/cloudflare/types/aisearch/namespaces/instance_update_params.py b/src/cloudflare/types/aisearch/namespaces/instance_update_params.py
index 057cd3d1241..b23aae86afd 100644
--- a/src/cloudflare/types/aisearch/namespaces/instance_update_params.py
+++ b/src/cloudflare/types/aisearch/namespaces/instance_update_params.py
@@ -362,8 +362,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(TypedDict, total=False):
selector: Required[str]
"""CSS selector to extract content from pages matching the path pattern.
- Supports standard CSS selectors including class, ID, element, and attribute
- selectors.
+ Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single
+ element; if multiple elements match, the selector is ignored and the full page
+ is used.
"""
@@ -372,10 +373,16 @@ class SourceParamsWebCrawlerParseOptions(TypedDict, total=False):
"""
List of path-to-selector mappings for extracting specific content from crawled
pages. Each entry pairs a URL glob pattern with a CSS selector. The first
- matching path wins. Only the matched HTML fragment is stored and indexed.
+ matching path wins. Only the matched HTML fragment is stored and indexed. Omit
+ the field to disable content selection — empty arrays are rejected.
"""
include_headers: Dict[str, str]
+ """Up to 5 custom HTTP headers sent with each crawl request.
+
+ Names must be RFC-7230 token characters (no spaces, colons, or control
+ characters); values must be HTAB + printable ASCII (no CR/LF).
+ """
include_images: bool
diff --git a/src/cloudflare/types/aisearch/namespaces/instance_update_response.py b/src/cloudflare/types/aisearch/namespaces/instance_update_response.py
index 7de705537a7..ca593a5cf2a 100644
--- a/src/cloudflare/types/aisearch/namespaces/instance_update_response.py
+++ b/src/cloudflare/types/aisearch/namespaces/instance_update_response.py
@@ -166,8 +166,9 @@ class SourceParamsWebCrawlerParseOptionsContentSelector(BaseModel):
selector: str
"""CSS selector to extract content from pages matching the path pattern.
- Supports standard CSS selectors including class, ID, element, and attribute
- selectors.
+ Must not contain disallowed characters (;, `, $, {, }, \\)). Must target a single
+ element; if multiple elements match, the selector is ignored and the full page
+ is used.
"""
@@ -176,10 +177,16 @@ class SourceParamsWebCrawlerParseOptions(BaseModel):
"""
List of path-to-selector mappings for extracting specific content from crawled
pages. Each entry pairs a URL glob pattern with a CSS selector. The first
- matching path wins. Only the matched HTML fragment is stored and indexed.
+ matching path wins. Only the matched HTML fragment is stored and indexed. Omit
+ the field to disable content selection — empty arrays are rejected.
"""
include_headers: Optional[Dict[str, str]] = None
+ """Up to 5 custom HTTP headers sent with each crawl request.
+
+ Names must be RFC-7230 token characters (no spaces, colons, or control
+ characters); values must be HTAB + printable ASCII (no CR/LF).
+ """
include_images: Optional[bool] = None
diff --git a/src/cloudflare/types/billing/usage_paygo_response.py b/src/cloudflare/types/billing/usage_paygo_response.py
index 23db8801493..9b5a22770dd 100644
--- a/src/cloudflare/types/billing/usage_paygo_response.py
+++ b/src/cloudflare/types/billing/usage_paygo_response.py
@@ -30,7 +30,11 @@ class UsagePaygoResponseItem(BaseModel):
"""Specifies the quantity consumed during this charge period."""
consumed_unit: str = FieldInfo(alias="ConsumedUnit")
- """Specifies the unit of measurement for consumed quantity."""
+ """
+ A display name for the unit of measurement used for the product (for example,
+ "GB-months", "GB-seconds"). May be empty when the unit is implicit in the
+ service name.
+ """
contracted_cost: float = FieldInfo(alias="ContractedCost")
"""Specifies the cost for this charge period in the billing currency."""
diff --git a/src/cloudflare/types/cache/__init__.py b/src/cloudflare/types/cache/__init__.py
index a8c1ab90c62..fe3581cc0b9 100644
--- a/src/cloudflare/types/cache/__init__.py
+++ b/src/cloudflare/types/cache/__init__.py
@@ -19,27 +19,29 @@
from .cache_reserve_edit_response import CacheReserveEditResponse as CacheReserveEditResponse
from .cache_reserve_clear_response import CacheReserveClearResponse as CacheReserveClearResponse
from .cache_reserve_status_response import CacheReserveStatusResponse as CacheReserveStatusResponse
+from .cache_purge_environment_params import CachePurgeEnvironmentParams as CachePurgeEnvironmentParams
from .smart_tiered_cache_edit_params import SmartTieredCacheEditParams as SmartTieredCacheEditParams
-from .origin_cloud_region_edit_params import OriginCloudRegionEditParams as OriginCloudRegionEditParams
+from .origin_cloud_region_list_params import OriginCloudRegionListParams as OriginCloudRegionListParams
from .smart_tiered_cache_get_response import SmartTieredCacheGetResponse as SmartTieredCacheGetResponse
-from .origin_cloud_region_get_response import OriginCloudRegionGetResponse as OriginCloudRegionGetResponse
+from .cache_purge_environment_response import CachePurgeEnvironmentResponse as CachePurgeEnvironmentResponse
+from .smart_tiered_cache_create_params import SmartTieredCacheCreateParams as SmartTieredCacheCreateParams
from .smart_tiered_cache_edit_response import SmartTieredCacheEditResponse as SmartTieredCacheEditResponse
-from .origin_cloud_region_create_params import OriginCloudRegionCreateParams as OriginCloudRegionCreateParams
-from .origin_cloud_region_edit_response import OriginCloudRegionEditResponse as OriginCloudRegionEditResponse
-from .origin_cloud_region_list_response import OriginCloudRegionListResponse as OriginCloudRegionListResponse
+from .origin_cloud_region_update_params import OriginCloudRegionUpdateParams as OriginCloudRegionUpdateParams
from .regional_tiered_cache_edit_params import RegionalTieredCacheEditParams as RegionalTieredCacheEditParams
from .regional_tiered_cache_get_response import RegionalTieredCacheGetResponse as RegionalTieredCacheGetResponse
+from .smart_tiered_cache_create_response import SmartTieredCacheCreateResponse as SmartTieredCacheCreateResponse
from .smart_tiered_cache_delete_response import SmartTieredCacheDeleteResponse as SmartTieredCacheDeleteResponse
-from .origin_cloud_region_create_response import OriginCloudRegionCreateResponse as OriginCloudRegionCreateResponse
from .origin_cloud_region_delete_response import OriginCloudRegionDeleteResponse as OriginCloudRegionDeleteResponse
from .regional_tiered_cache_edit_response import RegionalTieredCacheEditResponse as RegionalTieredCacheEditResponse
-from .origin_cloud_region_bulk_edit_params import OriginCloudRegionBulkEditParams as OriginCloudRegionBulkEditParams
-from .origin_cloud_region_bulk_edit_response import (
- OriginCloudRegionBulkEditResponse as OriginCloudRegionBulkEditResponse,
+from .origin_cloud_region_bulk_update_params import (
+ OriginCloudRegionBulkUpdateParams as OriginCloudRegionBulkUpdateParams,
)
from .origin_cloud_region_bulk_delete_response import (
OriginCloudRegionBulkDeleteResponse as OriginCloudRegionBulkDeleteResponse,
)
+from .origin_cloud_region_bulk_update_response import (
+ OriginCloudRegionBulkUpdateResponse as OriginCloudRegionBulkUpdateResponse,
+)
from .origin_cloud_region_supported_regions_response import (
OriginCloudRegionSupportedRegionsResponse as OriginCloudRegionSupportedRegionsResponse,
)
diff --git a/src/cloudflare/types/cache/cache_purge_environment_params.py b/src/cloudflare/types/cache/cache_purge_environment_params.py
new file mode 100644
index 00000000000..2c6e2490ec6
--- /dev/null
+++ b/src/cloudflare/types/cache/cache_purge_environment_params.py
@@ -0,0 +1,95 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Dict, Union, Iterable
+from typing_extensions import Required, TypeAlias, TypedDict
+
+from ..._types import SequenceNotStr
+
+__all__ = [
+ "CachePurgeEnvironmentParams",
+ "CachePurgeFlexPurgeByTags",
+ "CachePurgeFlexPurgeByHostnames",
+ "CachePurgeFlexPurgeByPrefixes",
+ "CachePurgeEverything",
+ "CachePurgeSingleFile",
+ "CachePurgeSingleFileWithURLAndHeaders",
+ "CachePurgeSingleFileWithURLAndHeadersFile",
+]
+
+
+class CachePurgeFlexPurgeByTags(TypedDict, total=False):
+ zone_id: Required[str]
+
+ tags: SequenceNotStr[str]
+ """
+ For more information on cache tags and purging by tags, please refer to
+ [purge by cache-tags documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-tags/).
+ """
+
+
+class CachePurgeFlexPurgeByHostnames(TypedDict, total=False):
+ zone_id: Required[str]
+
+ hosts: SequenceNotStr[str]
+ """
+ For more information purging by hostnames, please refer to
+ [purge by hostname documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-hostname/).
+ """
+
+
+class CachePurgeFlexPurgeByPrefixes(TypedDict, total=False):
+ zone_id: Required[str]
+
+ prefixes: SequenceNotStr[str]
+ """
+ For more information on purging by prefixes, please refer to
+ [purge by prefix documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/purge_by_prefix/).
+ """
+
+
+class CachePurgeEverything(TypedDict, total=False):
+ zone_id: Required[str]
+
+ purge_everything: bool
+ """
+ For more information, please refer to
+ [purge everything documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-everything/).
+ """
+
+
+class CachePurgeSingleFile(TypedDict, total=False):
+ zone_id: Required[str]
+
+ files: SequenceNotStr[str]
+ """
+ For more information on purging files, please refer to
+ [purge by single-file documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-single-file/).
+ """
+
+
+class CachePurgeSingleFileWithURLAndHeaders(TypedDict, total=False):
+ zone_id: Required[str]
+
+ files: Iterable[CachePurgeSingleFileWithURLAndHeadersFile]
+ """
+ For more information on purging files with URL and headers, please refer to
+ [purge by single-file documentation page](https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-single-file/).
+ """
+
+
+class CachePurgeSingleFileWithURLAndHeadersFile(TypedDict, total=False):
+ headers: Dict[str, str]
+
+ url: str
+
+
+CachePurgeEnvironmentParams: TypeAlias = Union[
+ CachePurgeFlexPurgeByTags,
+ CachePurgeFlexPurgeByHostnames,
+ CachePurgeFlexPurgeByPrefixes,
+ CachePurgeEverything,
+ CachePurgeSingleFile,
+ CachePurgeSingleFileWithURLAndHeaders,
+]
diff --git a/src/cloudflare/types/cache/cache_purge_environment_response.py b/src/cloudflare/types/cache/cache_purge_environment_response.py
new file mode 100644
index 00000000000..2e571b469b4
--- /dev/null
+++ b/src/cloudflare/types/cache/cache_purge_environment_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from ..._models import BaseModel
+
+__all__ = ["CachePurgeEnvironmentResponse"]
+
+
+class CachePurgeEnvironmentResponse(BaseModel):
+ id: str
diff --git a/src/cloudflare/types/cache/origin_cloud_region.py b/src/cloudflare/types/cache/origin_cloud_region.py
index 54afe283353..2e254f85cf2 100644
--- a/src/cloudflare/types/cache/origin_cloud_region.py
+++ b/src/cloudflare/types/cache/origin_cloud_region.py
@@ -4,8 +4,6 @@
from datetime import datetime
from typing_extensions import Literal
-from pydantic import Field as FieldInfo
-
from ..._models import BaseModel
__all__ = ["OriginCloudRegion"]
@@ -14,8 +12,11 @@
class OriginCloudRegion(BaseModel):
"""A single origin IP-to-cloud-region mapping."""
- origin_ip: str = FieldInfo(alias="origin-ip")
- """The origin IP address (IPv4 or IPv6, canonicalized)."""
+ origin_ip: str
+ """The origin IP address (IPv4 or IPv6).
+
+ Normalized to canonical form (RFC 5952 for IPv6).
+ """
region: str
"""Cloud vendor region identifier."""
diff --git a/src/cloudflare/types/cache/origin_cloud_region_bulk_delete_response.py b/src/cloudflare/types/cache/origin_cloud_region_bulk_delete_response.py
index d5ea3f1b7d1..556b1e749d8 100644
--- a/src/cloudflare/types/cache/origin_cloud_region_bulk_delete_response.py
+++ b/src/cloudflare/types/cache/origin_cloud_region_bulk_delete_response.py
@@ -1,20 +1,16 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing import List, Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from pydantic import Field as FieldInfo
from ..._models import BaseModel
-__all__ = ["OriginCloudRegionBulkDeleteResponse", "Value", "ValueFailed", "ValueSucceeded"]
+__all__ = ["OriginCloudRegionBulkDeleteResponse", "Failed", "Succeeded"]
-class ValueFailed(BaseModel):
+class Failed(BaseModel):
"""Result for a single item in a batch operation."""
- origin_ip: str = FieldInfo(alias="origin-ip")
+ origin_ip: str
"""The origin IP address for this item."""
error: Optional[str] = None
@@ -23,17 +19,22 @@ class ValueFailed(BaseModel):
region: Optional[str] = None
"""Cloud vendor region identifier.
- Present on succeeded items for patch operations.
+ Present on succeeded items (the new value for upsert, the deleted value for
+ delete).
"""
vendor: Optional[str] = None
- """Cloud vendor identifier. Present on succeeded items for patch operations."""
+ """Cloud vendor identifier.
+
+ Present on succeeded items (the new value for upsert, the deleted value for
+ delete).
+ """
-class ValueSucceeded(BaseModel):
+class Succeeded(BaseModel):
"""Result for a single item in a batch operation."""
- origin_ip: str = FieldInfo(alias="origin-ip")
+ origin_ip: str
"""The origin IP address for this item."""
error: Optional[str] = None
@@ -42,33 +43,23 @@ class ValueSucceeded(BaseModel):
region: Optional[str] = None
"""Cloud vendor region identifier.
- Present on succeeded items for patch operations.
+ Present on succeeded items (the new value for upsert, the deleted value for
+ delete).
"""
vendor: Optional[str] = None
- """Cloud vendor identifier. Present on succeeded items for patch operations."""
-
+ """Cloud vendor identifier.
-class Value(BaseModel):
- failed: List[ValueFailed]
- """Items that could not be applied, with error details."""
-
- succeeded: List[ValueSucceeded]
- """Items that were successfully applied."""
+ Present on succeeded items (the new value for upsert, the deleted value for
+ delete).
+ """
class OriginCloudRegionBulkDeleteResponse(BaseModel):
"""Response result for a batch origin cloud region operation."""
- id: Literal["origin_public_cloud_region"]
-
- editable: bool
- """Whether the setting can be modified by the current user."""
-
- value: Value
-
- modified_on: Optional[datetime] = None
- """Time the mapping set was last modified.
+ failed: List[Failed]
+ """Items that could not be applied, with error details."""
- Null when no items were successfully applied.
- """
+ succeeded: List[Succeeded]
+ """Items that were successfully applied."""
diff --git a/src/cloudflare/types/cache/origin_cloud_region_bulk_edit_response.py b/src/cloudflare/types/cache/origin_cloud_region_bulk_edit_response.py
deleted file mode 100644
index 097de32e532..00000000000
--- a/src/cloudflare/types/cache/origin_cloud_region_bulk_edit_response.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from pydantic import Field as FieldInfo
-
-from ..._models import BaseModel
-
-__all__ = ["OriginCloudRegionBulkEditResponse", "Value", "ValueFailed", "ValueSucceeded"]
-
-
-class ValueFailed(BaseModel):
- """Result for a single item in a batch operation."""
-
- origin_ip: str = FieldInfo(alias="origin-ip")
- """The origin IP address for this item."""
-
- error: Optional[str] = None
- """Error message explaining why the item failed. Present only on failed items."""
-
- region: Optional[str] = None
- """Cloud vendor region identifier.
-
- Present on succeeded items for patch operations.
- """
-
- vendor: Optional[str] = None
- """Cloud vendor identifier. Present on succeeded items for patch operations."""
-
-
-class ValueSucceeded(BaseModel):
- """Result for a single item in a batch operation."""
-
- origin_ip: str = FieldInfo(alias="origin-ip")
- """The origin IP address for this item."""
-
- error: Optional[str] = None
- """Error message explaining why the item failed. Present only on failed items."""
-
- region: Optional[str] = None
- """Cloud vendor region identifier.
-
- Present on succeeded items for patch operations.
- """
-
- vendor: Optional[str] = None
- """Cloud vendor identifier. Present on succeeded items for patch operations."""
-
-
-class Value(BaseModel):
- failed: List[ValueFailed]
- """Items that could not be applied, with error details."""
-
- succeeded: List[ValueSucceeded]
- """Items that were successfully applied."""
-
-
-class OriginCloudRegionBulkEditResponse(BaseModel):
- """Response result for a batch origin cloud region operation."""
-
- id: Literal["origin_public_cloud_region"]
-
- editable: bool
- """Whether the setting can be modified by the current user."""
-
- value: Value
-
- modified_on: Optional[datetime] = None
- """Time the mapping set was last modified.
-
- Null when no items were successfully applied.
- """
diff --git a/src/cloudflare/types/cache/origin_cloud_region_bulk_edit_params.py b/src/cloudflare/types/cache/origin_cloud_region_bulk_update_params.py
similarity index 59%
rename from src/cloudflare/types/cache/origin_cloud_region_bulk_edit_params.py
rename to src/cloudflare/types/cache/origin_cloud_region_bulk_update_params.py
index c1edc6dc142..f8eaddf731a 100644
--- a/src/cloudflare/types/cache/origin_cloud_region_bulk_edit_params.py
+++ b/src/cloudflare/types/cache/origin_cloud_region_bulk_update_params.py
@@ -5,10 +5,10 @@
from typing import Iterable
from typing_extensions import Literal, Required, TypedDict
-__all__ = ["OriginCloudRegionBulkEditParams", "Body"]
+__all__ = ["OriginCloudRegionBulkUpdateParams", "Body"]
-class OriginCloudRegionBulkEditParams(TypedDict, total=False):
+class OriginCloudRegionBulkUpdateParams(TypedDict, total=False):
zone_id: Required[str]
"""Identifier."""
@@ -16,12 +16,15 @@ class OriginCloudRegionBulkEditParams(TypedDict, total=False):
class Body(TypedDict, total=False):
- """Request body for creating or updating an origin cloud region mapping."""
+ """Request body for creating or replacing an origin cloud region mapping."""
- ip: Required[str]
+ origin_ip: Required[str]
"""Origin IP address (IPv4 or IPv6).
- Normalized to canonical form before storage (RFC 5952 for IPv6).
+ For the single PUT endpoint (`PUT /origin/cloud_regions/{origin_ip}`), this
+ field must match the path parameter or the request will be rejected with a 400
+ error. For the batch PUT endpoint, this field identifies which mapping to
+ upsert.
"""
region: Required[str]
diff --git a/src/cloudflare/types/cache/origin_cloud_region_bulk_update_response.py b/src/cloudflare/types/cache/origin_cloud_region_bulk_update_response.py
new file mode 100644
index 00000000000..7bce9f3f3fe
--- /dev/null
+++ b/src/cloudflare/types/cache/origin_cloud_region_bulk_update_response.py
@@ -0,0 +1,65 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+
+from ..._models import BaseModel
+
+__all__ = ["OriginCloudRegionBulkUpdateResponse", "Failed", "Succeeded"]
+
+
+class Failed(BaseModel):
+ """Result for a single item in a batch operation."""
+
+ origin_ip: str
+ """The origin IP address for this item."""
+
+ error: Optional[str] = None
+ """Error message explaining why the item failed. Present only on failed items."""
+
+ region: Optional[str] = None
+ """Cloud vendor region identifier.
+
+ Present on succeeded items (the new value for upsert, the deleted value for
+ delete).
+ """
+
+ vendor: Optional[str] = None
+ """Cloud vendor identifier.
+
+ Present on succeeded items (the new value for upsert, the deleted value for
+ delete).
+ """
+
+
+class Succeeded(BaseModel):
+ """Result for a single item in a batch operation."""
+
+ origin_ip: str
+ """The origin IP address for this item."""
+
+ error: Optional[str] = None
+ """Error message explaining why the item failed. Present only on failed items."""
+
+ region: Optional[str] = None
+ """Cloud vendor region identifier.
+
+ Present on succeeded items (the new value for upsert, the deleted value for
+ delete).
+ """
+
+ vendor: Optional[str] = None
+ """Cloud vendor identifier.
+
+ Present on succeeded items (the new value for upsert, the deleted value for
+ delete).
+ """
+
+
+class OriginCloudRegionBulkUpdateResponse(BaseModel):
+ """Response result for a batch origin cloud region operation."""
+
+ failed: List[Failed]
+ """Items that could not be applied, with error details."""
+
+ succeeded: List[Succeeded]
+ """Items that were successfully applied."""
diff --git a/src/cloudflare/types/cache/origin_cloud_region_create_params.py b/src/cloudflare/types/cache/origin_cloud_region_create_params.py
deleted file mode 100644
index 001b5377dd7..00000000000
--- a/src/cloudflare/types/cache/origin_cloud_region_create_params.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# 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__ = ["OriginCloudRegionCreateParams"]
-
-
-class OriginCloudRegionCreateParams(TypedDict, total=False):
- zone_id: Required[str]
- """Identifier."""
-
- ip: Required[str]
- """Origin IP address (IPv4 or IPv6).
-
- Normalized to canonical form before storage (RFC 5952 for IPv6).
- """
-
- region: Required[str]
- """Cloud vendor region identifier.
-
- Must be a valid region for the specified vendor as returned by the
- supported_regions endpoint.
- """
-
- vendor: Required[Literal["aws", "azure", "gcp", "oci"]]
- """Cloud vendor hosting the origin. Must be one of the supported vendors."""
diff --git a/src/cloudflare/types/cache/origin_cloud_region_create_response.py b/src/cloudflare/types/cache/origin_cloud_region_create_response.py
deleted file mode 100644
index 370d4051a68..00000000000
--- a/src/cloudflare/types/cache/origin_cloud_region_create_response.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from ..._models import BaseModel
-from .origin_cloud_region import OriginCloudRegion
-
-__all__ = ["OriginCloudRegionCreateResponse"]
-
-
-class OriginCloudRegionCreateResponse(BaseModel):
- """Response result for a single origin cloud region mapping."""
-
- id: Literal["origin_public_cloud_region"]
-
- editable: bool
- """Whether the setting can be modified by the current user."""
-
- value: OriginCloudRegion
- """A single origin IP-to-cloud-region mapping."""
-
- modified_on: Optional[datetime] = None
- """Time the mapping was last modified."""
diff --git a/src/cloudflare/types/cache/origin_cloud_region_delete_response.py b/src/cloudflare/types/cache/origin_cloud_region_delete_response.py
index fb8012e50c7..8aec199f2f9 100644
--- a/src/cloudflare/types/cache/origin_cloud_region_delete_response.py
+++ b/src/cloudflare/types/cache/origin_cloud_region_delete_response.py
@@ -1,25 +1,12 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Optional
-from datetime import datetime
-from typing_extensions import Literal
-
from ..._models import BaseModel
-from .origin_cloud_region import OriginCloudRegion
__all__ = ["OriginCloudRegionDeleteResponse"]
class OriginCloudRegionDeleteResponse(BaseModel):
- """Response result for a single origin cloud region mapping."""
-
- id: Literal["origin_public_cloud_region"]
-
- editable: bool
- """Whether the setting can be modified by the current user."""
-
- value: OriginCloudRegion
- """A single origin IP-to-cloud-region mapping."""
+ """Response result for a delete operation. Identifies the deleted mapping."""
- modified_on: Optional[datetime] = None
- """Time the mapping was last modified."""
+ origin_ip: str
+ """The origin IP address whose mapping was deleted."""
diff --git a/src/cloudflare/types/cache/origin_cloud_region_edit_response.py b/src/cloudflare/types/cache/origin_cloud_region_edit_response.py
deleted file mode 100644
index d84400575d2..00000000000
--- a/src/cloudflare/types/cache/origin_cloud_region_edit_response.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from ..._models import BaseModel
-from .origin_cloud_region import OriginCloudRegion
-
-__all__ = ["OriginCloudRegionEditResponse"]
-
-
-class OriginCloudRegionEditResponse(BaseModel):
- """Response result for a list of origin cloud region mappings."""
-
- id: Literal["origin_public_cloud_region"]
-
- editable: bool
- """Whether the setting can be modified by the current user."""
-
- value: List[OriginCloudRegion]
-
- modified_on: Optional[datetime] = None
- """Time the mapping set was last modified. Null when no mappings exist."""
diff --git a/src/cloudflare/types/cache/origin_cloud_region_get_response.py b/src/cloudflare/types/cache/origin_cloud_region_get_response.py
deleted file mode 100644
index 1cb87ebebcf..00000000000
--- a/src/cloudflare/types/cache/origin_cloud_region_get_response.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from ..._models import BaseModel
-from .origin_cloud_region import OriginCloudRegion
-
-__all__ = ["OriginCloudRegionGetResponse"]
-
-
-class OriginCloudRegionGetResponse(BaseModel):
- """Response result for a single origin cloud region mapping."""
-
- id: Literal["origin_public_cloud_region"]
-
- editable: bool
- """Whether the setting can be modified by the current user."""
-
- value: OriginCloudRegion
- """A single origin IP-to-cloud-region mapping."""
-
- modified_on: Optional[datetime] = None
- """Time the mapping was last modified."""
diff --git a/src/cloudflare/types/cache/origin_cloud_region_list_params.py b/src/cloudflare/types/cache/origin_cloud_region_list_params.py
new file mode 100644
index 00000000000..665c443d240
--- /dev/null
+++ b/src/cloudflare/types/cache/origin_cloud_region_list_params.py
@@ -0,0 +1,18 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["OriginCloudRegionListParams"]
+
+
+class OriginCloudRegionListParams(TypedDict, total=False):
+ zone_id: Required[str]
+ """Identifier."""
+
+ page: int
+ """Page number of paginated results."""
+
+ per_page: int
+ """Number of items per page."""
diff --git a/src/cloudflare/types/cache/origin_cloud_region_list_response.py b/src/cloudflare/types/cache/origin_cloud_region_list_response.py
deleted file mode 100644
index fc9fcf49a68..00000000000
--- a/src/cloudflare/types/cache/origin_cloud_region_list_response.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from ..._models import BaseModel
-from .origin_cloud_region import OriginCloudRegion
-
-__all__ = ["OriginCloudRegionListResponse"]
-
-
-class OriginCloudRegionListResponse(BaseModel):
- """Response result for a list of origin cloud region mappings."""
-
- id: Literal["origin_public_cloud_region"]
-
- editable: bool
- """Whether the setting can be modified by the current user."""
-
- value: List[OriginCloudRegion]
-
- modified_on: Optional[datetime] = None
- """Time the mapping set was last modified. Null when no mappings exist."""
diff --git a/src/cloudflare/types/cache/origin_cloud_region_edit_params.py b/src/cloudflare/types/cache/origin_cloud_region_update_params.py
similarity index 50%
rename from src/cloudflare/types/cache/origin_cloud_region_edit_params.py
rename to src/cloudflare/types/cache/origin_cloud_region_update_params.py
index 270268f630a..cc8a9e813a6 100644
--- a/src/cloudflare/types/cache/origin_cloud_region_edit_params.py
+++ b/src/cloudflare/types/cache/origin_cloud_region_update_params.py
@@ -2,19 +2,24 @@
from __future__ import annotations
-from typing_extensions import Literal, Required, TypedDict
+from typing_extensions import Literal, Required, Annotated, TypedDict
-__all__ = ["OriginCloudRegionEditParams"]
+from ..._utils import PropertyInfo
+__all__ = ["OriginCloudRegionUpdateParams"]
-class OriginCloudRegionEditParams(TypedDict, total=False):
+
+class OriginCloudRegionUpdateParams(TypedDict, total=False):
zone_id: Required[str]
"""Identifier."""
- ip: Required[str]
+ body_origin_ip: Required[Annotated[str, PropertyInfo(alias="origin_ip")]]
"""Origin IP address (IPv4 or IPv6).
- Normalized to canonical form before storage (RFC 5952 for IPv6).
+ For the single PUT endpoint (`PUT /origin/cloud_regions/{origin_ip}`), this
+ field must match the path parameter or the request will be rejected with a 400
+ error. For the batch PUT endpoint, this field identifies which mapping to
+ upsert.
"""
region: Required[str]
diff --git a/src/cloudflare/types/cache/smart_tiered_cache_create_params.py b/src/cloudflare/types/cache/smart_tiered_cache_create_params.py
new file mode 100644
index 00000000000..83ca7c702fa
--- /dev/null
+++ b/src/cloudflare/types/cache/smart_tiered_cache_create_params.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, Required, TypedDict
+
+__all__ = ["SmartTieredCacheCreateParams"]
+
+
+class SmartTieredCacheCreateParams(TypedDict, total=False):
+ zone_id: Required[str]
+ """Identifier."""
+
+ value: Required[Literal["on", "off"]]
+ """Enable or disable the Smart Tiered Cache."""
diff --git a/src/cloudflare/types/cache/smart_tiered_cache_create_response.py b/src/cloudflare/types/cache/smart_tiered_cache_create_response.py
new file mode 100644
index 00000000000..67cc88ded15
--- /dev/null
+++ b/src/cloudflare/types/cache/smart_tiered_cache_create_response.py
@@ -0,0 +1,23 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["SmartTieredCacheCreateResponse"]
+
+
+class SmartTieredCacheCreateResponse(BaseModel):
+ id: Literal["tiered_cache_smart_topology_enable"]
+ """The identifier of the caching setting."""
+
+ editable: bool
+ """Whether the setting is editable."""
+
+ value: Literal["on", "off"]
+ """Value of the Smart Tiered Cache zone setting."""
+
+ modified_on: Optional[datetime] = None
+ """Last time this setting was modified."""
diff --git a/src/cloudflare/types/cloudforce_one/threat_event_list_params.py b/src/cloudflare/types/cloudforce_one/threat_event_list_params.py
index a8204dc0e89..01dda459066 100644
--- a/src/cloudflare/types/cloudforce_one/threat_event_list_params.py
+++ b/src/cloudflare/types/cloudforce_one/threat_event_list_params.py
@@ -33,7 +33,7 @@ class ThreatEventListParams(TypedDict, total=False):
force_refresh: Annotated[bool, PropertyInfo(alias="forceRefresh")]
- format: Literal["json", "stix2"]
+ format: Literal["json", "stix2", "taxii"]
order: Literal["asc", "desc"]
diff --git a/src/cloudflare/types/intel/indicator_feed_get_response.py b/src/cloudflare/types/intel/indicator_feed_get_response.py
index 6373b835d80..654460a6802 100644
--- a/src/cloudflare/types/intel/indicator_feed_get_response.py
+++ b/src/cloudflare/types/intel/indicator_feed_get_response.py
@@ -6,7 +6,103 @@
from ..._models import BaseModel
-__all__ = ["IndicatorFeedGetResponse"]
+__all__ = [
+ "IndicatorFeedGetResponse",
+ "LastUploadSummary",
+ "LastUploadSummaryPersisted",
+ "LastUploadSummarySkipped",
+ "LastUploadSummaryUploaded",
+]
+
+
+class LastUploadSummaryPersisted(BaseModel):
+ """Net delta applied to feed indicators by this upload.
+
+ Snapshot
+ uploads emit both *_added and *_removed; delta-add emits only
+ *_added; delta-remove emits only *_removed.
+ """
+
+ domains_added: Optional[int] = None
+
+ domains_removed: Optional[int] = None
+
+ ips_added: Optional[int] = None
+
+ ips_removed: Optional[int] = None
+
+ urls_added: Optional[int] = None
+
+ urls_removed: Optional[int] = None
+
+
+class LastUploadSummarySkipped(BaseModel):
+ """
+ Counts of indicators that were uploaded but did not reach
+ QuickSilver, broken down by reason.
+ """
+
+ allowlisted_domains: Optional[int] = None
+ """Domains filtered by the global popularity allowlist at QS provisioning time.
+
+ Popular domains (bing.com, naver.com, etc.) are protected from
+ custom-threat-feed enforcement.
+ """
+
+ expired_indicators: Optional[int] = None
+ """Indicators in the upload whose valid_until is already in the past.
+
+ These are not added to QS; the expiration cron handles cleanup.
+ """
+
+ invalid_indicators: Optional[int] = None
+ """Reserved for future use.
+
+ Currently always 0 — the unifier aborts the entire upload on a single bad
+ indicator.
+ """
+
+
+class LastUploadSummaryUploaded(BaseModel):
+ """Indicator counts from the unified file the loader received"""
+
+ domains: Optional[int] = None
+ """Number of domain indicators in the upload"""
+
+ ips: Optional[int] = None
+ """Number of IP indicators in the upload"""
+
+ urls: Optional[int] = None
+ """Number of URL indicators in the upload"""
+
+
+class LastUploadSummary(BaseModel):
+ """Summary of indicator counts from the last successful upload to this
+ feed.
+
+ Populated by the custom-threat-feeds loader at the end of each
+ successful load. Absent (omitted) when no upload has completed
+ successfully or the upload errored before the summary write.
+ Surfaces silent-failure paths so operators can see when their
+ indicators were dropped (popularity allowlist, expired valid_until,
+ etc.) without reading loader logs.
+ """
+
+ persisted: Optional[LastUploadSummaryPersisted] = None
+ """Net delta applied to feed indicators by this upload.
+
+ Snapshot uploads emit both _\\__added and _\\__removed; delta-add emits only
+ _\\__added; delta-remove emits only _\\__removed.
+ """
+
+ skipped: Optional[LastUploadSummarySkipped] = None
+ """
+ Counts of indicators that were uploaded but did not reach QuickSilver, broken
+ down by reason.
+ """
+
+ uploaded: Optional[LastUploadSummaryUploaded] = None
+ """Indicator counts from the unified file the loader received"""
class IndicatorFeedGetResponse(BaseModel):
@@ -28,6 +124,16 @@ class IndicatorFeedGetResponse(BaseModel):
is_public: Optional[bool] = None
"""Whether the indicator feed is exposed to customers"""
+ last_upload_summary: Optional[LastUploadSummary] = None
+ """Summary of indicator counts from the last successful upload to this feed.
+
+ Populated by the custom-threat-feeds loader at the end of each successful load.
+ Absent (omitted) when no upload has completed successfully or the upload errored
+ before the summary write. Surfaces silent-failure paths so operators can see
+ when their indicators were dropped (popularity allowlist, expired valid_until,
+ etc.) without reading loader logs.
+ """
+
latest_upload_status: Optional[Literal["Mirroring", "Unifying", "Loading", "Provisioning", "Complete", "Error"]] = (
None
)
@@ -39,7 +145,7 @@ class IndicatorFeedGetResponse(BaseModel):
name: Optional[str] = None
"""The name of the indicator feed"""
- provider_id: Optional[str] = None
+ provider_id: Optional[int] = None
"""The unique identifier for the provider"""
provider_name: Optional[str] = None
diff --git a/src/cloudflare/types/load_balancers/monitor_group.py b/src/cloudflare/types/load_balancers/monitor_group.py
index bd6ac9c5a38..8edc3a67c1b 100644
--- a/src/cloudflare/types/load_balancers/monitor_group.py
+++ b/src/cloudflare/types/load_balancers/monitor_group.py
@@ -44,8 +44,8 @@ class MonitorGroup(BaseModel):
members: List[Member]
"""List of monitors in this group"""
- created_at: Optional[datetime] = None
+ created_on: Optional[datetime] = None
"""The timestamp of when the monitor group was created"""
- updated_at: Optional[datetime] = None
+ modified_on: Optional[datetime] = None
"""The timestamp of when the monitor group was last updated"""
diff --git a/src/cloudflare/types/load_balancers/monitor_group_create_params.py b/src/cloudflare/types/load_balancers/monitor_group_create_params.py
index 0d9b6714ddd..8152ce1b8e7 100644
--- a/src/cloudflare/types/load_balancers/monitor_group_create_params.py
+++ b/src/cloudflare/types/load_balancers/monitor_group_create_params.py
@@ -12,12 +12,6 @@ class MonitorGroupCreateParams(TypedDict, total=False):
account_id: Required[str]
"""Identifier."""
- id: Required[str]
- """
- The ID of the Monitor Group to use for checking the health of origins within
- this pool.
- """
-
description: Required[str]
"""A short description of the monitor group"""
diff --git a/src/cloudflare/types/load_balancers/monitor_group_edit_params.py b/src/cloudflare/types/load_balancers/monitor_group_edit_params.py
index 212f85f5360..1b3ff37abf6 100644
--- a/src/cloudflare/types/load_balancers/monitor_group_edit_params.py
+++ b/src/cloudflare/types/load_balancers/monitor_group_edit_params.py
@@ -12,12 +12,6 @@ class MonitorGroupEditParams(TypedDict, total=False):
account_id: Required[str]
"""Identifier."""
- id: Required[str]
- """
- The ID of the Monitor Group to use for checking the health of origins within
- this pool.
- """
-
description: Required[str]
"""A short description of the monitor group"""
diff --git a/src/cloudflare/types/load_balancers/monitor_group_update_params.py b/src/cloudflare/types/load_balancers/monitor_group_update_params.py
index 9122012730b..b7f82358e16 100644
--- a/src/cloudflare/types/load_balancers/monitor_group_update_params.py
+++ b/src/cloudflare/types/load_balancers/monitor_group_update_params.py
@@ -12,12 +12,6 @@ class MonitorGroupUpdateParams(TypedDict, total=False):
account_id: Required[str]
"""Identifier."""
- id: Required[str]
- """
- The ID of the Monitor Group to use for checking the health of origins within
- this pool.
- """
-
description: Required[str]
"""A short description of the monitor group"""
diff --git a/src/cloudflare/types/load_balancers/monitor_groups/__init__.py b/src/cloudflare/types/load_balancers/monitor_groups/__init__.py
new file mode 100644
index 00000000000..9a9f7de1c68
--- /dev/null
+++ b/src/cloudflare/types/load_balancers/monitor_groups/__init__.py
@@ -0,0 +1,5 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .reference_get_response import ReferenceGetResponse as ReferenceGetResponse
diff --git a/src/cloudflare/types/load_balancers/monitor_groups/reference_get_response.py b/src/cloudflare/types/load_balancers/monitor_groups/reference_get_response.py
new file mode 100644
index 00000000000..91f6725f1c8
--- /dev/null
+++ b/src/cloudflare/types/load_balancers/monitor_groups/reference_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 typing_extensions import Literal
+
+from ...._models import BaseModel
+
+__all__ = ["ReferenceGetResponse"]
+
+
+class ReferenceGetResponse(BaseModel):
+ reference_type: Optional[Literal["*", "referral", "referrer"]] = None
+
+ resource_id: Optional[str] = None
+
+ resource_name: Optional[str] = None
+
+ resource_type: Optional[str] = None
diff --git a/src/cloudflare/types/radar/bgp/ips/__init__.py b/src/cloudflare/types/radar/bgp/ips/__init__.py
new file mode 100644
index 00000000000..1e88101779d
--- /dev/null
+++ b/src/cloudflare/types/radar/bgp/ips/__init__.py
@@ -0,0 +1,6 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .top_ases_params import TopAsesParams as TopAsesParams
+from .top_ases_response import TopAsesResponse as TopAsesResponse
diff --git a/src/cloudflare/types/radar/bgp/ips/top_ases_params.py b/src/cloudflare/types/radar/bgp/ips/top_ases_params.py
new file mode 100644
index 00000000000..6395aa7357e
--- /dev/null
+++ b/src/cloudflare/types/radar/bgp/ips/top_ases_params.py
@@ -0,0 +1,28 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union
+from datetime import datetime
+from typing_extensions import Literal, Annotated, TypedDict
+
+from ....._utils import PropertyInfo
+
+__all__ = ["TopAsesParams"]
+
+
+class TopAsesParams(TypedDict, total=False):
+ country: str
+ """Optional ISO 3166-1 alpha-2 country filter. Omit for global top-N."""
+
+ date: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")]
+ """Filters results by the specified datetime (ISO 8601)."""
+
+ format: Literal["JSON", "CSV"]
+ """Format in which results will be returned."""
+
+ limit: int
+ """Limits the number of objects returned in the response."""
+
+ metric: Literal["v4_24s", "v6_48s"]
+ """Ranking metric: IPv4 /24 count or IPv6 /48 count."""
diff --git a/src/cloudflare/types/radar/bgp/ips/top_ases_response.py b/src/cloudflare/types/radar/bgp/ips/top_ases_response.py
new file mode 100644
index 00000000000..97accf39d42
--- /dev/null
+++ b/src/cloudflare/types/radar/bgp/ips/top_ases_response.py
@@ -0,0 +1,28 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+
+from pydantic import Field as FieldInfo
+
+from ....._models import BaseModel
+
+__all__ = ["TopAsesResponse", "ASN"]
+
+
+class ASN(BaseModel):
+ asn: int
+
+ v4_24s: int
+
+ v6_48s: int
+
+
+class TopAsesResponse(BaseModel):
+ anchor_ts: datetime = FieldInfo(alias="anchorTs")
+
+ asns: List[ASN]
+
+ country: Optional[str] = None
+
+ metric: str
diff --git a/src/cloudflare/types/radar/bgp/rpki/__init__.py b/src/cloudflare/types/radar/bgp/rpki/__init__.py
index c93307a5f29..7e7cd69c969 100644
--- a/src/cloudflare/types/radar/bgp/rpki/__init__.py
+++ b/src/cloudflare/types/radar/bgp/rpki/__init__.py
@@ -5,6 +5,8 @@
from .aspa_changes_params import ASPAChangesParams as ASPAChangesParams
from .aspa_snapshot_params import ASPASnapshotParams as ASPASnapshotParams
from .aspa_changes_response import ASPAChangesResponse as ASPAChangesResponse
+from .roa_timeseries_params import RoaTimeseriesParams as RoaTimeseriesParams
from .aspa_snapshot_response import ASPASnapshotResponse as ASPASnapshotResponse
from .aspa_timeseries_params import ASPATimeseriesParams as ASPATimeseriesParams
+from .roa_timeseries_response import RoaTimeseriesResponse as RoaTimeseriesResponse
from .aspa_timeseries_response import ASPATimeseriesResponse as ASPATimeseriesResponse
diff --git a/src/cloudflare/types/radar/bgp/rpki/roa_timeseries_params.py b/src/cloudflare/types/radar/bgp/rpki/roa_timeseries_params.py
new file mode 100644
index 00000000000..f75f6dce597
--- /dev/null
+++ b/src/cloudflare/types/radar/bgp/rpki/roa_timeseries_params.py
@@ -0,0 +1,49 @@
+# 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, Annotated, TypedDict
+
+from ....._types import SequenceNotStr
+from ....._utils import PropertyInfo
+
+__all__ = ["RoaTimeseriesParams"]
+
+
+class RoaTimeseriesParams(TypedDict, total=False):
+ asn: SequenceNotStr[str]
+ """Filters results by Autonomous System Number.
+
+ Specify one or more ASNs. Multiple values generate one series per ASN.
+ """
+
+ date_end: Annotated[Union[str, datetime], PropertyInfo(alias="dateEnd", format="iso8601")]
+ """End of the date range (inclusive)."""
+
+ date_start: Annotated[Union[str, datetime], PropertyInfo(alias="dateStart", format="iso8601")]
+ """Start of the date range (inclusive)."""
+
+ format: Literal["JSON", "CSV"]
+ """Format in which results will be returned."""
+
+ location: SequenceNotStr[str]
+ """Filters results by location.
+
+ Specify a comma-separated list of alpha-2 location codes.
+ """
+
+ metric: Literal[
+ "validPfxsRatio", "validPfxsV4Ratio", "validPfxsV6Ratio", "validIpsRatio", "validIpsV4Ratio", "validIpsV6Ratio"
+ ]
+ """Which RPKI ROA validation metric to return.
+
+ validPfxsRatio = ratio of RPKI-valid prefixes (IPv4+IPv6 combined).
+ validPfxsV4Ratio / validPfxsV6Ratio = same, split by IP version. validIpsRatio =
+ ratio of RPKI-valid address space (IPv4 /24s + IPv6 /48s). validIpsV4Ratio /
+ validIpsV6Ratio = same, split by IP version.
+ """
+
+ name: SequenceNotStr[str]
+ """Array of names used to label the series in the response."""
diff --git a/src/cloudflare/types/radar/bgp/rpki/roa_timeseries_response.py b/src/cloudflare/types/radar/bgp/rpki/roa_timeseries_response.py
new file mode 100644
index 00000000000..c8dc7aff509
--- /dev/null
+++ b/src/cloudflare/types/radar/bgp/rpki/roa_timeseries_response.py
@@ -0,0 +1,30 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List
+from datetime import datetime
+
+from pydantic import Field as FieldInfo
+
+from ....._models import BaseModel
+
+__all__ = ["RoaTimeseriesResponse", "Meta", "Serie0"]
+
+
+class Meta(BaseModel):
+ data_time: datetime = FieldInfo(alias="dataTime")
+ """Timestamp of the underlying data."""
+
+ query_time: datetime = FieldInfo(alias="queryTime")
+ """Timestamp when the query was executed."""
+
+
+class Serie0(BaseModel):
+ timestamps: List[datetime]
+
+ values: List[str]
+
+
+class RoaTimeseriesResponse(BaseModel):
+ meta: Meta
+
+ serie_0: Serie0
diff --git a/src/cloudflare/types/resource_sharing/resource_create_params.py b/src/cloudflare/types/resource_sharing/resource_create_params.py
index a5b1f95764f..2594e4a9d7c 100644
--- a/src/cloudflare/types/resource_sharing/resource_create_params.py
+++ b/src/cloudflare/types/resource_sharing/resource_create_params.py
@@ -27,6 +27,7 @@ class ResourceCreateParams(TypedDict, total=False):
"gateway-destination-ip",
"gateway-block-page-settings",
"gateway-extended-email-matching",
+ "idp-federation-grant",
]
]
"""Resource Type."""
diff --git a/src/cloudflare/types/resource_sharing/resource_create_response.py b/src/cloudflare/types/resource_sharing/resource_create_response.py
index 9100a80af02..6ade1d9fbe3 100644
--- a/src/cloudflare/types/resource_sharing/resource_create_response.py
+++ b/src/cloudflare/types/resource_sharing/resource_create_response.py
@@ -33,6 +33,7 @@ class ResourceCreateResponse(BaseModel):
"gateway-destination-ip",
"gateway-block-page-settings",
"gateway-extended-email-matching",
+ "idp-federation-grant",
]
"""Resource Type."""
diff --git a/src/cloudflare/types/resource_sharing/resource_delete_response.py b/src/cloudflare/types/resource_sharing/resource_delete_response.py
index d1ddf972f39..deff33152bc 100644
--- a/src/cloudflare/types/resource_sharing/resource_delete_response.py
+++ b/src/cloudflare/types/resource_sharing/resource_delete_response.py
@@ -33,6 +33,7 @@ class ResourceDeleteResponse(BaseModel):
"gateway-destination-ip",
"gateway-block-page-settings",
"gateway-extended-email-matching",
+ "idp-federation-grant",
]
"""Resource Type."""
diff --git a/src/cloudflare/types/resource_sharing/resource_get_response.py b/src/cloudflare/types/resource_sharing/resource_get_response.py
index 1eeb5c85987..a357bb5074f 100644
--- a/src/cloudflare/types/resource_sharing/resource_get_response.py
+++ b/src/cloudflare/types/resource_sharing/resource_get_response.py
@@ -33,6 +33,7 @@ class ResourceGetResponse(BaseModel):
"gateway-destination-ip",
"gateway-block-page-settings",
"gateway-extended-email-matching",
+ "idp-federation-grant",
]
"""Resource Type."""
diff --git a/src/cloudflare/types/resource_sharing/resource_list_params.py b/src/cloudflare/types/resource_sharing/resource_list_params.py
index cad9c27cae1..7b1bcc36f3c 100644
--- a/src/cloudflare/types/resource_sharing/resource_list_params.py
+++ b/src/cloudflare/types/resource_sharing/resource_list_params.py
@@ -23,6 +23,7 @@ class ResourceListParams(TypedDict, total=False):
"gateway-destination-ip",
"gateway-block-page-settings",
"gateway-extended-email-matching",
+ "idp-federation-grant",
]
"""Filter share resources by resource_type."""
diff --git a/src/cloudflare/types/resource_sharing/resource_list_response.py b/src/cloudflare/types/resource_sharing/resource_list_response.py
index bfda9a7d3da..28474135379 100644
--- a/src/cloudflare/types/resource_sharing/resource_list_response.py
+++ b/src/cloudflare/types/resource_sharing/resource_list_response.py
@@ -33,6 +33,7 @@ class ResourceListResponse(BaseModel):
"gateway-destination-ip",
"gateway-block-page-settings",
"gateway-extended-email-matching",
+ "idp-federation-grant",
]
"""Resource Type."""
diff --git a/src/cloudflare/types/resource_sharing/resource_sharing_create_params.py b/src/cloudflare/types/resource_sharing/resource_sharing_create_params.py
index d5adacfdba7..ea065a8f253 100644
--- a/src/cloudflare/types/resource_sharing/resource_sharing_create_params.py
+++ b/src/cloudflare/types/resource_sharing/resource_sharing_create_params.py
@@ -47,6 +47,7 @@ class Resource(TypedDict, total=False):
"gateway-destination-ip",
"gateway-block-page-settings",
"gateway-extended-email-matching",
+ "idp-federation-grant",
]
]
"""Resource Type."""
diff --git a/src/cloudflare/types/resource_sharing/resource_sharing_create_response.py b/src/cloudflare/types/resource_sharing/resource_sharing_create_response.py
index c0b6774c64e..a0993e761f3 100644
--- a/src/cloudflare/types/resource_sharing/resource_sharing_create_response.py
+++ b/src/cloudflare/types/resource_sharing/resource_sharing_create_response.py
@@ -34,6 +34,7 @@ class Resource(BaseModel):
"gateway-destination-ip",
"gateway-block-page-settings",
"gateway-extended-email-matching",
+ "idp-federation-grant",
]
"""Resource Type."""
diff --git a/src/cloudflare/types/resource_sharing/resource_sharing_delete_response.py b/src/cloudflare/types/resource_sharing/resource_sharing_delete_response.py
index c3cd3665093..fbbd5a5bd1b 100644
--- a/src/cloudflare/types/resource_sharing/resource_sharing_delete_response.py
+++ b/src/cloudflare/types/resource_sharing/resource_sharing_delete_response.py
@@ -34,6 +34,7 @@ class Resource(BaseModel):
"gateway-destination-ip",
"gateway-block-page-settings",
"gateway-extended-email-matching",
+ "idp-federation-grant",
]
"""Resource Type."""
diff --git a/src/cloudflare/types/resource_sharing/resource_sharing_get_response.py b/src/cloudflare/types/resource_sharing/resource_sharing_get_response.py
index 2a3cdc1c320..e15aa02faf6 100644
--- a/src/cloudflare/types/resource_sharing/resource_sharing_get_response.py
+++ b/src/cloudflare/types/resource_sharing/resource_sharing_get_response.py
@@ -34,6 +34,7 @@ class Resource(BaseModel):
"gateway-destination-ip",
"gateway-block-page-settings",
"gateway-extended-email-matching",
+ "idp-federation-grant",
]
"""Resource Type."""
diff --git a/src/cloudflare/types/resource_sharing/resource_sharing_list_params.py b/src/cloudflare/types/resource_sharing/resource_sharing_list_params.py
index 5b96649e2c3..bcc0490aa51 100644
--- a/src/cloudflare/types/resource_sharing/resource_sharing_list_params.py
+++ b/src/cloudflare/types/resource_sharing/resource_sharing_list_params.py
@@ -5,6 +5,8 @@
from typing import List
from typing_extensions import Literal, Required, TypedDict
+from ..._types import SequenceNotStr
+
__all__ = ["ResourceSharingListParams"]
@@ -40,6 +42,7 @@ class ResourceSharingListParams(TypedDict, total=False):
"gateway-destination-ip",
"gateway-block-page-settings",
"gateway-extended-email-matching",
+ "idp-federation-grant",
]
]
"""Filter share resources by resource_types."""
@@ -47,5 +50,14 @@ class ResourceSharingListParams(TypedDict, total=False):
status: Literal["active", "deleting", "deleted"]
"""Filter shares by status."""
+ tag: SequenceNotStr[str]
+ """Filter shares by tag.
+
+ Each value is either `key=value` (matches shares whose tags contain that
+ key/value pair) or `key` alone (matches shares that have any value for that
+ key). May be repeated; multiple `tag` parameters are ANDed together. Maximum 20
+ `tag` parameters per request.
+ """
+
target_type: Literal["account", "organization"]
"""Filter shares by target_type."""
diff --git a/src/cloudflare/types/resource_sharing/resource_sharing_list_response.py b/src/cloudflare/types/resource_sharing/resource_sharing_list_response.py
index 4a89eb0af47..5581ed31b37 100644
--- a/src/cloudflare/types/resource_sharing/resource_sharing_list_response.py
+++ b/src/cloudflare/types/resource_sharing/resource_sharing_list_response.py
@@ -34,6 +34,7 @@ class Resource(BaseModel):
"gateway-destination-ip",
"gateway-block-page-settings",
"gateway-extended-email-matching",
+ "idp-federation-grant",
]
"""Resource Type."""
diff --git a/src/cloudflare/types/resource_sharing/resource_sharing_update_response.py b/src/cloudflare/types/resource_sharing/resource_sharing_update_response.py
index f8cf8f102b8..c955262c0fa 100644
--- a/src/cloudflare/types/resource_sharing/resource_sharing_update_response.py
+++ b/src/cloudflare/types/resource_sharing/resource_sharing_update_response.py
@@ -34,6 +34,7 @@ class Resource(BaseModel):
"gateway-destination-ip",
"gateway-block-page-settings",
"gateway-extended-email-matching",
+ "idp-federation-grant",
]
"""Resource Type."""
diff --git a/src/cloudflare/types/resource_sharing/resource_update_response.py b/src/cloudflare/types/resource_sharing/resource_update_response.py
index 0d53b6b87f1..f207220bf2d 100644
--- a/src/cloudflare/types/resource_sharing/resource_update_response.py
+++ b/src/cloudflare/types/resource_sharing/resource_update_response.py
@@ -33,6 +33,7 @@ class ResourceUpdateResponse(BaseModel):
"gateway-destination-ip",
"gateway-block-page-settings",
"gateway-extended-email-matching",
+ "idp-federation-grant",
]
"""Resource Type."""
diff --git a/src/cloudflare/types/url_scanner/scan_get_response.py b/src/cloudflare/types/url_scanner/scan_get_response.py
index e1d334d1dd5..2256930cd19 100644
--- a/src/cloudflare/types/url_scanner/scan_get_response.py
+++ b/src/cloudflare/types/url_scanner/scan_get_response.py
@@ -76,6 +76,11 @@
"MetaProcessorsAgentReadinessChecksCommerceAp2EvidenceFinding",
"MetaProcessorsAgentReadinessChecksCommerceAp2EvidenceRequest",
"MetaProcessorsAgentReadinessChecksCommerceAp2EvidenceResponse",
+ "MetaProcessorsAgentReadinessChecksCommerceMpp",
+ "MetaProcessorsAgentReadinessChecksCommerceMppEvidence",
+ "MetaProcessorsAgentReadinessChecksCommerceMppEvidenceFinding",
+ "MetaProcessorsAgentReadinessChecksCommerceMppEvidenceRequest",
+ "MetaProcessorsAgentReadinessChecksCommerceMppEvidenceResponse",
"MetaProcessorsAgentReadinessChecksCommerceUcp",
"MetaProcessorsAgentReadinessChecksCommerceUcpEvidence",
"MetaProcessorsAgentReadinessChecksCommerceUcpEvidenceFinding",
@@ -875,6 +880,58 @@ class MetaProcessorsAgentReadinessChecksCommerceAp2(BaseModel):
message: Optional[str] = None
+class MetaProcessorsAgentReadinessChecksCommerceMppEvidenceFinding(BaseModel):
+ outcome: str
+
+ summary: str
+
+
+class MetaProcessorsAgentReadinessChecksCommerceMppEvidenceRequest(BaseModel):
+ method: str
+
+ url: str
+
+ headers: Optional[object] = None
+
+
+class MetaProcessorsAgentReadinessChecksCommerceMppEvidenceResponse(BaseModel):
+ status: int
+
+ status_text: str = FieldInfo(alias="statusText")
+
+ body_preview: Optional[str] = FieldInfo(alias="bodyPreview", default=None)
+
+ body_size: Optional[int] = FieldInfo(alias="bodySize", default=None)
+
+ headers: Optional[object] = None
+
+ redirected_to: Optional[str] = FieldInfo(alias="redirectedTo", default=None)
+
+
+class MetaProcessorsAgentReadinessChecksCommerceMppEvidence(BaseModel):
+ action: str
+
+ label: str
+
+ finding: Optional[MetaProcessorsAgentReadinessChecksCommerceMppEvidenceFinding] = None
+
+ request: Optional[MetaProcessorsAgentReadinessChecksCommerceMppEvidenceRequest] = None
+
+ response: Optional[MetaProcessorsAgentReadinessChecksCommerceMppEvidenceResponse] = None
+
+
+class MetaProcessorsAgentReadinessChecksCommerceMpp(BaseModel):
+ status: str
+
+ details: Optional[object] = None
+
+ duration_ms: Optional[float] = FieldInfo(alias="durationMs", default=None)
+
+ evidence: Optional[List[MetaProcessorsAgentReadinessChecksCommerceMppEvidence]] = None
+
+ message: Optional[str] = None
+
+
class MetaProcessorsAgentReadinessChecksCommerceUcpEvidenceFinding(BaseModel):
outcome: str
@@ -984,6 +1041,8 @@ class MetaProcessorsAgentReadinessChecksCommerce(BaseModel):
ap2: MetaProcessorsAgentReadinessChecksCommerceAp2
+ mpp: MetaProcessorsAgentReadinessChecksCommerceMpp
+
ucp: MetaProcessorsAgentReadinessChecksCommerceUcp
x402: MetaProcessorsAgentReadinessChecksCommerceX402
diff --git a/src/cloudflare/types/user/user_edit_response.py b/src/cloudflare/types/user/user_edit_response.py
index c273145becf..be3722d9da3 100644
--- a/src/cloudflare/types/user/user_edit_response.py
+++ b/src/cloudflare/types/user/user_edit_response.py
@@ -9,9 +9,12 @@
class UserEditResponse(BaseModel):
- id: Optional[str] = None
+ id: str
"""Identifier of the user."""
+ email: str
+ """Current email address of the user."""
+
betas: Optional[List[str]] = None
"""Lists the betas that the user is participating in."""
diff --git a/src/cloudflare/types/user/user_get_response.py b/src/cloudflare/types/user/user_get_response.py
index dae3cff17b6..a04ec9f8646 100644
--- a/src/cloudflare/types/user/user_get_response.py
+++ b/src/cloudflare/types/user/user_get_response.py
@@ -9,9 +9,12 @@
class UserGetResponse(BaseModel):
- id: Optional[str] = None
+ id: str
"""Identifier of the user."""
+ email: str
+ """Current email address of the user."""
+
betas: Optional[List[str]] = None
"""Lists the betas that the user is participating in."""
diff --git a/src/cloudflare/types/zero_trust/resource_library/__init__.py b/src/cloudflare/types/zero_trust/resource_library/__init__.py
new file mode 100644
index 00000000000..a7887df737c
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/resource_library/__init__.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .category_list_params import CategoryListParams as CategoryListParams
+from .category_get_response import CategoryGetResponse as CategoryGetResponse
+from .category_list_response import CategoryListResponse as CategoryListResponse
+from .application_list_params import ApplicationListParams as ApplicationListParams
+from .application_get_response import ApplicationGetResponse as ApplicationGetResponse
+from .application_list_response import ApplicationListResponse as ApplicationListResponse
diff --git a/src/cloudflare/types/zero_trust/resource_library/application_get_response.py b/src/cloudflare/types/zero_trust/resource_library/application_get_response.py
new file mode 100644
index 00000000000..1f58ccac8dc
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/resource_library/application_get_response.py
@@ -0,0 +1,64 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from typing_extensions import Literal
+
+from ...._models import BaseModel
+
+__all__ = ["ApplicationGetResponse"]
+
+
+class ApplicationGetResponse(BaseModel):
+ id: str
+ """Returns the application ID."""
+
+ application_confidence_score: float
+ """Confidence score for the application. Returns -1 when no score is available."""
+
+ application_source: str
+ """Returns the application source."""
+
+ application_type: str
+ """Returns the application type."""
+
+ application_type_description: str
+ """Returns the application type description."""
+
+ created_at: str
+ """Returns the application creation time."""
+
+ gen_ai_score: float
+ """GenAI score for the application. Returns -1 when no score is available."""
+
+ hostnames: List[str]
+ """Returns the list of hostnames for the application."""
+
+ human_id: str
+ """Returns the human readable ID."""
+
+ ip_subnets: List[str]
+ """Returns the list of IP subnets for the application."""
+
+ name: str
+ """Returns the application name."""
+
+ port_protocols: List[str]
+ """Returns the list of port protocols for the application."""
+
+ support_domains: List[str]
+ """Returns the list of support domains for the application."""
+
+ supported: List[Literal["GATEWAY", "ACCESS", "CASB"]]
+ """Cloudflare products that support this application."""
+
+ updated_at: str
+ """Returns the application update time."""
+
+ version: str
+ """Returns the application version."""
+
+ application_score_composition: Optional[object] = None
+ """Returns the score composition breakdown for the application."""
+
+ intel_id: Optional[int] = None
+ """Returns the Intel API ID for the application."""
diff --git a/src/cloudflare/types/zero_trust/resource_library/application_list_params.py b/src/cloudflare/types/zero_trust/resource_library/application_list_params.py
new file mode 100644
index 00000000000..2bf196f9cc5
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/resource_library/application_list_params.py
@@ -0,0 +1,51 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["ApplicationListParams"]
+
+
+class ApplicationListParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ filter: str
+ """Filter applications using key:value format. Supported filter keys:
+
+ - name: Filter by application name (e.g., name:HR)
+ - id: Filter by application ID (e.g., id:0b63249c-95bf-4cc0-a7cc-d7faaaf1dac0)
+ - human_id: Filter by human-readable ID (e.g., human_id:HR)
+ - hostname: Filter by hostname or support domain (e.g.,
+ hostname:portal.example.com)
+ - source: Filter by application source name (e.g., source:cloudflare)
+ - ip_subnet: Filter by IP subnet using CIDR containment — returns applications
+ where any stored subnet contains the search value (e.g., ip_subnet:10.0.1.5/32
+ matches apps with 10.0.0.0/16)
+ - intel_id: Filter by Intel API ID (e.g., intel_id:498). also supports multiple
+ values (e.g., intel_id:498,1001)
+ - category_id: Filter by category ID (e.g.,
+ category_id:37f8ec03-8766-49d4-9a15-369b044c842c).
+ - category_name: Filter by category name (e.g., category_name:HR).
+ - supported: Filter by supported Cloudflare product (e.g., supported:ACCESS).
+ Values: GATEWAY, ACCESS, CASB. .
+ """
+
+ limit: int
+ """Limit of number of results to return (max 250)."""
+
+ offset: int
+ """Offset of results to return."""
+
+ order_by: str
+ """Order results by field name and direction (e.g., name:asc).
+
+ Ignored when search is provided; results are ranked by relevance instead.
+ """
+
+ search: str
+ """Fuzzy search across application name and hostnames.
+
+ Results are ranked by relevance. Must be between 2 and 200 characters. Can be
+ combined with filter parameters.
+ """
diff --git a/src/cloudflare/types/zero_trust/resource_library/application_list_response.py b/src/cloudflare/types/zero_trust/resource_library/application_list_response.py
new file mode 100644
index 00000000000..5af97f59f64
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/resource_library/application_list_response.py
@@ -0,0 +1,64 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from typing_extensions import Literal
+
+from ...._models import BaseModel
+
+__all__ = ["ApplicationListResponse"]
+
+
+class ApplicationListResponse(BaseModel):
+ id: str
+ """Returns the application ID."""
+
+ application_confidence_score: float
+ """Confidence score for the application. Returns -1 when no score is available."""
+
+ application_source: str
+ """Returns the application source."""
+
+ application_type: str
+ """Returns the application type."""
+
+ application_type_description: str
+ """Returns the application type description."""
+
+ created_at: str
+ """Returns the application creation time."""
+
+ gen_ai_score: float
+ """GenAI score for the application. Returns -1 when no score is available."""
+
+ hostnames: List[str]
+ """Returns the list of hostnames for the application."""
+
+ human_id: str
+ """Returns the human readable ID."""
+
+ ip_subnets: List[str]
+ """Returns the list of IP subnets for the application."""
+
+ name: str
+ """Returns the application name."""
+
+ port_protocols: List[str]
+ """Returns the list of port protocols for the application."""
+
+ support_domains: List[str]
+ """Returns the list of support domains for the application."""
+
+ supported: List[Literal["GATEWAY", "ACCESS", "CASB"]]
+ """Cloudflare products that support this application."""
+
+ updated_at: str
+ """Returns the application update time."""
+
+ version: str
+ """Returns the application version."""
+
+ application_score_composition: Optional[object] = None
+ """Returns the score composition breakdown for the application."""
+
+ intel_id: Optional[int] = None
+ """Returns the Intel API ID for the application."""
diff --git a/src/cloudflare/types/zero_trust/resource_library/category_get_response.py b/src/cloudflare/types/zero_trust/resource_library/category_get_response.py
new file mode 100644
index 00000000000..ee8be02c33e
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/resource_library/category_get_response.py
@@ -0,0 +1,19 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from ...._models import BaseModel
+
+__all__ = ["CategoryGetResponse"]
+
+
+class CategoryGetResponse(BaseModel):
+ id: str
+ """Returns the category ID."""
+
+ created_at: str
+ """Returns the category creation time."""
+
+ description: str
+ """Returns the category description."""
+
+ name: str
+ """Returns the category name."""
diff --git a/src/cloudflare/types/zero_trust/resource_library/category_list_params.py b/src/cloudflare/types/zero_trust/resource_library/category_list_params.py
new file mode 100644
index 00000000000..5d80d7606f3
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/resource_library/category_list_params.py
@@ -0,0 +1,17 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["CategoryListParams"]
+
+
+class CategoryListParams(TypedDict, total=False):
+ account_id: Required[str]
+
+ limit: int
+ """Limit of number of results to return."""
+
+ offset: int
+ """Offset of results to return."""
diff --git a/src/cloudflare/types/zero_trust/resource_library/category_list_response.py b/src/cloudflare/types/zero_trust/resource_library/category_list_response.py
new file mode 100644
index 00000000000..38b891339bf
--- /dev/null
+++ b/src/cloudflare/types/zero_trust/resource_library/category_list_response.py
@@ -0,0 +1,19 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from ...._models import BaseModel
+
+__all__ = ["CategoryListResponse"]
+
+
+class CategoryListResponse(BaseModel):
+ id: str
+ """Returns the category ID."""
+
+ created_at: str
+ """Returns the category creation time."""
+
+ description: str
+ """Returns the category description."""
+
+ name: str
+ """Returns the category name."""
diff --git a/tests/api_resources/ai_gateway/billing/__init__.py b/tests/api_resources/ai_gateway/billing/__init__.py
new file mode 100644
index 00000000000..fd8019a9a1a
--- /dev/null
+++ b/tests/api_resources/ai_gateway/billing/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/ai_gateway/billing/test_spending_limit.py b/tests/api_resources/ai_gateway/billing/test_spending_limit.py
new file mode 100644
index 00000000000..53db9bdcef8
--- /dev/null
+++ b/tests/api_resources/ai_gateway/billing/test_spending_limit.py
@@ -0,0 +1,276 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare.types.ai_gateway.billing import SpendingLimitGetResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestSpendingLimit:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: Cloudflare) -> None:
+ spending_limit = client.ai_gateway.billing.spending_limit.create(
+ account_id="account_id",
+ amount=10000,
+ duration="monthly",
+ strategy="fixed",
+ )
+ assert_matches_type(object, spending_limit, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Cloudflare) -> None:
+ response = client.ai_gateway.billing.spending_limit.with_raw_response.create(
+ account_id="account_id",
+ amount=10000,
+ duration="monthly",
+ strategy="fixed",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ spending_limit = response.parse()
+ assert_matches_type(object, spending_limit, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: Cloudflare) -> None:
+ with client.ai_gateway.billing.spending_limit.with_streaming_response.create(
+ account_id="account_id",
+ amount=10000,
+ duration="monthly",
+ strategy="fixed",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ spending_limit = response.parse()
+ assert_matches_type(object, spending_limit, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_create(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.ai_gateway.billing.spending_limit.with_raw_response.create(
+ account_id="",
+ amount=10000,
+ duration="monthly",
+ strategy="fixed",
+ )
+
+ @parametrize
+ def test_method_delete(self, client: Cloudflare) -> None:
+ spending_limit = client.ai_gateway.billing.spending_limit.delete(
+ account_id="account_id",
+ )
+ assert_matches_type(object, spending_limit, path=["response"])
+
+ @parametrize
+ def test_raw_response_delete(self, client: Cloudflare) -> None:
+ response = client.ai_gateway.billing.spending_limit.with_raw_response.delete(
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ spending_limit = response.parse()
+ assert_matches_type(object, spending_limit, path=["response"])
+
+ @parametrize
+ def test_streaming_response_delete(self, client: Cloudflare) -> None:
+ with client.ai_gateway.billing.spending_limit.with_streaming_response.delete(
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ spending_limit = response.parse()
+ assert_matches_type(object, spending_limit, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_delete(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.ai_gateway.billing.spending_limit.with_raw_response.delete(
+ account_id="",
+ )
+
+ @parametrize
+ def test_method_get(self, client: Cloudflare) -> None:
+ spending_limit = client.ai_gateway.billing.spending_limit.get(
+ account_id="account_id",
+ )
+ assert_matches_type(SpendingLimitGetResponse, spending_limit, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Cloudflare) -> None:
+ response = client.ai_gateway.billing.spending_limit.with_raw_response.get(
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ spending_limit = response.parse()
+ assert_matches_type(SpendingLimitGetResponse, spending_limit, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Cloudflare) -> None:
+ with client.ai_gateway.billing.spending_limit.with_streaming_response.get(
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ spending_limit = response.parse()
+ assert_matches_type(SpendingLimitGetResponse, spending_limit, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_get(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.ai_gateway.billing.spending_limit.with_raw_response.get(
+ account_id="",
+ )
+
+
+class TestAsyncSpendingLimit:
+ 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:
+ spending_limit = await async_client.ai_gateway.billing.spending_limit.create(
+ account_id="account_id",
+ amount=10000,
+ duration="monthly",
+ strategy="fixed",
+ )
+ assert_matches_type(object, spending_limit, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.ai_gateway.billing.spending_limit.with_raw_response.create(
+ account_id="account_id",
+ amount=10000,
+ duration="monthly",
+ strategy="fixed",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ spending_limit = await response.parse()
+ assert_matches_type(object, spending_limit, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.ai_gateway.billing.spending_limit.with_streaming_response.create(
+ account_id="account_id",
+ amount=10000,
+ duration="monthly",
+ strategy="fixed",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ spending_limit = await response.parse()
+ assert_matches_type(object, spending_limit, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_create(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.ai_gateway.billing.spending_limit.with_raw_response.create(
+ account_id="",
+ amount=10000,
+ duration="monthly",
+ strategy="fixed",
+ )
+
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncCloudflare) -> None:
+ spending_limit = await async_client.ai_gateway.billing.spending_limit.delete(
+ account_id="account_id",
+ )
+ assert_matches_type(object, spending_limit, path=["response"])
+
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.ai_gateway.billing.spending_limit.with_raw_response.delete(
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ spending_limit = await response.parse()
+ assert_matches_type(object, spending_limit, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.ai_gateway.billing.spending_limit.with_streaming_response.delete(
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ spending_limit = await response.parse()
+ assert_matches_type(object, spending_limit, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.ai_gateway.billing.spending_limit.with_raw_response.delete(
+ account_id="",
+ )
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncCloudflare) -> None:
+ spending_limit = await async_client.ai_gateway.billing.spending_limit.get(
+ account_id="account_id",
+ )
+ assert_matches_type(SpendingLimitGetResponse, spending_limit, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.ai_gateway.billing.spending_limit.with_raw_response.get(
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ spending_limit = await response.parse()
+ assert_matches_type(SpendingLimitGetResponse, spending_limit, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.ai_gateway.billing.spending_limit.with_streaming_response.get(
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ spending_limit = await response.parse()
+ assert_matches_type(SpendingLimitGetResponse, spending_limit, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_get(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.ai_gateway.billing.spending_limit.with_raw_response.get(
+ account_id="",
+ )
diff --git a/tests/api_resources/ai_gateway/billing/test_topup.py b/tests/api_resources/ai_gateway/billing/test_topup.py
new file mode 100644
index 00000000000..d25adb2ed35
--- /dev/null
+++ b/tests/api_resources/ai_gateway/billing/test_topup.py
@@ -0,0 +1,195 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare.types.ai_gateway.billing import (
+ TopupCreateResponse,
+ TopupStatusResponse,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestTopup:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: Cloudflare) -> None:
+ topup = client.ai_gateway.billing.topup.create(
+ account_id="account_id",
+ amount=5000,
+ )
+ assert_matches_type(TopupCreateResponse, topup, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Cloudflare) -> None:
+ response = client.ai_gateway.billing.topup.with_raw_response.create(
+ account_id="account_id",
+ amount=5000,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ topup = response.parse()
+ assert_matches_type(TopupCreateResponse, topup, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: Cloudflare) -> None:
+ with client.ai_gateway.billing.topup.with_streaming_response.create(
+ account_id="account_id",
+ amount=5000,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ topup = response.parse()
+ assert_matches_type(TopupCreateResponse, topup, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_create(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.ai_gateway.billing.topup.with_raw_response.create(
+ account_id="",
+ amount=5000,
+ )
+
+ @parametrize
+ def test_method_status(self, client: Cloudflare) -> None:
+ topup = client.ai_gateway.billing.topup.status(
+ account_id="account_id",
+ payment_intent_id="in_1abc",
+ )
+ assert_matches_type(TopupStatusResponse, topup, path=["response"])
+
+ @parametrize
+ def test_raw_response_status(self, client: Cloudflare) -> None:
+ response = client.ai_gateway.billing.topup.with_raw_response.status(
+ account_id="account_id",
+ payment_intent_id="in_1abc",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ topup = response.parse()
+ assert_matches_type(TopupStatusResponse, topup, path=["response"])
+
+ @parametrize
+ def test_streaming_response_status(self, client: Cloudflare) -> None:
+ with client.ai_gateway.billing.topup.with_streaming_response.status(
+ account_id="account_id",
+ payment_intent_id="in_1abc",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ topup = response.parse()
+ assert_matches_type(TopupStatusResponse, topup, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_status(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.ai_gateway.billing.topup.with_raw_response.status(
+ account_id="",
+ payment_intent_id="in_1abc",
+ )
+
+
+class TestAsyncTopup:
+ 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:
+ topup = await async_client.ai_gateway.billing.topup.create(
+ account_id="account_id",
+ amount=5000,
+ )
+ assert_matches_type(TopupCreateResponse, topup, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.ai_gateway.billing.topup.with_raw_response.create(
+ account_id="account_id",
+ amount=5000,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ topup = await response.parse()
+ assert_matches_type(TopupCreateResponse, topup, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.ai_gateway.billing.topup.with_streaming_response.create(
+ account_id="account_id",
+ amount=5000,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ topup = await response.parse()
+ assert_matches_type(TopupCreateResponse, topup, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_create(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.ai_gateway.billing.topup.with_raw_response.create(
+ account_id="",
+ amount=5000,
+ )
+
+ @parametrize
+ async def test_method_status(self, async_client: AsyncCloudflare) -> None:
+ topup = await async_client.ai_gateway.billing.topup.status(
+ account_id="account_id",
+ payment_intent_id="in_1abc",
+ )
+ assert_matches_type(TopupStatusResponse, topup, path=["response"])
+
+ @parametrize
+ async def test_raw_response_status(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.ai_gateway.billing.topup.with_raw_response.status(
+ account_id="account_id",
+ payment_intent_id="in_1abc",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ topup = await response.parse()
+ assert_matches_type(TopupStatusResponse, topup, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_status(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.ai_gateway.billing.topup.with_streaming_response.status(
+ account_id="account_id",
+ payment_intent_id="in_1abc",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ topup = await response.parse()
+ assert_matches_type(TopupStatusResponse, topup, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_status(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.ai_gateway.billing.topup.with_raw_response.status(
+ account_id="",
+ payment_intent_id="in_1abc",
+ )
diff --git a/tests/api_resources/ai_gateway/billing/topup/__init__.py b/tests/api_resources/ai_gateway/billing/topup/__init__.py
new file mode 100644
index 00000000000..fd8019a9a1a
--- /dev/null
+++ b/tests/api_resources/ai_gateway/billing/topup/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/ai_gateway/billing/topup/test_config.py b/tests/api_resources/ai_gateway/billing/topup/test_config.py
new file mode 100644
index 00000000000..ed9ff473f13
--- /dev/null
+++ b/tests/api_resources/ai_gateway/billing/topup/test_config.py
@@ -0,0 +1,268 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare.types.ai_gateway.billing.topup import ConfigGetResponse, ConfigCreateResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestConfig:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_create(self, client: Cloudflare) -> None:
+ config = client.ai_gateway.billing.topup.config.create(
+ account_id="account_id",
+ amount=5000,
+ threshold=500,
+ )
+ assert_matches_type(ConfigCreateResponse, config, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Cloudflare) -> None:
+ response = client.ai_gateway.billing.topup.config.with_raw_response.create(
+ account_id="account_id",
+ amount=5000,
+ threshold=500,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ config = response.parse()
+ assert_matches_type(ConfigCreateResponse, config, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: Cloudflare) -> None:
+ with client.ai_gateway.billing.topup.config.with_streaming_response.create(
+ account_id="account_id",
+ amount=5000,
+ threshold=500,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ config = response.parse()
+ assert_matches_type(ConfigCreateResponse, config, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_create(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.ai_gateway.billing.topup.config.with_raw_response.create(
+ account_id="",
+ amount=5000,
+ threshold=500,
+ )
+
+ @parametrize
+ def test_method_delete(self, client: Cloudflare) -> None:
+ config = client.ai_gateway.billing.topup.config.delete(
+ account_id="account_id",
+ )
+ assert_matches_type(object, config, path=["response"])
+
+ @parametrize
+ def test_raw_response_delete(self, client: Cloudflare) -> None:
+ response = client.ai_gateway.billing.topup.config.with_raw_response.delete(
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ config = response.parse()
+ assert_matches_type(object, config, path=["response"])
+
+ @parametrize
+ def test_streaming_response_delete(self, client: Cloudflare) -> None:
+ with client.ai_gateway.billing.topup.config.with_streaming_response.delete(
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ config = response.parse()
+ assert_matches_type(object, config, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_delete(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.ai_gateway.billing.topup.config.with_raw_response.delete(
+ account_id="",
+ )
+
+ @parametrize
+ def test_method_get(self, client: Cloudflare) -> None:
+ config = client.ai_gateway.billing.topup.config.get(
+ account_id="account_id",
+ )
+ assert_matches_type(ConfigGetResponse, config, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Cloudflare) -> None:
+ response = client.ai_gateway.billing.topup.config.with_raw_response.get(
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ config = response.parse()
+ assert_matches_type(ConfigGetResponse, config, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Cloudflare) -> None:
+ with client.ai_gateway.billing.topup.config.with_streaming_response.get(
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ config = response.parse()
+ assert_matches_type(ConfigGetResponse, config, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_get(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.ai_gateway.billing.topup.config.with_raw_response.get(
+ account_id="",
+ )
+
+
+class TestAsyncConfig:
+ 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:
+ config = await async_client.ai_gateway.billing.topup.config.create(
+ account_id="account_id",
+ amount=5000,
+ threshold=500,
+ )
+ assert_matches_type(ConfigCreateResponse, config, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.ai_gateway.billing.topup.config.with_raw_response.create(
+ account_id="account_id",
+ amount=5000,
+ threshold=500,
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ config = await response.parse()
+ assert_matches_type(ConfigCreateResponse, config, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.ai_gateway.billing.topup.config.with_streaming_response.create(
+ account_id="account_id",
+ amount=5000,
+ threshold=500,
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ config = await response.parse()
+ assert_matches_type(ConfigCreateResponse, config, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_create(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.ai_gateway.billing.topup.config.with_raw_response.create(
+ account_id="",
+ amount=5000,
+ threshold=500,
+ )
+
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncCloudflare) -> None:
+ config = await async_client.ai_gateway.billing.topup.config.delete(
+ account_id="account_id",
+ )
+ assert_matches_type(object, config, path=["response"])
+
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.ai_gateway.billing.topup.config.with_raw_response.delete(
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ config = await response.parse()
+ assert_matches_type(object, config, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.ai_gateway.billing.topup.config.with_streaming_response.delete(
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ config = await response.parse()
+ assert_matches_type(object, config, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_delete(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.ai_gateway.billing.topup.config.with_raw_response.delete(
+ account_id="",
+ )
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncCloudflare) -> None:
+ config = await async_client.ai_gateway.billing.topup.config.get(
+ account_id="account_id",
+ )
+ assert_matches_type(ConfigGetResponse, config, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.ai_gateway.billing.topup.config.with_raw_response.get(
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ config = await response.parse()
+ assert_matches_type(ConfigGetResponse, config, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.ai_gateway.billing.topup.config.with_streaming_response.get(
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ config = await response.parse()
+ assert_matches_type(ConfigGetResponse, config, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_get(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.ai_gateway.billing.topup.config.with_raw_response.get(
+ account_id="",
+ )
diff --git a/tests/api_resources/ai_gateway/test_billing.py b/tests/api_resources/ai_gateway/test_billing.py
new file mode 100644
index 00000000000..504c2ce6593
--- /dev/null
+++ b/tests/api_resources/ai_gateway/test_billing.py
@@ -0,0 +1,385 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare.types.ai_gateway import (
+ BillingUsageHistoryResponse,
+ BillingCreditBalanceResponse,
+ BillingInvoiceHistoryResponse,
+ BillingInvoicePreviewResponse,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestBilling:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @pytest.mark.skip(reason="HTTP 404 error from prism -- route not in spec")
+ @parametrize
+ def test_method_credit_balance(self, client: Cloudflare) -> None:
+ billing = client.ai_gateway.billing.credit_balance(
+ account_id="account_id",
+ )
+ assert_matches_type(BillingCreditBalanceResponse, billing, path=["response"])
+
+ @pytest.mark.skip(reason="HTTP 404 error from prism -- route not in spec")
+ @parametrize
+ def test_raw_response_credit_balance(self, client: Cloudflare) -> None:
+ response = client.ai_gateway.billing.with_raw_response.credit_balance(
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ billing = response.parse()
+ assert_matches_type(BillingCreditBalanceResponse, billing, path=["response"])
+
+ @pytest.mark.skip(reason="HTTP 404 error from prism -- route not in spec")
+ @parametrize
+ def test_streaming_response_credit_balance(self, client: Cloudflare) -> None:
+ with client.ai_gateway.billing.with_streaming_response.credit_balance(
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ billing = response.parse()
+ assert_matches_type(BillingCreditBalanceResponse, billing, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="HTTP 404 error from prism -- route not in spec")
+ @parametrize
+ def test_path_params_credit_balance(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.ai_gateway.billing.with_raw_response.credit_balance(
+ account_id="",
+ )
+
+ @parametrize
+ def test_method_invoice_history(self, client: Cloudflare) -> None:
+ billing = client.ai_gateway.billing.invoice_history(
+ account_id="account_id",
+ )
+ assert_matches_type(BillingInvoiceHistoryResponse, billing, path=["response"])
+
+ @parametrize
+ def test_method_invoice_history_with_all_params(self, client: Cloudflare) -> None:
+ billing = client.ai_gateway.billing.invoice_history(
+ account_id="account_id",
+ type="all",
+ )
+ assert_matches_type(BillingInvoiceHistoryResponse, billing, path=["response"])
+
+ @parametrize
+ def test_raw_response_invoice_history(self, client: Cloudflare) -> None:
+ response = client.ai_gateway.billing.with_raw_response.invoice_history(
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ billing = response.parse()
+ assert_matches_type(BillingInvoiceHistoryResponse, billing, path=["response"])
+
+ @parametrize
+ def test_streaming_response_invoice_history(self, client: Cloudflare) -> None:
+ with client.ai_gateway.billing.with_streaming_response.invoice_history(
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ billing = response.parse()
+ assert_matches_type(BillingInvoiceHistoryResponse, billing, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_invoice_history(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.ai_gateway.billing.with_raw_response.invoice_history(
+ account_id="",
+ )
+
+ @parametrize
+ def test_method_invoice_preview(self, client: Cloudflare) -> None:
+ billing = client.ai_gateway.billing.invoice_preview(
+ account_id="account_id",
+ )
+ assert_matches_type(BillingInvoicePreviewResponse, billing, path=["response"])
+
+ @parametrize
+ def test_raw_response_invoice_preview(self, client: Cloudflare) -> None:
+ response = client.ai_gateway.billing.with_raw_response.invoice_preview(
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ billing = response.parse()
+ assert_matches_type(BillingInvoicePreviewResponse, billing, path=["response"])
+
+ @parametrize
+ def test_streaming_response_invoice_preview(self, client: Cloudflare) -> None:
+ with client.ai_gateway.billing.with_streaming_response.invoice_preview(
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ billing = response.parse()
+ assert_matches_type(BillingInvoicePreviewResponse, billing, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_invoice_preview(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.ai_gateway.billing.with_raw_response.invoice_preview(
+ account_id="",
+ )
+
+ @parametrize
+ def test_method_usage_history(self, client: Cloudflare) -> None:
+ billing = client.ai_gateway.billing.usage_history(
+ account_id="account_id",
+ value_grouping_window="day",
+ )
+ assert_matches_type(BillingUsageHistoryResponse, billing, path=["response"])
+
+ @parametrize
+ def test_method_usage_history_with_all_params(self, client: Cloudflare) -> None:
+ billing = client.ai_gateway.billing.usage_history(
+ account_id="account_id",
+ value_grouping_window="day",
+ end_time=1700086400000,
+ start_time=1700000000000,
+ )
+ assert_matches_type(BillingUsageHistoryResponse, billing, path=["response"])
+
+ @parametrize
+ def test_raw_response_usage_history(self, client: Cloudflare) -> None:
+ response = client.ai_gateway.billing.with_raw_response.usage_history(
+ account_id="account_id",
+ value_grouping_window="day",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ billing = response.parse()
+ assert_matches_type(BillingUsageHistoryResponse, billing, path=["response"])
+
+ @parametrize
+ def test_streaming_response_usage_history(self, client: Cloudflare) -> None:
+ with client.ai_gateway.billing.with_streaming_response.usage_history(
+ account_id="account_id",
+ value_grouping_window="day",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ billing = response.parse()
+ assert_matches_type(BillingUsageHistoryResponse, billing, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_usage_history(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.ai_gateway.billing.with_raw_response.usage_history(
+ account_id="",
+ value_grouping_window="day",
+ )
+
+
+class TestAsyncBilling:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @pytest.mark.skip(reason="HTTP 404 error from prism -- route not in spec")
+ @parametrize
+ async def test_method_credit_balance(self, async_client: AsyncCloudflare) -> None:
+ billing = await async_client.ai_gateway.billing.credit_balance(
+ account_id="account_id",
+ )
+ assert_matches_type(BillingCreditBalanceResponse, billing, path=["response"])
+
+ @pytest.mark.skip(reason="HTTP 404 error from prism -- route not in spec")
+ @parametrize
+ async def test_raw_response_credit_balance(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.ai_gateway.billing.with_raw_response.credit_balance(
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ billing = await response.parse()
+ assert_matches_type(BillingCreditBalanceResponse, billing, path=["response"])
+
+ @pytest.mark.skip(reason="HTTP 404 error from prism -- route not in spec")
+ @parametrize
+ async def test_streaming_response_credit_balance(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.ai_gateway.billing.with_streaming_response.credit_balance(
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ billing = await response.parse()
+ assert_matches_type(BillingCreditBalanceResponse, billing, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="HTTP 404 error from prism -- route not in spec")
+ @parametrize
+ async def test_path_params_credit_balance(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.ai_gateway.billing.with_raw_response.credit_balance(
+ account_id="",
+ )
+
+ @parametrize
+ async def test_method_invoice_history(self, async_client: AsyncCloudflare) -> None:
+ billing = await async_client.ai_gateway.billing.invoice_history(
+ account_id="account_id",
+ )
+ assert_matches_type(BillingInvoiceHistoryResponse, billing, path=["response"])
+
+ @parametrize
+ async def test_method_invoice_history_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ billing = await async_client.ai_gateway.billing.invoice_history(
+ account_id="account_id",
+ type="all",
+ )
+ assert_matches_type(BillingInvoiceHistoryResponse, billing, path=["response"])
+
+ @parametrize
+ async def test_raw_response_invoice_history(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.ai_gateway.billing.with_raw_response.invoice_history(
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ billing = await response.parse()
+ assert_matches_type(BillingInvoiceHistoryResponse, billing, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_invoice_history(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.ai_gateway.billing.with_streaming_response.invoice_history(
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ billing = await response.parse()
+ assert_matches_type(BillingInvoiceHistoryResponse, billing, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_invoice_history(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.ai_gateway.billing.with_raw_response.invoice_history(
+ account_id="",
+ )
+
+ @parametrize
+ async def test_method_invoice_preview(self, async_client: AsyncCloudflare) -> None:
+ billing = await async_client.ai_gateway.billing.invoice_preview(
+ account_id="account_id",
+ )
+ assert_matches_type(BillingInvoicePreviewResponse, billing, path=["response"])
+
+ @parametrize
+ async def test_raw_response_invoice_preview(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.ai_gateway.billing.with_raw_response.invoice_preview(
+ account_id="account_id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ billing = await response.parse()
+ assert_matches_type(BillingInvoicePreviewResponse, billing, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_invoice_preview(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.ai_gateway.billing.with_streaming_response.invoice_preview(
+ account_id="account_id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ billing = await response.parse()
+ assert_matches_type(BillingInvoicePreviewResponse, billing, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_invoice_preview(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.ai_gateway.billing.with_raw_response.invoice_preview(
+ account_id="",
+ )
+
+ @parametrize
+ async def test_method_usage_history(self, async_client: AsyncCloudflare) -> None:
+ billing = await async_client.ai_gateway.billing.usage_history(
+ account_id="account_id",
+ value_grouping_window="day",
+ )
+ assert_matches_type(BillingUsageHistoryResponse, billing, path=["response"])
+
+ @parametrize
+ async def test_method_usage_history_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ billing = await async_client.ai_gateway.billing.usage_history(
+ account_id="account_id",
+ value_grouping_window="day",
+ end_time=1700086400000,
+ start_time=1700000000000,
+ )
+ assert_matches_type(BillingUsageHistoryResponse, billing, path=["response"])
+
+ @parametrize
+ async def test_raw_response_usage_history(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.ai_gateway.billing.with_raw_response.usage_history(
+ account_id="account_id",
+ value_grouping_window="day",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ billing = await response.parse()
+ assert_matches_type(BillingUsageHistoryResponse, billing, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_usage_history(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.ai_gateway.billing.with_streaming_response.usage_history(
+ account_id="account_id",
+ value_grouping_window="day",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ billing = await response.parse()
+ assert_matches_type(BillingUsageHistoryResponse, billing, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_usage_history(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.ai_gateway.billing.with_raw_response.usage_history(
+ account_id="",
+ value_grouping_window="day",
+ )
diff --git a/tests/api_resources/aisearch/namespaces/test_instances.py b/tests/api_resources/aisearch/namespaces/test_instances.py
index 4190bfaa776..fd694678253 100644
--- a/tests/api_resources/aisearch/namespaces/test_instances.py
+++ b/tests/api_resources/aisearch/namespaces/test_instances.py
@@ -116,10 +116,14 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None:
"content_selector": [
{
"path": "**/blog/**",
- "selector": "article .post-body",
- }
+ "selector": "article div.post-body",
+ },
+ {
+ "path": "**/docs/**",
+ "selector": "main",
+ },
],
- "include_headers": {"foo": "string"},
+ "include_headers": {"cache-control": "no-cache, no-store"},
"include_images": True,
"specific_sitemaps": [
"https://example.com/sitemap.xml",
@@ -273,10 +277,14 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None:
"content_selector": [
{
"path": "**/blog/**",
- "selector": "article .post-body",
- }
+ "selector": "article div.post-body",
+ },
+ {
+ "path": "**/docs/**",
+ "selector": "main",
+ },
],
- "include_headers": {"foo": "string"},
+ "include_headers": {"cache-control": "no-cache, no-store"},
"include_images": True,
"specific_sitemaps": [
"https://example.com/sitemap.xml",
@@ -943,10 +951,14 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare
"content_selector": [
{
"path": "**/blog/**",
- "selector": "article .post-body",
- }
+ "selector": "article div.post-body",
+ },
+ {
+ "path": "**/docs/**",
+ "selector": "main",
+ },
],
- "include_headers": {"foo": "string"},
+ "include_headers": {"cache-control": "no-cache, no-store"},
"include_images": True,
"specific_sitemaps": [
"https://example.com/sitemap.xml",
@@ -1100,10 +1112,14 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare
"content_selector": [
{
"path": "**/blog/**",
- "selector": "article .post-body",
- }
+ "selector": "article div.post-body",
+ },
+ {
+ "path": "**/docs/**",
+ "selector": "main",
+ },
],
- "include_headers": {"foo": "string"},
+ "include_headers": {"cache-control": "no-cache, no-store"},
"include_images": True,
"specific_sitemaps": [
"https://example.com/sitemap.xml",
diff --git a/tests/api_resources/aisearch/test_instances.py b/tests/api_resources/aisearch/test_instances.py
index 1aaf5fde4e6..fcb88148c66 100644
--- a/tests/api_resources/aisearch/test_instances.py
+++ b/tests/api_resources/aisearch/test_instances.py
@@ -114,10 +114,14 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None:
"content_selector": [
{
"path": "**/blog/**",
- "selector": "article .post-body",
- }
+ "selector": "article div.post-body",
+ },
+ {
+ "path": "**/docs/**",
+ "selector": "main",
+ },
],
- "include_headers": {"foo": "string"},
+ "include_headers": {"cache-control": "no-cache, no-store"},
"include_images": True,
"specific_sitemaps": [
"https://example.com/sitemap.xml",
@@ -259,10 +263,14 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None:
"content_selector": [
{
"path": "**/blog/**",
- "selector": "article .post-body",
- }
+ "selector": "article div.post-body",
+ },
+ {
+ "path": "**/docs/**",
+ "selector": "main",
+ },
],
- "include_headers": {"foo": "string"},
+ "include_headers": {"cache-control": "no-cache, no-store"},
"include_images": True,
"specific_sitemaps": [
"https://example.com/sitemap.xml",
@@ -837,10 +845,14 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare
"content_selector": [
{
"path": "**/blog/**",
- "selector": "article .post-body",
- }
+ "selector": "article div.post-body",
+ },
+ {
+ "path": "**/docs/**",
+ "selector": "main",
+ },
],
- "include_headers": {"foo": "string"},
+ "include_headers": {"cache-control": "no-cache, no-store"},
"include_images": True,
"specific_sitemaps": [
"https://example.com/sitemap.xml",
@@ -982,10 +994,14 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare
"content_selector": [
{
"path": "**/blog/**",
- "selector": "article .post-body",
- }
+ "selector": "article div.post-body",
+ },
+ {
+ "path": "**/docs/**",
+ "selector": "main",
+ },
],
- "include_headers": {"foo": "string"},
+ "include_headers": {"cache-control": "no-cache, no-store"},
"include_images": True,
"specific_sitemaps": [
"https://example.com/sitemap.xml",
diff --git a/tests/api_resources/cache/test_origin_cloud_regions.py b/tests/api_resources/cache/test_origin_cloud_regions.py
index 53a5c9bf953..2f13fa37d50 100644
--- a/tests/api_resources/cache/test_origin_cloud_regions.py
+++ b/tests/api_resources/cache/test_origin_cloud_regions.py
@@ -9,14 +9,12 @@
from cloudflare import Cloudflare, AsyncCloudflare
from tests.utils import assert_matches_type
+from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray
from cloudflare.types.cache import (
- OriginCloudRegionGetResponse,
- OriginCloudRegionEditResponse,
- OriginCloudRegionListResponse,
- OriginCloudRegionCreateResponse,
+ OriginCloudRegion,
OriginCloudRegionDeleteResponse,
- OriginCloudRegionBulkEditResponse,
OriginCloudRegionBulkDeleteResponse,
+ OriginCloudRegionBulkUpdateResponse,
OriginCloudRegionSupportedRegionsResponse,
)
@@ -26,21 +24,25 @@
class TestOriginCloudRegions:
parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+ @pytest.mark.skip(reason="HTTP 404 error from prism -- route not in spec")
@parametrize
- def test_method_create(self, client: Cloudflare) -> None:
- origin_cloud_region = client.cache.origin_cloud_regions.create(
+ def test_method_update(self, client: Cloudflare) -> None:
+ origin_cloud_region = client.cache.origin_cloud_regions.update(
+ path_origin_ip="192.0.2.1",
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
- ip="192.0.2.1",
+ body_origin_ip="192.0.2.1",
region="us-east-1",
vendor="aws",
)
- assert_matches_type(Optional[OriginCloudRegionCreateResponse], origin_cloud_region, path=["response"])
+ assert_matches_type(Optional[OriginCloudRegion], origin_cloud_region, path=["response"])
+ @pytest.mark.skip(reason="HTTP 404 error from prism -- route not in spec")
@parametrize
- def test_raw_response_create(self, client: Cloudflare) -> None:
- response = client.cache.origin_cloud_regions.with_raw_response.create(
+ def test_raw_response_update(self, client: Cloudflare) -> None:
+ response = client.cache.origin_cloud_regions.with_raw_response.update(
+ path_origin_ip="192.0.2.1",
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
- ip="192.0.2.1",
+ body_origin_ip="192.0.2.1",
region="us-east-1",
vendor="aws",
)
@@ -48,13 +50,15 @@ def test_raw_response_create(self, client: Cloudflare) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
origin_cloud_region = response.parse()
- assert_matches_type(Optional[OriginCloudRegionCreateResponse], origin_cloud_region, path=["response"])
+ assert_matches_type(Optional[OriginCloudRegion], origin_cloud_region, path=["response"])
+ @pytest.mark.skip(reason="HTTP 404 error from prism -- route not in spec")
@parametrize
- def test_streaming_response_create(self, client: Cloudflare) -> None:
- with client.cache.origin_cloud_regions.with_streaming_response.create(
+ def test_streaming_response_update(self, client: Cloudflare) -> None:
+ with client.cache.origin_cloud_regions.with_streaming_response.update(
+ path_origin_ip="192.0.2.1",
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
- ip="192.0.2.1",
+ body_origin_ip="192.0.2.1",
region="us-east-1",
vendor="aws",
) as response:
@@ -62,16 +66,27 @@ def test_streaming_response_create(self, client: Cloudflare) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
origin_cloud_region = response.parse()
- assert_matches_type(Optional[OriginCloudRegionCreateResponse], origin_cloud_region, path=["response"])
+ assert_matches_type(Optional[OriginCloudRegion], origin_cloud_region, path=["response"])
assert cast(Any, response.is_closed) is True
+ @pytest.mark.skip(reason="HTTP 404 error from prism -- route not in spec")
@parametrize
- def test_path_params_create(self, client: Cloudflare) -> None:
+ def test_path_params_update(self, client: Cloudflare) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
- client.cache.origin_cloud_regions.with_raw_response.create(
+ client.cache.origin_cloud_regions.with_raw_response.update(
+ path_origin_ip="192.0.2.1",
zone_id="",
- ip="192.0.2.1",
+ body_origin_ip="192.0.2.1",
+ region="us-east-1",
+ vendor="aws",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `path_origin_ip` but received ''"):
+ client.cache.origin_cloud_regions.with_raw_response.update(
+ path_origin_ip="",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ body_origin_ip="192.0.2.1",
region="us-east-1",
vendor="aws",
)
@@ -81,7 +96,16 @@ def test_method_list(self, client: Cloudflare) -> None:
origin_cloud_region = client.cache.origin_cloud_regions.list(
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
)
- assert_matches_type(Optional[OriginCloudRegionListResponse], origin_cloud_region, path=["response"])
+ assert_matches_type(SyncV4PagePaginationArray[OriginCloudRegion], origin_cloud_region, path=["response"])
+
+ @parametrize
+ def test_method_list_with_all_params(self, client: Cloudflare) -> None:
+ origin_cloud_region = client.cache.origin_cloud_regions.list(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ page=1,
+ per_page=1,
+ )
+ assert_matches_type(SyncV4PagePaginationArray[OriginCloudRegion], origin_cloud_region, path=["response"])
@parametrize
def test_raw_response_list(self, client: Cloudflare) -> None:
@@ -92,7 +116,7 @@ def test_raw_response_list(self, client: Cloudflare) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
origin_cloud_region = response.parse()
- assert_matches_type(Optional[OriginCloudRegionListResponse], origin_cloud_region, path=["response"])
+ assert_matches_type(SyncV4PagePaginationArray[OriginCloudRegion], origin_cloud_region, path=["response"])
@parametrize
def test_streaming_response_list(self, client: Cloudflare) -> None:
@@ -103,7 +127,7 @@ def test_streaming_response_list(self, client: Cloudflare) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
origin_cloud_region = response.parse()
- assert_matches_type(Optional[OriginCloudRegionListResponse], origin_cloud_region, path=["response"])
+ assert_matches_type(SyncV4PagePaginationArray[OriginCloudRegion], origin_cloud_region, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -201,36 +225,36 @@ def test_path_params_bulk_delete(self, client: Cloudflare) -> None:
)
@parametrize
- def test_method_bulk_edit(self, client: Cloudflare) -> None:
- origin_cloud_region = client.cache.origin_cloud_regions.bulk_edit(
+ def test_method_bulk_update(self, client: Cloudflare) -> None:
+ origin_cloud_region = client.cache.origin_cloud_regions.bulk_update(
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
body=[
{
- "ip": "192.0.2.1",
+ "origin_ip": "192.0.2.1",
"region": "us-east-1",
"vendor": "aws",
},
{
- "ip": "2001:db8::1",
+ "origin_ip": "2001:db8::1",
"region": "us-central1",
"vendor": "gcp",
},
],
)
- assert_matches_type(Optional[OriginCloudRegionBulkEditResponse], origin_cloud_region, path=["response"])
+ assert_matches_type(Optional[OriginCloudRegionBulkUpdateResponse], origin_cloud_region, path=["response"])
@parametrize
- def test_raw_response_bulk_edit(self, client: Cloudflare) -> None:
- response = client.cache.origin_cloud_regions.with_raw_response.bulk_edit(
+ def test_raw_response_bulk_update(self, client: Cloudflare) -> None:
+ response = client.cache.origin_cloud_regions.with_raw_response.bulk_update(
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
body=[
{
- "ip": "192.0.2.1",
+ "origin_ip": "192.0.2.1",
"region": "us-east-1",
"vendor": "aws",
},
{
- "ip": "2001:db8::1",
+ "origin_ip": "2001:db8::1",
"region": "us-central1",
"vendor": "gcp",
},
@@ -240,20 +264,20 @@ def test_raw_response_bulk_edit(self, client: Cloudflare) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
origin_cloud_region = response.parse()
- assert_matches_type(Optional[OriginCloudRegionBulkEditResponse], origin_cloud_region, path=["response"])
+ assert_matches_type(Optional[OriginCloudRegionBulkUpdateResponse], origin_cloud_region, path=["response"])
@parametrize
- def test_streaming_response_bulk_edit(self, client: Cloudflare) -> None:
- with client.cache.origin_cloud_regions.with_streaming_response.bulk_edit(
+ def test_streaming_response_bulk_update(self, client: Cloudflare) -> None:
+ with client.cache.origin_cloud_regions.with_streaming_response.bulk_update(
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
body=[
{
- "ip": "192.0.2.1",
+ "origin_ip": "192.0.2.1",
"region": "us-east-1",
"vendor": "aws",
},
{
- "ip": "2001:db8::1",
+ "origin_ip": "2001:db8::1",
"region": "us-central1",
"vendor": "gcp",
},
@@ -263,86 +287,36 @@ def test_streaming_response_bulk_edit(self, client: Cloudflare) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
origin_cloud_region = response.parse()
- assert_matches_type(Optional[OriginCloudRegionBulkEditResponse], origin_cloud_region, path=["response"])
+ assert_matches_type(Optional[OriginCloudRegionBulkUpdateResponse], origin_cloud_region, path=["response"])
assert cast(Any, response.is_closed) is True
@parametrize
- def test_path_params_bulk_edit(self, client: Cloudflare) -> None:
+ def test_path_params_bulk_update(self, client: Cloudflare) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
- client.cache.origin_cloud_regions.with_raw_response.bulk_edit(
+ client.cache.origin_cloud_regions.with_raw_response.bulk_update(
zone_id="",
body=[
{
- "ip": "192.0.2.1",
+ "origin_ip": "192.0.2.1",
"region": "us-east-1",
"vendor": "aws",
},
{
- "ip": "2001:db8::1",
+ "origin_ip": "2001:db8::1",
"region": "us-central1",
"vendor": "gcp",
},
],
)
- @parametrize
- def test_method_edit(self, client: Cloudflare) -> None:
- origin_cloud_region = client.cache.origin_cloud_regions.edit(
- zone_id="023e105f4ecef8ad9ca31a8372d0c353",
- ip="2001:db8::1",
- region="us-central1",
- vendor="gcp",
- )
- assert_matches_type(Optional[OriginCloudRegionEditResponse], origin_cloud_region, path=["response"])
-
- @parametrize
- def test_raw_response_edit(self, client: Cloudflare) -> None:
- response = client.cache.origin_cloud_regions.with_raw_response.edit(
- zone_id="023e105f4ecef8ad9ca31a8372d0c353",
- ip="2001:db8::1",
- region="us-central1",
- vendor="gcp",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- origin_cloud_region = response.parse()
- assert_matches_type(Optional[OriginCloudRegionEditResponse], origin_cloud_region, path=["response"])
-
- @parametrize
- def test_streaming_response_edit(self, client: Cloudflare) -> None:
- with client.cache.origin_cloud_regions.with_streaming_response.edit(
- zone_id="023e105f4ecef8ad9ca31a8372d0c353",
- ip="2001:db8::1",
- region="us-central1",
- vendor="gcp",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- origin_cloud_region = response.parse()
- assert_matches_type(Optional[OriginCloudRegionEditResponse], origin_cloud_region, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_edit(self, client: Cloudflare) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
- client.cache.origin_cloud_regions.with_raw_response.edit(
- zone_id="",
- ip="2001:db8::1",
- region="us-central1",
- vendor="gcp",
- )
-
@parametrize
def test_method_get(self, client: Cloudflare) -> None:
origin_cloud_region = client.cache.origin_cloud_regions.get(
origin_ip="192.0.2.1",
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
)
- assert_matches_type(Optional[OriginCloudRegionGetResponse], origin_cloud_region, path=["response"])
+ assert_matches_type(Optional[OriginCloudRegion], origin_cloud_region, path=["response"])
@parametrize
def test_raw_response_get(self, client: Cloudflare) -> None:
@@ -354,7 +328,7 @@ def test_raw_response_get(self, client: Cloudflare) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
origin_cloud_region = response.parse()
- assert_matches_type(Optional[OriginCloudRegionGetResponse], origin_cloud_region, path=["response"])
+ assert_matches_type(Optional[OriginCloudRegion], origin_cloud_region, path=["response"])
@parametrize
def test_streaming_response_get(self, client: Cloudflare) -> None:
@@ -366,7 +340,7 @@ def test_streaming_response_get(self, client: Cloudflare) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
origin_cloud_region = response.parse()
- assert_matches_type(Optional[OriginCloudRegionGetResponse], origin_cloud_region, path=["response"])
+ assert_matches_type(Optional[OriginCloudRegion], origin_cloud_region, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -430,21 +404,25 @@ class TestAsyncOriginCloudRegions:
"async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
)
+ @pytest.mark.skip(reason="HTTP 404 error from prism -- route not in spec")
@parametrize
- async def test_method_create(self, async_client: AsyncCloudflare) -> None:
- origin_cloud_region = await async_client.cache.origin_cloud_regions.create(
+ async def test_method_update(self, async_client: AsyncCloudflare) -> None:
+ origin_cloud_region = await async_client.cache.origin_cloud_regions.update(
+ path_origin_ip="192.0.2.1",
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
- ip="192.0.2.1",
+ body_origin_ip="192.0.2.1",
region="us-east-1",
vendor="aws",
)
- assert_matches_type(Optional[OriginCloudRegionCreateResponse], origin_cloud_region, path=["response"])
+ assert_matches_type(Optional[OriginCloudRegion], origin_cloud_region, path=["response"])
+ @pytest.mark.skip(reason="HTTP 404 error from prism -- route not in spec")
@parametrize
- async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None:
- response = await async_client.cache.origin_cloud_regions.with_raw_response.create(
+ async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.cache.origin_cloud_regions.with_raw_response.update(
+ path_origin_ip="192.0.2.1",
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
- ip="192.0.2.1",
+ body_origin_ip="192.0.2.1",
region="us-east-1",
vendor="aws",
)
@@ -452,13 +430,15 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
origin_cloud_region = await response.parse()
- assert_matches_type(Optional[OriginCloudRegionCreateResponse], origin_cloud_region, path=["response"])
+ assert_matches_type(Optional[OriginCloudRegion], origin_cloud_region, path=["response"])
+ @pytest.mark.skip(reason="HTTP 404 error from prism -- route not in spec")
@parametrize
- async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None:
- async with async_client.cache.origin_cloud_regions.with_streaming_response.create(
+ async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.cache.origin_cloud_regions.with_streaming_response.update(
+ path_origin_ip="192.0.2.1",
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
- ip="192.0.2.1",
+ body_origin_ip="192.0.2.1",
region="us-east-1",
vendor="aws",
) as response:
@@ -466,16 +446,27 @@ async def test_streaming_response_create(self, async_client: AsyncCloudflare) ->
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
origin_cloud_region = await response.parse()
- assert_matches_type(Optional[OriginCloudRegionCreateResponse], origin_cloud_region, path=["response"])
+ assert_matches_type(Optional[OriginCloudRegion], origin_cloud_region, path=["response"])
assert cast(Any, response.is_closed) is True
+ @pytest.mark.skip(reason="HTTP 404 error from prism -- route not in spec")
@parametrize
- async def test_path_params_create(self, async_client: AsyncCloudflare) -> None:
+ async def test_path_params_update(self, async_client: AsyncCloudflare) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
- await async_client.cache.origin_cloud_regions.with_raw_response.create(
+ await async_client.cache.origin_cloud_regions.with_raw_response.update(
+ path_origin_ip="192.0.2.1",
zone_id="",
- ip="192.0.2.1",
+ body_origin_ip="192.0.2.1",
+ region="us-east-1",
+ vendor="aws",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `path_origin_ip` but received ''"):
+ await async_client.cache.origin_cloud_regions.with_raw_response.update(
+ path_origin_ip="",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ body_origin_ip="192.0.2.1",
region="us-east-1",
vendor="aws",
)
@@ -485,7 +476,16 @@ async def test_method_list(self, async_client: AsyncCloudflare) -> None:
origin_cloud_region = await async_client.cache.origin_cloud_regions.list(
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
)
- assert_matches_type(Optional[OriginCloudRegionListResponse], origin_cloud_region, path=["response"])
+ assert_matches_type(AsyncV4PagePaginationArray[OriginCloudRegion], origin_cloud_region, path=["response"])
+
+ @parametrize
+ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ origin_cloud_region = await async_client.cache.origin_cloud_regions.list(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ page=1,
+ per_page=1,
+ )
+ assert_matches_type(AsyncV4PagePaginationArray[OriginCloudRegion], origin_cloud_region, path=["response"])
@parametrize
async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None:
@@ -496,7 +496,7 @@ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
origin_cloud_region = await response.parse()
- assert_matches_type(Optional[OriginCloudRegionListResponse], origin_cloud_region, path=["response"])
+ assert_matches_type(AsyncV4PagePaginationArray[OriginCloudRegion], origin_cloud_region, path=["response"])
@parametrize
async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None:
@@ -507,7 +507,7 @@ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> N
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
origin_cloud_region = await response.parse()
- assert_matches_type(Optional[OriginCloudRegionListResponse], origin_cloud_region, path=["response"])
+ assert_matches_type(AsyncV4PagePaginationArray[OriginCloudRegion], origin_cloud_region, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -605,36 +605,36 @@ async def test_path_params_bulk_delete(self, async_client: AsyncCloudflare) -> N
)
@parametrize
- async def test_method_bulk_edit(self, async_client: AsyncCloudflare) -> None:
- origin_cloud_region = await async_client.cache.origin_cloud_regions.bulk_edit(
+ async def test_method_bulk_update(self, async_client: AsyncCloudflare) -> None:
+ origin_cloud_region = await async_client.cache.origin_cloud_regions.bulk_update(
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
body=[
{
- "ip": "192.0.2.1",
+ "origin_ip": "192.0.2.1",
"region": "us-east-1",
"vendor": "aws",
},
{
- "ip": "2001:db8::1",
+ "origin_ip": "2001:db8::1",
"region": "us-central1",
"vendor": "gcp",
},
],
)
- assert_matches_type(Optional[OriginCloudRegionBulkEditResponse], origin_cloud_region, path=["response"])
+ assert_matches_type(Optional[OriginCloudRegionBulkUpdateResponse], origin_cloud_region, path=["response"])
@parametrize
- async def test_raw_response_bulk_edit(self, async_client: AsyncCloudflare) -> None:
- response = await async_client.cache.origin_cloud_regions.with_raw_response.bulk_edit(
+ async def test_raw_response_bulk_update(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.cache.origin_cloud_regions.with_raw_response.bulk_update(
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
body=[
{
- "ip": "192.0.2.1",
+ "origin_ip": "192.0.2.1",
"region": "us-east-1",
"vendor": "aws",
},
{
- "ip": "2001:db8::1",
+ "origin_ip": "2001:db8::1",
"region": "us-central1",
"vendor": "gcp",
},
@@ -644,20 +644,20 @@ async def test_raw_response_bulk_edit(self, async_client: AsyncCloudflare) -> No
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
origin_cloud_region = await response.parse()
- assert_matches_type(Optional[OriginCloudRegionBulkEditResponse], origin_cloud_region, path=["response"])
+ assert_matches_type(Optional[OriginCloudRegionBulkUpdateResponse], origin_cloud_region, path=["response"])
@parametrize
- async def test_streaming_response_bulk_edit(self, async_client: AsyncCloudflare) -> None:
- async with async_client.cache.origin_cloud_regions.with_streaming_response.bulk_edit(
+ async def test_streaming_response_bulk_update(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.cache.origin_cloud_regions.with_streaming_response.bulk_update(
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
body=[
{
- "ip": "192.0.2.1",
+ "origin_ip": "192.0.2.1",
"region": "us-east-1",
"vendor": "aws",
},
{
- "ip": "2001:db8::1",
+ "origin_ip": "2001:db8::1",
"region": "us-central1",
"vendor": "gcp",
},
@@ -667,86 +667,36 @@ async def test_streaming_response_bulk_edit(self, async_client: AsyncCloudflare)
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
origin_cloud_region = await response.parse()
- assert_matches_type(Optional[OriginCloudRegionBulkEditResponse], origin_cloud_region, path=["response"])
+ assert_matches_type(Optional[OriginCloudRegionBulkUpdateResponse], origin_cloud_region, path=["response"])
assert cast(Any, response.is_closed) is True
@parametrize
- async def test_path_params_bulk_edit(self, async_client: AsyncCloudflare) -> None:
+ async def test_path_params_bulk_update(self, async_client: AsyncCloudflare) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
- await async_client.cache.origin_cloud_regions.with_raw_response.bulk_edit(
+ await async_client.cache.origin_cloud_regions.with_raw_response.bulk_update(
zone_id="",
body=[
{
- "ip": "192.0.2.1",
+ "origin_ip": "192.0.2.1",
"region": "us-east-1",
"vendor": "aws",
},
{
- "ip": "2001:db8::1",
+ "origin_ip": "2001:db8::1",
"region": "us-central1",
"vendor": "gcp",
},
],
)
- @parametrize
- async def test_method_edit(self, async_client: AsyncCloudflare) -> None:
- origin_cloud_region = await async_client.cache.origin_cloud_regions.edit(
- zone_id="023e105f4ecef8ad9ca31a8372d0c353",
- ip="2001:db8::1",
- region="us-central1",
- vendor="gcp",
- )
- assert_matches_type(Optional[OriginCloudRegionEditResponse], origin_cloud_region, path=["response"])
-
- @parametrize
- async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None:
- response = await async_client.cache.origin_cloud_regions.with_raw_response.edit(
- zone_id="023e105f4ecef8ad9ca31a8372d0c353",
- ip="2001:db8::1",
- region="us-central1",
- vendor="gcp",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- origin_cloud_region = await response.parse()
- assert_matches_type(Optional[OriginCloudRegionEditResponse], origin_cloud_region, path=["response"])
-
- @parametrize
- async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> None:
- async with async_client.cache.origin_cloud_regions.with_streaming_response.edit(
- zone_id="023e105f4ecef8ad9ca31a8372d0c353",
- ip="2001:db8::1",
- region="us-central1",
- vendor="gcp",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- origin_cloud_region = await response.parse()
- assert_matches_type(Optional[OriginCloudRegionEditResponse], origin_cloud_region, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_edit(self, async_client: AsyncCloudflare) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
- await async_client.cache.origin_cloud_regions.with_raw_response.edit(
- zone_id="",
- ip="2001:db8::1",
- region="us-central1",
- vendor="gcp",
- )
-
@parametrize
async def test_method_get(self, async_client: AsyncCloudflare) -> None:
origin_cloud_region = await async_client.cache.origin_cloud_regions.get(
origin_ip="192.0.2.1",
zone_id="023e105f4ecef8ad9ca31a8372d0c353",
)
- assert_matches_type(Optional[OriginCloudRegionGetResponse], origin_cloud_region, path=["response"])
+ assert_matches_type(Optional[OriginCloudRegion], origin_cloud_region, path=["response"])
@parametrize
async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
@@ -758,7 +708,7 @@ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
origin_cloud_region = await response.parse()
- assert_matches_type(Optional[OriginCloudRegionGetResponse], origin_cloud_region, path=["response"])
+ assert_matches_type(Optional[OriginCloudRegion], origin_cloud_region, path=["response"])
@parametrize
async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
@@ -770,7 +720,7 @@ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> No
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
origin_cloud_region = await response.parse()
- assert_matches_type(Optional[OriginCloudRegionGetResponse], origin_cloud_region, path=["response"])
+ assert_matches_type(Optional[OriginCloudRegion], origin_cloud_region, path=["response"])
assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/cache/test_smart_tiered_cache.py b/tests/api_resources/cache/test_smart_tiered_cache.py
index 3457741e5fe..df662413fd1 100644
--- a/tests/api_resources/cache/test_smart_tiered_cache.py
+++ b/tests/api_resources/cache/test_smart_tiered_cache.py
@@ -12,6 +12,7 @@
from cloudflare.types.cache import (
SmartTieredCacheGetResponse,
SmartTieredCacheEditResponse,
+ SmartTieredCacheCreateResponse,
SmartTieredCacheDeleteResponse,
)
@@ -21,6 +22,48 @@
class TestSmartTieredCache:
parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+ @parametrize
+ def test_method_create(self, client: Cloudflare) -> None:
+ smart_tiered_cache = client.cache.smart_tiered_cache.create(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ value="on",
+ )
+ assert_matches_type(Optional[SmartTieredCacheCreateResponse], smart_tiered_cache, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Cloudflare) -> None:
+ response = client.cache.smart_tiered_cache.with_raw_response.create(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ value="on",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ smart_tiered_cache = response.parse()
+ assert_matches_type(Optional[SmartTieredCacheCreateResponse], smart_tiered_cache, path=["response"])
+
+ @parametrize
+ def test_streaming_response_create(self, client: Cloudflare) -> None:
+ with client.cache.smart_tiered_cache.with_streaming_response.create(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ value="on",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ smart_tiered_cache = response.parse()
+ assert_matches_type(Optional[SmartTieredCacheCreateResponse], smart_tiered_cache, 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 `zone_id` but received ''"):
+ client.cache.smart_tiered_cache.with_raw_response.create(
+ zone_id="",
+ value="on",
+ )
+
@parametrize
def test_method_delete(self, client: Cloudflare) -> None:
smart_tiered_cache = client.cache.smart_tiered_cache.delete(
@@ -145,6 +188,48 @@ class TestAsyncSmartTieredCache:
"async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
)
+ @parametrize
+ async def test_method_create(self, async_client: AsyncCloudflare) -> None:
+ smart_tiered_cache = await async_client.cache.smart_tiered_cache.create(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ value="on",
+ )
+ assert_matches_type(Optional[SmartTieredCacheCreateResponse], smart_tiered_cache, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.cache.smart_tiered_cache.with_raw_response.create(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ value="on",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ smart_tiered_cache = await response.parse()
+ assert_matches_type(Optional[SmartTieredCacheCreateResponse], smart_tiered_cache, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.cache.smart_tiered_cache.with_streaming_response.create(
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ value="on",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ smart_tiered_cache = await response.parse()
+ assert_matches_type(Optional[SmartTieredCacheCreateResponse], smart_tiered_cache, 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 `zone_id` but received ''"):
+ await async_client.cache.smart_tiered_cache.with_raw_response.create(
+ zone_id="",
+ value="on",
+ )
+
@parametrize
async def test_method_delete(self, async_client: AsyncCloudflare) -> None:
smart_tiered_cache = await async_client.cache.smart_tiered_cache.delete(
diff --git a/tests/api_resources/load_balancers/monitor_groups/__init__.py b/tests/api_resources/load_balancers/monitor_groups/__init__.py
new file mode 100644
index 00000000000..fd8019a9a1a
--- /dev/null
+++ b/tests/api_resources/load_balancers/monitor_groups/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/load_balancers/monitor_groups/test_references.py b/tests/api_resources/load_balancers/monitor_groups/test_references.py
new file mode 100644
index 00000000000..5185de60184
--- /dev/null
+++ b/tests/api_resources/load_balancers/monitor_groups/test_references.py
@@ -0,0 +1,121 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare.pagination import SyncSinglePage, AsyncSinglePage
+from cloudflare.types.load_balancers.monitor_groups import ReferenceGetResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestReferences:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_get(self, client: Cloudflare) -> None:
+ reference = client.load_balancers.monitor_groups.references.get(
+ monitor_group_id="f1aba936b94213e5b8dca0c0dbf1f9cc",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(SyncSinglePage[ReferenceGetResponse], reference, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Cloudflare) -> None:
+ response = client.load_balancers.monitor_groups.references.with_raw_response.get(
+ monitor_group_id="f1aba936b94213e5b8dca0c0dbf1f9cc",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ reference = response.parse()
+ assert_matches_type(SyncSinglePage[ReferenceGetResponse], reference, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Cloudflare) -> None:
+ with client.load_balancers.monitor_groups.references.with_streaming_response.get(
+ monitor_group_id="f1aba936b94213e5b8dca0c0dbf1f9cc",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ reference = response.parse()
+ assert_matches_type(SyncSinglePage[ReferenceGetResponse], reference, 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.load_balancers.monitor_groups.references.with_raw_response.get(
+ monitor_group_id="f1aba936b94213e5b8dca0c0dbf1f9cc",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `monitor_group_id` but received ''"):
+ client.load_balancers.monitor_groups.references.with_raw_response.get(
+ monitor_group_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+
+class TestAsyncReferences:
+ 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:
+ reference = await async_client.load_balancers.monitor_groups.references.get(
+ monitor_group_id="f1aba936b94213e5b8dca0c0dbf1f9cc",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(AsyncSinglePage[ReferenceGetResponse], reference, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.load_balancers.monitor_groups.references.with_raw_response.get(
+ monitor_group_id="f1aba936b94213e5b8dca0c0dbf1f9cc",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ reference = await response.parse()
+ assert_matches_type(AsyncSinglePage[ReferenceGetResponse], reference, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.load_balancers.monitor_groups.references.with_streaming_response.get(
+ monitor_group_id="f1aba936b94213e5b8dca0c0dbf1f9cc",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ reference = await response.parse()
+ assert_matches_type(AsyncSinglePage[ReferenceGetResponse], reference, 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.load_balancers.monitor_groups.references.with_raw_response.get(
+ monitor_group_id="f1aba936b94213e5b8dca0c0dbf1f9cc",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `monitor_group_id` but received ''"):
+ await async_client.load_balancers.monitor_groups.references.with_raw_response.get(
+ monitor_group_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
diff --git a/tests/api_resources/load_balancers/test_monitor_groups.py b/tests/api_resources/load_balancers/test_monitor_groups.py
index 7c9ecf52ac8..a1b26f3a034 100644
--- a/tests/api_resources/load_balancers/test_monitor_groups.py
+++ b/tests/api_resources/load_balancers/test_monitor_groups.py
@@ -20,11 +20,11 @@
class TestMonitorGroups:
parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+ @pytest.mark.skip(reason="HTTP 422 error from prism")
@parametrize
def test_method_create(self, client: Cloudflare) -> None:
monitor_group = client.load_balancers.monitor_groups.create(
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -37,11 +37,11 @@ def test_method_create(self, client: Cloudflare) -> None:
)
assert_matches_type(MonitorGroup, monitor_group, path=["response"])
+ @pytest.mark.skip(reason="HTTP 422 error from prism")
@parametrize
def test_raw_response_create(self, client: Cloudflare) -> None:
response = client.load_balancers.monitor_groups.with_raw_response.create(
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -58,11 +58,11 @@ def test_raw_response_create(self, client: Cloudflare) -> None:
monitor_group = response.parse()
assert_matches_type(MonitorGroup, monitor_group, path=["response"])
+ @pytest.mark.skip(reason="HTTP 422 error from prism")
@parametrize
def test_streaming_response_create(self, client: Cloudflare) -> None:
with client.load_balancers.monitor_groups.with_streaming_response.create(
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -81,12 +81,12 @@ def test_streaming_response_create(self, client: Cloudflare) -> None:
assert cast(Any, response.is_closed) is True
+ @pytest.mark.skip(reason="HTTP 422 error from prism")
@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.load_balancers.monitor_groups.with_raw_response.create(
account_id="",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -103,7 +103,6 @@ def test_method_update(self, client: Cloudflare) -> None:
monitor_group = client.load_balancers.monitor_groups.update(
monitor_group_id="17b5962d775c646f3f9725cbc7a53df4",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -121,7 +120,6 @@ def test_raw_response_update(self, client: Cloudflare) -> None:
response = client.load_balancers.monitor_groups.with_raw_response.update(
monitor_group_id="17b5962d775c646f3f9725cbc7a53df4",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -143,7 +141,6 @@ def test_streaming_response_update(self, client: Cloudflare) -> None:
with client.load_balancers.monitor_groups.with_streaming_response.update(
monitor_group_id="17b5962d775c646f3f9725cbc7a53df4",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -168,7 +165,6 @@ def test_path_params_update(self, client: Cloudflare) -> None:
client.load_balancers.monitor_groups.with_raw_response.update(
monitor_group_id="17b5962d775c646f3f9725cbc7a53df4",
account_id="",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -184,7 +180,6 @@ def test_path_params_update(self, client: Cloudflare) -> None:
client.load_balancers.monitor_groups.with_raw_response.update(
monitor_group_id="",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -287,7 +282,6 @@ def test_method_edit(self, client: Cloudflare) -> None:
monitor_group = client.load_balancers.monitor_groups.edit(
monitor_group_id="17b5962d775c646f3f9725cbc7a53df4",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -305,7 +299,6 @@ def test_raw_response_edit(self, client: Cloudflare) -> None:
response = client.load_balancers.monitor_groups.with_raw_response.edit(
monitor_group_id="17b5962d775c646f3f9725cbc7a53df4",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -327,7 +320,6 @@ def test_streaming_response_edit(self, client: Cloudflare) -> None:
with client.load_balancers.monitor_groups.with_streaming_response.edit(
monitor_group_id="17b5962d775c646f3f9725cbc7a53df4",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -352,7 +344,6 @@ def test_path_params_edit(self, client: Cloudflare) -> None:
client.load_balancers.monitor_groups.with_raw_response.edit(
monitor_group_id="17b5962d775c646f3f9725cbc7a53df4",
account_id="",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -368,7 +359,6 @@ def test_path_params_edit(self, client: Cloudflare) -> None:
client.load_balancers.monitor_groups.with_raw_response.edit(
monitor_group_id="",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -434,11 +424,11 @@ class TestAsyncMonitorGroups:
"async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
)
+ @pytest.mark.skip(reason="HTTP 422 error from prism")
@parametrize
async def test_method_create(self, async_client: AsyncCloudflare) -> None:
monitor_group = await async_client.load_balancers.monitor_groups.create(
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -451,11 +441,11 @@ async def test_method_create(self, async_client: AsyncCloudflare) -> None:
)
assert_matches_type(MonitorGroup, monitor_group, path=["response"])
+ @pytest.mark.skip(reason="HTTP 422 error from prism")
@parametrize
async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None:
response = await async_client.load_balancers.monitor_groups.with_raw_response.create(
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -472,11 +462,11 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None:
monitor_group = await response.parse()
assert_matches_type(MonitorGroup, monitor_group, path=["response"])
+ @pytest.mark.skip(reason="HTTP 422 error from prism")
@parametrize
async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None:
async with async_client.load_balancers.monitor_groups.with_streaming_response.create(
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -495,12 +485,12 @@ async def test_streaming_response_create(self, async_client: AsyncCloudflare) ->
assert cast(Any, response.is_closed) is True
+ @pytest.mark.skip(reason="HTTP 422 error from prism")
@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.load_balancers.monitor_groups.with_raw_response.create(
account_id="",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -517,7 +507,6 @@ async def test_method_update(self, async_client: AsyncCloudflare) -> None:
monitor_group = await async_client.load_balancers.monitor_groups.update(
monitor_group_id="17b5962d775c646f3f9725cbc7a53df4",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -535,7 +524,6 @@ async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None:
response = await async_client.load_balancers.monitor_groups.with_raw_response.update(
monitor_group_id="17b5962d775c646f3f9725cbc7a53df4",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -557,7 +545,6 @@ async def test_streaming_response_update(self, async_client: AsyncCloudflare) ->
async with async_client.load_balancers.monitor_groups.with_streaming_response.update(
monitor_group_id="17b5962d775c646f3f9725cbc7a53df4",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -582,7 +569,6 @@ async def test_path_params_update(self, async_client: AsyncCloudflare) -> None:
await async_client.load_balancers.monitor_groups.with_raw_response.update(
monitor_group_id="17b5962d775c646f3f9725cbc7a53df4",
account_id="",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -598,7 +584,6 @@ async def test_path_params_update(self, async_client: AsyncCloudflare) -> None:
await async_client.load_balancers.monitor_groups.with_raw_response.update(
monitor_group_id="",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -701,7 +686,6 @@ async def test_method_edit(self, async_client: AsyncCloudflare) -> None:
monitor_group = await async_client.load_balancers.monitor_groups.edit(
monitor_group_id="17b5962d775c646f3f9725cbc7a53df4",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -719,7 +703,6 @@ async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None:
response = await async_client.load_balancers.monitor_groups.with_raw_response.edit(
monitor_group_id="17b5962d775c646f3f9725cbc7a53df4",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -741,7 +724,6 @@ async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> N
async with async_client.load_balancers.monitor_groups.with_streaming_response.edit(
monitor_group_id="17b5962d775c646f3f9725cbc7a53df4",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -766,7 +748,6 @@ async def test_path_params_edit(self, async_client: AsyncCloudflare) -> None:
await async_client.load_balancers.monitor_groups.with_raw_response.edit(
monitor_group_id="17b5962d775c646f3f9725cbc7a53df4",
account_id="",
- id="id",
description="Primary datacenter monitors",
members=[
{
@@ -782,7 +763,6 @@ async def test_path_params_edit(self, async_client: AsyncCloudflare) -> None:
await async_client.load_balancers.monitor_groups.with_raw_response.edit(
monitor_group_id="",
account_id="023e105f4ecef8ad9ca31a8372d0c353",
- id="id",
description="Primary datacenter monitors",
members=[
{
diff --git a/tests/api_resources/radar/bgp/ips/__init__.py b/tests/api_resources/radar/bgp/ips/__init__.py
new file mode 100644
index 00000000000..fd8019a9a1a
--- /dev/null
+++ b/tests/api_resources/radar/bgp/ips/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/radar/bgp/ips/test_top.py b/tests/api_resources/radar/bgp/ips/test_top.py
new file mode 100644
index 00000000000..66239dbb817
--- /dev/null
+++ b/tests/api_resources/radar/bgp/ips/test_top.py
@@ -0,0 +1,97 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare._utils import parse_datetime
+from cloudflare.types.radar.bgp.ips import TopAsesResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestTop:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_ases(self, client: Cloudflare) -> None:
+ top = client.radar.bgp.ips.top.ases()
+ assert_matches_type(TopAsesResponse, top, path=["response"])
+
+ @parametrize
+ def test_method_ases_with_all_params(self, client: Cloudflare) -> None:
+ top = client.radar.bgp.ips.top.ases(
+ country="US",
+ date=parse_datetime("2024-09-19T00:00:00Z"),
+ format="JSON",
+ limit=5,
+ metric="v4_24s",
+ )
+ assert_matches_type(TopAsesResponse, top, path=["response"])
+
+ @parametrize
+ def test_raw_response_ases(self, client: Cloudflare) -> None:
+ response = client.radar.bgp.ips.top.with_raw_response.ases()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ top = response.parse()
+ assert_matches_type(TopAsesResponse, top, path=["response"])
+
+ @parametrize
+ def test_streaming_response_ases(self, client: Cloudflare) -> None:
+ with client.radar.bgp.ips.top.with_streaming_response.ases() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ top = response.parse()
+ assert_matches_type(TopAsesResponse, top, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncTop:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_ases(self, async_client: AsyncCloudflare) -> None:
+ top = await async_client.radar.bgp.ips.top.ases()
+ assert_matches_type(TopAsesResponse, top, path=["response"])
+
+ @parametrize
+ async def test_method_ases_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ top = await async_client.radar.bgp.ips.top.ases(
+ country="US",
+ date=parse_datetime("2024-09-19T00:00:00Z"),
+ format="JSON",
+ limit=5,
+ metric="v4_24s",
+ )
+ assert_matches_type(TopAsesResponse, top, path=["response"])
+
+ @parametrize
+ async def test_raw_response_ases(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.radar.bgp.ips.top.with_raw_response.ases()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ top = await response.parse()
+ assert_matches_type(TopAsesResponse, top, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_ases(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.radar.bgp.ips.top.with_streaming_response.ases() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ top = await response.parse()
+ assert_matches_type(TopAsesResponse, top, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/radar/bgp/rpki/test_roas.py b/tests/api_resources/radar/bgp/rpki/test_roas.py
new file mode 100644
index 00000000000..7469de8431f
--- /dev/null
+++ b/tests/api_resources/radar/bgp/rpki/test_roas.py
@@ -0,0 +1,101 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare._utils import parse_datetime
+from cloudflare.types.radar.bgp.rpki import RoaTimeseriesResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestRoas:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_timeseries(self, client: Cloudflare) -> None:
+ roa = client.radar.bgp.rpki.roas.timeseries()
+ assert_matches_type(RoaTimeseriesResponse, roa, path=["response"])
+
+ @parametrize
+ def test_method_timeseries_with_all_params(self, client: Cloudflare) -> None:
+ roa = client.radar.bgp.rpki.roas.timeseries(
+ asn=["string"],
+ date_end=parse_datetime("2023-09-01T11:41:33.782Z"),
+ date_start=parse_datetime("2023-09-01T11:41:33.782Z"),
+ format="JSON",
+ location=["string"],
+ metric="validPfxsRatio",
+ name=["main_series"],
+ )
+ assert_matches_type(RoaTimeseriesResponse, roa, path=["response"])
+
+ @parametrize
+ def test_raw_response_timeseries(self, client: Cloudflare) -> None:
+ response = client.radar.bgp.rpki.roas.with_raw_response.timeseries()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ roa = response.parse()
+ assert_matches_type(RoaTimeseriesResponse, roa, path=["response"])
+
+ @parametrize
+ def test_streaming_response_timeseries(self, client: Cloudflare) -> None:
+ with client.radar.bgp.rpki.roas.with_streaming_response.timeseries() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ roa = response.parse()
+ assert_matches_type(RoaTimeseriesResponse, roa, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncRoas:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_timeseries(self, async_client: AsyncCloudflare) -> None:
+ roa = await async_client.radar.bgp.rpki.roas.timeseries()
+ assert_matches_type(RoaTimeseriesResponse, roa, path=["response"])
+
+ @parametrize
+ async def test_method_timeseries_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ roa = await async_client.radar.bgp.rpki.roas.timeseries(
+ asn=["string"],
+ date_end=parse_datetime("2023-09-01T11:41:33.782Z"),
+ date_start=parse_datetime("2023-09-01T11:41:33.782Z"),
+ format="JSON",
+ location=["string"],
+ metric="validPfxsRatio",
+ name=["main_series"],
+ )
+ assert_matches_type(RoaTimeseriesResponse, roa, path=["response"])
+
+ @parametrize
+ async def test_raw_response_timeseries(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.radar.bgp.rpki.roas.with_raw_response.timeseries()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ roa = await response.parse()
+ assert_matches_type(RoaTimeseriesResponse, roa, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_timeseries(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.radar.bgp.rpki.roas.with_streaming_response.timeseries() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ roa = await response.parse()
+ assert_matches_type(RoaTimeseriesResponse, roa, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/security_center/insights/test_audit_logs.py b/tests/api_resources/security_center/insights/test_audit_logs.py
index 8316d66f419..2c28155fc5d 100644
--- a/tests/api_resources/security_center/insights/test_audit_logs.py
+++ b/tests/api_resources/security_center/insights/test_audit_logs.py
@@ -67,7 +67,6 @@ def test_streaming_response_list(self, client: Cloudflare) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip(reason="path_params test expects ValueError for account_id/zone_id but endpoint accepts both")
@parametrize
def test_path_params_list(self, client: Cloudflare) -> None:
with pytest.raises(ValueError, match=r"You must provide either account_id or zone_id"):
diff --git a/tests/api_resources/test_cache.py b/tests/api_resources/test_cache.py
index 30ba1b0bf1e..181b5c81e77 100644
--- a/tests/api_resources/test_cache.py
+++ b/tests/api_resources/test_cache.py
@@ -9,7 +9,10 @@
from cloudflare import Cloudflare, AsyncCloudflare
from tests.utils import assert_matches_type
-from cloudflare.types.cache import CachePurgeResponse
+from cloudflare.types.cache import (
+ CachePurgeResponse,
+ CachePurgeEnvironmentResponse,
+)
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -310,6 +313,365 @@ def test_path_params_purge_overload_6(self, client: Cloudflare) -> None:
zone_id="",
)
+ @parametrize
+ def test_method_purge_environment_overload_1(self, client: Cloudflare) -> None:
+ cache = client.cache.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ def test_method_purge_environment_with_all_params_overload_1(self, client: Cloudflare) -> None:
+ cache = client.cache.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ tags=["a-cache-tag", "another-cache-tag"],
+ )
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ def test_raw_response_purge_environment_overload_1(self, client: Cloudflare) -> None:
+ response = client.cache.with_raw_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cache = response.parse()
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ def test_streaming_response_purge_environment_overload_1(self, client: Cloudflare) -> None:
+ with client.cache.with_streaming_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cache = response.parse()
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_purge_environment_overload_1(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
+ client.cache.with_raw_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `environment_id` but received ''"):
+ client.cache.with_raw_response.purge_environment(
+ environment_id="",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ @parametrize
+ def test_method_purge_environment_overload_2(self, client: Cloudflare) -> None:
+ cache = client.cache.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ def test_method_purge_environment_with_all_params_overload_2(self, client: Cloudflare) -> None:
+ cache = client.cache.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ hosts=["www.example.com", "images.example.com"],
+ )
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ def test_raw_response_purge_environment_overload_2(self, client: Cloudflare) -> None:
+ response = client.cache.with_raw_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cache = response.parse()
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ def test_streaming_response_purge_environment_overload_2(self, client: Cloudflare) -> None:
+ with client.cache.with_streaming_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cache = response.parse()
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_purge_environment_overload_2(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
+ client.cache.with_raw_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `environment_id` but received ''"):
+ client.cache.with_raw_response.purge_environment(
+ environment_id="",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ @parametrize
+ def test_method_purge_environment_overload_3(self, client: Cloudflare) -> None:
+ cache = client.cache.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ def test_method_purge_environment_with_all_params_overload_3(self, client: Cloudflare) -> None:
+ cache = client.cache.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ prefixes=["www.example.com/foo", "images.example.com/bar/baz"],
+ )
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ def test_raw_response_purge_environment_overload_3(self, client: Cloudflare) -> None:
+ response = client.cache.with_raw_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cache = response.parse()
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ def test_streaming_response_purge_environment_overload_3(self, client: Cloudflare) -> None:
+ with client.cache.with_streaming_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cache = response.parse()
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_purge_environment_overload_3(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
+ client.cache.with_raw_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `environment_id` but received ''"):
+ client.cache.with_raw_response.purge_environment(
+ environment_id="",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ @parametrize
+ def test_method_purge_environment_overload_4(self, client: Cloudflare) -> None:
+ cache = client.cache.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ def test_method_purge_environment_with_all_params_overload_4(self, client: Cloudflare) -> None:
+ cache = client.cache.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ purge_everything=True,
+ )
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ def test_raw_response_purge_environment_overload_4(self, client: Cloudflare) -> None:
+ response = client.cache.with_raw_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cache = response.parse()
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ def test_streaming_response_purge_environment_overload_4(self, client: Cloudflare) -> None:
+ with client.cache.with_streaming_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cache = response.parse()
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_purge_environment_overload_4(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
+ client.cache.with_raw_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `environment_id` but received ''"):
+ client.cache.with_raw_response.purge_environment(
+ environment_id="",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ @parametrize
+ def test_method_purge_environment_overload_5(self, client: Cloudflare) -> None:
+ cache = client.cache.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ def test_method_purge_environment_with_all_params_overload_5(self, client: Cloudflare) -> None:
+ cache = client.cache.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ files=["http://www.example.com/css/styles.css", "http://www.example.com/js/index.js"],
+ )
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ def test_raw_response_purge_environment_overload_5(self, client: Cloudflare) -> None:
+ response = client.cache.with_raw_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cache = response.parse()
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ def test_streaming_response_purge_environment_overload_5(self, client: Cloudflare) -> None:
+ with client.cache.with_streaming_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cache = response.parse()
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_purge_environment_overload_5(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
+ client.cache.with_raw_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `environment_id` but received ''"):
+ client.cache.with_raw_response.purge_environment(
+ environment_id="",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ @parametrize
+ def test_method_purge_environment_overload_6(self, client: Cloudflare) -> None:
+ cache = client.cache.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ def test_method_purge_environment_with_all_params_overload_6(self, client: Cloudflare) -> None:
+ cache = client.cache.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ files=[
+ {
+ "headers": {
+ "Accept-Language": "zh-CN",
+ "CF-Device-Type": "desktop",
+ "CF-IPCountry": "US",
+ },
+ "url": "http://www.example.com/cat_picture.jpg",
+ },
+ {
+ "headers": {
+ "Accept-Language": "en-US",
+ "CF-Device-Type": "mobile",
+ "CF-IPCountry": "EU",
+ },
+ "url": "http://www.example.com/dog_picture.jpg",
+ },
+ ],
+ )
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ def test_raw_response_purge_environment_overload_6(self, client: Cloudflare) -> None:
+ response = client.cache.with_raw_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cache = response.parse()
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ def test_streaming_response_purge_environment_overload_6(self, client: Cloudflare) -> None:
+ with client.cache.with_streaming_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cache = response.parse()
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_purge_environment_overload_6(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
+ client.cache.with_raw_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `environment_id` but received ''"):
+ client.cache.with_raw_response.purge_environment(
+ environment_id="",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
class TestAsyncCache:
parametrize = pytest.mark.parametrize(
@@ -608,3 +970,362 @@ async def test_path_params_purge_overload_6(self, async_client: AsyncCloudflare)
await async_client.cache.with_raw_response.purge(
zone_id="",
)
+
+ @parametrize
+ async def test_method_purge_environment_overload_1(self, async_client: AsyncCloudflare) -> None:
+ cache = await async_client.cache.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ async def test_method_purge_environment_with_all_params_overload_1(self, async_client: AsyncCloudflare) -> None:
+ cache = await async_client.cache.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ tags=["a-cache-tag", "another-cache-tag"],
+ )
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ async def test_raw_response_purge_environment_overload_1(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.cache.with_raw_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cache = await response.parse()
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_purge_environment_overload_1(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.cache.with_streaming_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cache = await response.parse()
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_purge_environment_overload_1(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
+ await async_client.cache.with_raw_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `environment_id` but received ''"):
+ await async_client.cache.with_raw_response.purge_environment(
+ environment_id="",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ @parametrize
+ async def test_method_purge_environment_overload_2(self, async_client: AsyncCloudflare) -> None:
+ cache = await async_client.cache.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ async def test_method_purge_environment_with_all_params_overload_2(self, async_client: AsyncCloudflare) -> None:
+ cache = await async_client.cache.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ hosts=["www.example.com", "images.example.com"],
+ )
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ async def test_raw_response_purge_environment_overload_2(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.cache.with_raw_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cache = await response.parse()
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_purge_environment_overload_2(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.cache.with_streaming_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cache = await response.parse()
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_purge_environment_overload_2(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
+ await async_client.cache.with_raw_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `environment_id` but received ''"):
+ await async_client.cache.with_raw_response.purge_environment(
+ environment_id="",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ @parametrize
+ async def test_method_purge_environment_overload_3(self, async_client: AsyncCloudflare) -> None:
+ cache = await async_client.cache.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ async def test_method_purge_environment_with_all_params_overload_3(self, async_client: AsyncCloudflare) -> None:
+ cache = await async_client.cache.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ prefixes=["www.example.com/foo", "images.example.com/bar/baz"],
+ )
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ async def test_raw_response_purge_environment_overload_3(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.cache.with_raw_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cache = await response.parse()
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_purge_environment_overload_3(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.cache.with_streaming_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cache = await response.parse()
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_purge_environment_overload_3(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
+ await async_client.cache.with_raw_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `environment_id` but received ''"):
+ await async_client.cache.with_raw_response.purge_environment(
+ environment_id="",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ @parametrize
+ async def test_method_purge_environment_overload_4(self, async_client: AsyncCloudflare) -> None:
+ cache = await async_client.cache.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ async def test_method_purge_environment_with_all_params_overload_4(self, async_client: AsyncCloudflare) -> None:
+ cache = await async_client.cache.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ purge_everything=True,
+ )
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ async def test_raw_response_purge_environment_overload_4(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.cache.with_raw_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cache = await response.parse()
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_purge_environment_overload_4(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.cache.with_streaming_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cache = await response.parse()
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_purge_environment_overload_4(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
+ await async_client.cache.with_raw_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `environment_id` but received ''"):
+ await async_client.cache.with_raw_response.purge_environment(
+ environment_id="",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ @parametrize
+ async def test_method_purge_environment_overload_5(self, async_client: AsyncCloudflare) -> None:
+ cache = await async_client.cache.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ async def test_method_purge_environment_with_all_params_overload_5(self, async_client: AsyncCloudflare) -> None:
+ cache = await async_client.cache.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ files=["http://www.example.com/css/styles.css", "http://www.example.com/js/index.js"],
+ )
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ async def test_raw_response_purge_environment_overload_5(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.cache.with_raw_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cache = await response.parse()
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_purge_environment_overload_5(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.cache.with_streaming_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cache = await response.parse()
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_purge_environment_overload_5(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
+ await async_client.cache.with_raw_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `environment_id` but received ''"):
+ await async_client.cache.with_raw_response.purge_environment(
+ environment_id="",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ @parametrize
+ async def test_method_purge_environment_overload_6(self, async_client: AsyncCloudflare) -> None:
+ cache = await async_client.cache.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ async def test_method_purge_environment_with_all_params_overload_6(self, async_client: AsyncCloudflare) -> None:
+ cache = await async_client.cache.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ files=[
+ {
+ "headers": {
+ "Accept-Language": "zh-CN",
+ "CF-Device-Type": "desktop",
+ "CF-IPCountry": "US",
+ },
+ "url": "http://www.example.com/cat_picture.jpg",
+ },
+ {
+ "headers": {
+ "Accept-Language": "en-US",
+ "CF-Device-Type": "mobile",
+ "CF-IPCountry": "EU",
+ },
+ "url": "http://www.example.com/dog_picture.jpg",
+ },
+ ],
+ )
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ async def test_raw_response_purge_environment_overload_6(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.cache.with_raw_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ cache = await response.parse()
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_purge_environment_overload_6(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.cache.with_streaming_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ cache = await response.parse()
+ assert_matches_type(Optional[CachePurgeEnvironmentResponse], cache, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_purge_environment_overload_6(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"):
+ await async_client.cache.with_raw_response.purge_environment(
+ environment_id="023e105f4ecef8ad9ca31a8372d0c353",
+ zone_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `environment_id` but received ''"):
+ await async_client.cache.with_raw_response.purge_environment(
+ environment_id="",
+ zone_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
diff --git a/tests/api_resources/test_resource_sharing.py b/tests/api_resources/test_resource_sharing.py
index 879e6040c9b..c6f74647ef4 100644
--- a/tests/api_resources/test_resource_sharing.py
+++ b/tests/api_resources/test_resource_sharing.py
@@ -175,6 +175,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None:
per_page=20,
resource_types=["custom-ruleset"],
status="active",
+ tag=["env=production"],
target_type="account",
)
assert_matches_type(SyncV4PagePaginationArray[ResourceSharingListResponse], resource_sharing, path=["response"])
@@ -477,6 +478,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare)
per_page=20,
resource_types=["custom-ruleset"],
status="active",
+ tag=["env=production"],
target_type="account",
)
assert_matches_type(
diff --git a/tests/api_resources/test_zones.py b/tests/api_resources/test_zones.py
index 0ee90986d59..60b348fbaea 100644
--- a/tests/api_resources/test_zones.py
+++ b/tests/api_resources/test_zones.py
@@ -83,6 +83,7 @@ def test_method_list_with_all_params(self, client: Cloudflare) -> None:
page=1,
per_page=5,
status="initializing",
+ type=["full"],
)
assert_matches_type(SyncV4PagePaginationArray[Zone], zone, path=["response"])
@@ -302,6 +303,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare)
page=1,
per_page=5,
status="initializing",
+ type=["full"],
)
assert_matches_type(AsyncV4PagePaginationArray[Zone], zone, path=["response"])
diff --git a/tests/api_resources/zero_trust/resource_library/__init__.py b/tests/api_resources/zero_trust/resource_library/__init__.py
new file mode 100644
index 00000000000..fd8019a9a1a
--- /dev/null
+++ b/tests/api_resources/zero_trust/resource_library/__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/resource_library/test_applications.py b/tests/api_resources/zero_trust/resource_library/test_applications.py
new file mode 100644
index 00000000000..196f47c079f
--- /dev/null
+++ b/tests/api_resources/zero_trust/resource_library/test_applications.py
@@ -0,0 +1,224 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, Optional, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare.pagination import SyncSinglePage, AsyncSinglePage
+from cloudflare.types.zero_trust.resource_library import (
+ ApplicationGetResponse,
+ ApplicationListResponse,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestApplications:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_list(self, client: Cloudflare) -> None:
+ application = client.zero_trust.resource_library.applications.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(SyncSinglePage[ApplicationListResponse], application, path=["response"])
+
+ @parametrize
+ def test_method_list_with_all_params(self, client: Cloudflare) -> None:
+ application = client.zero_trust.resource_library.applications.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ filter="filter",
+ limit=0,
+ offset=0,
+ order_by="order_by",
+ search="xx",
+ )
+ assert_matches_type(SyncSinglePage[ApplicationListResponse], application, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Cloudflare) -> None:
+ response = client.zero_trust.resource_library.applications.with_raw_response.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ application = response.parse()
+ assert_matches_type(SyncSinglePage[ApplicationListResponse], application, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Cloudflare) -> None:
+ with client.zero_trust.resource_library.applications.with_streaming_response.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ application = response.parse()
+ assert_matches_type(SyncSinglePage[ApplicationListResponse], application, 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.resource_library.applications.with_raw_response.list(
+ account_id="",
+ )
+
+ @parametrize
+ def test_method_get(self, client: Cloudflare) -> None:
+ application = client.zero_trust.resource_library.applications.get(
+ id="0b63249c-95bf-4cc0-a7cc-d7faaaf1dac0",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[ApplicationGetResponse], application, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Cloudflare) -> None:
+ response = client.zero_trust.resource_library.applications.with_raw_response.get(
+ id="0b63249c-95bf-4cc0-a7cc-d7faaaf1dac0",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ application = response.parse()
+ assert_matches_type(Optional[ApplicationGetResponse], application, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Cloudflare) -> None:
+ with client.zero_trust.resource_library.applications.with_streaming_response.get(
+ id="0b63249c-95bf-4cc0-a7cc-d7faaaf1dac0",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ application = response.parse()
+ assert_matches_type(Optional[ApplicationGetResponse], application, 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.resource_library.applications.with_raw_response.get(
+ id="0b63249c-95bf-4cc0-a7cc-d7faaaf1dac0",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.zero_trust.resource_library.applications.with_raw_response.get(
+ id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+
+class TestAsyncApplications:
+ 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:
+ application = await async_client.zero_trust.resource_library.applications.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(AsyncSinglePage[ApplicationListResponse], application, path=["response"])
+
+ @parametrize
+ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ application = await async_client.zero_trust.resource_library.applications.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ filter="filter",
+ limit=0,
+ offset=0,
+ order_by="order_by",
+ search="xx",
+ )
+ assert_matches_type(AsyncSinglePage[ApplicationListResponse], application, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.resource_library.applications.with_raw_response.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ application = await response.parse()
+ assert_matches_type(AsyncSinglePage[ApplicationListResponse], application, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.resource_library.applications.with_streaming_response.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ application = await response.parse()
+ assert_matches_type(AsyncSinglePage[ApplicationListResponse], application, 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.resource_library.applications.with_raw_response.list(
+ account_id="",
+ )
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncCloudflare) -> None:
+ application = await async_client.zero_trust.resource_library.applications.get(
+ id="0b63249c-95bf-4cc0-a7cc-d7faaaf1dac0",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[ApplicationGetResponse], application, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.resource_library.applications.with_raw_response.get(
+ id="0b63249c-95bf-4cc0-a7cc-d7faaaf1dac0",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ application = await response.parse()
+ assert_matches_type(Optional[ApplicationGetResponse], application, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.resource_library.applications.with_streaming_response.get(
+ id="0b63249c-95bf-4cc0-a7cc-d7faaaf1dac0",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ application = await response.parse()
+ assert_matches_type(Optional[ApplicationGetResponse], application, 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.resource_library.applications.with_raw_response.get(
+ id="0b63249c-95bf-4cc0-a7cc-d7faaaf1dac0",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.zero_trust.resource_library.applications.with_raw_response.get(
+ id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
diff --git a/tests/api_resources/zero_trust/resource_library/test_categories.py b/tests/api_resources/zero_trust/resource_library/test_categories.py
new file mode 100644
index 00000000000..5d084bd3e21
--- /dev/null
+++ b/tests/api_resources/zero_trust/resource_library/test_categories.py
@@ -0,0 +1,215 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, Optional, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare.pagination import SyncSinglePage, AsyncSinglePage
+from cloudflare.types.zero_trust.resource_library import CategoryGetResponse, CategoryListResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestCategories:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_list(self, client: Cloudflare) -> None:
+ category = client.zero_trust.resource_library.categories.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(SyncSinglePage[CategoryListResponse], category, path=["response"])
+
+ @parametrize
+ def test_method_list_with_all_params(self, client: Cloudflare) -> None:
+ category = client.zero_trust.resource_library.categories.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ limit=0,
+ offset=0,
+ )
+ assert_matches_type(SyncSinglePage[CategoryListResponse], category, path=["response"])
+
+ @parametrize
+ def test_raw_response_list(self, client: Cloudflare) -> None:
+ response = client.zero_trust.resource_library.categories.with_raw_response.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ category = response.parse()
+ assert_matches_type(SyncSinglePage[CategoryListResponse], category, path=["response"])
+
+ @parametrize
+ def test_streaming_response_list(self, client: Cloudflare) -> None:
+ with client.zero_trust.resource_library.categories.with_streaming_response.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ category = response.parse()
+ assert_matches_type(SyncSinglePage[CategoryListResponse], category, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_list(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.zero_trust.resource_library.categories.with_raw_response.list(
+ account_id="",
+ )
+
+ @parametrize
+ def test_method_get(self, client: Cloudflare) -> None:
+ category = client.zero_trust.resource_library.categories.get(
+ id="0b63249c-95bf-4cc0-a7cc-d7faaaf1dac0",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[CategoryGetResponse], category, path=["response"])
+
+ @parametrize
+ def test_raw_response_get(self, client: Cloudflare) -> None:
+ response = client.zero_trust.resource_library.categories.with_raw_response.get(
+ id="0b63249c-95bf-4cc0-a7cc-d7faaaf1dac0",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ category = response.parse()
+ assert_matches_type(Optional[CategoryGetResponse], category, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get(self, client: Cloudflare) -> None:
+ with client.zero_trust.resource_library.categories.with_streaming_response.get(
+ id="0b63249c-95bf-4cc0-a7cc-d7faaaf1dac0",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ category = response.parse()
+ assert_matches_type(Optional[CategoryGetResponse], category, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_get(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.zero_trust.resource_library.categories.with_raw_response.get(
+ id="0b63249c-95bf-4cc0-a7cc-d7faaaf1dac0",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.zero_trust.resource_library.categories.with_raw_response.get(
+ id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+
+class TestAsyncCategories:
+ 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:
+ category = await async_client.zero_trust.resource_library.categories.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(AsyncSinglePage[CategoryListResponse], category, path=["response"])
+
+ @parametrize
+ async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ category = await async_client.zero_trust.resource_library.categories.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ limit=0,
+ offset=0,
+ )
+ assert_matches_type(AsyncSinglePage[CategoryListResponse], category, path=["response"])
+
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.resource_library.categories.with_raw_response.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ category = await response.parse()
+ assert_matches_type(AsyncSinglePage[CategoryListResponse], category, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.resource_library.categories.with_streaming_response.list(
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ category = await response.parse()
+ assert_matches_type(AsyncSinglePage[CategoryListResponse], category, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_list(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.zero_trust.resource_library.categories.with_raw_response.list(
+ account_id="",
+ )
+
+ @parametrize
+ async def test_method_get(self, async_client: AsyncCloudflare) -> None:
+ category = await async_client.zero_trust.resource_library.categories.get(
+ id="0b63249c-95bf-4cc0-a7cc-d7faaaf1dac0",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(Optional[CategoryGetResponse], category, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.zero_trust.resource_library.categories.with_raw_response.get(
+ id="0b63249c-95bf-4cc0-a7cc-d7faaaf1dac0",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ category = await response.parse()
+ assert_matches_type(Optional[CategoryGetResponse], category, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.zero_trust.resource_library.categories.with_streaming_response.get(
+ id="0b63249c-95bf-4cc0-a7cc-d7faaaf1dac0",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ category = await response.parse()
+ assert_matches_type(Optional[CategoryGetResponse], category, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_get(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.zero_trust.resource_library.categories.with_raw_response.get(
+ id="0b63249c-95bf-4cc0-a7cc-d7faaaf1dac0",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.zero_trust.resource_library.categories.with_raw_response.get(
+ id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )