diff --git a/.stats.yml b/.stats.yml index ca71746c0ec..f2ae3e506be 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 2404 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-874436f83bd9c383144c69da47c4b767bb9c6f4f2bb4945af58cf3b6015f0f62.yml -openapi_spec_hash: beaf9a654991bf65d642e05c03460e4c -config_hash: 2f529580a17438fc62cd0b47db41b6f1 +configured_endpoints: 2409 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-2638067e2ee443dc7c7a5fa38c2a7ed38f7bbd6de7db58aa4b364539ea96000c.yml +openapi_spec_hash: b955d89313a0c7f4e27f2aaa04cd13a8 +config_hash: bbf6df558b7c0807286a2085dd306dde diff --git a/api.md b/api.md index b05e7b8d057..7152ccab0d6 100644 --- a/api.md +++ b/api.md @@ -211,6 +211,8 @@ from cloudflare.types import ( # [Calls](src/cloudflare/resources/calls/api.md) +# [Moq](src/cloudflare/resources/moq/api.md) + # [CloudforceOne](src/cloudflare/resources/cloudforce_one/api.md) # [AIGateway](src/cloudflare/resources/ai_gateway/api.md) diff --git a/src/cloudflare/_client.py b/src/cloudflare/_client.py index af5c148ccc9..ef29c9e0f72 100644 --- a/src/cloudflare/_client.py +++ b/src/cloudflare/_client.py @@ -47,6 +47,7 @@ dns, iam, ips, + moq, rum, ssl, argo, @@ -163,6 +164,7 @@ from .resources.dns.dns import DNSResource, AsyncDNSResource from .resources.iam.iam import IAMResource, AsyncIAMResource from .resources.ips.ips import IPsResource, AsyncIPsResource + from .resources.moq.moq import MoqResource, AsyncMoqResource from .resources.rum.rum import RUMResource, AsyncRUMResource from .resources.ssl.ssl import SSLResource, AsyncSSLResource from .resources.argo.argo import ArgoResource, AsyncArgoResource @@ -965,6 +967,12 @@ def calls(self) -> CallsResource: return CallsResource(self) + @cached_property + def moq(self) -> MoqResource: + from .resources.moq import MoqResource + + return MoqResource(self) + @cached_property def cloudforce_one(self) -> CloudforceOneResource: from .resources.cloudforce_one import CloudforceOneResource @@ -1917,6 +1925,12 @@ def calls(self) -> AsyncCallsResource: return AsyncCallsResource(self) + @cached_property + def moq(self) -> AsyncMoqResource: + from .resources.moq import AsyncMoqResource + + return AsyncMoqResource(self) + @cached_property def cloudforce_one(self) -> AsyncCloudforceOneResource: from .resources.cloudforce_one import AsyncCloudforceOneResource @@ -2793,6 +2807,12 @@ def calls(self) -> calls.CallsResourceWithRawResponse: return CallsResourceWithRawResponse(self._client.calls) + @cached_property + def moq(self) -> moq.MoqResourceWithRawResponse: + from .resources.moq import MoqResourceWithRawResponse + + return MoqResourceWithRawResponse(self._client.moq) + @cached_property def cloudforce_one(self) -> cloudforce_one.CloudforceOneResourceWithRawResponse: from .resources.cloudforce_one import CloudforceOneResourceWithRawResponse @@ -3496,6 +3516,12 @@ def calls(self) -> calls.AsyncCallsResourceWithRawResponse: return AsyncCallsResourceWithRawResponse(self._client.calls) + @cached_property + def moq(self) -> moq.AsyncMoqResourceWithRawResponse: + from .resources.moq import AsyncMoqResourceWithRawResponse + + return AsyncMoqResourceWithRawResponse(self._client.moq) + @cached_property def cloudforce_one(self) -> cloudforce_one.AsyncCloudforceOneResourceWithRawResponse: from .resources.cloudforce_one import AsyncCloudforceOneResourceWithRawResponse @@ -4199,6 +4225,12 @@ def calls(self) -> calls.CallsResourceWithStreamingResponse: return CallsResourceWithStreamingResponse(self._client.calls) + @cached_property + def moq(self) -> moq.MoqResourceWithStreamingResponse: + from .resources.moq import MoqResourceWithStreamingResponse + + return MoqResourceWithStreamingResponse(self._client.moq) + @cached_property def cloudforce_one(self) -> cloudforce_one.CloudforceOneResourceWithStreamingResponse: from .resources.cloudforce_one import CloudforceOneResourceWithStreamingResponse @@ -4910,6 +4942,12 @@ def calls(self) -> calls.AsyncCallsResourceWithStreamingResponse: return AsyncCallsResourceWithStreamingResponse(self._client.calls) + @cached_property + def moq(self) -> moq.AsyncMoqResourceWithStreamingResponse: + from .resources.moq import AsyncMoqResourceWithStreamingResponse + + return AsyncMoqResourceWithStreamingResponse(self._client.moq) + @cached_property def cloudforce_one(self) -> cloudforce_one.AsyncCloudforceOneResourceWithStreamingResponse: from .resources.cloudforce_one import AsyncCloudforceOneResourceWithStreamingResponse diff --git a/src/cloudflare/resources/email_routing/api.md b/src/cloudflare/resources/email_routing/api.md index 26a1d76019a..60551e95244 100644 --- a/src/cloudflare/resources/email_routing/api.md +++ b/src/cloudflare/resources/email_routing/api.md @@ -39,7 +39,6 @@ Methods: - client.email_routing.rules.create(\*, zone_id, \*\*params) -> Optional[EmailRoutingRule] - client.email_routing.rules.update(rule_identifier, \*, zone_id, \*\*params) -> Optional[EmailRoutingRule] -- client.email_routing.rules.list(\*, zone_id, \*\*params) -> SyncV4PagePaginationArray[EmailRoutingRule] - client.email_routing.rules.delete(rule_identifier, \*, zone_id) -> Optional[EmailRoutingRule] - client.email_routing.rules.get(rule_identifier, \*, zone_id) -> Optional[EmailRoutingRule] diff --git a/src/cloudflare/resources/email_routing/rules/rules.py b/src/cloudflare/resources/email_routing/rules/rules.py index b38ce74c7a0..cff2f977c39 100644 --- a/src/cloudflare/resources/email_routing/rules/rules.py +++ b/src/cloudflare/resources/email_routing/rules/rules.py @@ -26,9 +26,8 @@ async_to_streamed_response_wrapper, ) from ...._wrappers import ResultWrapper -from ....pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray -from ...._base_client import AsyncPaginator, make_request_options -from ....types.email_routing import rule_list_params, rule_create_params, rule_update_params +from ...._base_client import make_request_options +from ....types.email_routing import rule_create_params, rule_update_params from ....types.email_routing.action_param import ActionParam from ....types.email_routing.matcher_param import MatcherParam from ....types.email_routing.email_routing_rule import EmailRoutingRule @@ -202,62 +201,6 @@ def update( cast_to=cast(Type[Optional[EmailRoutingRule]], ResultWrapper[EmailRoutingRule]), ) - def list( - self, - *, - zone_id: str, - enabled: Literal[True, False] | Omit = omit, - page: float | Omit = omit, - per_page: 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, - ) -> SyncV4PagePaginationArray[EmailRoutingRule]: - """ - Lists existing routing rules. - - Args: - zone_id: Identifier. - - enabled: Filter by enabled routing rules. - - page: Page number of paginated results. - - per_page: Maximum number of results per page. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not zone_id: - raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") - return self._get_api_list( - path_template("/zones/{zone_id}/email/routing/rules", zone_id=zone_id), - page=SyncV4PagePaginationArray[EmailRoutingRule], - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "enabled": enabled, - "page": page, - "per_page": per_page, - }, - rule_list_params.RuleListParams, - ), - ), - model=EmailRoutingRule, - ) - def delete( self, rule_identifier: str, @@ -521,62 +464,6 @@ async def update( cast_to=cast(Type[Optional[EmailRoutingRule]], ResultWrapper[EmailRoutingRule]), ) - def list( - self, - *, - zone_id: str, - enabled: Literal[True, False] | Omit = omit, - page: float | Omit = omit, - per_page: 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, - ) -> AsyncPaginator[EmailRoutingRule, AsyncV4PagePaginationArray[EmailRoutingRule]]: - """ - Lists existing routing rules. - - Args: - zone_id: Identifier. - - enabled: Filter by enabled routing rules. - - page: Page number of paginated results. - - per_page: Maximum number of results per page. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not zone_id: - raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") - return self._get_api_list( - path_template("/zones/{zone_id}/email/routing/rules", zone_id=zone_id), - page=AsyncV4PagePaginationArray[EmailRoutingRule], - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "enabled": enabled, - "page": page, - "per_page": per_page, - }, - rule_list_params.RuleListParams, - ), - ), - model=EmailRoutingRule, - ) - async def delete( self, rule_identifier: str, @@ -684,9 +571,6 @@ def __init__(self, rules: RulesResource) -> None: self.update = to_raw_response_wrapper( rules.update, ) - self.list = to_raw_response_wrapper( - rules.list, - ) self.delete = to_raw_response_wrapper( rules.delete, ) @@ -709,9 +593,6 @@ def __init__(self, rules: AsyncRulesResource) -> None: self.update = async_to_raw_response_wrapper( rules.update, ) - self.list = async_to_raw_response_wrapper( - rules.list, - ) self.delete = async_to_raw_response_wrapper( rules.delete, ) @@ -734,9 +615,6 @@ def __init__(self, rules: RulesResource) -> None: self.update = to_streamed_response_wrapper( rules.update, ) - self.list = to_streamed_response_wrapper( - rules.list, - ) self.delete = to_streamed_response_wrapper( rules.delete, ) @@ -759,9 +637,6 @@ def __init__(self, rules: AsyncRulesResource) -> None: self.update = async_to_streamed_response_wrapper( rules.update, ) - self.list = async_to_streamed_response_wrapper( - rules.list, - ) self.delete = async_to_streamed_response_wrapper( rules.delete, ) diff --git a/src/cloudflare/resources/email_security/investigate/move.py b/src/cloudflare/resources/email_security/investigate/move.py index 8fa530641c6..d23739406cb 100644 --- a/src/cloudflare/resources/email_security/investigate/move.py +++ b/src/cloudflare/resources/email_security/investigate/move.py @@ -53,6 +53,19 @@ def create( destination: Literal[ "Inbox", "JunkEmail", "DeletedItems", "RecoverableItemsDeletions", "RecoverableItemsPurges" ], + expected_disposition: Literal[ + "MALICIOUS", + "MALICIOUS-BEC", + "SUSPICIOUS", + "SPOOF", + "SPAM", + "BULK", + "ENCRYPTED", + "EXTERNAL", + "UNKNOWN", + "NONE", + ] + | 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, @@ -89,7 +102,13 @@ def create( investigate_id=investigate_id, ), page=SyncSinglePage[MoveCreateResponse], - body=maybe_transform({"destination": destination}, move_create_params.MoveCreateParams), + body=maybe_transform( + { + "destination": destination, + "expected_disposition": expected_disposition, + }, + move_create_params.MoveCreateParams, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -104,6 +123,19 @@ def bulk( destination: Literal[ "Inbox", "JunkEmail", "DeletedItems", "RecoverableItemsDeletions", "RecoverableItemsPurges" ], + expected_disposition: Literal[ + "MALICIOUS", + "MALICIOUS-BEC", + "SUSPICIOUS", + "SPOOF", + "SPAM", + "BULK", + "ENCRYPTED", + "EXTERNAL", + "UNKNOWN", + "NONE", + ] + | Omit = omit, ids: SequenceNotStr[str] | Omit = omit, postfix_ids: SequenceNotStr[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -142,6 +174,7 @@ def bulk( body=maybe_transform( { "destination": destination, + "expected_disposition": expected_disposition, "ids": ids, "postfix_ids": postfix_ids, }, @@ -183,6 +216,19 @@ def create( destination: Literal[ "Inbox", "JunkEmail", "DeletedItems", "RecoverableItemsDeletions", "RecoverableItemsPurges" ], + expected_disposition: Literal[ + "MALICIOUS", + "MALICIOUS-BEC", + "SUSPICIOUS", + "SPOOF", + "SPAM", + "BULK", + "ENCRYPTED", + "EXTERNAL", + "UNKNOWN", + "NONE", + ] + | 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, @@ -219,7 +265,13 @@ def create( investigate_id=investigate_id, ), page=AsyncSinglePage[MoveCreateResponse], - body=maybe_transform({"destination": destination}, move_create_params.MoveCreateParams), + body=maybe_transform( + { + "destination": destination, + "expected_disposition": expected_disposition, + }, + move_create_params.MoveCreateParams, + ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), @@ -234,6 +286,19 @@ def bulk( destination: Literal[ "Inbox", "JunkEmail", "DeletedItems", "RecoverableItemsDeletions", "RecoverableItemsPurges" ], + expected_disposition: Literal[ + "MALICIOUS", + "MALICIOUS-BEC", + "SUSPICIOUS", + "SPOOF", + "SPAM", + "BULK", + "ENCRYPTED", + "EXTERNAL", + "UNKNOWN", + "NONE", + ] + | Omit = omit, ids: SequenceNotStr[str] | Omit = omit, postfix_ids: SequenceNotStr[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -272,6 +337,7 @@ def bulk( body=maybe_transform( { "destination": destination, + "expected_disposition": expected_disposition, "ids": ids, "postfix_ids": postfix_ids, }, diff --git a/src/cloudflare/resources/moq/__init__.py b/src/cloudflare/resources/moq/__init__.py new file mode 100644 index 00000000000..02338c3f29f --- /dev/null +++ b/src/cloudflare/resources/moq/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .moq import ( + MoqResource, + AsyncMoqResource, + MoqResourceWithRawResponse, + AsyncMoqResourceWithRawResponse, + MoqResourceWithStreamingResponse, + AsyncMoqResourceWithStreamingResponse, +) +from .relays import ( + RelaysResource, + AsyncRelaysResource, + RelaysResourceWithRawResponse, + AsyncRelaysResourceWithRawResponse, + RelaysResourceWithStreamingResponse, + AsyncRelaysResourceWithStreamingResponse, +) + +__all__ = [ + "RelaysResource", + "AsyncRelaysResource", + "RelaysResourceWithRawResponse", + "AsyncRelaysResourceWithRawResponse", + "RelaysResourceWithStreamingResponse", + "AsyncRelaysResourceWithStreamingResponse", + "MoqResource", + "AsyncMoqResource", + "MoqResourceWithRawResponse", + "AsyncMoqResourceWithRawResponse", + "MoqResourceWithStreamingResponse", + "AsyncMoqResourceWithStreamingResponse", +] diff --git a/src/cloudflare/resources/moq/api.md b/src/cloudflare/resources/moq/api.md new file mode 100644 index 00000000000..1e91155e3fa --- /dev/null +++ b/src/cloudflare/resources/moq/api.md @@ -0,0 +1,34 @@ +# Moq + +## Relays + +Types: + +```python +from cloudflare.types.moq import ( + RelayCreateResponse, + RelayUpdateResponse, + RelayListResponse, + RelayGetResponse, +) +``` + +Methods: + +- client.moq.relays.create(\*, account_id, \*\*params) -> Optional[RelayCreateResponse] +- client.moq.relays.update(relay_id, \*, account_id, \*\*params) -> Optional[RelayUpdateResponse] +- client.moq.relays.list(\*, account_id, \*\*params) -> SyncSinglePage[RelayListResponse] +- client.moq.relays.delete(relay_id, \*, account_id) -> object +- client.moq.relays.get(relay_id, \*, account_id) -> Optional[RelayGetResponse] + +### Tokens + +Types: + +```python +from cloudflare.types.moq.relays import TokenRotateResponse +``` + +Methods: + +- client.moq.relays.tokens.rotate(relay_id, \*, account_id, \*\*params) -> Optional[TokenRotateResponse] diff --git a/src/cloudflare/resources/moq/moq.py b/src/cloudflare/resources/moq/moq.py new file mode 100644 index 00000000000..092ebafe1d1 --- /dev/null +++ b/src/cloudflare/resources/moq/moq.py @@ -0,0 +1,102 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from .relays.relays import ( + RelaysResource, + AsyncRelaysResource, + RelaysResourceWithRawResponse, + AsyncRelaysResourceWithRawResponse, + RelaysResourceWithStreamingResponse, + AsyncRelaysResourceWithStreamingResponse, +) + +__all__ = ["MoqResource", "AsyncMoqResource"] + + +class MoqResource(SyncAPIResource): + @cached_property + def relays(self) -> RelaysResource: + return RelaysResource(self._client) + + @cached_property + def with_raw_response(self) -> MoqResourceWithRawResponse: + """ + 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 MoqResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> MoqResourceWithStreamingResponse: + """ + 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 MoqResourceWithStreamingResponse(self) + + +class AsyncMoqResource(AsyncAPIResource): + @cached_property + def relays(self) -> AsyncRelaysResource: + return AsyncRelaysResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncMoqResourceWithRawResponse: + """ + 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 AsyncMoqResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncMoqResourceWithStreamingResponse: + """ + 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 AsyncMoqResourceWithStreamingResponse(self) + + +class MoqResourceWithRawResponse: + def __init__(self, moq: MoqResource) -> None: + self._moq = moq + + @cached_property + def relays(self) -> RelaysResourceWithRawResponse: + return RelaysResourceWithRawResponse(self._moq.relays) + + +class AsyncMoqResourceWithRawResponse: + def __init__(self, moq: AsyncMoqResource) -> None: + self._moq = moq + + @cached_property + def relays(self) -> AsyncRelaysResourceWithRawResponse: + return AsyncRelaysResourceWithRawResponse(self._moq.relays) + + +class MoqResourceWithStreamingResponse: + def __init__(self, moq: MoqResource) -> None: + self._moq = moq + + @cached_property + def relays(self) -> RelaysResourceWithStreamingResponse: + return RelaysResourceWithStreamingResponse(self._moq.relays) + + +class AsyncMoqResourceWithStreamingResponse: + def __init__(self, moq: AsyncMoqResource) -> None: + self._moq = moq + + @cached_property + def relays(self) -> AsyncRelaysResourceWithStreamingResponse: + return AsyncRelaysResourceWithStreamingResponse(self._moq.relays) diff --git a/src/cloudflare/resources/moq/relays/__init__.py b/src/cloudflare/resources/moq/relays/__init__.py new file mode 100644 index 00000000000..c69bba67272 --- /dev/null +++ b/src/cloudflare/resources/moq/relays/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .relays import ( + RelaysResource, + AsyncRelaysResource, + RelaysResourceWithRawResponse, + AsyncRelaysResourceWithRawResponse, + RelaysResourceWithStreamingResponse, + AsyncRelaysResourceWithStreamingResponse, +) +from .tokens import ( + TokensResource, + AsyncTokensResource, + TokensResourceWithRawResponse, + AsyncTokensResourceWithRawResponse, + TokensResourceWithStreamingResponse, + AsyncTokensResourceWithStreamingResponse, +) + +__all__ = [ + "TokensResource", + "AsyncTokensResource", + "TokensResourceWithRawResponse", + "AsyncTokensResourceWithRawResponse", + "TokensResourceWithStreamingResponse", + "AsyncTokensResourceWithStreamingResponse", + "RelaysResource", + "AsyncRelaysResource", + "RelaysResourceWithRawResponse", + "AsyncRelaysResourceWithRawResponse", + "RelaysResourceWithStreamingResponse", + "AsyncRelaysResourceWithStreamingResponse", +] diff --git a/src/cloudflare/resources/moq/relays/relays.py b/src/cloudflare/resources/moq/relays/relays.py new file mode 100644 index 00000000000..11eed213e54 --- /dev/null +++ b/src/cloudflare/resources/moq/relays/relays.py @@ -0,0 +1,709 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Type, Union, Optional, cast +from datetime import datetime + +import httpx + +from .tokens import ( + TokensResource, + AsyncTokensResource, + TokensResourceWithRawResponse, + AsyncTokensResourceWithRawResponse, + TokensResourceWithStreamingResponse, + AsyncTokensResourceWithStreamingResponse, +) +from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._wrappers import ResultWrapper +from ....types.moq import relay_list_params, relay_create_params, relay_update_params +from ....pagination import SyncSinglePage, AsyncSinglePage +from ...._base_client import AsyncPaginator, make_request_options +from ....types.moq.relay_get_response import RelayGetResponse +from ....types.moq.relay_list_response import RelayListResponse +from ....types.moq.relay_create_response import RelayCreateResponse +from ....types.moq.relay_update_response import RelayUpdateResponse + +__all__ = ["RelaysResource", "AsyncRelaysResource"] + + +class RelaysResource(SyncAPIResource): + @cached_property + def tokens(self) -> TokensResource: + return TokensResource(self._client) + + @cached_property + def with_raw_response(self) -> RelaysResourceWithRawResponse: + """ + 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 RelaysResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> RelaysResourceWithStreamingResponse: + """ + 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 RelaysResourceWithStreamingResponse(self) + + def create( + self, + *, + account_id: str, + name: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[RelayCreateResponse]: + """Provisions a new MoQ relay instance. + + Auto-creates a publish+subscribe token and + a subscribe-only token. Token values are included in the response (shown once). + Config is set to defaults (lingering subscribe enabled, 30s ceiling, origin + fallback off). Use PUT to modify. + + Args: + account_id: Cloudflare account identifier. + + name: Human-readable name for the relay. + + 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}/moq/relays", account_id=account_id), + body=maybe_transform({"name": name}, relay_create_params.RelayCreateParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[RelayCreateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[RelayCreateResponse]], ResultWrapper[RelayCreateResponse]), + ) + + def update( + self, + relay_id: str, + *, + account_id: str, + config: relay_update_params.Config | Omit = omit, + name: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[RelayUpdateResponse]: + """Updates a relay's name and/or configuration. + + Partial updates: omitted fields are + preserved. Config sub-objects replace as whole objects when present. + origin_fallback and lingering_subscribe are mutually exclusive. + + Args: + account_id: Cloudflare account identifier. + + config: origin_fallback and lingering_subscribe are mutually exclusive. + + 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 relay_id: + raise ValueError(f"Expected a non-empty value for `relay_id` but received {relay_id!r}") + return self._put( + path_template("/accounts/{account_id}/moq/relays/{relay_id}", account_id=account_id, relay_id=relay_id), + body=maybe_transform( + { + "config": config, + "name": name, + }, + relay_update_params.RelayUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[RelayUpdateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[RelayUpdateResponse]], ResultWrapper[RelayUpdateResponse]), + ) + + def list( + self, + *, + account_id: str, + asc: bool | Omit = omit, + created_after: Union[str, datetime] | Omit = omit, + created_before: Union[str, datetime] | 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, + ) -> SyncSinglePage[RelayListResponse]: + """Lists all MoQ relays for the account. + + Returns only metadata. Config, status, and + tokens are omitted. + + Results are cursor-paginated (keyset on the `created` timestamp). Use + `created_before` / `created_after` with the `created` value of the first/last + item in a page to fetch the adjacent page. `result_info` reports the page + `count` and the `total` matching the cursor filters. + + Args: + account_id: Cloudflare account identifier. + + asc: Sort order by `created`. When true, results are returned oldest-first + (ascending); otherwise newest-first (descending, the default). + + created_after: Cursor for pagination. Returns relays created strictly after this RFC 3339 + timestamp (typically the `created` value of the last item on the current page, + to fetch the next page). + + created_before: Cursor for pagination. Returns relays created strictly before this RFC 3339 + timestamp (typically the `created` value of the first item on the current page, + to fetch the previous page). + + per_page: Maximum number of relays to return per page. + + 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}/moq/relays", account_id=account_id), + page=SyncSinglePage[RelayListResponse], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "asc": asc, + "created_after": created_after, + "created_before": created_before, + "per_page": per_page, + }, + relay_list_params.RelayListParams, + ), + ), + model=RelayListResponse, + ) + + def delete( + self, + relay_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> object: + """ + Soft-deletes a MoQ relay. + + Args: + account_id: Cloudflare account 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 relay_id: + raise ValueError(f"Expected a non-empty value for `relay_id` but received {relay_id!r}") + return self._delete( + path_template("/accounts/{account_id}/moq/relays/{relay_id}", account_id=account_id, relay_id=relay_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[object]]._unwrapper, + ), + cast_to=cast(Type[object], ResultWrapper[object]), + ) + + def get( + self, + relay_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[RelayGetResponse]: + """Retrieves a single MoQ relay including config and status. + + Tokens are NOT + included. + + Args: + account_id: Cloudflare account 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 relay_id: + raise ValueError(f"Expected a non-empty value for `relay_id` but received {relay_id!r}") + return self._get( + path_template("/accounts/{account_id}/moq/relays/{relay_id}", account_id=account_id, relay_id=relay_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[RelayGetResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[RelayGetResponse]], ResultWrapper[RelayGetResponse]), + ) + + +class AsyncRelaysResource(AsyncAPIResource): + @cached_property + def tokens(self) -> AsyncTokensResource: + return AsyncTokensResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncRelaysResourceWithRawResponse: + """ + 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 AsyncRelaysResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncRelaysResourceWithStreamingResponse: + """ + 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 AsyncRelaysResourceWithStreamingResponse(self) + + async def create( + self, + *, + account_id: str, + name: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[RelayCreateResponse]: + """Provisions a new MoQ relay instance. + + Auto-creates a publish+subscribe token and + a subscribe-only token. Token values are included in the response (shown once). + Config is set to defaults (lingering subscribe enabled, 30s ceiling, origin + fallback off). Use PUT to modify. + + Args: + account_id: Cloudflare account identifier. + + name: Human-readable name for the relay. + + 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}/moq/relays", account_id=account_id), + body=await async_maybe_transform({"name": name}, relay_create_params.RelayCreateParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[RelayCreateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[RelayCreateResponse]], ResultWrapper[RelayCreateResponse]), + ) + + async def update( + self, + relay_id: str, + *, + account_id: str, + config: relay_update_params.Config | Omit = omit, + name: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[RelayUpdateResponse]: + """Updates a relay's name and/or configuration. + + Partial updates: omitted fields are + preserved. Config sub-objects replace as whole objects when present. + origin_fallback and lingering_subscribe are mutually exclusive. + + Args: + account_id: Cloudflare account identifier. + + config: origin_fallback and lingering_subscribe are mutually exclusive. + + 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 relay_id: + raise ValueError(f"Expected a non-empty value for `relay_id` but received {relay_id!r}") + return await self._put( + path_template("/accounts/{account_id}/moq/relays/{relay_id}", account_id=account_id, relay_id=relay_id), + body=await async_maybe_transform( + { + "config": config, + "name": name, + }, + relay_update_params.RelayUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[RelayUpdateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[RelayUpdateResponse]], ResultWrapper[RelayUpdateResponse]), + ) + + def list( + self, + *, + account_id: str, + asc: bool | Omit = omit, + created_after: Union[str, datetime] | Omit = omit, + created_before: Union[str, datetime] | 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, + ) -> AsyncPaginator[RelayListResponse, AsyncSinglePage[RelayListResponse]]: + """Lists all MoQ relays for the account. + + Returns only metadata. Config, status, and + tokens are omitted. + + Results are cursor-paginated (keyset on the `created` timestamp). Use + `created_before` / `created_after` with the `created` value of the first/last + item in a page to fetch the adjacent page. `result_info` reports the page + `count` and the `total` matching the cursor filters. + + Args: + account_id: Cloudflare account identifier. + + asc: Sort order by `created`. When true, results are returned oldest-first + (ascending); otherwise newest-first (descending, the default). + + created_after: Cursor for pagination. Returns relays created strictly after this RFC 3339 + timestamp (typically the `created` value of the last item on the current page, + to fetch the next page). + + created_before: Cursor for pagination. Returns relays created strictly before this RFC 3339 + timestamp (typically the `created` value of the first item on the current page, + to fetch the previous page). + + per_page: Maximum number of relays to return per page. + + 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}/moq/relays", account_id=account_id), + page=AsyncSinglePage[RelayListResponse], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "asc": asc, + "created_after": created_after, + "created_before": created_before, + "per_page": per_page, + }, + relay_list_params.RelayListParams, + ), + ), + model=RelayListResponse, + ) + + async def delete( + self, + relay_id: str, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> object: + """ + Soft-deletes a MoQ relay. + + Args: + account_id: Cloudflare account 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 relay_id: + raise ValueError(f"Expected a non-empty value for `relay_id` but received {relay_id!r}") + return await self._delete( + path_template("/accounts/{account_id}/moq/relays/{relay_id}", account_id=account_id, relay_id=relay_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[object]]._unwrapper, + ), + cast_to=cast(Type[object], ResultWrapper[object]), + ) + + async def get( + self, + relay_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[RelayGetResponse]: + """Retrieves a single MoQ relay including config and status. + + Tokens are NOT + included. + + Args: + account_id: Cloudflare account 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 relay_id: + raise ValueError(f"Expected a non-empty value for `relay_id` but received {relay_id!r}") + return await self._get( + path_template("/accounts/{account_id}/moq/relays/{relay_id}", account_id=account_id, relay_id=relay_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[RelayGetResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[RelayGetResponse]], ResultWrapper[RelayGetResponse]), + ) + + +class RelaysResourceWithRawResponse: + def __init__(self, relays: RelaysResource) -> None: + self._relays = relays + + self.create = to_raw_response_wrapper( + relays.create, + ) + self.update = to_raw_response_wrapper( + relays.update, + ) + self.list = to_raw_response_wrapper( + relays.list, + ) + self.delete = to_raw_response_wrapper( + relays.delete, + ) + self.get = to_raw_response_wrapper( + relays.get, + ) + + @cached_property + def tokens(self) -> TokensResourceWithRawResponse: + return TokensResourceWithRawResponse(self._relays.tokens) + + +class AsyncRelaysResourceWithRawResponse: + def __init__(self, relays: AsyncRelaysResource) -> None: + self._relays = relays + + self.create = async_to_raw_response_wrapper( + relays.create, + ) + self.update = async_to_raw_response_wrapper( + relays.update, + ) + self.list = async_to_raw_response_wrapper( + relays.list, + ) + self.delete = async_to_raw_response_wrapper( + relays.delete, + ) + self.get = async_to_raw_response_wrapper( + relays.get, + ) + + @cached_property + def tokens(self) -> AsyncTokensResourceWithRawResponse: + return AsyncTokensResourceWithRawResponse(self._relays.tokens) + + +class RelaysResourceWithStreamingResponse: + def __init__(self, relays: RelaysResource) -> None: + self._relays = relays + + self.create = to_streamed_response_wrapper( + relays.create, + ) + self.update = to_streamed_response_wrapper( + relays.update, + ) + self.list = to_streamed_response_wrapper( + relays.list, + ) + self.delete = to_streamed_response_wrapper( + relays.delete, + ) + self.get = to_streamed_response_wrapper( + relays.get, + ) + + @cached_property + def tokens(self) -> TokensResourceWithStreamingResponse: + return TokensResourceWithStreamingResponse(self._relays.tokens) + + +class AsyncRelaysResourceWithStreamingResponse: + def __init__(self, relays: AsyncRelaysResource) -> None: + self._relays = relays + + self.create = async_to_streamed_response_wrapper( + relays.create, + ) + self.update = async_to_streamed_response_wrapper( + relays.update, + ) + self.list = async_to_streamed_response_wrapper( + relays.list, + ) + self.delete = async_to_streamed_response_wrapper( + relays.delete, + ) + self.get = async_to_streamed_response_wrapper( + relays.get, + ) + + @cached_property + def tokens(self) -> AsyncTokensResourceWithStreamingResponse: + return AsyncTokensResourceWithStreamingResponse(self._relays.tokens) diff --git a/src/cloudflare/resources/moq/relays/tokens.py b/src/cloudflare/resources/moq/relays/tokens.py new file mode 100644 index 00000000000..c09937159b1 --- /dev/null +++ b/src/cloudflare/resources/moq/relays/tokens.py @@ -0,0 +1,203 @@ +# 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, 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.moq.relays import token_rotate_params +from ....types.moq.relays.token_rotate_response import TokenRotateResponse + +__all__ = ["TokensResource", "AsyncTokensResource"] + + +class TokensResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> TokensResourceWithRawResponse: + """ + 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 TokensResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> TokensResourceWithStreamingResponse: + """ + 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 TokensResourceWithStreamingResponse(self) + + def rotate( + self, + relay_id: str, + *, + account_id: str, + type: Literal["publish_subscribe", "subscribe"], + # 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[TokenRotateResponse]: + """Generates a new token for the specified type. + + The old token is immediately + invalidated. Token value is shown once in the response. + + Args: + account_id: Cloudflare account identifier. + + type: Which token type to rotate. + + 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 relay_id: + raise ValueError(f"Expected a non-empty value for `relay_id` but received {relay_id!r}") + return self._post( + path_template( + "/accounts/{account_id}/moq/relays/{relay_id}/tokens/rotate", account_id=account_id, relay_id=relay_id + ), + body=maybe_transform({"type": type}, token_rotate_params.TokenRotateParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[TokenRotateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[TokenRotateResponse]], ResultWrapper[TokenRotateResponse]), + ) + + +class AsyncTokensResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncTokensResourceWithRawResponse: + """ + 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 AsyncTokensResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncTokensResourceWithStreamingResponse: + """ + 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 AsyncTokensResourceWithStreamingResponse(self) + + async def rotate( + self, + relay_id: str, + *, + account_id: str, + type: Literal["publish_subscribe", "subscribe"], + # 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[TokenRotateResponse]: + """Generates a new token for the specified type. + + The old token is immediately + invalidated. Token value is shown once in the response. + + Args: + account_id: Cloudflare account identifier. + + type: Which token type to rotate. + + 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 relay_id: + raise ValueError(f"Expected a non-empty value for `relay_id` but received {relay_id!r}") + return await self._post( + path_template( + "/accounts/{account_id}/moq/relays/{relay_id}/tokens/rotate", account_id=account_id, relay_id=relay_id + ), + body=await async_maybe_transform({"type": type}, token_rotate_params.TokenRotateParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[TokenRotateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[TokenRotateResponse]], ResultWrapper[TokenRotateResponse]), + ) + + +class TokensResourceWithRawResponse: + def __init__(self, tokens: TokensResource) -> None: + self._tokens = tokens + + self.rotate = to_raw_response_wrapper( + tokens.rotate, + ) + + +class AsyncTokensResourceWithRawResponse: + def __init__(self, tokens: AsyncTokensResource) -> None: + self._tokens = tokens + + self.rotate = async_to_raw_response_wrapper( + tokens.rotate, + ) + + +class TokensResourceWithStreamingResponse: + def __init__(self, tokens: TokensResource) -> None: + self._tokens = tokens + + self.rotate = to_streamed_response_wrapper( + tokens.rotate, + ) + + +class AsyncTokensResourceWithStreamingResponse: + def __init__(self, tokens: AsyncTokensResource) -> None: + self._tokens = tokens + + self.rotate = async_to_streamed_response_wrapper( + tokens.rotate, + ) diff --git a/src/cloudflare/types/email_routing/__init__.py b/src/cloudflare/types/email_routing/__init__.py index 553bab1e508..9eaa27e5189 100644 --- a/src/cloudflare/types/email_routing/__init__.py +++ b/src/cloudflare/types/email_routing/__init__.py @@ -12,7 +12,6 @@ from .dns_get_params import DNSGetParams as DNSGetParams from .dns_edit_params import DNSEditParams as DNSEditParams from .dns_get_response import DNSGetResponse as DNSGetResponse -from .rule_list_params import RuleListParams as RuleListParams from .dns_create_params import DNSCreateParams as DNSCreateParams from .email_routing_rule import EmailRoutingRule as EmailRoutingRule from .rule_create_params import RuleCreateParams as RuleCreateParams diff --git a/src/cloudflare/types/email_routing/rule_list_params.py b/src/cloudflare/types/email_routing/rule_list_params.py deleted file mode 100644 index bb27b3d4885..00000000000 --- a/src/cloudflare/types/email_routing/rule_list_params.py +++ /dev/null @@ -1,21 +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__ = ["RuleListParams"] - - -class RuleListParams(TypedDict, total=False): - zone_id: Required[str] - """Identifier.""" - - enabled: Literal[True, False] - """Filter by enabled routing rules.""" - - page: float - """Page number of paginated results.""" - - per_page: float - """Maximum number of results per page.""" diff --git a/src/cloudflare/types/email_routing/settings.py b/src/cloudflare/types/email_routing/settings.py index 9688cfbe2d1..900c3cfce4d 100644 --- a/src/cloudflare/types/email_routing/settings.py +++ b/src/cloudflare/types/email_routing/settings.py @@ -31,6 +31,12 @@ class Settings(BaseModel): status: Optional[Literal["ready", "unconfigured", "misconfigured", "misconfigured/locked", "unlocked"]] = None """Show the state of your account, and the type or configuration error.""" + support_subaddress: Optional[Literal[True, False]] = None + """ + Whether subaddressing (plus-addressing) is honored when matching incoming mail + against routing rules. + """ + tag: Optional[str] = None """Email Routing settings tag. diff --git a/src/cloudflare/types/email_security/investigate/move_bulk_params.py b/src/cloudflare/types/email_security/investigate/move_bulk_params.py index 35a0e5ac6d6..1942bb4ded6 100644 --- a/src/cloudflare/types/email_security/investigate/move_bulk_params.py +++ b/src/cloudflare/types/email_security/investigate/move_bulk_params.py @@ -17,6 +17,10 @@ class MoveBulkParams(TypedDict, total=False): Literal["Inbox", "JunkEmail", "DeletedItems", "RecoverableItemsDeletions", "RecoverableItemsPurges"] ] + expected_disposition: Literal[ + "MALICIOUS", "MALICIOUS-BEC", "SUSPICIOUS", "SPOOF", "SPAM", "BULK", "ENCRYPTED", "EXTERNAL", "UNKNOWN", "NONE" + ] + ids: SequenceNotStr[str] """List of message IDs to move""" diff --git a/src/cloudflare/types/email_security/investigate/move_create_params.py b/src/cloudflare/types/email_security/investigate/move_create_params.py index 0e389b2ae93..fc7c88c605d 100644 --- a/src/cloudflare/types/email_security/investigate/move_create_params.py +++ b/src/cloudflare/types/email_security/investigate/move_create_params.py @@ -14,3 +14,7 @@ class MoveCreateParams(TypedDict, total=False): destination: Required[ Literal["Inbox", "JunkEmail", "DeletedItems", "RecoverableItemsDeletions", "RecoverableItemsPurges"] ] + + expected_disposition: Literal[ + "MALICIOUS", "MALICIOUS-BEC", "SUSPICIOUS", "SPOOF", "SPAM", "BULK", "ENCRYPTED", "EXTERNAL", "UNKNOWN", "NONE" + ] diff --git a/src/cloudflare/types/moq/__init__.py b/src/cloudflare/types/moq/__init__.py new file mode 100644 index 00000000000..6c12a15de24 --- /dev/null +++ b/src/cloudflare/types/moq/__init__.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .relay_list_params import RelayListParams as RelayListParams +from .relay_get_response import RelayGetResponse as RelayGetResponse +from .relay_create_params import RelayCreateParams as RelayCreateParams +from .relay_list_response import RelayListResponse as RelayListResponse +from .relay_update_params import RelayUpdateParams as RelayUpdateParams +from .relay_create_response import RelayCreateResponse as RelayCreateResponse +from .relay_update_response import RelayUpdateResponse as RelayUpdateResponse diff --git a/src/cloudflare/types/moq/relay_create_params.py b/src/cloudflare/types/moq/relay_create_params.py new file mode 100644 index 00000000000..104c3d032c1 --- /dev/null +++ b/src/cloudflare/types/moq/relay_create_params.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["RelayCreateParams"] + + +class RelayCreateParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account identifier.""" + + name: Required[str] + """Human-readable name for the relay.""" diff --git a/src/cloudflare/types/moq/relay_create_response.py b/src/cloudflare/types/moq/relay_create_response.py new file mode 100644 index 00000000000..1cf2516282e --- /dev/null +++ b/src/cloudflare/types/moq/relay_create_response.py @@ -0,0 +1,69 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime + +from ..._models import BaseModel + +__all__ = [ + "RelayCreateResponse", + "Config", + "ConfigLingeringSubscribe", + "ConfigOriginFallback", + "ConfigOriginFallbackOrigin", +] + + +class ConfigLingeringSubscribe(BaseModel): + enabled: Optional[bool] = None + + max_timeout_ms: Optional[int] = None + """Relay-level ceiling on lingering subscribe timeout (ms). Default 30000.""" + + +class ConfigOriginFallbackOrigin(BaseModel): + """A single upstream origin relay.""" + + url: Optional[str] = None + """Upstream origin relay URL.""" + + +class ConfigOriginFallback(BaseModel): + enabled: Optional[bool] = None + + origins: Optional[List[ConfigOriginFallbackOrigin]] = None + """Ordered list of upstream origin relays. + + Each entry is an object (not a bare string) so per-origin configuration can be + added in the future without another breaking change. + """ + + +class Config(BaseModel): + """origin_fallback and lingering_subscribe are mutually exclusive.""" + + lingering_subscribe: Optional[ConfigLingeringSubscribe] = None + + origin_fallback: Optional[ConfigOriginFallback] = None + + +class RelayCreateResponse(BaseModel): + """Relay with auto-generated tokens (shown once).""" + + config: Config + """origin_fallback and lingering_subscribe are mutually exclusive.""" + + created: datetime + + modified: datetime + + name: str + + token_publish_subscribe: str + """Full access token (publish + subscribe). Treat as sensitive.""" + + token_subscribe: str + """Subscribe-only token. Treat as sensitive.""" + + uid: str + """Server-generated unique identifier (32 hex chars).""" diff --git a/src/cloudflare/types/moq/relay_get_response.py b/src/cloudflare/types/moq/relay_get_response.py new file mode 100644 index 00000000000..b8d008ebd7e --- /dev/null +++ b/src/cloudflare/types/moq/relay_get_response.py @@ -0,0 +1,66 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = [ + "RelayGetResponse", + "Config", + "ConfigLingeringSubscribe", + "ConfigOriginFallback", + "ConfigOriginFallbackOrigin", +] + + +class ConfigLingeringSubscribe(BaseModel): + enabled: Optional[bool] = None + + max_timeout_ms: Optional[int] = None + """Relay-level ceiling on lingering subscribe timeout (ms). Default 30000.""" + + +class ConfigOriginFallbackOrigin(BaseModel): + """A single upstream origin relay.""" + + url: Optional[str] = None + """Upstream origin relay URL.""" + + +class ConfigOriginFallback(BaseModel): + enabled: Optional[bool] = None + + origins: Optional[List[ConfigOriginFallbackOrigin]] = None + """Ordered list of upstream origin relays. + + Each entry is an object (not a bare string) so per-origin configuration can be + added in the future without another breaking change. + """ + + +class Config(BaseModel): + """origin_fallback and lingering_subscribe are mutually exclusive.""" + + lingering_subscribe: Optional[ConfigLingeringSubscribe] = None + + origin_fallback: Optional[ConfigOriginFallback] = None + + +class RelayGetResponse(BaseModel): + """Full relay details (no tokens).""" + + config: Config + """origin_fallback and lingering_subscribe are mutually exclusive.""" + + created: datetime + + modified: datetime + + name: str + + uid: str + + status: Optional[Literal["connected"]] = None + """\"connected" when active, omitted otherwise.""" diff --git a/src/cloudflare/types/moq/relay_list_params.py b/src/cloudflare/types/moq/relay_list_params.py new file mode 100644 index 00000000000..6abd6a25248 --- /dev/null +++ b/src/cloudflare/types/moq/relay_list_params.py @@ -0,0 +1,41 @@ +# 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 Required, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["RelayListParams"] + + +class RelayListParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account identifier.""" + + asc: bool + """Sort order by `created`. + + When true, results are returned oldest-first (ascending); otherwise newest-first + (descending, the default). + """ + + created_after: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """Cursor for pagination. + + Returns relays created strictly after this RFC 3339 timestamp (typically the + `created` value of the last item on the current page, to fetch the next page). + """ + + created_before: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] + """Cursor for pagination. + + Returns relays created strictly before this RFC 3339 timestamp (typically the + `created` value of the first item on the current page, to fetch the previous + page). + """ + + per_page: int + """Maximum number of relays to return per page.""" diff --git a/src/cloudflare/types/moq/relay_list_response.py b/src/cloudflare/types/moq/relay_list_response.py new file mode 100644 index 00000000000..00576f6b42a --- /dev/null +++ b/src/cloudflare/types/moq/relay_list_response.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from datetime import datetime + +from ..._models import BaseModel + +__all__ = ["RelayListResponse"] + + +class RelayListResponse(BaseModel): + """Abbreviated relay for list responses.""" + + created: datetime + + modified: datetime + + name: str + + uid: str diff --git a/src/cloudflare/types/moq/relay_update_params.py b/src/cloudflare/types/moq/relay_update_params.py new file mode 100644 index 00000000000..1a00e6e8cf2 --- /dev/null +++ b/src/cloudflare/types/moq/relay_update_params.py @@ -0,0 +1,57 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable +from typing_extensions import Required, TypedDict + +__all__ = [ + "RelayUpdateParams", + "Config", + "ConfigLingeringSubscribe", + "ConfigOriginFallback", + "ConfigOriginFallbackOrigin", +] + + +class RelayUpdateParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account identifier.""" + + config: Config + """origin_fallback and lingering_subscribe are mutually exclusive.""" + + name: str + + +class ConfigLingeringSubscribe(TypedDict, total=False): + enabled: bool + + max_timeout_ms: int + """Relay-level ceiling on lingering subscribe timeout (ms). Default 30000.""" + + +class ConfigOriginFallbackOrigin(TypedDict, total=False): + """A single upstream origin relay.""" + + url: str + """Upstream origin relay URL.""" + + +class ConfigOriginFallback(TypedDict, total=False): + enabled: bool + + origins: Iterable[ConfigOriginFallbackOrigin] + """Ordered list of upstream origin relays. + + Each entry is an object (not a bare string) so per-origin configuration can be + added in the future without another breaking change. + """ + + +class Config(TypedDict, total=False): + """origin_fallback and lingering_subscribe are mutually exclusive.""" + + lingering_subscribe: ConfigLingeringSubscribe + + origin_fallback: ConfigOriginFallback diff --git a/src/cloudflare/types/moq/relay_update_response.py b/src/cloudflare/types/moq/relay_update_response.py new file mode 100644 index 00000000000..10e35818945 --- /dev/null +++ b/src/cloudflare/types/moq/relay_update_response.py @@ -0,0 +1,66 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = [ + "RelayUpdateResponse", + "Config", + "ConfigLingeringSubscribe", + "ConfigOriginFallback", + "ConfigOriginFallbackOrigin", +] + + +class ConfigLingeringSubscribe(BaseModel): + enabled: Optional[bool] = None + + max_timeout_ms: Optional[int] = None + """Relay-level ceiling on lingering subscribe timeout (ms). Default 30000.""" + + +class ConfigOriginFallbackOrigin(BaseModel): + """A single upstream origin relay.""" + + url: Optional[str] = None + """Upstream origin relay URL.""" + + +class ConfigOriginFallback(BaseModel): + enabled: Optional[bool] = None + + origins: Optional[List[ConfigOriginFallbackOrigin]] = None + """Ordered list of upstream origin relays. + + Each entry is an object (not a bare string) so per-origin configuration can be + added in the future without another breaking change. + """ + + +class Config(BaseModel): + """origin_fallback and lingering_subscribe are mutually exclusive.""" + + lingering_subscribe: Optional[ConfigLingeringSubscribe] = None + + origin_fallback: Optional[ConfigOriginFallback] = None + + +class RelayUpdateResponse(BaseModel): + """Full relay details (no tokens).""" + + config: Config + """origin_fallback and lingering_subscribe are mutually exclusive.""" + + created: datetime + + modified: datetime + + name: str + + uid: str + + status: Optional[Literal["connected"]] = None + """\"connected" when active, omitted otherwise.""" diff --git a/src/cloudflare/types/moq/relays/__init__.py b/src/cloudflare/types/moq/relays/__init__.py new file mode 100644 index 00000000000..e1548b499d4 --- /dev/null +++ b/src/cloudflare/types/moq/relays/__init__.py @@ -0,0 +1,6 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .token_rotate_params import TokenRotateParams as TokenRotateParams +from .token_rotate_response import TokenRotateResponse as TokenRotateResponse diff --git a/src/cloudflare/types/moq/relays/token_rotate_params.py b/src/cloudflare/types/moq/relays/token_rotate_params.py new file mode 100644 index 00000000000..07611c3cffc --- /dev/null +++ b/src/cloudflare/types/moq/relays/token_rotate_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__ = ["TokenRotateParams"] + + +class TokenRotateParams(TypedDict, total=False): + account_id: Required[str] + """Cloudflare account identifier.""" + + type: Required[Literal["publish_subscribe", "subscribe"]] + """Which token type to rotate.""" diff --git a/src/cloudflare/types/moq/relays/token_rotate_response.py b/src/cloudflare/types/moq/relays/token_rotate_response.py new file mode 100644 index 00000000000..5f71a3081dc --- /dev/null +++ b/src/cloudflare/types/moq/relays/token_rotate_response.py @@ -0,0 +1,14 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = ["TokenRotateResponse"] + + +class TokenRotateResponse(BaseModel): + token: str + """New token value (shown once). Treat as sensitive.""" + + type: Literal["publish_subscribe", "subscribe"] diff --git a/src/cloudflare/types/rulesets/rule_create_params.py b/src/cloudflare/types/rulesets/rule_create_params.py index 6a8c82757e1..9c5b7d9ea6b 100644 --- a/src/cloudflare/types/rulesets/rule_create_params.py +++ b/src/cloudflare/types/rulesets/rule_create_params.py @@ -220,6 +220,9 @@ "SetCacheSettingsRuleActionParametersEdgeTTLStatusCodeTTLStatusCodeRange", "SetCacheSettingsRuleActionParametersServeStale", "SetCacheSettingsRuleActionParametersSharedDictionary", + "SetCacheSettingsRuleActionParametersVary", + "SetCacheSettingsRuleActionParametersVaryDefault", + "SetCacheSettingsRuleActionParametersVaryHeaders", "SetCacheSettingsRuleExposedCredentialCheck", "SetCacheSettingsRulePosition", "SetCacheSettingsRulePositionBeforePosition", @@ -3425,6 +3428,64 @@ class SetCacheSettingsRuleActionParametersSharedDictionary(TypedDict, total=Fals """ +class SetCacheSettingsRuleActionParametersVaryDefault(TypedDict, total=False): + """ + Controls how a single request header (or the default for all headers) contributes to the cache key. + """ + + action: Required[Literal["bypass", "passthrough", "normalize"]] + """How the header value is treated when building the cache key.""" + + languages: SequenceNotStr[str] + """The set of languages to normalize against. + + Only valid for the `accept-language` header. + """ + + media_types: SequenceNotStr[str] + """The set of media types to normalize against. + + Only valid for the `accept` header. + """ + + +class SetCacheSettingsRuleActionParametersVaryHeaders(TypedDict, total=False): + """ + Controls how a single request header (or the default for all headers) contributes to the cache key. + """ + + action: Required[Literal["bypass", "passthrough", "normalize"]] + """How the header value is treated when building the cache key.""" + + languages: SequenceNotStr[str] + """The set of languages to normalize against. + + Only valid for the `accept-language` header. + """ + + media_types: SequenceNotStr[str] + """The set of media types to normalize against. + + Only valid for the `accept` header. + """ + + +class SetCacheSettingsRuleActionParametersVary(TypedDict, total=False): + """Controls how cached responses vary based on request headers. + + At least one of `default` or `headers` must be set, and `default` is required when `headers` is set. + """ + + default: SetCacheSettingsRuleActionParametersVaryDefault + """ + Controls how a single request header (or the default for all headers) + contributes to the cache key. + """ + + headers: Dict[str, SetCacheSettingsRuleActionParametersVaryHeaders] + """A mapping of lowercase request header names to their vary configuration.""" + + class SetCacheSettingsRuleActionParameters(TypedDict, total=False): """The parameters configuring the rule's action.""" @@ -3500,6 +3561,13 @@ class SetCacheSettingsRuleActionParameters(TypedDict, total=False): strip_set_cookie: bool """Whether to strip Set-Cookie headers from the origin response before caching.""" + vary: SetCacheSettingsRuleActionParametersVary + """Controls how cached responses vary based on request headers. + + At least one of `default` or `headers` must be set, and `default` is required + when `headers` is set. + """ + class SetCacheSettingsRuleExposedCredentialCheck(TypedDict, total=False): """Configuration for exposed credential checking.""" diff --git a/src/cloudflare/types/rulesets/rule_edit_params.py b/src/cloudflare/types/rulesets/rule_edit_params.py index c914421bbdf..272ed9c3a2f 100644 --- a/src/cloudflare/types/rulesets/rule_edit_params.py +++ b/src/cloudflare/types/rulesets/rule_edit_params.py @@ -220,6 +220,9 @@ "SetCacheSettingsRuleActionParametersEdgeTTLStatusCodeTTLStatusCodeRange", "SetCacheSettingsRuleActionParametersServeStale", "SetCacheSettingsRuleActionParametersSharedDictionary", + "SetCacheSettingsRuleActionParametersVary", + "SetCacheSettingsRuleActionParametersVaryDefault", + "SetCacheSettingsRuleActionParametersVaryHeaders", "SetCacheSettingsRuleExposedCredentialCheck", "SetCacheSettingsRulePosition", "SetCacheSettingsRulePositionBeforePosition", @@ -3476,6 +3479,64 @@ class SetCacheSettingsRuleActionParametersSharedDictionary(TypedDict, total=Fals """ +class SetCacheSettingsRuleActionParametersVaryDefault(TypedDict, total=False): + """ + Controls how a single request header (or the default for all headers) contributes to the cache key. + """ + + action: Required[Literal["bypass", "passthrough", "normalize"]] + """How the header value is treated when building the cache key.""" + + languages: SequenceNotStr[str] + """The set of languages to normalize against. + + Only valid for the `accept-language` header. + """ + + media_types: SequenceNotStr[str] + """The set of media types to normalize against. + + Only valid for the `accept` header. + """ + + +class SetCacheSettingsRuleActionParametersVaryHeaders(TypedDict, total=False): + """ + Controls how a single request header (or the default for all headers) contributes to the cache key. + """ + + action: Required[Literal["bypass", "passthrough", "normalize"]] + """How the header value is treated when building the cache key.""" + + languages: SequenceNotStr[str] + """The set of languages to normalize against. + + Only valid for the `accept-language` header. + """ + + media_types: SequenceNotStr[str] + """The set of media types to normalize against. + + Only valid for the `accept` header. + """ + + +class SetCacheSettingsRuleActionParametersVary(TypedDict, total=False): + """Controls how cached responses vary based on request headers. + + At least one of `default` or `headers` must be set, and `default` is required when `headers` is set. + """ + + default: SetCacheSettingsRuleActionParametersVaryDefault + """ + Controls how a single request header (or the default for all headers) + contributes to the cache key. + """ + + headers: Dict[str, SetCacheSettingsRuleActionParametersVaryHeaders] + """A mapping of lowercase request header names to their vary configuration.""" + + class SetCacheSettingsRuleActionParameters(TypedDict, total=False): """The parameters configuring the rule's action.""" @@ -3551,6 +3612,13 @@ class SetCacheSettingsRuleActionParameters(TypedDict, total=False): strip_set_cookie: bool """Whether to strip Set-Cookie headers from the origin response before caching.""" + vary: SetCacheSettingsRuleActionParametersVary + """Controls how cached responses vary based on request headers. + + At least one of `default` or `headers` must be set, and `default` is required + when `headers` is set. + """ + class SetCacheSettingsRuleExposedCredentialCheck(TypedDict, total=False): """Configuration for exposed credential checking.""" diff --git a/src/cloudflare/types/rulesets/set_cache_settings_rule.py b/src/cloudflare/types/rulesets/set_cache_settings_rule.py index 8b1f40e5af7..c5c8c06032f 100644 --- a/src/cloudflare/types/rulesets/set_cache_settings_rule.py +++ b/src/cloudflare/types/rulesets/set_cache_settings_rule.py @@ -28,6 +28,9 @@ "ActionParametersEdgeTTLStatusCodeTTLStatusCodeRange", "ActionParametersServeStale", "ActionParametersSharedDictionary", + "ActionParametersVary", + "ActionParametersVaryDefault", + "ActionParametersVaryHeaders", "ExposedCredentialCheck", "Ratelimit", ] @@ -253,6 +256,64 @@ class ActionParametersSharedDictionary(BaseModel): """ +class ActionParametersVaryDefault(BaseModel): + """ + Controls how a single request header (or the default for all headers) contributes to the cache key. + """ + + action: Literal["bypass", "passthrough", "normalize"] + """How the header value is treated when building the cache key.""" + + languages: Optional[List[str]] = None + """The set of languages to normalize against. + + Only valid for the `accept-language` header. + """ + + media_types: Optional[List[str]] = None + """The set of media types to normalize against. + + Only valid for the `accept` header. + """ + + +class ActionParametersVaryHeaders(BaseModel): + """ + Controls how a single request header (or the default for all headers) contributes to the cache key. + """ + + action: Literal["bypass", "passthrough", "normalize"] + """How the header value is treated when building the cache key.""" + + languages: Optional[List[str]] = None + """The set of languages to normalize against. + + Only valid for the `accept-language` header. + """ + + media_types: Optional[List[str]] = None + """The set of media types to normalize against. + + Only valid for the `accept` header. + """ + + +class ActionParametersVary(BaseModel): + """Controls how cached responses vary based on request headers. + + At least one of `default` or `headers` must be set, and `default` is required when `headers` is set. + """ + + default: Optional[ActionParametersVaryDefault] = None + """ + Controls how a single request header (or the default for all headers) + contributes to the cache key. + """ + + headers: Optional[Dict[str, ActionParametersVaryHeaders]] = None + """A mapping of lowercase request header names to their vary configuration.""" + + class ActionParameters(BaseModel): """The parameters configuring the rule's action.""" @@ -328,6 +389,13 @@ class ActionParameters(BaseModel): strip_set_cookie: Optional[bool] = None """Whether to strip Set-Cookie headers from the origin response before caching.""" + vary: Optional[ActionParametersVary] = None + """Controls how cached responses vary based on request headers. + + At least one of `default` or `headers` must be set, and `default` is required + when `headers` is set. + """ + class ExposedCredentialCheck(BaseModel): """Configuration for exposed credential checking.""" diff --git a/src/cloudflare/types/rulesets/set_cache_settings_rule_param.py b/src/cloudflare/types/rulesets/set_cache_settings_rule_param.py index b223d45297d..3ed01b1a11e 100644 --- a/src/cloudflare/types/rulesets/set_cache_settings_rule_param.py +++ b/src/cloudflare/types/rulesets/set_cache_settings_rule_param.py @@ -27,6 +27,9 @@ "ActionParametersEdgeTTLStatusCodeTTLStatusCodeRange", "ActionParametersServeStale", "ActionParametersSharedDictionary", + "ActionParametersVary", + "ActionParametersVaryDefault", + "ActionParametersVaryHeaders", "ExposedCredentialCheck", "Ratelimit", ] @@ -260,6 +263,64 @@ class ActionParametersSharedDictionary(TypedDict, total=False): """ +class ActionParametersVaryDefault(TypedDict, total=False): + """ + Controls how a single request header (or the default for all headers) contributes to the cache key. + """ + + action: Required[Literal["bypass", "passthrough", "normalize"]] + """How the header value is treated when building the cache key.""" + + languages: SequenceNotStr[str] + """The set of languages to normalize against. + + Only valid for the `accept-language` header. + """ + + media_types: SequenceNotStr[str] + """The set of media types to normalize against. + + Only valid for the `accept` header. + """ + + +class ActionParametersVaryHeaders(TypedDict, total=False): + """ + Controls how a single request header (or the default for all headers) contributes to the cache key. + """ + + action: Required[Literal["bypass", "passthrough", "normalize"]] + """How the header value is treated when building the cache key.""" + + languages: SequenceNotStr[str] + """The set of languages to normalize against. + + Only valid for the `accept-language` header. + """ + + media_types: SequenceNotStr[str] + """The set of media types to normalize against. + + Only valid for the `accept` header. + """ + + +class ActionParametersVary(TypedDict, total=False): + """Controls how cached responses vary based on request headers. + + At least one of `default` or `headers` must be set, and `default` is required when `headers` is set. + """ + + default: ActionParametersVaryDefault + """ + Controls how a single request header (or the default for all headers) + contributes to the cache key. + """ + + headers: Dict[str, ActionParametersVaryHeaders] + """A mapping of lowercase request header names to their vary configuration.""" + + class ActionParameters(TypedDict, total=False): """The parameters configuring the rule's action.""" @@ -335,6 +396,13 @@ class ActionParameters(TypedDict, total=False): strip_set_cookie: bool """Whether to strip Set-Cookie headers from the origin response before caching.""" + vary: ActionParametersVary + """Controls how cached responses vary based on request headers. + + At least one of `default` or `headers` must be set, and `default` is required + when `headers` is set. + """ + class ExposedCredentialCheck(TypedDict, total=False): """Configuration for exposed credential checking.""" diff --git a/tests/api_resources/email_routing/test_rules.py b/tests/api_resources/email_routing/test_rules.py index 33b96b74828..03090d5bfc2 100644 --- a/tests/api_resources/email_routing/test_rules.py +++ b/tests/api_resources/email_routing/test_rules.py @@ -9,7 +9,6 @@ from cloudflare import Cloudflare, AsyncCloudflare from tests.utils import assert_matches_type -from cloudflare.pagination import SyncV4PagePaginationArray, AsyncV4PagePaginationArray from cloudflare.types.email_routing import EmailRoutingRule base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -169,54 +168,6 @@ def test_path_params_update(self, client: Cloudflare) -> None: matchers=[{"type": "literal"}], ) - @parametrize - def test_method_list(self, client: Cloudflare) -> None: - rule = client.email_routing.rules.list( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - assert_matches_type(SyncV4PagePaginationArray[EmailRoutingRule], rule, path=["response"]) - - @parametrize - def test_method_list_with_all_params(self, client: Cloudflare) -> None: - rule = client.email_routing.rules.list( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - enabled=True, - page=1, - per_page=5, - ) - assert_matches_type(SyncV4PagePaginationArray[EmailRoutingRule], rule, path=["response"]) - - @parametrize - def test_raw_response_list(self, client: Cloudflare) -> None: - response = client.email_routing.rules.with_raw_response.list( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - rule = response.parse() - assert_matches_type(SyncV4PagePaginationArray[EmailRoutingRule], rule, path=["response"]) - - @parametrize - def test_streaming_response_list(self, client: Cloudflare) -> None: - with client.email_routing.rules.with_streaming_response.list( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - rule = response.parse() - assert_matches_type(SyncV4PagePaginationArray[EmailRoutingRule], rule, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_list(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): - client.email_routing.rules.with_raw_response.list( - zone_id="", - ) - @parametrize def test_method_delete(self, client: Cloudflare) -> None: rule = client.email_routing.rules.delete( @@ -470,54 +421,6 @@ async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: matchers=[{"type": "literal"}], ) - @parametrize - async def test_method_list(self, async_client: AsyncCloudflare) -> None: - rule = await async_client.email_routing.rules.list( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - assert_matches_type(AsyncV4PagePaginationArray[EmailRoutingRule], rule, path=["response"]) - - @parametrize - async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: - rule = await async_client.email_routing.rules.list( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - enabled=True, - page=1, - per_page=5, - ) - assert_matches_type(AsyncV4PagePaginationArray[EmailRoutingRule], rule, path=["response"]) - - @parametrize - async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: - response = await async_client.email_routing.rules.with_raw_response.list( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - rule = await response.parse() - assert_matches_type(AsyncV4PagePaginationArray[EmailRoutingRule], rule, path=["response"]) - - @parametrize - async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: - async with async_client.email_routing.rules.with_streaming_response.list( - zone_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - rule = await response.parse() - assert_matches_type(AsyncV4PagePaginationArray[EmailRoutingRule], rule, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - async def test_path_params_list(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): - await async_client.email_routing.rules.with_raw_response.list( - zone_id="", - ) - @parametrize async def test_method_delete(self, async_client: AsyncCloudflare) -> None: rule = await async_client.email_routing.rules.delete( diff --git a/tests/api_resources/email_security/investigate/test_move.py b/tests/api_resources/email_security/investigate/test_move.py index cf738cea491..19eadebcef0 100644 --- a/tests/api_resources/email_security/investigate/test_move.py +++ b/tests/api_resources/email_security/investigate/test_move.py @@ -30,6 +30,16 @@ def test_method_create(self, client: Cloudflare) -> None: ) assert_matches_type(SyncSinglePage[MoveCreateResponse], move, path=["response"]) + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + move = client.email_security.investigate.move.create( + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + destination="Inbox", + expected_disposition="MALICIOUS", + ) + assert_matches_type(SyncSinglePage[MoveCreateResponse], move, path=["response"]) + @parametrize def test_raw_response_create(self, client: Cloudflare) -> None: response = client.email_security.investigate.move.with_raw_response.create( @@ -87,6 +97,7 @@ def test_method_bulk_with_all_params(self, client: Cloudflare) -> None: move = client.email_security.investigate.move.bulk( account_id="023e105f4ecef8ad9ca31a8372d0c353", destination="Inbox", + expected_disposition="MALICIOUS", ids=["4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678"], postfix_ids=["4Njp3P0STMz2c02Q"], ) @@ -141,6 +152,16 @@ async def test_method_create(self, async_client: AsyncCloudflare) -> None: ) assert_matches_type(AsyncSinglePage[MoveCreateResponse], move, path=["response"]) + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + move = await async_client.email_security.investigate.move.create( + investigate_id="4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + destination="Inbox", + expected_disposition="MALICIOUS", + ) + assert_matches_type(AsyncSinglePage[MoveCreateResponse], move, path=["response"]) + @parametrize async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: response = await async_client.email_security.investigate.move.with_raw_response.create( @@ -198,6 +219,7 @@ async def test_method_bulk_with_all_params(self, async_client: AsyncCloudflare) move = await async_client.email_security.investigate.move.bulk( account_id="023e105f4ecef8ad9ca31a8372d0c353", destination="Inbox", + expected_disposition="MALICIOUS", ids=["4Njp3P0STMz2c02Q-2024-01-05T10:00:00-12345678"], postfix_ids=["4Njp3P0STMz2c02Q"], ) diff --git a/tests/api_resources/moq/__init__.py b/tests/api_resources/moq/__init__.py new file mode 100644 index 00000000000..fd8019a9a1a --- /dev/null +++ b/tests/api_resources/moq/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/moq/relays/__init__.py b/tests/api_resources/moq/relays/__init__.py new file mode 100644 index 00000000000..fd8019a9a1a --- /dev/null +++ b/tests/api_resources/moq/relays/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/moq/relays/test_tokens.py b/tests/api_resources/moq/relays/test_tokens.py new file mode 100644 index 00000000000..f39caa3990e --- /dev/null +++ b/tests/api_resources/moq/relays/test_tokens.py @@ -0,0 +1,130 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, Optional, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.types.moq.relays import TokenRotateResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestTokens: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_rotate(self, client: Cloudflare) -> None: + token = client.moq.relays.tokens.rotate( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + type="publish_subscribe", + ) + assert_matches_type(Optional[TokenRotateResponse], token, path=["response"]) + + @parametrize + def test_raw_response_rotate(self, client: Cloudflare) -> None: + response = client.moq.relays.tokens.with_raw_response.rotate( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + type="publish_subscribe", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + token = response.parse() + assert_matches_type(Optional[TokenRotateResponse], token, path=["response"]) + + @parametrize + def test_streaming_response_rotate(self, client: Cloudflare) -> None: + with client.moq.relays.tokens.with_streaming_response.rotate( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + type="publish_subscribe", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + token = response.parse() + assert_matches_type(Optional[TokenRotateResponse], token, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_rotate(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.moq.relays.tokens.with_raw_response.rotate( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="", + type="publish_subscribe", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `relay_id` but received ''"): + client.moq.relays.tokens.with_raw_response.rotate( + relay_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + type="publish_subscribe", + ) + + +class TestAsyncTokens: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_rotate(self, async_client: AsyncCloudflare) -> None: + token = await async_client.moq.relays.tokens.rotate( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + type="publish_subscribe", + ) + assert_matches_type(Optional[TokenRotateResponse], token, path=["response"]) + + @parametrize + async def test_raw_response_rotate(self, async_client: AsyncCloudflare) -> None: + response = await async_client.moq.relays.tokens.with_raw_response.rotate( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + type="publish_subscribe", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + token = await response.parse() + assert_matches_type(Optional[TokenRotateResponse], token, path=["response"]) + + @parametrize + async def test_streaming_response_rotate(self, async_client: AsyncCloudflare) -> None: + async with async_client.moq.relays.tokens.with_streaming_response.rotate( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + type="publish_subscribe", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + token = await response.parse() + assert_matches_type(Optional[TokenRotateResponse], token, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_rotate(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.moq.relays.tokens.with_raw_response.rotate( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="", + type="publish_subscribe", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `relay_id` but received ''"): + await async_client.moq.relays.tokens.with_raw_response.rotate( + relay_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + type="publish_subscribe", + ) diff --git a/tests/api_resources/moq/test_relays.py b/tests/api_resources/moq/test_relays.py new file mode 100644 index 00000000000..ca73a9d4df8 --- /dev/null +++ b/tests/api_resources/moq/test_relays.py @@ -0,0 +1,539 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, Optional, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare._utils import parse_datetime +from cloudflare.types.moq import ( + RelayGetResponse, + RelayListResponse, + RelayCreateResponse, + RelayUpdateResponse, +) +from cloudflare.pagination import SyncSinglePage, AsyncSinglePage + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestRelays: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + relay = client.moq.relays.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Production Live Stream", + ) + assert_matches_type(Optional[RelayCreateResponse], relay, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.moq.relays.with_raw_response.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Production Live Stream", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + relay = response.parse() + assert_matches_type(Optional[RelayCreateResponse], relay, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.moq.relays.with_streaming_response.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Production Live Stream", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + relay = response.parse() + assert_matches_type(Optional[RelayCreateResponse], relay, 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.moq.relays.with_raw_response.create( + account_id="", + name="Production Live Stream", + ) + + @parametrize + def test_method_update(self, client: Cloudflare) -> None: + relay = client.moq.relays.update( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[RelayUpdateResponse], relay, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: Cloudflare) -> None: + relay = client.moq.relays.update( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + config={ + "lingering_subscribe": { + "enabled": True, + "max_timeout_ms": 0, + }, + "origin_fallback": { + "enabled": True, + "origins": [{"url": "url"}], + }, + }, + name="name", + ) + assert_matches_type(Optional[RelayUpdateResponse], relay, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Cloudflare) -> None: + response = client.moq.relays.with_raw_response.update( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + relay = response.parse() + assert_matches_type(Optional[RelayUpdateResponse], relay, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Cloudflare) -> None: + with client.moq.relays.with_streaming_response.update( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + relay = response.parse() + assert_matches_type(Optional[RelayUpdateResponse], relay, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_update(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.moq.relays.with_raw_response.update( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `relay_id` but received ''"): + client.moq.relays.with_raw_response.update( + relay_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + relay = client.moq.relays.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(SyncSinglePage[RelayListResponse], relay, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: Cloudflare) -> None: + relay = client.moq.relays.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + asc=True, + created_after=parse_datetime("2026-03-27T15:00:00Z"), + created_before=parse_datetime("2026-03-27T15:00:00Z"), + per_page=50, + ) + assert_matches_type(SyncSinglePage[RelayListResponse], relay, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.moq.relays.with_raw_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + relay = response.parse() + assert_matches_type(SyncSinglePage[RelayListResponse], relay, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.moq.relays.with_streaming_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + relay = response.parse() + assert_matches_type(SyncSinglePage[RelayListResponse], relay, 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.moq.relays.with_raw_response.list( + account_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + relay = client.moq.relays.delete( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(object, relay, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.moq.relays.with_raw_response.delete( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + relay = response.parse() + assert_matches_type(object, relay, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.moq.relays.with_streaming_response.delete( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + relay = response.parse() + assert_matches_type(object, relay, 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.moq.relays.with_raw_response.delete( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `relay_id` but received ''"): + client.moq.relays.with_raw_response.delete( + relay_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + relay = client.moq.relays.get( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[RelayGetResponse], relay, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.moq.relays.with_raw_response.get( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + relay = response.parse() + assert_matches_type(Optional[RelayGetResponse], relay, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.moq.relays.with_streaming_response.get( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + relay = response.parse() + assert_matches_type(Optional[RelayGetResponse], relay, 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.moq.relays.with_raw_response.get( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `relay_id` but received ''"): + client.moq.relays.with_raw_response.get( + relay_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + +class TestAsyncRelays: + 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: + relay = await async_client.moq.relays.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Production Live Stream", + ) + assert_matches_type(Optional[RelayCreateResponse], relay, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.moq.relays.with_raw_response.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Production Live Stream", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + relay = await response.parse() + assert_matches_type(Optional[RelayCreateResponse], relay, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.moq.relays.with_streaming_response.create( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + name="Production Live Stream", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + relay = await response.parse() + assert_matches_type(Optional[RelayCreateResponse], relay, 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.moq.relays.with_raw_response.create( + account_id="", + name="Production Live Stream", + ) + + @parametrize + async def test_method_update(self, async_client: AsyncCloudflare) -> None: + relay = await async_client.moq.relays.update( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[RelayUpdateResponse], relay, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncCloudflare) -> None: + relay = await async_client.moq.relays.update( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + config={ + "lingering_subscribe": { + "enabled": True, + "max_timeout_ms": 0, + }, + "origin_fallback": { + "enabled": True, + "origins": [{"url": "url"}], + }, + }, + name="name", + ) + assert_matches_type(Optional[RelayUpdateResponse], relay, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncCloudflare) -> None: + response = await async_client.moq.relays.with_raw_response.update( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + relay = await response.parse() + assert_matches_type(Optional[RelayUpdateResponse], relay, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncCloudflare) -> None: + async with async_client.moq.relays.with_streaming_response.update( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + relay = await response.parse() + assert_matches_type(Optional[RelayUpdateResponse], relay, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_update(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.moq.relays.with_raw_response.update( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `relay_id` but received ''"): + await async_client.moq.relays.with_raw_response.update( + relay_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + relay = await async_client.moq.relays.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(AsyncSinglePage[RelayListResponse], relay, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncCloudflare) -> None: + relay = await async_client.moq.relays.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + asc=True, + created_after=parse_datetime("2026-03-27T15:00:00Z"), + created_before=parse_datetime("2026-03-27T15:00:00Z"), + per_page=50, + ) + assert_matches_type(AsyncSinglePage[RelayListResponse], relay, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.moq.relays.with_raw_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + relay = await response.parse() + assert_matches_type(AsyncSinglePage[RelayListResponse], relay, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.moq.relays.with_streaming_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + relay = await response.parse() + assert_matches_type(AsyncSinglePage[RelayListResponse], relay, 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.moq.relays.with_raw_response.list( + account_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + relay = await async_client.moq.relays.delete( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(object, relay, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.moq.relays.with_raw_response.delete( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + relay = await response.parse() + assert_matches_type(object, relay, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.moq.relays.with_streaming_response.delete( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + relay = await response.parse() + assert_matches_type(object, relay, 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.moq.relays.with_raw_response.delete( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `relay_id` but received ''"): + await async_client.moq.relays.with_raw_response.delete( + relay_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + relay = await async_client.moq.relays.get( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[RelayGetResponse], relay, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.moq.relays.with_raw_response.get( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + relay = await response.parse() + assert_matches_type(Optional[RelayGetResponse], relay, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.moq.relays.with_streaming_response.get( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + relay = await response.parse() + assert_matches_type(Optional[RelayGetResponse], relay, 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.moq.relays.with_raw_response.get( + relay_id="a1b2c3d4e5f67890a1b2c3d4e5f67890", + account_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `relay_id` but received ''"): + await async_client.moq.relays.with_raw_response.get( + relay_id="", + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) diff --git a/tests/api_resources/rulesets/test_rules.py b/tests/api_resources/rulesets/test_rules.py index 0270791a0b1..2b88ce437de 100644 --- a/tests/api_resources/rulesets/test_rules.py +++ b/tests/api_resources/rulesets/test_rules.py @@ -1688,6 +1688,20 @@ def test_method_create_with_all_params_overload_17(self, client: Cloudflare) -> "strip_etags": True, "strip_last_modified": True, "strip_set_cookie": True, + "vary": { + "default": { + "action": "normalize", + "languages": ["en"], + "media_types": ["image/webp"], + }, + "headers": { + "accept": { + "action": "normalize", + "languages": ["en"], + "media_types": ["image/webp", "image/png"], + } + }, + }, }, description="Configure settings for how the response is cached.", enabled=True, @@ -4042,6 +4056,20 @@ def test_method_edit_with_all_params_overload_17(self, client: Cloudflare) -> No "strip_etags": True, "strip_last_modified": True, "strip_set_cookie": True, + "vary": { + "default": { + "action": "normalize", + "languages": ["en"], + "media_types": ["image/webp"], + }, + "headers": { + "accept": { + "action": "normalize", + "languages": ["en"], + "media_types": ["image/webp", "image/png"], + } + }, + }, }, description="Configure settings for how the response is cached.", enabled=True, @@ -6149,6 +6177,20 @@ async def test_method_create_with_all_params_overload_17(self, async_client: Asy "strip_etags": True, "strip_last_modified": True, "strip_set_cookie": True, + "vary": { + "default": { + "action": "normalize", + "languages": ["en"], + "media_types": ["image/webp"], + }, + "headers": { + "accept": { + "action": "normalize", + "languages": ["en"], + "media_types": ["image/webp", "image/png"], + } + }, + }, }, description="Configure settings for how the response is cached.", enabled=True, @@ -8503,6 +8545,20 @@ async def test_method_edit_with_all_params_overload_17(self, async_client: Async "strip_etags": True, "strip_last_modified": True, "strip_set_cookie": True, + "vary": { + "default": { + "action": "normalize", + "languages": ["en"], + "media_types": ["image/webp"], + }, + "headers": { + "accept": { + "action": "normalize", + "languages": ["en"], + "media_types": ["image/webp", "image/png"], + } + }, + }, }, description="Configure settings for how the response is cached.", enabled=True,