diff --git a/.stats.yml b/.stats.yml index ca71746c0ec..67bc894f95f 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: 2412 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare/cloudflare-ee348bae3bc19d58249c0a0334ea1be47869fd3c73ea0cbbf505f185acc85393.yml +openapi_spec_hash: ce574d5447a6a01dde1d36709a279533 +config_hash: a23f4c71ccd6c6117c24f63ae415dcf7 diff --git a/api.md b/api.md index b05e7b8d057..1abe5e33c0f 100644 --- a/api.md +++ b/api.md @@ -75,6 +75,8 @@ from cloudflare.types import ( # [EmailSecurity](src/cloudflare/resources/email_security/api.md) +# [EmailAuth](src/cloudflare/resources/email_auth/api.md) + # [EmailRouting](src/cloudflare/resources/email_routing/api.md) # [EmailSending](src/cloudflare/resources/email_sending/api.md) @@ -211,6 +213,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..51991d7bc79 100644 --- a/src/cloudflare/_client.py +++ b/src/cloudflare/_client.py @@ -47,6 +47,7 @@ dns, iam, ips, + moq, rum, ssl, argo, @@ -88,6 +89,7 @@ addressing, ai_gateway, audit_logs, + email_auth, hyperdrive, page_rules, zero_trust, @@ -163,6 +165,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 @@ -204,6 +207,7 @@ from .resources.addressing.addressing import AddressingResource, AsyncAddressingResource from .resources.ai_gateway.ai_gateway import AIGatewayResource, AsyncAIGatewayResource from .resources.audit_logs.audit_logs import AuditLogsResource, AsyncAuditLogsResource + from .resources.email_auth.email_auth import EmailAuthResource, AsyncEmailAuthResource from .resources.hyperdrive.hyperdrive import HyperdriveResource, AsyncHyperdriveResource from .resources.page_rules.page_rules import PageRulesResource, AsyncPageRulesResource from .resources.zero_trust.zero_trust import ZeroTrustResource, AsyncZeroTrustResource @@ -557,6 +561,12 @@ def email_security(self) -> EmailSecurityResource: return EmailSecurityResource(self) + @cached_property + def email_auth(self) -> EmailAuthResource: + from .resources.email_auth import EmailAuthResource + + return EmailAuthResource(self) + @cached_property def email_routing(self) -> EmailRoutingResource: from .resources.email_routing import EmailRoutingResource @@ -965,6 +975,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 @@ -1509,6 +1525,12 @@ def email_security(self) -> AsyncEmailSecurityResource: return AsyncEmailSecurityResource(self) + @cached_property + def email_auth(self) -> AsyncEmailAuthResource: + from .resources.email_auth import AsyncEmailAuthResource + + return AsyncEmailAuthResource(self) + @cached_property def email_routing(self) -> AsyncEmailRoutingResource: from .resources.email_routing import AsyncEmailRoutingResource @@ -1917,6 +1939,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 @@ -2381,6 +2409,12 @@ def email_security(self) -> email_security.EmailSecurityResourceWithRawResponse: return EmailSecurityResourceWithRawResponse(self._client.email_security) + @cached_property + def email_auth(self) -> email_auth.EmailAuthResourceWithRawResponse: + from .resources.email_auth import EmailAuthResourceWithRawResponse + + return EmailAuthResourceWithRawResponse(self._client.email_auth) + @cached_property def email_routing(self) -> email_routing.EmailRoutingResourceWithRawResponse: from .resources.email_routing import EmailRoutingResourceWithRawResponse @@ -2793,6 +2827,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 @@ -3084,6 +3124,12 @@ def email_security(self) -> email_security.AsyncEmailSecurityResourceWithRawResp return AsyncEmailSecurityResourceWithRawResponse(self._client.email_security) + @cached_property + def email_auth(self) -> email_auth.AsyncEmailAuthResourceWithRawResponse: + from .resources.email_auth import AsyncEmailAuthResourceWithRawResponse + + return AsyncEmailAuthResourceWithRawResponse(self._client.email_auth) + @cached_property def email_routing(self) -> email_routing.AsyncEmailRoutingResourceWithRawResponse: from .resources.email_routing import AsyncEmailRoutingResourceWithRawResponse @@ -3496,6 +3542,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 @@ -3787,6 +3839,12 @@ def email_security(self) -> email_security.EmailSecurityResourceWithStreamingRes return EmailSecurityResourceWithStreamingResponse(self._client.email_security) + @cached_property + def email_auth(self) -> email_auth.EmailAuthResourceWithStreamingResponse: + from .resources.email_auth import EmailAuthResourceWithStreamingResponse + + return EmailAuthResourceWithStreamingResponse(self._client.email_auth) + @cached_property def email_routing(self) -> email_routing.EmailRoutingResourceWithStreamingResponse: from .resources.email_routing import EmailRoutingResourceWithStreamingResponse @@ -4199,6 +4257,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 @@ -4492,6 +4556,12 @@ def email_security(self) -> email_security.AsyncEmailSecurityResourceWithStreami return AsyncEmailSecurityResourceWithStreamingResponse(self._client.email_security) + @cached_property + def email_auth(self) -> email_auth.AsyncEmailAuthResourceWithStreamingResponse: + from .resources.email_auth import AsyncEmailAuthResourceWithStreamingResponse + + return AsyncEmailAuthResourceWithStreamingResponse(self._client.email_auth) + @cached_property def email_routing(self) -> email_routing.AsyncEmailRoutingResourceWithStreamingResponse: from .resources.email_routing import AsyncEmailRoutingResourceWithStreamingResponse @@ -4910,6 +4980,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/ai_gateway/billing/spending_limit.py b/src/cloudflare/resources/ai_gateway/billing/spending_limit.py index 8235d6ccb1c..1d7a18a89a4 100644 --- a/src/cloudflare/resources/ai_gateway/billing/spending_limit.py +++ b/src/cloudflare/resources/ai_gateway/billing/spending_limit.py @@ -2,6 +2,7 @@ from __future__ import annotations +import typing_extensions from typing import Type, cast from typing_extensions import Literal @@ -45,6 +46,7 @@ def with_streaming_response(self) -> SpendingLimitResourceWithStreamingResponse: """ return SpendingLimitResourceWithStreamingResponse(self) + @typing_extensions.deprecated("deprecated") def create( self, *, @@ -60,7 +62,10 @@ def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> object: """ - Configure a spending limit with amount, strategy, and duration. + Deprecated: spending limits can no longer be created, enabled, or modified and + this endpoint always responds 403. Use the new AI Gateway spend limits instead: + https://developers.cloudflare.com/ai-gateway/features/spend-limits/. Existing + limits can be removed via DELETE /spending-limit. Args: amount: Spending limit amount in cents (min 100). @@ -194,6 +199,7 @@ def with_streaming_response(self) -> AsyncSpendingLimitResourceWithStreamingResp """ return AsyncSpendingLimitResourceWithStreamingResponse(self) + @typing_extensions.deprecated("deprecated") async def create( self, *, @@ -209,7 +215,10 @@ async def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> object: """ - Configure a spending limit with amount, strategy, and duration. + Deprecated: spending limits can no longer be created, enabled, or modified and + this endpoint always responds 403. Use the new AI Gateway spend limits instead: + https://developers.cloudflare.com/ai-gateway/features/spend-limits/. Existing + limits can be removed via DELETE /spending-limit. Args: amount: Spending limit amount in cents (min 100). @@ -327,8 +336,10 @@ class SpendingLimitResourceWithRawResponse: def __init__(self, spending_limit: SpendingLimitResource) -> None: self._spending_limit = spending_limit - self.create = to_raw_response_wrapper( - spending_limit.create, + self.create = ( # pyright: ignore[reportDeprecated] + to_raw_response_wrapper( + spending_limit.create, # pyright: ignore[reportDeprecated], + ) ) self.delete = to_raw_response_wrapper( spending_limit.delete, @@ -342,8 +353,10 @@ class AsyncSpendingLimitResourceWithRawResponse: def __init__(self, spending_limit: AsyncSpendingLimitResource) -> None: self._spending_limit = spending_limit - self.create = async_to_raw_response_wrapper( - spending_limit.create, + self.create = ( # pyright: ignore[reportDeprecated] + async_to_raw_response_wrapper( + spending_limit.create, # pyright: ignore[reportDeprecated], + ) ) self.delete = async_to_raw_response_wrapper( spending_limit.delete, @@ -357,8 +370,10 @@ class SpendingLimitResourceWithStreamingResponse: def __init__(self, spending_limit: SpendingLimitResource) -> None: self._spending_limit = spending_limit - self.create = to_streamed_response_wrapper( - spending_limit.create, + self.create = ( # pyright: ignore[reportDeprecated] + to_streamed_response_wrapper( + spending_limit.create, # pyright: ignore[reportDeprecated], + ) ) self.delete = to_streamed_response_wrapper( spending_limit.delete, @@ -372,8 +387,10 @@ class AsyncSpendingLimitResourceWithStreamingResponse: def __init__(self, spending_limit: AsyncSpendingLimitResource) -> None: self._spending_limit = spending_limit - self.create = async_to_streamed_response_wrapper( - spending_limit.create, + self.create = ( # pyright: ignore[reportDeprecated] + async_to_streamed_response_wrapper( + spending_limit.create, # pyright: ignore[reportDeprecated], + ) ) self.delete = async_to_streamed_response_wrapper( spending_limit.delete, diff --git a/src/cloudflare/resources/email_auth/__init__.py b/src/cloudflare/resources/email_auth/__init__.py new file mode 100644 index 00000000000..92bb375f807 --- /dev/null +++ b/src/cloudflare/resources/email_auth/__init__.py @@ -0,0 +1,47 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .spf import ( + SPFResource, + AsyncSPFResource, + SPFResourceWithRawResponse, + AsyncSPFResourceWithRawResponse, + SPFResourceWithStreamingResponse, + AsyncSPFResourceWithStreamingResponse, +) +from .email_auth import ( + EmailAuthResource, + AsyncEmailAuthResource, + EmailAuthResourceWithRawResponse, + AsyncEmailAuthResourceWithRawResponse, + EmailAuthResourceWithStreamingResponse, + AsyncEmailAuthResourceWithStreamingResponse, +) +from .dmarc_reports import ( + DMARCReportsResource, + AsyncDMARCReportsResource, + DMARCReportsResourceWithRawResponse, + AsyncDMARCReportsResourceWithRawResponse, + DMARCReportsResourceWithStreamingResponse, + AsyncDMARCReportsResourceWithStreamingResponse, +) + +__all__ = [ + "DMARCReportsResource", + "AsyncDMARCReportsResource", + "DMARCReportsResourceWithRawResponse", + "AsyncDMARCReportsResourceWithRawResponse", + "DMARCReportsResourceWithStreamingResponse", + "AsyncDMARCReportsResourceWithStreamingResponse", + "SPFResource", + "AsyncSPFResource", + "SPFResourceWithRawResponse", + "AsyncSPFResourceWithRawResponse", + "SPFResourceWithStreamingResponse", + "AsyncSPFResourceWithStreamingResponse", + "EmailAuthResource", + "AsyncEmailAuthResource", + "EmailAuthResourceWithRawResponse", + "AsyncEmailAuthResourceWithRawResponse", + "EmailAuthResourceWithStreamingResponse", + "AsyncEmailAuthResourceWithStreamingResponse", +] diff --git a/src/cloudflare/resources/email_auth/api.md b/src/cloudflare/resources/email_auth/api.md new file mode 100644 index 00000000000..08ac48bd434 --- /dev/null +++ b/src/cloudflare/resources/email_auth/api.md @@ -0,0 +1,28 @@ +# EmailAuth + +## DMARCReports + +Types: + +```python +from cloudflare.types.email_auth import DMARCReportEditResponse, DMARCReportGetResponse +``` + +Methods: + +- client.email_auth.dmarc_reports.edit(\*, zone_id, \*\*params) -> Optional[DMARCReportEditResponse] +- client.email_auth.dmarc_reports.get(\*, zone_id) -> Optional[DMARCReportGetResponse] + +## SPF + +### Inspect + +Types: + +```python +from cloudflare.types.email_auth.spf import InspectGetResponse +``` + +Methods: + +- client.email_auth.spf.inspect.get(\*, zone_id, \*\*params) -> Optional[InspectGetResponse] diff --git a/src/cloudflare/resources/email_auth/dmarc_reports.py b/src/cloudflare/resources/email_auth/dmarc_reports.py new file mode 100644 index 00000000000..a5cc3ae70d7 --- /dev/null +++ b/src/cloudflare/resources/email_auth/dmarc_reports.py @@ -0,0 +1,307 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Type, Optional, cast + +import httpx + +from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ..._utils import path_template, maybe_transform, 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.email_auth import dmarc_report_edit_params +from ...types.email_auth.dmarc_report_get_response import DMARCReportGetResponse +from ...types.email_auth.dmarc_report_edit_response import DMARCReportEditResponse + +__all__ = ["DMARCReportsResource", "AsyncDMARCReportsResource"] + + +class DMARCReportsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> DMARCReportsResourceWithRawResponse: + """ + 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 DMARCReportsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> DMARCReportsResourceWithStreamingResponse: + """ + 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 DMARCReportsResourceWithStreamingResponse(self) + + def edit( + self, + *, + zone_id: str, + enabled: Optional[bool] | Omit = omit, + skip_wizard: Optional[bool] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[DMARCReportEditResponse]: + """Updates the DMARC report configuration for a zone. + + At least one of `enabled` or + `skip_wizard` must be provided. When enabling, the handler will ensure the DMARC + RUA record exists in DNS. + + Args: + zone_id: Identifier. + + enabled: Enable or disable DMARC reports for this zone + + skip_wizard: Skip the DMARC setup wizard + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._patch( + path_template("/zones/{zone_id}/email/auth/dmarc-reports", zone_id=zone_id), + body=maybe_transform( + { + "enabled": enabled, + "skip_wizard": skip_wizard, + }, + dmarc_report_edit_params.DMARCReportEditParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[DMARCReportEditResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[DMARCReportEditResponse]], ResultWrapper[DMARCReportEditResponse]), + ) + + def get( + self, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[DMARCReportGetResponse]: + """Retrieves the current DMARC report configuration and status for a zone. + + Returns + the RUA prefix, enabled status, approved sources, and DNS records. + + Args: + zone_id: Identifier. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._get( + path_template("/zones/{zone_id}/email/auth/dmarc-reports", zone_id=zone_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[DMARCReportGetResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[DMARCReportGetResponse]], ResultWrapper[DMARCReportGetResponse]), + ) + + +class AsyncDMARCReportsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncDMARCReportsResourceWithRawResponse: + """ + 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 AsyncDMARCReportsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncDMARCReportsResourceWithStreamingResponse: + """ + 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 AsyncDMARCReportsResourceWithStreamingResponse(self) + + async def edit( + self, + *, + zone_id: str, + enabled: Optional[bool] | Omit = omit, + skip_wizard: Optional[bool] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[DMARCReportEditResponse]: + """Updates the DMARC report configuration for a zone. + + At least one of `enabled` or + `skip_wizard` must be provided. When enabling, the handler will ensure the DMARC + RUA record exists in DNS. + + Args: + zone_id: Identifier. + + enabled: Enable or disable DMARC reports for this zone + + skip_wizard: Skip the DMARC setup wizard + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return await self._patch( + path_template("/zones/{zone_id}/email/auth/dmarc-reports", zone_id=zone_id), + body=await async_maybe_transform( + { + "enabled": enabled, + "skip_wizard": skip_wizard, + }, + dmarc_report_edit_params.DMARCReportEditParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[DMARCReportEditResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[DMARCReportEditResponse]], ResultWrapper[DMARCReportEditResponse]), + ) + + async def get( + self, + *, + zone_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> Optional[DMARCReportGetResponse]: + """Retrieves the current DMARC report configuration and status for a zone. + + Returns + the RUA prefix, enabled status, approved sources, and DNS records. + + Args: + zone_id: Identifier. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return await self._get( + path_template("/zones/{zone_id}/email/auth/dmarc-reports", zone_id=zone_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[DMARCReportGetResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[DMARCReportGetResponse]], ResultWrapper[DMARCReportGetResponse]), + ) + + +class DMARCReportsResourceWithRawResponse: + def __init__(self, dmarc_reports: DMARCReportsResource) -> None: + self._dmarc_reports = dmarc_reports + + self.edit = to_raw_response_wrapper( + dmarc_reports.edit, + ) + self.get = to_raw_response_wrapper( + dmarc_reports.get, + ) + + +class AsyncDMARCReportsResourceWithRawResponse: + def __init__(self, dmarc_reports: AsyncDMARCReportsResource) -> None: + self._dmarc_reports = dmarc_reports + + self.edit = async_to_raw_response_wrapper( + dmarc_reports.edit, + ) + self.get = async_to_raw_response_wrapper( + dmarc_reports.get, + ) + + +class DMARCReportsResourceWithStreamingResponse: + def __init__(self, dmarc_reports: DMARCReportsResource) -> None: + self._dmarc_reports = dmarc_reports + + self.edit = to_streamed_response_wrapper( + dmarc_reports.edit, + ) + self.get = to_streamed_response_wrapper( + dmarc_reports.get, + ) + + +class AsyncDMARCReportsResourceWithStreamingResponse: + def __init__(self, dmarc_reports: AsyncDMARCReportsResource) -> None: + self._dmarc_reports = dmarc_reports + + self.edit = async_to_streamed_response_wrapper( + dmarc_reports.edit, + ) + self.get = async_to_streamed_response_wrapper( + dmarc_reports.get, + ) diff --git a/src/cloudflare/resources/email_auth/email_auth.py b/src/cloudflare/resources/email_auth/email_auth.py new file mode 100644 index 00000000000..9a9e4be4906 --- /dev/null +++ b/src/cloudflare/resources/email_auth/email_auth.py @@ -0,0 +1,134 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .spf.spf import ( + SPFResource, + AsyncSPFResource, + SPFResourceWithRawResponse, + AsyncSPFResourceWithRawResponse, + SPFResourceWithStreamingResponse, + AsyncSPFResourceWithStreamingResponse, +) +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from .dmarc_reports import ( + DMARCReportsResource, + AsyncDMARCReportsResource, + DMARCReportsResourceWithRawResponse, + AsyncDMARCReportsResourceWithRawResponse, + DMARCReportsResourceWithStreamingResponse, + AsyncDMARCReportsResourceWithStreamingResponse, +) + +__all__ = ["EmailAuthResource", "AsyncEmailAuthResource"] + + +class EmailAuthResource(SyncAPIResource): + @cached_property + def dmarc_reports(self) -> DMARCReportsResource: + return DMARCReportsResource(self._client) + + @cached_property + def spf(self) -> SPFResource: + return SPFResource(self._client) + + @cached_property + def with_raw_response(self) -> EmailAuthResourceWithRawResponse: + """ + 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 EmailAuthResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> EmailAuthResourceWithStreamingResponse: + """ + 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 EmailAuthResourceWithStreamingResponse(self) + + +class AsyncEmailAuthResource(AsyncAPIResource): + @cached_property + def dmarc_reports(self) -> AsyncDMARCReportsResource: + return AsyncDMARCReportsResource(self._client) + + @cached_property + def spf(self) -> AsyncSPFResource: + return AsyncSPFResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncEmailAuthResourceWithRawResponse: + """ + 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 AsyncEmailAuthResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncEmailAuthResourceWithStreamingResponse: + """ + 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 AsyncEmailAuthResourceWithStreamingResponse(self) + + +class EmailAuthResourceWithRawResponse: + def __init__(self, email_auth: EmailAuthResource) -> None: + self._email_auth = email_auth + + @cached_property + def dmarc_reports(self) -> DMARCReportsResourceWithRawResponse: + return DMARCReportsResourceWithRawResponse(self._email_auth.dmarc_reports) + + @cached_property + def spf(self) -> SPFResourceWithRawResponse: + return SPFResourceWithRawResponse(self._email_auth.spf) + + +class AsyncEmailAuthResourceWithRawResponse: + def __init__(self, email_auth: AsyncEmailAuthResource) -> None: + self._email_auth = email_auth + + @cached_property + def dmarc_reports(self) -> AsyncDMARCReportsResourceWithRawResponse: + return AsyncDMARCReportsResourceWithRawResponse(self._email_auth.dmarc_reports) + + @cached_property + def spf(self) -> AsyncSPFResourceWithRawResponse: + return AsyncSPFResourceWithRawResponse(self._email_auth.spf) + + +class EmailAuthResourceWithStreamingResponse: + def __init__(self, email_auth: EmailAuthResource) -> None: + self._email_auth = email_auth + + @cached_property + def dmarc_reports(self) -> DMARCReportsResourceWithStreamingResponse: + return DMARCReportsResourceWithStreamingResponse(self._email_auth.dmarc_reports) + + @cached_property + def spf(self) -> SPFResourceWithStreamingResponse: + return SPFResourceWithStreamingResponse(self._email_auth.spf) + + +class AsyncEmailAuthResourceWithStreamingResponse: + def __init__(self, email_auth: AsyncEmailAuthResource) -> None: + self._email_auth = email_auth + + @cached_property + def dmarc_reports(self) -> AsyncDMARCReportsResourceWithStreamingResponse: + return AsyncDMARCReportsResourceWithStreamingResponse(self._email_auth.dmarc_reports) + + @cached_property + def spf(self) -> AsyncSPFResourceWithStreamingResponse: + return AsyncSPFResourceWithStreamingResponse(self._email_auth.spf) diff --git a/src/cloudflare/resources/email_auth/spf/__init__.py b/src/cloudflare/resources/email_auth/spf/__init__.py new file mode 100644 index 00000000000..a4cb6ce4d95 --- /dev/null +++ b/src/cloudflare/resources/email_auth/spf/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .spf import ( + SPFResource, + AsyncSPFResource, + SPFResourceWithRawResponse, + AsyncSPFResourceWithRawResponse, + SPFResourceWithStreamingResponse, + AsyncSPFResourceWithStreamingResponse, +) +from .inspect import ( + InspectResource, + AsyncInspectResource, + InspectResourceWithRawResponse, + AsyncInspectResourceWithRawResponse, + InspectResourceWithStreamingResponse, + AsyncInspectResourceWithStreamingResponse, +) + +__all__ = [ + "InspectResource", + "AsyncInspectResource", + "InspectResourceWithRawResponse", + "AsyncInspectResourceWithRawResponse", + "InspectResourceWithStreamingResponse", + "AsyncInspectResourceWithStreamingResponse", + "SPFResource", + "AsyncSPFResource", + "SPFResourceWithRawResponse", + "AsyncSPFResourceWithRawResponse", + "SPFResourceWithStreamingResponse", + "AsyncSPFResourceWithStreamingResponse", +] diff --git a/src/cloudflare/resources/email_auth/spf/inspect.py b/src/cloudflare/resources/email_auth/spf/inspect.py new file mode 100644 index 00000000000..8d52113efe9 --- /dev/null +++ b/src/cloudflare/resources/email_auth/spf/inspect.py @@ -0,0 +1,208 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Type, Optional, cast + +import httpx + +from ...._types import Body, Query, Headers, NotGiven, not_given +from ...._utils import path_template, maybe_transform, async_maybe_transform +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ...._wrappers import ResultWrapper +from ...._base_client import make_request_options +from ....types.email_auth.spf import inspect_get_params +from ....types.email_auth.spf.inspect_get_response import InspectGetResponse + +__all__ = ["InspectResource", "AsyncInspectResource"] + + +class InspectResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> InspectResourceWithRawResponse: + """ + 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 InspectResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> InspectResourceWithStreamingResponse: + """ + 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 InspectResourceWithStreamingResponse(self) + + def get( + self, + *, + zone_id: str, + 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[InspectGetResponse]: + """ + Inspects a specific SPF TXT record and returns a parsed tree structure in the + spflimit-worker format. + + The record ID must be provided via the `id` query parameter. + + Returns a recursive tree showing: + + - Parsed components with their qualifiers and types + - Nested includes recursively resolved within components + - Per-component and total lookup counts + - Detailed error information with context + + Args: + zone_id: Identifier. + + id: DNS record ID (rec_tag) to inspect + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._get( + path_template("/zones/{zone_id}/email/auth/spf/inspect", zone_id=zone_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform({"id": id}, inspect_get_params.InspectGetParams), + post_parser=ResultWrapper[Optional[InspectGetResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[InspectGetResponse]], ResultWrapper[InspectGetResponse]), + ) + + +class AsyncInspectResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncInspectResourceWithRawResponse: + """ + 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 AsyncInspectResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncInspectResourceWithStreamingResponse: + """ + 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 AsyncInspectResourceWithStreamingResponse(self) + + async def get( + self, + *, + zone_id: str, + 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[InspectGetResponse]: + """ + Inspects a specific SPF TXT record and returns a parsed tree structure in the + spflimit-worker format. + + The record ID must be provided via the `id` query parameter. + + Returns a recursive tree showing: + + - Parsed components with their qualifiers and types + - Nested includes recursively resolved within components + - Per-component and total lookup counts + - Detailed error information with context + + Args: + zone_id: Identifier. + + id: DNS record ID (rec_tag) to inspect + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return await self._get( + path_template("/zones/{zone_id}/email/auth/spf/inspect", zone_id=zone_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform({"id": id}, inspect_get_params.InspectGetParams), + post_parser=ResultWrapper[Optional[InspectGetResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[InspectGetResponse]], ResultWrapper[InspectGetResponse]), + ) + + +class InspectResourceWithRawResponse: + def __init__(self, inspect: InspectResource) -> None: + self._inspect = inspect + + self.get = to_raw_response_wrapper( + inspect.get, + ) + + +class AsyncInspectResourceWithRawResponse: + def __init__(self, inspect: AsyncInspectResource) -> None: + self._inspect = inspect + + self.get = async_to_raw_response_wrapper( + inspect.get, + ) + + +class InspectResourceWithStreamingResponse: + def __init__(self, inspect: InspectResource) -> None: + self._inspect = inspect + + self.get = to_streamed_response_wrapper( + inspect.get, + ) + + +class AsyncInspectResourceWithStreamingResponse: + def __init__(self, inspect: AsyncInspectResource) -> None: + self._inspect = inspect + + self.get = async_to_streamed_response_wrapper( + inspect.get, + ) diff --git a/src/cloudflare/resources/email_auth/spf/spf.py b/src/cloudflare/resources/email_auth/spf/spf.py new file mode 100644 index 00000000000..ef37938656b --- /dev/null +++ b/src/cloudflare/resources/email_auth/spf/spf.py @@ -0,0 +1,102 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .inspect import ( + InspectResource, + AsyncInspectResource, + InspectResourceWithRawResponse, + AsyncInspectResourceWithRawResponse, + InspectResourceWithStreamingResponse, + AsyncInspectResourceWithStreamingResponse, +) +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource + +__all__ = ["SPFResource", "AsyncSPFResource"] + + +class SPFResource(SyncAPIResource): + @cached_property + def inspect(self) -> InspectResource: + return InspectResource(self._client) + + @cached_property + def with_raw_response(self) -> SPFResourceWithRawResponse: + """ + 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 SPFResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> SPFResourceWithStreamingResponse: + """ + 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 SPFResourceWithStreamingResponse(self) + + +class AsyncSPFResource(AsyncAPIResource): + @cached_property + def inspect(self) -> AsyncInspectResource: + return AsyncInspectResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncSPFResourceWithRawResponse: + """ + 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 AsyncSPFResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncSPFResourceWithStreamingResponse: + """ + 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 AsyncSPFResourceWithStreamingResponse(self) + + +class SPFResourceWithRawResponse: + def __init__(self, spf: SPFResource) -> None: + self._spf = spf + + @cached_property + def inspect(self) -> InspectResourceWithRawResponse: + return InspectResourceWithRawResponse(self._spf.inspect) + + +class AsyncSPFResourceWithRawResponse: + def __init__(self, spf: AsyncSPFResource) -> None: + self._spf = spf + + @cached_property + def inspect(self) -> AsyncInspectResourceWithRawResponse: + return AsyncInspectResourceWithRawResponse(self._spf.inspect) + + +class SPFResourceWithStreamingResponse: + def __init__(self, spf: SPFResource) -> None: + self._spf = spf + + @cached_property + def inspect(self) -> InspectResourceWithStreamingResponse: + return InspectResourceWithStreamingResponse(self._spf.inspect) + + +class AsyncSPFResourceWithStreamingResponse: + def __init__(self, spf: AsyncSPFResource) -> None: + self._spf = spf + + @cached_property + def inspect(self) -> AsyncInspectResourceWithStreamingResponse: + return AsyncInspectResourceWithStreamingResponse(self._spf.inspect) 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..8b3e963eae5 --- /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..434c6a9d326 --- /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..75102e3b192 --- /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/resources/zero_trust/organizations/organizations.py b/src/cloudflare/resources/zero_trust/organizations/organizations.py index d66cc53d08b..a6bbf066792 100644 --- a/src/cloudflare/resources/zero_trust/organizations/organizations.py +++ b/src/cloudflare/resources/zero_trust/organizations/organizations.py @@ -76,8 +76,8 @@ def create( is_ui_read_only: bool | Omit = omit, login_design: LoginDesignParam | Omit = omit, mfa_config: organization_create_params.MfaConfig | Omit = omit, + mfa_piv_key_requirements: organization_create_params.MfaPivKeyRequirements | Omit = omit, mfa_required_for_all_apps: bool | Omit = omit, - mfa_ssh_piv_key_requirements: organization_create_params.MfaSSHPivKeyRequirements | Omit = omit, session_duration: str | Omit = omit, ui_read_only_toggle_reason: str | Omit = omit, user_seat_expiration_inactive_time: str | Omit = omit, @@ -123,13 +123,13 @@ def create( mfa_config: Configures multi-factor authentication (MFA) settings for an organization. + mfa_piv_key_requirements: Configures PIV key requirements for MFA using hardware security keys. + mfa_required_for_all_apps: Determines whether global MFA settings apply to applications by default. The organization must have MFA enabled with at least one authentication method and a session duration configured. Note: 'allowed_authenticators' cannot only contain - 'ssh_piv_key' if the organization has any non-infrastructure applications - because PIV keys are only compatible with infrastructure apps. - - mfa_ssh_piv_key_requirements: Configures SSH PIV key requirements for MFA using hardware security keys. + 'piv_key' if the organization has any non-infrastructure applications because + PIV keys are only compatible with infrastructure apps. session_duration: The amount of time that tokens issued for applications will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, s, m, @@ -183,8 +183,8 @@ def create( "is_ui_read_only": is_ui_read_only, "login_design": login_design, "mfa_config": mfa_config, + "mfa_piv_key_requirements": mfa_piv_key_requirements, "mfa_required_for_all_apps": mfa_required_for_all_apps, - "mfa_ssh_piv_key_requirements": mfa_ssh_piv_key_requirements, "session_duration": session_duration, "ui_read_only_toggle_reason": ui_read_only_toggle_reason, "user_seat_expiration_inactive_time": user_seat_expiration_inactive_time, @@ -216,8 +216,8 @@ def update( is_ui_read_only: bool | Omit = omit, login_design: LoginDesignParam | Omit = omit, mfa_config: organization_update_params.MfaConfig | Omit = omit, + mfa_piv_key_requirements: organization_update_params.MfaPivKeyRequirements | Omit = omit, mfa_required_for_all_apps: bool | Omit = omit, - mfa_ssh_piv_key_requirements: organization_update_params.MfaSSHPivKeyRequirements | Omit = omit, name: str | Omit = omit, session_duration: str | Omit = omit, ui_read_only_toggle_reason: str | Omit = omit, @@ -262,13 +262,13 @@ def update( mfa_config: Configures multi-factor authentication (MFA) settings for an organization. + mfa_piv_key_requirements: Configures PIV key requirements for MFA using hardware security keys. + mfa_required_for_all_apps: Determines whether global MFA settings apply to applications by default. The organization must have MFA enabled with at least one authentication method and a session duration configured. Note: 'allowed_authenticators' cannot only contain - 'ssh_piv_key' if the organization has any non-infrastructure applications - because PIV keys are only compatible with infrastructure apps. - - mfa_ssh_piv_key_requirements: Configures SSH PIV key requirements for MFA using hardware security keys. + 'piv_key' if the organization has any non-infrastructure applications because + PIV keys are only compatible with infrastructure apps. name: The name of your Zero Trust organization. @@ -324,8 +324,8 @@ def update( "is_ui_read_only": is_ui_read_only, "login_design": login_design, "mfa_config": mfa_config, + "mfa_piv_key_requirements": mfa_piv_key_requirements, "mfa_required_for_all_apps": mfa_required_for_all_apps, - "mfa_ssh_piv_key_requirements": mfa_ssh_piv_key_requirements, "name": name, "session_duration": session_duration, "ui_read_only_toggle_reason": ui_read_only_toggle_reason, @@ -526,8 +526,8 @@ async def create( is_ui_read_only: bool | Omit = omit, login_design: LoginDesignParam | Omit = omit, mfa_config: organization_create_params.MfaConfig | Omit = omit, + mfa_piv_key_requirements: organization_create_params.MfaPivKeyRequirements | Omit = omit, mfa_required_for_all_apps: bool | Omit = omit, - mfa_ssh_piv_key_requirements: organization_create_params.MfaSSHPivKeyRequirements | Omit = omit, session_duration: str | Omit = omit, ui_read_only_toggle_reason: str | Omit = omit, user_seat_expiration_inactive_time: str | Omit = omit, @@ -573,13 +573,13 @@ async def create( mfa_config: Configures multi-factor authentication (MFA) settings for an organization. + mfa_piv_key_requirements: Configures PIV key requirements for MFA using hardware security keys. + mfa_required_for_all_apps: Determines whether global MFA settings apply to applications by default. The organization must have MFA enabled with at least one authentication method and a session duration configured. Note: 'allowed_authenticators' cannot only contain - 'ssh_piv_key' if the organization has any non-infrastructure applications - because PIV keys are only compatible with infrastructure apps. - - mfa_ssh_piv_key_requirements: Configures SSH PIV key requirements for MFA using hardware security keys. + 'piv_key' if the organization has any non-infrastructure applications because + PIV keys are only compatible with infrastructure apps. session_duration: The amount of time that tokens issued for applications will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or µs), ms, s, m, @@ -633,8 +633,8 @@ async def create( "is_ui_read_only": is_ui_read_only, "login_design": login_design, "mfa_config": mfa_config, + "mfa_piv_key_requirements": mfa_piv_key_requirements, "mfa_required_for_all_apps": mfa_required_for_all_apps, - "mfa_ssh_piv_key_requirements": mfa_ssh_piv_key_requirements, "session_duration": session_duration, "ui_read_only_toggle_reason": ui_read_only_toggle_reason, "user_seat_expiration_inactive_time": user_seat_expiration_inactive_time, @@ -666,8 +666,8 @@ async def update( is_ui_read_only: bool | Omit = omit, login_design: LoginDesignParam | Omit = omit, mfa_config: organization_update_params.MfaConfig | Omit = omit, + mfa_piv_key_requirements: organization_update_params.MfaPivKeyRequirements | Omit = omit, mfa_required_for_all_apps: bool | Omit = omit, - mfa_ssh_piv_key_requirements: organization_update_params.MfaSSHPivKeyRequirements | Omit = omit, name: str | Omit = omit, session_duration: str | Omit = omit, ui_read_only_toggle_reason: str | Omit = omit, @@ -712,13 +712,13 @@ async def update( mfa_config: Configures multi-factor authentication (MFA) settings for an organization. + mfa_piv_key_requirements: Configures PIV key requirements for MFA using hardware security keys. + mfa_required_for_all_apps: Determines whether global MFA settings apply to applications by default. The organization must have MFA enabled with at least one authentication method and a session duration configured. Note: 'allowed_authenticators' cannot only contain - 'ssh_piv_key' if the organization has any non-infrastructure applications - because PIV keys are only compatible with infrastructure apps. - - mfa_ssh_piv_key_requirements: Configures SSH PIV key requirements for MFA using hardware security keys. + 'piv_key' if the organization has any non-infrastructure applications because + PIV keys are only compatible with infrastructure apps. name: The name of your Zero Trust organization. @@ -774,8 +774,8 @@ async def update( "is_ui_read_only": is_ui_read_only, "login_design": login_design, "mfa_config": mfa_config, + "mfa_piv_key_requirements": mfa_piv_key_requirements, "mfa_required_for_all_apps": mfa_required_for_all_apps, - "mfa_ssh_piv_key_requirements": mfa_ssh_piv_key_requirements, "name": name, "session_duration": session_duration, "ui_read_only_toggle_reason": ui_read_only_toggle_reason, diff --git a/src/cloudflare/types/email_auth/__init__.py b/src/cloudflare/types/email_auth/__init__.py new file mode 100644 index 00000000000..e0d836b6f81 --- /dev/null +++ b/src/cloudflare/types/email_auth/__init__.py @@ -0,0 +1,7 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .dmarc_report_edit_params import DMARCReportEditParams as DMARCReportEditParams +from .dmarc_report_get_response import DMARCReportGetResponse as DMARCReportGetResponse +from .dmarc_report_edit_response import DMARCReportEditResponse as DMARCReportEditResponse diff --git a/src/cloudflare/types/email_auth/dmarc_report_edit_params.py b/src/cloudflare/types/email_auth/dmarc_report_edit_params.py new file mode 100644 index 00000000000..4d154790632 --- /dev/null +++ b/src/cloudflare/types/email_auth/dmarc_report_edit_params.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Required, TypedDict + +__all__ = ["DMARCReportEditParams"] + + +class DMARCReportEditParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier.""" + + enabled: Optional[bool] + """Enable or disable DMARC reports for this zone""" + + skip_wizard: Optional[bool] + """Skip the DMARC setup wizard""" diff --git a/src/cloudflare/types/email_auth/dmarc_report_edit_response.py b/src/cloudflare/types/email_auth/dmarc_report_edit_response.py new file mode 100644 index 00000000000..5e8b1598303 --- /dev/null +++ b/src/cloudflare/types/email_auth/dmarc_report_edit_response.py @@ -0,0 +1,251 @@ +# 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__ = [ + "DMARCReportEditResponse", + "ApprovedSource", + "Records", + "RecordsBimiRecord", + "RecordsCnamedkimRecord", + "RecordsCnamedmarcRecord", + "RecordsCnamespfRecord", + "RecordsDKIMRecord", + "RecordsDMARCRecord", + "RecordsSPFRecord", +] + + +class ApprovedSource(BaseModel): + """A single approved sending source""" + + created: Optional[datetime] = None + """Deprecated, use created_at""" + + created_at: Optional[datetime] = None + """Creation timestamp""" + + domain: Optional[str] = None + """The source domain""" + + ips: Optional[List[str]] = None + """Resolved IP addresses from SPF""" + + modified: Optional[datetime] = None + """Deprecated, use modified_at""" + + modified_at: Optional[datetime] = None + """Last modification timestamp""" + + name: Optional[str] = None + """Source name (typically same as domain)""" + + slug: Optional[str] = None + """URL-friendly identifier""" + + tag: Optional[str] = None + """Source UUID""" + + +class RecordsBimiRecord(BaseModel): + """Summary of a single DNS record""" + + id: Optional[str] = None + """DNS record ID""" + + content: Optional[str] = None + """Record content""" + + name: Optional[str] = None + """DNS record name""" + + ttl: Optional[int] = None + """Time to live in seconds""" + + type: Optional[str] = None + """Record type""" + + +class RecordsCnamedkimRecord(BaseModel): + """Summary of a single DNS record""" + + id: Optional[str] = None + """DNS record ID""" + + content: Optional[str] = None + """Record content""" + + name: Optional[str] = None + """DNS record name""" + + ttl: Optional[int] = None + """Time to live in seconds""" + + type: Optional[str] = None + """Record type""" + + +class RecordsCnamedmarcRecord(BaseModel): + """Summary of a single DNS record""" + + id: Optional[str] = None + """DNS record ID""" + + content: Optional[str] = None + """Record content""" + + name: Optional[str] = None + """DNS record name""" + + ttl: Optional[int] = None + """Time to live in seconds""" + + type: Optional[str] = None + """Record type""" + + +class RecordsCnamespfRecord(BaseModel): + """Summary of a single DNS record""" + + id: Optional[str] = None + """DNS record ID""" + + content: Optional[str] = None + """Record content""" + + name: Optional[str] = None + """DNS record name""" + + ttl: Optional[int] = None + """Time to live in seconds""" + + type: Optional[str] = None + """Record type""" + + +class RecordsDKIMRecord(BaseModel): + """Summary of a single DNS record""" + + id: Optional[str] = None + """DNS record ID""" + + content: Optional[str] = None + """Record content""" + + name: Optional[str] = None + """DNS record name""" + + ttl: Optional[int] = None + """Time to live in seconds""" + + type: Optional[str] = None + """Record type""" + + +class RecordsDMARCRecord(BaseModel): + """Summary of a single DNS record""" + + id: Optional[str] = None + """DNS record ID""" + + content: Optional[str] = None + """Record content""" + + name: Optional[str] = None + """DNS record name""" + + ttl: Optional[int] = None + """Time to live in seconds""" + + type: Optional[str] = None + """Record type""" + + +class RecordsSPFRecord(BaseModel): + """Summary of a single DNS record""" + + id: Optional[str] = None + """DNS record ID""" + + content: Optional[str] = None + """Record content""" + + name: Optional[str] = None + """DNS record name""" + + ttl: Optional[int] = None + """Time to live in seconds""" + + type: Optional[str] = None + """Record type""" + + +class Records(BaseModel): + """Live DNS records for the zone, grouped by type""" + + bimi_records: Optional[List[RecordsBimiRecord]] = None + """BIMI TXT records""" + + cname_dkim_records: Optional[List[RecordsCnamedkimRecord]] = None + """CNAME records for DKIM""" + + cname_dmarc_records: Optional[List[RecordsCnamedmarcRecord]] = None + """CNAME records at \\__dmarc (problematic)""" + + cname_spf_records: Optional[List[RecordsCnamespfRecord]] = None + """CNAME records for SPF""" + + dkim_records: Optional[List[RecordsDKIMRecord]] = None + """DKIM TXT records""" + + dmarc_records: Optional[List[RecordsDMARCRecord]] = None + """DMARC TXT records""" + + spf_records: Optional[List[RecordsSPFRecord]] = None + """SPF TXT records""" + + +class DMARCReportEditResponse(BaseModel): + """Response for GET/PATCH /dmarc-reports""" + + approved_sources: Optional[List[ApprovedSource]] = None + """List of approved sending sources (omitted when empty)""" + + created: Optional[datetime] = None + """Deprecated, use created_at""" + + created_at: Optional[datetime] = None + """Creation timestamp""" + + enabled: Optional[bool] = None + """Whether DMARC reports are enabled""" + + modified: Optional[datetime] = None + """Deprecated, use modified_at""" + + modified_at: Optional[datetime] = None + """Last modification timestamp""" + + records: Optional[Records] = None + """Live DNS records for the zone, grouped by type""" + + rua_prefix: Optional[str] = None + """Prefix for DMARC RUA addresses (32-char hex string)""" + + skip_wizard: Optional[bool] = None + """Whether to skip the setup wizard""" + + status: Optional[ + Literal["missing-dmarc-report", "multiple-dmarc-reports", "missing-dmarc-rua", "cname-on-dmarc-record"] + ] = None + """DMARC configuration status""" + + tag: Optional[str] = None + """Use `zone_id` instead""" + + zone_id: Optional[str] = None + """Zone identifier""" diff --git a/src/cloudflare/types/email_auth/dmarc_report_get_response.py b/src/cloudflare/types/email_auth/dmarc_report_get_response.py new file mode 100644 index 00000000000..c8457be9bbb --- /dev/null +++ b/src/cloudflare/types/email_auth/dmarc_report_get_response.py @@ -0,0 +1,251 @@ +# 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__ = [ + "DMARCReportGetResponse", + "ApprovedSource", + "Records", + "RecordsBimiRecord", + "RecordsCnamedkimRecord", + "RecordsCnamedmarcRecord", + "RecordsCnamespfRecord", + "RecordsDKIMRecord", + "RecordsDMARCRecord", + "RecordsSPFRecord", +] + + +class ApprovedSource(BaseModel): + """A single approved sending source""" + + created: Optional[datetime] = None + """Deprecated, use created_at""" + + created_at: Optional[datetime] = None + """Creation timestamp""" + + domain: Optional[str] = None + """The source domain""" + + ips: Optional[List[str]] = None + """Resolved IP addresses from SPF""" + + modified: Optional[datetime] = None + """Deprecated, use modified_at""" + + modified_at: Optional[datetime] = None + """Last modification timestamp""" + + name: Optional[str] = None + """Source name (typically same as domain)""" + + slug: Optional[str] = None + """URL-friendly identifier""" + + tag: Optional[str] = None + """Source UUID""" + + +class RecordsBimiRecord(BaseModel): + """Summary of a single DNS record""" + + id: Optional[str] = None + """DNS record ID""" + + content: Optional[str] = None + """Record content""" + + name: Optional[str] = None + """DNS record name""" + + ttl: Optional[int] = None + """Time to live in seconds""" + + type: Optional[str] = None + """Record type""" + + +class RecordsCnamedkimRecord(BaseModel): + """Summary of a single DNS record""" + + id: Optional[str] = None + """DNS record ID""" + + content: Optional[str] = None + """Record content""" + + name: Optional[str] = None + """DNS record name""" + + ttl: Optional[int] = None + """Time to live in seconds""" + + type: Optional[str] = None + """Record type""" + + +class RecordsCnamedmarcRecord(BaseModel): + """Summary of a single DNS record""" + + id: Optional[str] = None + """DNS record ID""" + + content: Optional[str] = None + """Record content""" + + name: Optional[str] = None + """DNS record name""" + + ttl: Optional[int] = None + """Time to live in seconds""" + + type: Optional[str] = None + """Record type""" + + +class RecordsCnamespfRecord(BaseModel): + """Summary of a single DNS record""" + + id: Optional[str] = None + """DNS record ID""" + + content: Optional[str] = None + """Record content""" + + name: Optional[str] = None + """DNS record name""" + + ttl: Optional[int] = None + """Time to live in seconds""" + + type: Optional[str] = None + """Record type""" + + +class RecordsDKIMRecord(BaseModel): + """Summary of a single DNS record""" + + id: Optional[str] = None + """DNS record ID""" + + content: Optional[str] = None + """Record content""" + + name: Optional[str] = None + """DNS record name""" + + ttl: Optional[int] = None + """Time to live in seconds""" + + type: Optional[str] = None + """Record type""" + + +class RecordsDMARCRecord(BaseModel): + """Summary of a single DNS record""" + + id: Optional[str] = None + """DNS record ID""" + + content: Optional[str] = None + """Record content""" + + name: Optional[str] = None + """DNS record name""" + + ttl: Optional[int] = None + """Time to live in seconds""" + + type: Optional[str] = None + """Record type""" + + +class RecordsSPFRecord(BaseModel): + """Summary of a single DNS record""" + + id: Optional[str] = None + """DNS record ID""" + + content: Optional[str] = None + """Record content""" + + name: Optional[str] = None + """DNS record name""" + + ttl: Optional[int] = None + """Time to live in seconds""" + + type: Optional[str] = None + """Record type""" + + +class Records(BaseModel): + """Live DNS records for the zone, grouped by type""" + + bimi_records: Optional[List[RecordsBimiRecord]] = None + """BIMI TXT records""" + + cname_dkim_records: Optional[List[RecordsCnamedkimRecord]] = None + """CNAME records for DKIM""" + + cname_dmarc_records: Optional[List[RecordsCnamedmarcRecord]] = None + """CNAME records at \\__dmarc (problematic)""" + + cname_spf_records: Optional[List[RecordsCnamespfRecord]] = None + """CNAME records for SPF""" + + dkim_records: Optional[List[RecordsDKIMRecord]] = None + """DKIM TXT records""" + + dmarc_records: Optional[List[RecordsDMARCRecord]] = None + """DMARC TXT records""" + + spf_records: Optional[List[RecordsSPFRecord]] = None + """SPF TXT records""" + + +class DMARCReportGetResponse(BaseModel): + """Response for GET/PATCH /dmarc-reports""" + + approved_sources: Optional[List[ApprovedSource]] = None + """List of approved sending sources (omitted when empty)""" + + created: Optional[datetime] = None + """Deprecated, use created_at""" + + created_at: Optional[datetime] = None + """Creation timestamp""" + + enabled: Optional[bool] = None + """Whether DMARC reports are enabled""" + + modified: Optional[datetime] = None + """Deprecated, use modified_at""" + + modified_at: Optional[datetime] = None + """Last modification timestamp""" + + records: Optional[Records] = None + """Live DNS records for the zone, grouped by type""" + + rua_prefix: Optional[str] = None + """Prefix for DMARC RUA addresses (32-char hex string)""" + + skip_wizard: Optional[bool] = None + """Whether to skip the setup wizard""" + + status: Optional[ + Literal["missing-dmarc-report", "multiple-dmarc-reports", "missing-dmarc-rua", "cname-on-dmarc-record"] + ] = None + """DMARC configuration status""" + + tag: Optional[str] = None + """Use `zone_id` instead""" + + zone_id: Optional[str] = None + """Zone identifier""" diff --git a/src/cloudflare/types/email_auth/spf/__init__.py b/src/cloudflare/types/email_auth/spf/__init__.py new file mode 100644 index 00000000000..bbfb6b9d3ca --- /dev/null +++ b/src/cloudflare/types/email_auth/spf/__init__.py @@ -0,0 +1,6 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .inspect_get_params import InspectGetParams as InspectGetParams +from .inspect_get_response import InspectGetResponse as InspectGetResponse diff --git a/src/cloudflare/types/email_auth/spf/inspect_get_params.py b/src/cloudflare/types/email_auth/spf/inspect_get_params.py new file mode 100644 index 00000000000..594a4932b37 --- /dev/null +++ b/src/cloudflare/types/email_auth/spf/inspect_get_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__ = ["InspectGetParams"] + + +class InspectGetParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier.""" + + id: Required[str] + """DNS record ID (rec_tag) to inspect""" diff --git a/src/cloudflare/types/email_auth/spf/inspect_get_response.py b/src/cloudflare/types/email_auth/spf/inspect_get_response.py new file mode 100644 index 00000000000..0d743a61602 --- /dev/null +++ b/src/cloudflare/types/email_auth/spf/inspect_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 ...._models import BaseModel + +__all__ = ["InspectGetResponse", "Error"] + + +class Error(BaseModel): + """An error encountered during SPF inspection""" + + code: str + """Error code. Known values: + + - `lookup_failed` — DNS TXT lookup failed + - `spf_not_found` — no SPF record found + - `invalid_spf` — record does not start with `v=spf1` + - `invalid_domain` — PSL validation failed + - `loop_detected` — include/redirect cycle detected + - `invalid_mechanism` — unrecognised or malformed mechanism + - `resource_limit_exceeded` — internal resource protection limits exceeded + (recursion depth or query budget) + - `max_lookups` — RFC 7208 10-lookup limit exceeded + """ + + domain: str + """Domain where the error occurred""" + + message: str + """Human-readable error message""" + + details: Optional[str] = None + """Additional error-specific details (optional). + + - For `invalid_domain` errors: the invalid domain string + - For `invalid_mechanism` errors: the invalid mechanism text (e.g., + "invalidmech123") + - For `loop_detected` errors: the domain that caused the loop + - For other error types: not present + """ + + +class InspectGetResponse(BaseModel): + """Recursive SPF inspection tree""" + + components: List[object] + """Parsed SPF components (mechanisms)""" + + domain: str + """Domain being inspected""" + + record: str + """Raw SPF record content""" + + total_lookups: int + """Total number of DNS lookups performed across all includes""" + + errors: Optional[List[Error]] = None + """ + All errors encountered during inspection, collected from the entire tree. This + includes errors from nested includes at any depth, providing a quick overview of + all issues without needing to traverse the nested structure. Each error includes + a `domain` field to identify where it occurred. Empty array if no errors + (omitted from JSON when empty). + """ 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/magic_transit/gre_tunnel_bulk_update_response.py b/src/cloudflare/types/magic_transit/gre_tunnel_bulk_update_response.py index ffacd0ffc74..924cb5b6907 100644 --- a/src/cloudflare/types/magic_transit/gre_tunnel_bulk_update_response.py +++ b/src/cloudflare/types/magic_transit/gre_tunnel_bulk_update_response.py @@ -23,12 +23,18 @@ class ModifiedGRETunnelBGP(BaseModel): customer_asn: int """ASN used on the customer end of the BGP session""" + export_filter_id: Optional[str] = None + """ID of the BGP filter profile applied to routes advertised to the customer.""" + extra_prefixes: Optional[List[str]] = None """ Prefixes in this list will be advertised to the customer device, in addition to the routes in the Magic routing table. """ + import_filter_id: Optional[str] = None + """ID of the BGP filter profile applied to routes received from the customer.""" + md5_key: Optional[str] = None """MD5 key to use for session authentication. diff --git a/src/cloudflare/types/magic_transit/gre_tunnel_create_params.py b/src/cloudflare/types/magic_transit/gre_tunnel_create_params.py index 19e85148542..2c45cd93e3b 100644 --- a/src/cloudflare/types/magic_transit/gre_tunnel_create_params.py +++ b/src/cloudflare/types/magic_transit/gre_tunnel_create_params.py @@ -81,12 +81,18 @@ class BGP(TypedDict, total=False): customer_asn: Required[int] """ASN used on the customer end of the BGP session""" + export_filter_id: str + """ID of the BGP filter profile applied to routes advertised to the customer.""" + extra_prefixes: SequenceNotStr[str] """ Prefixes in this list will be advertised to the customer device, in addition to the routes in the Magic routing table. """ + import_filter_id: str + """ID of the BGP filter profile applied to routes received from the customer.""" + md5_key: str """MD5 key to use for session authentication. diff --git a/src/cloudflare/types/magic_transit/gre_tunnel_create_response.py b/src/cloudflare/types/magic_transit/gre_tunnel_create_response.py index ee95b6fa8b2..3ae3d7d2282 100644 --- a/src/cloudflare/types/magic_transit/gre_tunnel_create_response.py +++ b/src/cloudflare/types/magic_transit/gre_tunnel_create_response.py @@ -22,12 +22,18 @@ class BGP(BaseModel): customer_asn: int """ASN used on the customer end of the BGP session""" + export_filter_id: Optional[str] = None + """ID of the BGP filter profile applied to routes advertised to the customer.""" + extra_prefixes: Optional[List[str]] = None """ Prefixes in this list will be advertised to the customer device, in addition to the routes in the Magic routing table. """ + import_filter_id: Optional[str] = None + """ID of the BGP filter profile applied to routes received from the customer.""" + md5_key: Optional[str] = None """MD5 key to use for session authentication. diff --git a/src/cloudflare/types/magic_transit/gre_tunnel_delete_response.py b/src/cloudflare/types/magic_transit/gre_tunnel_delete_response.py index 2607e9e41bf..dc494813de7 100644 --- a/src/cloudflare/types/magic_transit/gre_tunnel_delete_response.py +++ b/src/cloudflare/types/magic_transit/gre_tunnel_delete_response.py @@ -23,12 +23,18 @@ class DeletedGRETunnelBGP(BaseModel): customer_asn: int """ASN used on the customer end of the BGP session""" + export_filter_id: Optional[str] = None + """ID of the BGP filter profile applied to routes advertised to the customer.""" + extra_prefixes: Optional[List[str]] = None """ Prefixes in this list will be advertised to the customer device, in addition to the routes in the Magic routing table. """ + import_filter_id: Optional[str] = None + """ID of the BGP filter profile applied to routes received from the customer.""" + md5_key: Optional[str] = None """MD5 key to use for session authentication. diff --git a/src/cloudflare/types/magic_transit/gre_tunnel_get_response.py b/src/cloudflare/types/magic_transit/gre_tunnel_get_response.py index ef8eb5cacd8..32fd9527373 100644 --- a/src/cloudflare/types/magic_transit/gre_tunnel_get_response.py +++ b/src/cloudflare/types/magic_transit/gre_tunnel_get_response.py @@ -23,12 +23,18 @@ class GRETunnelBGP(BaseModel): customer_asn: int """ASN used on the customer end of the BGP session""" + export_filter_id: Optional[str] = None + """ID of the BGP filter profile applied to routes advertised to the customer.""" + extra_prefixes: Optional[List[str]] = None """ Prefixes in this list will be advertised to the customer device, in addition to the routes in the Magic routing table. """ + import_filter_id: Optional[str] = None + """ID of the BGP filter profile applied to routes received from the customer.""" + md5_key: Optional[str] = None """MD5 key to use for session authentication. diff --git a/src/cloudflare/types/magic_transit/gre_tunnel_list_response.py b/src/cloudflare/types/magic_transit/gre_tunnel_list_response.py index e4d0cc9ec77..88c54249db2 100644 --- a/src/cloudflare/types/magic_transit/gre_tunnel_list_response.py +++ b/src/cloudflare/types/magic_transit/gre_tunnel_list_response.py @@ -23,12 +23,18 @@ class GRETunnelBGP(BaseModel): customer_asn: int """ASN used on the customer end of the BGP session""" + export_filter_id: Optional[str] = None + """ID of the BGP filter profile applied to routes advertised to the customer.""" + extra_prefixes: Optional[List[str]] = None """ Prefixes in this list will be advertised to the customer device, in addition to the routes in the Magic routing table. """ + import_filter_id: Optional[str] = None + """ID of the BGP filter profile applied to routes received from the customer.""" + md5_key: Optional[str] = None """MD5 key to use for session authentication. diff --git a/src/cloudflare/types/magic_transit/gre_tunnel_update_response.py b/src/cloudflare/types/magic_transit/gre_tunnel_update_response.py index a1bba508388..28ca8a99198 100644 --- a/src/cloudflare/types/magic_transit/gre_tunnel_update_response.py +++ b/src/cloudflare/types/magic_transit/gre_tunnel_update_response.py @@ -23,12 +23,18 @@ class ModifiedGRETunnelBGP(BaseModel): customer_asn: int """ASN used on the customer end of the BGP session""" + export_filter_id: Optional[str] = None + """ID of the BGP filter profile applied to routes advertised to the customer.""" + extra_prefixes: Optional[List[str]] = None """ Prefixes in this list will be advertised to the customer device, in addition to the routes in the Magic routing table. """ + import_filter_id: Optional[str] = None + """ID of the BGP filter profile applied to routes received from the customer.""" + md5_key: Optional[str] = None """MD5 key to use for session authentication. diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_bulk_update_response.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_bulk_update_response.py index 09d3a3e6bc4..2bd26657b61 100644 --- a/src/cloudflare/types/magic_transit/ipsec_tunnel_bulk_update_response.py +++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_bulk_update_response.py @@ -25,12 +25,18 @@ class ModifiedIPSECTunnelBGP(BaseModel): customer_asn: int """ASN used on the customer end of the BGP session""" + export_filter_id: Optional[str] = None + """ID of the BGP filter profile applied to routes advertised to the customer.""" + extra_prefixes: Optional[List[str]] = None """ Prefixes in this list will be advertised to the customer device, in addition to the routes in the Magic routing table. """ + import_filter_id: Optional[str] = None + """ID of the BGP filter profile applied to routes received from the customer.""" + md5_key: Optional[str] = None """MD5 key to use for session authentication. diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_create_params.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_create_params.py index cbfb544cfcf..42ad6c4cd85 100644 --- a/src/cloudflare/types/magic_transit/ipsec_tunnel_create_params.py +++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_create_params.py @@ -83,12 +83,18 @@ class BGP(TypedDict, total=False): customer_asn: Required[int] """ASN used on the customer end of the BGP session""" + export_filter_id: str + """ID of the BGP filter profile applied to routes advertised to the customer.""" + extra_prefixes: SequenceNotStr[str] """ Prefixes in this list will be advertised to the customer device, in addition to the routes in the Magic routing table. """ + import_filter_id: str + """ID of the BGP filter profile applied to routes received from the customer.""" + md5_key: str """MD5 key to use for session authentication. diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_create_response.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_create_response.py index 3dfa6eef0d3..3e415ceebb6 100644 --- a/src/cloudflare/types/magic_transit/ipsec_tunnel_create_response.py +++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_create_response.py @@ -24,12 +24,18 @@ class BGP(BaseModel): customer_asn: int """ASN used on the customer end of the BGP session""" + export_filter_id: Optional[str] = None + """ID of the BGP filter profile applied to routes advertised to the customer.""" + extra_prefixes: Optional[List[str]] = None """ Prefixes in this list will be advertised to the customer device, in addition to the routes in the Magic routing table. """ + import_filter_id: Optional[str] = None + """ID of the BGP filter profile applied to routes received from the customer.""" + md5_key: Optional[str] = None """MD5 key to use for session authentication. diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_delete_response.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_delete_response.py index 196c7dd3204..2b266a603ef 100644 --- a/src/cloudflare/types/magic_transit/ipsec_tunnel_delete_response.py +++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_delete_response.py @@ -25,12 +25,18 @@ class DeletedIPSECTunnelBGP(BaseModel): customer_asn: int """ASN used on the customer end of the BGP session""" + export_filter_id: Optional[str] = None + """ID of the BGP filter profile applied to routes advertised to the customer.""" + extra_prefixes: Optional[List[str]] = None """ Prefixes in this list will be advertised to the customer device, in addition to the routes in the Magic routing table. """ + import_filter_id: Optional[str] = None + """ID of the BGP filter profile applied to routes received from the customer.""" + md5_key: Optional[str] = None """MD5 key to use for session authentication. diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_get_response.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_get_response.py index f8bc64d3ba0..62e830f64ce 100644 --- a/src/cloudflare/types/magic_transit/ipsec_tunnel_get_response.py +++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_get_response.py @@ -25,12 +25,18 @@ class IPSECTunnelBGP(BaseModel): customer_asn: int """ASN used on the customer end of the BGP session""" + export_filter_id: Optional[str] = None + """ID of the BGP filter profile applied to routes advertised to the customer.""" + extra_prefixes: Optional[List[str]] = None """ Prefixes in this list will be advertised to the customer device, in addition to the routes in the Magic routing table. """ + import_filter_id: Optional[str] = None + """ID of the BGP filter profile applied to routes received from the customer.""" + md5_key: Optional[str] = None """MD5 key to use for session authentication. diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_list_response.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_list_response.py index 2b400df722d..5245477a780 100644 --- a/src/cloudflare/types/magic_transit/ipsec_tunnel_list_response.py +++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_list_response.py @@ -25,12 +25,18 @@ class IPSECTunnelBGP(BaseModel): customer_asn: int """ASN used on the customer end of the BGP session""" + export_filter_id: Optional[str] = None + """ID of the BGP filter profile applied to routes advertised to the customer.""" + extra_prefixes: Optional[List[str]] = None """ Prefixes in this list will be advertised to the customer device, in addition to the routes in the Magic routing table. """ + import_filter_id: Optional[str] = None + """ID of the BGP filter profile applied to routes received from the customer.""" + md5_key: Optional[str] = None """MD5 key to use for session authentication. diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_update_params.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_update_params.py index b8d6325f32e..c4d9e5b9bf4 100644 --- a/src/cloudflare/types/magic_transit/ipsec_tunnel_update_params.py +++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_update_params.py @@ -83,12 +83,18 @@ class BGP(TypedDict, total=False): customer_asn: Required[int] """ASN used on the customer end of the BGP session""" + export_filter_id: str + """ID of the BGP filter profile applied to routes advertised to the customer.""" + extra_prefixes: SequenceNotStr[str] """ Prefixes in this list will be advertised to the customer device, in addition to the routes in the Magic routing table. """ + import_filter_id: str + """ID of the BGP filter profile applied to routes received from the customer.""" + md5_key: str """MD5 key to use for session authentication. diff --git a/src/cloudflare/types/magic_transit/ipsec_tunnel_update_response.py b/src/cloudflare/types/magic_transit/ipsec_tunnel_update_response.py index 9e82141a51d..217447332b4 100644 --- a/src/cloudflare/types/magic_transit/ipsec_tunnel_update_response.py +++ b/src/cloudflare/types/magic_transit/ipsec_tunnel_update_response.py @@ -25,12 +25,18 @@ class ModifiedIPSECTunnelBGP(BaseModel): customer_asn: int """ASN used on the customer end of the BGP session""" + export_filter_id: Optional[str] = None + """ID of the BGP filter profile applied to routes advertised to the customer.""" + extra_prefixes: Optional[List[str]] = None """ Prefixes in this list will be advertised to the customer device, in addition to the routes in the Magic routing table. """ + import_filter_id: Optional[str] = None + """ID of the BGP filter profile applied to routes received from the customer.""" + md5_key: Optional[str] = None """MD5 key to use for session authentication. 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/src/cloudflare/types/zero_trust/access/application_create_params.py b/src/cloudflare/types/zero_trust/access/application_create_params.py index bc66ae1b3ee..a26b435aeff 100644 --- a/src/cloudflare/types/zero_trust/access/application_create_params.py +++ b/src/cloudflare/types/zero_trust/access/application_create_params.py @@ -3039,10 +3039,10 @@ class InfrastructureApplicationPolicyMfaConfig(TypedDict, total=False): Configures multi-factor authentication (MFA) settings for infrastructure applications. """ - allowed_authenticators: List[Literal["ssh_piv_key"]] + allowed_authenticators: List[Literal["piv_key"]] """Lists the MFA methods that users can authenticate with. - For infrastructure applications, only `ssh_piv_key` is supported. + For infrastructure applications, only `piv_key` is supported. """ mfa_disabled: bool diff --git a/src/cloudflare/types/zero_trust/access/application_create_response.py b/src/cloudflare/types/zero_trust/access/application_create_response.py index cc2f8dd4e3d..dd44a3f27ae 100644 --- a/src/cloudflare/types/zero_trust/access/application_create_response.py +++ b/src/cloudflare/types/zero_trust/access/application_create_response.py @@ -3068,10 +3068,10 @@ class InfrastructureApplicationPolicyMfaConfig(BaseModel): Configures multi-factor authentication (MFA) settings for infrastructure applications. """ - allowed_authenticators: Optional[List[Literal["ssh_piv_key"]]] = None + allowed_authenticators: Optional[List[Literal["piv_key"]]] = None """Lists the MFA methods that users can authenticate with. - For infrastructure applications, only `ssh_piv_key` is supported. + For infrastructure applications, only `piv_key` is supported. """ mfa_disabled: Optional[bool] = None diff --git a/src/cloudflare/types/zero_trust/access/application_get_response.py b/src/cloudflare/types/zero_trust/access/application_get_response.py index 6e024bb393d..07f245a1390 100644 --- a/src/cloudflare/types/zero_trust/access/application_get_response.py +++ b/src/cloudflare/types/zero_trust/access/application_get_response.py @@ -3068,10 +3068,10 @@ class InfrastructureApplicationPolicyMfaConfig(BaseModel): Configures multi-factor authentication (MFA) settings for infrastructure applications. """ - allowed_authenticators: Optional[List[Literal["ssh_piv_key"]]] = None + allowed_authenticators: Optional[List[Literal["piv_key"]]] = None """Lists the MFA methods that users can authenticate with. - For infrastructure applications, only `ssh_piv_key` is supported. + For infrastructure applications, only `piv_key` is supported. """ mfa_disabled: Optional[bool] = None diff --git a/src/cloudflare/types/zero_trust/access/application_list_response.py b/src/cloudflare/types/zero_trust/access/application_list_response.py index 9bf9d11f75a..d08bb9bc31b 100644 --- a/src/cloudflare/types/zero_trust/access/application_list_response.py +++ b/src/cloudflare/types/zero_trust/access/application_list_response.py @@ -3068,10 +3068,10 @@ class InfrastructureApplicationPolicyMfaConfig(BaseModel): Configures multi-factor authentication (MFA) settings for infrastructure applications. """ - allowed_authenticators: Optional[List[Literal["ssh_piv_key"]]] = None + allowed_authenticators: Optional[List[Literal["piv_key"]]] = None """Lists the MFA methods that users can authenticate with. - For infrastructure applications, only `ssh_piv_key` is supported. + For infrastructure applications, only `piv_key` is supported. """ mfa_disabled: Optional[bool] = None diff --git a/src/cloudflare/types/zero_trust/access/application_update_params.py b/src/cloudflare/types/zero_trust/access/application_update_params.py index 04d3ad5a066..d1917d8e54c 100644 --- a/src/cloudflare/types/zero_trust/access/application_update_params.py +++ b/src/cloudflare/types/zero_trust/access/application_update_params.py @@ -3039,10 +3039,10 @@ class InfrastructureApplicationPolicyMfaConfig(TypedDict, total=False): Configures multi-factor authentication (MFA) settings for infrastructure applications. """ - allowed_authenticators: List[Literal["ssh_piv_key"]] + allowed_authenticators: List[Literal["piv_key"]] """Lists the MFA methods that users can authenticate with. - For infrastructure applications, only `ssh_piv_key` is supported. + For infrastructure applications, only `piv_key` is supported. """ mfa_disabled: bool diff --git a/src/cloudflare/types/zero_trust/access/application_update_response.py b/src/cloudflare/types/zero_trust/access/application_update_response.py index e7020006b87..935cb9a3967 100644 --- a/src/cloudflare/types/zero_trust/access/application_update_response.py +++ b/src/cloudflare/types/zero_trust/access/application_update_response.py @@ -3068,10 +3068,10 @@ class InfrastructureApplicationPolicyMfaConfig(BaseModel): Configures multi-factor authentication (MFA) settings for infrastructure applications. """ - allowed_authenticators: Optional[List[Literal["ssh_piv_key"]]] = None + allowed_authenticators: Optional[List[Literal["piv_key"]]] = None """Lists the MFA methods that users can authenticate with. - For infrastructure applications, only `ssh_piv_key` is supported. + For infrastructure applications, only `piv_key` is supported. """ mfa_disabled: Optional[bool] = None diff --git a/src/cloudflare/types/zero_trust/organization.py b/src/cloudflare/types/zero_trust/organization.py index b4f96e14ab1..b50bb9f26f3 100644 --- a/src/cloudflare/types/zero_trust/organization.py +++ b/src/cloudflare/types/zero_trust/organization.py @@ -6,7 +6,7 @@ from ..._models import BaseModel from .login_design import LoginDesign -__all__ = ["Organization", "CustomPages", "MfaConfig", "MfaSSHPivKeyRequirements"] +__all__ = ["Organization", "CustomPages", "MfaConfig", "MfaPivKeyRequirements"] class CustomPages(BaseModel): @@ -23,7 +23,7 @@ class CustomPages(BaseModel): class MfaConfig(BaseModel): """Configures multi-factor authentication (MFA) settings for an organization.""" - allowed_authenticators: Optional[List[Literal["totp", "biometrics", "security_key", "ssh_piv_key"]]] = None + allowed_authenticators: Optional[List[Literal["totp", "biometrics", "security_key", "piv_key"]]] = None """Lists the MFA methods that users can authenticate with.""" amr_matching_session_duration: Optional[str] = None @@ -45,8 +45,8 @@ class MfaConfig(BaseModel): """ -class MfaSSHPivKeyRequirements(BaseModel): - """Configures SSH PIV key requirements for MFA using hardware security keys.""" +class MfaPivKeyRequirements(BaseModel): + """Configures PIV key requirements for MFA using hardware security keys.""" pin_policy: Optional[Literal["never", "once", "always"]] = None """Defines when a PIN is required to use the SSH key. @@ -57,8 +57,8 @@ class MfaSSHPivKeyRequirements(BaseModel): require_fips_device: Optional[bool] = None """ - Requires the SSH PIV key to be stored on a FIPS 140-2 Level 1 or higher - validated device. + Requires the PIV key to be stored on a FIPS 140-2 Level 1 or higher validated + device. """ ssh_key_size: Optional[List[Literal[256, 384, 521, 2048, 3072, 4096]]] = None @@ -128,18 +128,18 @@ class Organization(BaseModel): mfa_config: Optional[MfaConfig] = None """Configures multi-factor authentication (MFA) settings for an organization.""" + mfa_piv_key_requirements: Optional[MfaPivKeyRequirements] = None + """Configures PIV key requirements for MFA using hardware security keys.""" + mfa_required_for_all_apps: Optional[bool] = None """Determines whether global MFA settings apply to applications by default. The organization must have MFA enabled with at least one authentication method and a session duration configured. Note: 'allowed_authenticators' cannot only - contain 'ssh_piv_key' if the organization has any non-infrastructure - applications because PIV keys are only compatible with infrastructure apps. + contain 'piv_key' if the organization has any non-infrastructure applications + because PIV keys are only compatible with infrastructure apps. """ - mfa_ssh_piv_key_requirements: Optional[MfaSSHPivKeyRequirements] = None - """Configures SSH PIV key requirements for MFA using hardware security keys.""" - name: Optional[str] = None """The name of your Zero Trust organization.""" diff --git a/src/cloudflare/types/zero_trust/organization_create_params.py b/src/cloudflare/types/zero_trust/organization_create_params.py index 7ace8bedc86..28ae4b5321f 100644 --- a/src/cloudflare/types/zero_trust/organization_create_params.py +++ b/src/cloudflare/types/zero_trust/organization_create_params.py @@ -8,7 +8,7 @@ from ..._types import SequenceNotStr from .login_design_param import LoginDesignParam -__all__ = ["OrganizationCreateParams", "MfaConfig", "MfaSSHPivKeyRequirements"] +__all__ = ["OrganizationCreateParams", "MfaConfig", "MfaPivKeyRequirements"] class OrganizationCreateParams(TypedDict, total=False): @@ -64,18 +64,18 @@ class OrganizationCreateParams(TypedDict, total=False): mfa_config: MfaConfig """Configures multi-factor authentication (MFA) settings for an organization.""" + mfa_piv_key_requirements: MfaPivKeyRequirements + """Configures PIV key requirements for MFA using hardware security keys.""" + mfa_required_for_all_apps: bool """Determines whether global MFA settings apply to applications by default. The organization must have MFA enabled with at least one authentication method and a session duration configured. Note: 'allowed_authenticators' cannot only - contain 'ssh_piv_key' if the organization has any non-infrastructure - applications because PIV keys are only compatible with infrastructure apps. + contain 'piv_key' if the organization has any non-infrastructure applications + because PIV keys are only compatible with infrastructure apps. """ - mfa_ssh_piv_key_requirements: MfaSSHPivKeyRequirements - """Configures SSH PIV key requirements for MFA using hardware security keys.""" - session_duration: str """The amount of time that tokens issued for applications will be valid. @@ -105,7 +105,7 @@ class OrganizationCreateParams(TypedDict, total=False): class MfaConfig(TypedDict, total=False): """Configures multi-factor authentication (MFA) settings for an organization.""" - allowed_authenticators: List[Literal["totp", "biometrics", "security_key", "ssh_piv_key"]] + allowed_authenticators: List[Literal["totp", "biometrics", "security_key", "piv_key"]] """Lists the MFA methods that users can authenticate with.""" amr_matching_session_duration: str @@ -127,8 +127,8 @@ class MfaConfig(TypedDict, total=False): """ -class MfaSSHPivKeyRequirements(TypedDict, total=False): - """Configures SSH PIV key requirements for MFA using hardware security keys.""" +class MfaPivKeyRequirements(TypedDict, total=False): + """Configures PIV key requirements for MFA using hardware security keys.""" pin_policy: Literal["never", "once", "always"] """Defines when a PIN is required to use the SSH key. @@ -139,8 +139,8 @@ class MfaSSHPivKeyRequirements(TypedDict, total=False): require_fips_device: bool """ - Requires the SSH PIV key to be stored on a FIPS 140-2 Level 1 or higher - validated device. + Requires the PIV key to be stored on a FIPS 140-2 Level 1 or higher validated + device. """ ssh_key_size: Iterable[Literal[256, 384, 521, 2048, 3072, 4096]] diff --git a/src/cloudflare/types/zero_trust/organization_update_params.py b/src/cloudflare/types/zero_trust/organization_update_params.py index 1405dd3ffb4..ab77fea8cd1 100644 --- a/src/cloudflare/types/zero_trust/organization_update_params.py +++ b/src/cloudflare/types/zero_trust/organization_update_params.py @@ -8,7 +8,7 @@ from ..._types import SequenceNotStr from .login_design_param import LoginDesignParam -__all__ = ["OrganizationUpdateParams", "CustomPages", "MfaConfig", "MfaSSHPivKeyRequirements"] +__all__ = ["OrganizationUpdateParams", "CustomPages", "MfaConfig", "MfaPivKeyRequirements"] class OrganizationUpdateParams(TypedDict, total=False): @@ -63,18 +63,18 @@ class OrganizationUpdateParams(TypedDict, total=False): mfa_config: MfaConfig """Configures multi-factor authentication (MFA) settings for an organization.""" + mfa_piv_key_requirements: MfaPivKeyRequirements + """Configures PIV key requirements for MFA using hardware security keys.""" + mfa_required_for_all_apps: bool """Determines whether global MFA settings apply to applications by default. The organization must have MFA enabled with at least one authentication method and a session duration configured. Note: 'allowed_authenticators' cannot only - contain 'ssh_piv_key' if the organization has any non-infrastructure - applications because PIV keys are only compatible with infrastructure apps. + contain 'piv_key' if the organization has any non-infrastructure applications + because PIV keys are only compatible with infrastructure apps. """ - mfa_ssh_piv_key_requirements: MfaSSHPivKeyRequirements - """Configures SSH PIV key requirements for MFA using hardware security keys.""" - name: str """The name of your Zero Trust organization.""" @@ -118,7 +118,7 @@ class CustomPages(TypedDict, total=False): class MfaConfig(TypedDict, total=False): """Configures multi-factor authentication (MFA) settings for an organization.""" - allowed_authenticators: List[Literal["totp", "biometrics", "security_key", "ssh_piv_key"]] + allowed_authenticators: List[Literal["totp", "biometrics", "security_key", "piv_key"]] """Lists the MFA methods that users can authenticate with.""" amr_matching_session_duration: str @@ -140,8 +140,8 @@ class MfaConfig(TypedDict, total=False): """ -class MfaSSHPivKeyRequirements(TypedDict, total=False): - """Configures SSH PIV key requirements for MFA using hardware security keys.""" +class MfaPivKeyRequirements(TypedDict, total=False): + """Configures PIV key requirements for MFA using hardware security keys.""" pin_policy: Literal["never", "once", "always"] """Defines when a PIN is required to use the SSH key. @@ -152,8 +152,8 @@ class MfaSSHPivKeyRequirements(TypedDict, total=False): require_fips_device: bool """ - Requires the SSH PIV key to be stored on a FIPS 140-2 Level 1 or higher - validated device. + Requires the PIV key to be stored on a FIPS 140-2 Level 1 or higher validated + device. """ ssh_key_size: Iterable[Literal[256, 384, 521, 2048, 3072, 4096]] diff --git a/tests/api_resources/ai_gateway/billing/test_spending_limit.py b/tests/api_resources/ai_gateway/billing/test_spending_limit.py index 78b1b9aad87..55637811211 100644 --- a/tests/api_resources/ai_gateway/billing/test_spending_limit.py +++ b/tests/api_resources/ai_gateway/billing/test_spending_limit.py @@ -11,6 +11,8 @@ from tests.utils import assert_matches_type from cloudflare.types.ai_gateway.billing import SpendingLimitGetResponse +# pyright: reportDeprecated=false + base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -20,23 +22,26 @@ class TestSpendingLimit: @pytest.mark.skip(reason="HTTP 404 error from prism") @parametrize def test_method_create(self, client: Cloudflare) -> None: - spending_limit = client.ai_gateway.billing.spending_limit.create( - account_id="account_id", - amount=10000, - duration="monthly", - strategy="fixed", - ) + with pytest.warns(DeprecationWarning): + spending_limit = client.ai_gateway.billing.spending_limit.create( + account_id="account_id", + amount=10000, + duration="monthly", + strategy="fixed", + ) + assert_matches_type(object, spending_limit, path=["response"]) @pytest.mark.skip(reason="HTTP 404 error from prism") @parametrize def test_raw_response_create(self, client: Cloudflare) -> None: - response = client.ai_gateway.billing.spending_limit.with_raw_response.create( - account_id="account_id", - amount=10000, - duration="monthly", - strategy="fixed", - ) + with pytest.warns(DeprecationWarning): + response = client.ai_gateway.billing.spending_limit.with_raw_response.create( + account_id="account_id", + amount=10000, + duration="monthly", + strategy="fixed", + ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -46,30 +51,32 @@ def test_raw_response_create(self, client: Cloudflare) -> None: @pytest.mark.skip(reason="HTTP 404 error from prism") @parametrize def test_streaming_response_create(self, client: Cloudflare) -> None: - with client.ai_gateway.billing.spending_limit.with_streaming_response.create( - account_id="account_id", - amount=10000, - duration="monthly", - strategy="fixed", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" + with pytest.warns(DeprecationWarning): + with client.ai_gateway.billing.spending_limit.with_streaming_response.create( + account_id="account_id", + amount=10000, + duration="monthly", + strategy="fixed", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" - spending_limit = response.parse() - assert_matches_type(object, spending_limit, path=["response"]) + spending_limit = response.parse() + assert_matches_type(object, spending_limit, path=["response"]) assert cast(Any, response.is_closed) is True @pytest.mark.skip(reason="HTTP 404 error from prism") @parametrize def test_path_params_create(self, client: Cloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - client.ai_gateway.billing.spending_limit.with_raw_response.create( - account_id="", - amount=10000, - duration="monthly", - strategy="fixed", - ) + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + client.ai_gateway.billing.spending_limit.with_raw_response.create( + account_id="", + amount=10000, + duration="monthly", + strategy="fixed", + ) @pytest.mark.skip(reason="HTTP 404 error from prism") @parametrize @@ -164,23 +171,26 @@ class TestAsyncSpendingLimit: @pytest.mark.skip(reason="HTTP 404 error from prism") @parametrize async def test_method_create(self, async_client: AsyncCloudflare) -> None: - spending_limit = await async_client.ai_gateway.billing.spending_limit.create( - account_id="account_id", - amount=10000, - duration="monthly", - strategy="fixed", - ) + with pytest.warns(DeprecationWarning): + spending_limit = await async_client.ai_gateway.billing.spending_limit.create( + account_id="account_id", + amount=10000, + duration="monthly", + strategy="fixed", + ) + assert_matches_type(object, spending_limit, path=["response"]) @pytest.mark.skip(reason="HTTP 404 error from prism") @parametrize async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: - response = await async_client.ai_gateway.billing.spending_limit.with_raw_response.create( - account_id="account_id", - amount=10000, - duration="monthly", - strategy="fixed", - ) + with pytest.warns(DeprecationWarning): + response = await async_client.ai_gateway.billing.spending_limit.with_raw_response.create( + account_id="account_id", + amount=10000, + duration="monthly", + strategy="fixed", + ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -190,30 +200,32 @@ async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: @pytest.mark.skip(reason="HTTP 404 error from prism") @parametrize async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: - async with async_client.ai_gateway.billing.spending_limit.with_streaming_response.create( - account_id="account_id", - amount=10000, - duration="monthly", - strategy="fixed", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" + with pytest.warns(DeprecationWarning): + async with async_client.ai_gateway.billing.spending_limit.with_streaming_response.create( + account_id="account_id", + amount=10000, + duration="monthly", + strategy="fixed", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" - spending_limit = await response.parse() - assert_matches_type(object, spending_limit, path=["response"]) + spending_limit = await response.parse() + assert_matches_type(object, spending_limit, path=["response"]) assert cast(Any, response.is_closed) is True @pytest.mark.skip(reason="HTTP 404 error from prism") @parametrize async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): - await async_client.ai_gateway.billing.spending_limit.with_raw_response.create( - account_id="", - amount=10000, - duration="monthly", - strategy="fixed", - ) + with pytest.warns(DeprecationWarning): + with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"): + await async_client.ai_gateway.billing.spending_limit.with_raw_response.create( + account_id="", + amount=10000, + duration="monthly", + strategy="fixed", + ) @pytest.mark.skip(reason="HTTP 404 error from prism") @parametrize diff --git a/tests/api_resources/email_auth/__init__.py b/tests/api_resources/email_auth/__init__.py new file mode 100644 index 00000000000..fd8019a9a1a --- /dev/null +++ b/tests/api_resources/email_auth/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/email_auth/spf/__init__.py b/tests/api_resources/email_auth/spf/__init__.py new file mode 100644 index 00000000000..fd8019a9a1a --- /dev/null +++ b/tests/api_resources/email_auth/spf/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/email_auth/spf/test_inspect.py b/tests/api_resources/email_auth/spf/test_inspect.py new file mode 100644 index 00000000000..c18654d8d3a --- /dev/null +++ b/tests/api_resources/email_auth/spf/test_inspect.py @@ -0,0 +1,108 @@ +# 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.email_auth.spf import InspectGetResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestInspect: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + inspect = client.email_auth.spf.inspect.get( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + id="id", + ) + assert_matches_type(Optional[InspectGetResponse], inspect, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.email_auth.spf.inspect.with_raw_response.get( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + id="id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + inspect = response.parse() + assert_matches_type(Optional[InspectGetResponse], inspect, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.email_auth.spf.inspect.with_streaming_response.get( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + id="id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + inspect = response.parse() + assert_matches_type(Optional[InspectGetResponse], inspect, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.email_auth.spf.inspect.with_raw_response.get( + zone_id="", + id="id", + ) + + +class TestAsyncInspect: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + inspect = await async_client.email_auth.spf.inspect.get( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + id="id", + ) + assert_matches_type(Optional[InspectGetResponse], inspect, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.email_auth.spf.inspect.with_raw_response.get( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + id="id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + inspect = await response.parse() + assert_matches_type(Optional[InspectGetResponse], inspect, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.email_auth.spf.inspect.with_streaming_response.get( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + id="id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + inspect = await response.parse() + assert_matches_type(Optional[InspectGetResponse], inspect, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.email_auth.spf.inspect.with_raw_response.get( + zone_id="", + id="id", + ) diff --git a/tests/api_resources/email_auth/test_dmarc_reports.py b/tests/api_resources/email_auth/test_dmarc_reports.py new file mode 100644 index 00000000000..85d7655496e --- /dev/null +++ b/tests/api_resources/email_auth/test_dmarc_reports.py @@ -0,0 +1,194 @@ +# 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.email_auth import DMARCReportGetResponse, DMARCReportEditResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestDMARCReports: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_edit(self, client: Cloudflare) -> None: + dmarc_report = client.email_auth.dmarc_reports.edit( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[DMARCReportEditResponse], dmarc_report, path=["response"]) + + @parametrize + def test_method_edit_with_all_params(self, client: Cloudflare) -> None: + dmarc_report = client.email_auth.dmarc_reports.edit( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + enabled=True, + skip_wizard=False, + ) + assert_matches_type(Optional[DMARCReportEditResponse], dmarc_report, path=["response"]) + + @parametrize + def test_raw_response_edit(self, client: Cloudflare) -> None: + response = client.email_auth.dmarc_reports.with_raw_response.edit( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + dmarc_report = response.parse() + assert_matches_type(Optional[DMARCReportEditResponse], dmarc_report, path=["response"]) + + @parametrize + def test_streaming_response_edit(self, client: Cloudflare) -> None: + with client.email_auth.dmarc_reports.with_streaming_response.edit( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + dmarc_report = response.parse() + assert_matches_type(Optional[DMARCReportEditResponse], dmarc_report, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_edit(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.email_auth.dmarc_reports.with_raw_response.edit( + zone_id="", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + dmarc_report = client.email_auth.dmarc_reports.get( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[DMARCReportGetResponse], dmarc_report, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.email_auth.dmarc_reports.with_raw_response.get( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + dmarc_report = response.parse() + assert_matches_type(Optional[DMARCReportGetResponse], dmarc_report, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.email_auth.dmarc_reports.with_streaming_response.get( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + dmarc_report = response.parse() + assert_matches_type(Optional[DMARCReportGetResponse], dmarc_report, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_get(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.email_auth.dmarc_reports.with_raw_response.get( + zone_id="", + ) + + +class TestAsyncDMARCReports: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_edit(self, async_client: AsyncCloudflare) -> None: + dmarc_report = await async_client.email_auth.dmarc_reports.edit( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[DMARCReportEditResponse], dmarc_report, path=["response"]) + + @parametrize + async def test_method_edit_with_all_params(self, async_client: AsyncCloudflare) -> None: + dmarc_report = await async_client.email_auth.dmarc_reports.edit( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + enabled=True, + skip_wizard=False, + ) + assert_matches_type(Optional[DMARCReportEditResponse], dmarc_report, path=["response"]) + + @parametrize + async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None: + response = await async_client.email_auth.dmarc_reports.with_raw_response.edit( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + dmarc_report = await response.parse() + assert_matches_type(Optional[DMARCReportEditResponse], dmarc_report, path=["response"]) + + @parametrize + async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> None: + async with async_client.email_auth.dmarc_reports.with_streaming_response.edit( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + dmarc_report = await response.parse() + assert_matches_type(Optional[DMARCReportEditResponse], dmarc_report, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_edit(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.email_auth.dmarc_reports.with_raw_response.edit( + zone_id="", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + dmarc_report = await async_client.email_auth.dmarc_reports.get( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[DMARCReportGetResponse], dmarc_report, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.email_auth.dmarc_reports.with_raw_response.get( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + dmarc_report = await response.parse() + assert_matches_type(Optional[DMARCReportGetResponse], dmarc_report, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.email_auth.dmarc_reports.with_streaming_response.get( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + dmarc_report = await response.parse() + assert_matches_type(Optional[DMARCReportGetResponse], dmarc_report, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_get(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.email_auth.dmarc_reports.with_raw_response.get( + zone_id="", + ) 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/magic_transit/test_gre_tunnels.py b/tests/api_resources/magic_transit/test_gre_tunnels.py index 95128794a5d..dc8a2757d5f 100644 --- a/tests/api_resources/magic_transit/test_gre_tunnels.py +++ b/tests/api_resources/magic_transit/test_gre_tunnels.py @@ -48,7 +48,9 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: automatic_return_routing=True, bgp={ "customer_asn": 0, + "export_filter_id": "a1b2c3d4e5f647890a1b2c3d4e5f6789", "extra_prefixes": ["string"], + "import_filter_id": "a1b2c3d4e5f647890a1b2c3d4e5f6789", "md5_key": "md5_key", }, description="Tunnel for ISP X", @@ -456,7 +458,9 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare automatic_return_routing=True, bgp={ "customer_asn": 0, + "export_filter_id": "a1b2c3d4e5f647890a1b2c3d4e5f6789", "extra_prefixes": ["string"], + "import_filter_id": "a1b2c3d4e5f647890a1b2c3d4e5f6789", "md5_key": "md5_key", }, description="Tunnel for ISP X", diff --git a/tests/api_resources/magic_transit/test_ipsec_tunnels.py b/tests/api_resources/magic_transit/test_ipsec_tunnels.py index a9c532cf3eb..d7d4aa22b0e 100644 --- a/tests/api_resources/magic_transit/test_ipsec_tunnels.py +++ b/tests/api_resources/magic_transit/test_ipsec_tunnels.py @@ -46,7 +46,9 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: automatic_return_routing=True, bgp={ "customer_asn": 0, + "export_filter_id": "a1b2c3d4e5f647890a1b2c3d4e5f6789", "extra_prefixes": ["string"], + "import_filter_id": "a1b2c3d4e5f647890a1b2c3d4e5f6789", "md5_key": "md5_key", }, custom_remote_identities={"fqdn_id": "fqdn_id"}, @@ -130,7 +132,9 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: automatic_return_routing=True, bgp={ "customer_asn": 0, + "export_filter_id": "a1b2c3d4e5f647890a1b2c3d4e5f6789", "extra_prefixes": ["string"], + "import_filter_id": "a1b2c3d4e5f647890a1b2c3d4e5f6789", "md5_key": "md5_key", }, custom_remote_identities={"fqdn_id": "fqdn_id"}, @@ -576,7 +580,9 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare automatic_return_routing=True, bgp={ "customer_asn": 0, + "export_filter_id": "a1b2c3d4e5f647890a1b2c3d4e5f6789", "extra_prefixes": ["string"], + "import_filter_id": "a1b2c3d4e5f647890a1b2c3d4e5f6789", "md5_key": "md5_key", }, custom_remote_identities={"fqdn_id": "fqdn_id"}, @@ -660,7 +666,9 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare automatic_return_routing=True, bgp={ "customer_asn": 0, + "export_filter_id": "a1b2c3d4e5f647890a1b2c3d4e5f6789", "extra_prefixes": ["string"], + "import_filter_id": "a1b2c3d4e5f647890a1b2c3d4e5f6789", "md5_key": "md5_key", }, custom_remote_identities={"fqdn_id": "fqdn_id"}, 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, diff --git a/tests/api_resources/zero_trust/access/test_applications.py b/tests/api_resources/zero_trust/access/test_applications.py index 8de6e58e2a8..027d2b429d3 100644 --- a/tests/api_resources/zero_trust/access/test_applications.py +++ b/tests/api_resources/zero_trust/access/test_applications.py @@ -1084,7 +1084,7 @@ def test_method_create_with_all_params_overload_10(self, client: Cloudflare) -> }, "exclude": [{"certificate": {}}], "mfa_config": { - "allowed_authenticators": ["ssh_piv_key"], + "allowed_authenticators": ["piv_key"], "mfa_disabled": False, "session_duration": "24h", }, @@ -2874,7 +2874,7 @@ def test_method_update_with_all_params_overload_10(self, client: Cloudflare) -> }, "exclude": [{"certificate": {}}], "mfa_config": { - "allowed_authenticators": ["ssh_piv_key"], + "allowed_authenticators": ["piv_key"], "mfa_disabled": False, "session_duration": "24h", }, @@ -4879,7 +4879,7 @@ async def test_method_create_with_all_params_overload_10(self, async_client: Asy }, "exclude": [{"certificate": {}}], "mfa_config": { - "allowed_authenticators": ["ssh_piv_key"], + "allowed_authenticators": ["piv_key"], "mfa_disabled": False, "session_duration": "24h", }, @@ -6669,7 +6669,7 @@ async def test_method_update_with_all_params_overload_10(self, async_client: Asy }, "exclude": [{"certificate": {}}], "mfa_config": { - "allowed_authenticators": ["ssh_piv_key"], + "allowed_authenticators": ["piv_key"], "mfa_disabled": False, "session_duration": "24h", }, diff --git a/tests/api_resources/zero_trust/test_organizations.py b/tests/api_resources/zero_trust/test_organizations.py index acc5cd43afc..a45ee5e8ddc 100644 --- a/tests/api_resources/zero_trust/test_organizations.py +++ b/tests/api_resources/zero_trust/test_organizations.py @@ -55,14 +55,14 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: "required_aaguids": "2fc0579f-8113-47ea-b116-bb5a8db9202a", "session_duration": "24h", }, - mfa_required_for_all_apps=False, - mfa_ssh_piv_key_requirements={ + mfa_piv_key_requirements={ "pin_policy": "always", "require_fips_device": True, "ssh_key_size": [256, 2048], "ssh_key_type": ["ecdsa", "rsa"], "touch_policy": "always", }, + mfa_required_for_all_apps=False, session_duration="24h", ui_read_only_toggle_reason="Temporarily turn off the UI read only lock to make a change via the UI", user_seat_expiration_inactive_time="730h", @@ -153,14 +153,14 @@ def test_method_update_with_all_params(self, client: Cloudflare) -> None: "required_aaguids": "2fc0579f-8113-47ea-b116-bb5a8db9202a", "session_duration": "24h", }, - mfa_required_for_all_apps=False, - mfa_ssh_piv_key_requirements={ + mfa_piv_key_requirements={ "pin_policy": "always", "require_fips_device": True, "ssh_key_size": [256, 2048], "ssh_key_type": ["ecdsa", "rsa"], "touch_policy": "always", }, + mfa_required_for_all_apps=False, name="Widget Corps Internal Applications", session_duration="24h", ui_read_only_toggle_reason="Temporarily turn off the UI read only lock to make a change via the UI", @@ -369,14 +369,14 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare "required_aaguids": "2fc0579f-8113-47ea-b116-bb5a8db9202a", "session_duration": "24h", }, - mfa_required_for_all_apps=False, - mfa_ssh_piv_key_requirements={ + mfa_piv_key_requirements={ "pin_policy": "always", "require_fips_device": True, "ssh_key_size": [256, 2048], "ssh_key_type": ["ecdsa", "rsa"], "touch_policy": "always", }, + mfa_required_for_all_apps=False, session_duration="24h", ui_read_only_toggle_reason="Temporarily turn off the UI read only lock to make a change via the UI", user_seat_expiration_inactive_time="730h", @@ -467,14 +467,14 @@ async def test_method_update_with_all_params(self, async_client: AsyncCloudflare "required_aaguids": "2fc0579f-8113-47ea-b116-bb5a8db9202a", "session_duration": "24h", }, - mfa_required_for_all_apps=False, - mfa_ssh_piv_key_requirements={ + mfa_piv_key_requirements={ "pin_policy": "always", "require_fips_device": True, "ssh_key_size": [256, 2048], "ssh_key_type": ["ecdsa", "rsa"], "touch_policy": "always", }, + mfa_required_for_all_apps=False, name="Widget Corps Internal Applications", session_duration="24h", ui_read_only_toggle_reason="Temporarily turn off the UI read only lock to make a change via the UI",