From 4d0481058b267b697907e089dbfbb06a7311620b Mon Sep 17 00:00:00 2001 From: Musa Jundi Date: Thu, 11 Jun 2026 15:20:30 -0500 Subject: [PATCH] fix(addressing): restore regional_hostnames sub-resource The regional_hostnames sub-resource was incorrectly removed in a curated sync (923e0c4). The upstream aggregate schema and Stainless codegen (stainless-sdks/cloudflare-python generated branch) both have these endpoints. This restores the resource, types, and tests as-is from the generated branch. Restored: - addressing.regional_hostnames (create, list, delete, edit, get) - addressing.regional_hostnames.regions (list) - All associated param/response types - Tests for both resources --- .../resources/addressing/__init__.py | 14 + .../resources/addressing/addressing.py | 32 + src/cloudflare/resources/addressing/api.md | 34 + .../addressing/regional_hostnames/__init__.py | 33 + .../regional_hostnames/regional_hostnames.py | 669 ++++++++++++++++++ .../addressing/regional_hostnames/regions.py | 171 +++++ src/cloudflare/types/addressing/__init__.py | 7 + .../regional_hostname_create_params.py | 24 + .../regional_hostname_create_response.py | 24 + .../regional_hostname_delete_response.py | 45 ++ .../regional_hostname_edit_params.py | 15 + .../regional_hostname_edit_response.py | 24 + .../regional_hostname_get_response.py | 24 + .../regional_hostname_list_response.py | 24 + .../addressing/regional_hostnames/__init__.py | 2 + .../region_list_response.py | 15 + .../addressing/regional_hostnames/__init__.py | 1 + .../regional_hostnames/test_regions.py | 101 +++ .../addressing/test_regional_hostnames.py | 517 ++++++++++++++ 19 files changed, 1776 insertions(+) create mode 100644 src/cloudflare/resources/addressing/regional_hostnames/__init__.py create mode 100644 src/cloudflare/resources/addressing/regional_hostnames/regional_hostnames.py create mode 100644 src/cloudflare/resources/addressing/regional_hostnames/regions.py create mode 100644 src/cloudflare/types/addressing/regional_hostname_create_params.py create mode 100644 src/cloudflare/types/addressing/regional_hostname_create_response.py create mode 100644 src/cloudflare/types/addressing/regional_hostname_delete_response.py create mode 100644 src/cloudflare/types/addressing/regional_hostname_edit_params.py create mode 100644 src/cloudflare/types/addressing/regional_hostname_edit_response.py create mode 100644 src/cloudflare/types/addressing/regional_hostname_get_response.py create mode 100644 src/cloudflare/types/addressing/regional_hostname_list_response.py create mode 100644 src/cloudflare/types/addressing/regional_hostnames/region_list_response.py create mode 100644 tests/api_resources/addressing/regional_hostnames/__init__.py create mode 100644 tests/api_resources/addressing/regional_hostnames/test_regions.py create mode 100644 tests/api_resources/addressing/test_regional_hostnames.py diff --git a/src/cloudflare/resources/addressing/__init__.py b/src/cloudflare/resources/addressing/__init__.py index 662ac0127d3..7abbb395744 100644 --- a/src/cloudflare/resources/addressing/__init__.py +++ b/src/cloudflare/resources/addressing/__init__.py @@ -40,8 +40,22 @@ LOADocumentsResourceWithStreamingResponse, AsyncLOADocumentsResourceWithStreamingResponse, ) +from .regional_hostnames import ( + RegionalHostnamesResource, + AsyncRegionalHostnamesResource, + RegionalHostnamesResourceWithRawResponse, + AsyncRegionalHostnamesResourceWithRawResponse, + RegionalHostnamesResourceWithStreamingResponse, + AsyncRegionalHostnamesResourceWithStreamingResponse, +) __all__ = [ + "RegionalHostnamesResource", + "AsyncRegionalHostnamesResource", + "RegionalHostnamesResourceWithRawResponse", + "AsyncRegionalHostnamesResourceWithRawResponse", + "RegionalHostnamesResourceWithStreamingResponse", + "AsyncRegionalHostnamesResourceWithStreamingResponse", "ServicesResource", "AsyncServicesResource", "ServicesResourceWithRawResponse", diff --git a/src/cloudflare/resources/addressing/addressing.py b/src/cloudflare/resources/addressing/addressing.py index 0acf8ff9b20..2ddc2d78362 100644 --- a/src/cloudflare/resources/addressing/addressing.py +++ b/src/cloudflare/resources/addressing/addressing.py @@ -36,11 +36,23 @@ AddressMapsResourceWithStreamingResponse, AsyncAddressMapsResourceWithStreamingResponse, ) +from .regional_hostnames.regional_hostnames import ( + RegionalHostnamesResource, + AsyncRegionalHostnamesResource, + RegionalHostnamesResourceWithRawResponse, + AsyncRegionalHostnamesResourceWithRawResponse, + RegionalHostnamesResourceWithStreamingResponse, + AsyncRegionalHostnamesResourceWithStreamingResponse, +) __all__ = ["AddressingResource", "AsyncAddressingResource"] class AddressingResource(SyncAPIResource): + @cached_property + def regional_hostnames(self) -> RegionalHostnamesResource: + return RegionalHostnamesResource(self._client) + @cached_property def services(self) -> ServicesResource: return ServicesResource(self._client) @@ -78,6 +90,10 @@ def with_streaming_response(self) -> AddressingResourceWithStreamingResponse: class AsyncAddressingResource(AsyncAPIResource): + @cached_property + def regional_hostnames(self) -> AsyncRegionalHostnamesResource: + return AsyncRegionalHostnamesResource(self._client) + @cached_property def services(self) -> AsyncServicesResource: return AsyncServicesResource(self._client) @@ -118,6 +134,10 @@ class AddressingResourceWithRawResponse: def __init__(self, addressing: AddressingResource) -> None: self._addressing = addressing + @cached_property + def regional_hostnames(self) -> RegionalHostnamesResourceWithRawResponse: + return RegionalHostnamesResourceWithRawResponse(self._addressing.regional_hostnames) + @cached_property def services(self) -> ServicesResourceWithRawResponse: return ServicesResourceWithRawResponse(self._addressing.services) @@ -139,6 +159,10 @@ class AsyncAddressingResourceWithRawResponse: def __init__(self, addressing: AsyncAddressingResource) -> None: self._addressing = addressing + @cached_property + def regional_hostnames(self) -> AsyncRegionalHostnamesResourceWithRawResponse: + return AsyncRegionalHostnamesResourceWithRawResponse(self._addressing.regional_hostnames) + @cached_property def services(self) -> AsyncServicesResourceWithRawResponse: return AsyncServicesResourceWithRawResponse(self._addressing.services) @@ -160,6 +184,10 @@ class AddressingResourceWithStreamingResponse: def __init__(self, addressing: AddressingResource) -> None: self._addressing = addressing + @cached_property + def regional_hostnames(self) -> RegionalHostnamesResourceWithStreamingResponse: + return RegionalHostnamesResourceWithStreamingResponse(self._addressing.regional_hostnames) + @cached_property def services(self) -> ServicesResourceWithStreamingResponse: return ServicesResourceWithStreamingResponse(self._addressing.services) @@ -181,6 +209,10 @@ class AsyncAddressingResourceWithStreamingResponse: def __init__(self, addressing: AsyncAddressingResource) -> None: self._addressing = addressing + @cached_property + def regional_hostnames(self) -> AsyncRegionalHostnamesResourceWithStreamingResponse: + return AsyncRegionalHostnamesResourceWithStreamingResponse(self._addressing.regional_hostnames) + @cached_property def services(self) -> AsyncServicesResourceWithStreamingResponse: return AsyncServicesResourceWithStreamingResponse(self._addressing.services) diff --git a/src/cloudflare/resources/addressing/api.md b/src/cloudflare/resources/addressing/api.md index 12fed5eee5d..0e7c10008bd 100644 --- a/src/cloudflare/resources/addressing/api.md +++ b/src/cloudflare/resources/addressing/api.md @@ -1,5 +1,39 @@ # Addressing +## RegionalHostnames + +Types: + +```python +from cloudflare.types.addressing import ( + RegionalHostnameCreateResponse, + RegionalHostnameListResponse, + RegionalHostnameDeleteResponse, + RegionalHostnameEditResponse, + RegionalHostnameGetResponse, +) +``` + +Methods: + +- client.addressing.regional_hostnames.create(\*, zone_id, \*\*params) -> Optional[RegionalHostnameCreateResponse] +- client.addressing.regional_hostnames.list(\*, zone_id) -> SyncSinglePage[RegionalHostnameListResponse] +- client.addressing.regional_hostnames.delete(hostname, \*, zone_id) -> RegionalHostnameDeleteResponse +- client.addressing.regional_hostnames.edit(hostname, \*, zone_id, \*\*params) -> Optional[RegionalHostnameEditResponse] +- client.addressing.regional_hostnames.get(hostname, \*, zone_id) -> Optional[RegionalHostnameGetResponse] + +### Regions + +Types: + +```python +from cloudflare.types.addressing.regional_hostnames import RegionListResponse +``` + +Methods: + +- client.addressing.regional_hostnames.regions.list(\*, account_id) -> SyncSinglePage[RegionListResponse] + ## Services Types: diff --git a/src/cloudflare/resources/addressing/regional_hostnames/__init__.py b/src/cloudflare/resources/addressing/regional_hostnames/__init__.py new file mode 100644 index 00000000000..b81e8f7c300 --- /dev/null +++ b/src/cloudflare/resources/addressing/regional_hostnames/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .regions import ( + RegionsResource, + AsyncRegionsResource, + RegionsResourceWithRawResponse, + AsyncRegionsResourceWithRawResponse, + RegionsResourceWithStreamingResponse, + AsyncRegionsResourceWithStreamingResponse, +) +from .regional_hostnames import ( + RegionalHostnamesResource, + AsyncRegionalHostnamesResource, + RegionalHostnamesResourceWithRawResponse, + AsyncRegionalHostnamesResourceWithRawResponse, + RegionalHostnamesResourceWithStreamingResponse, + AsyncRegionalHostnamesResourceWithStreamingResponse, +) + +__all__ = [ + "RegionsResource", + "AsyncRegionsResource", + "RegionsResourceWithRawResponse", + "AsyncRegionsResourceWithRawResponse", + "RegionsResourceWithStreamingResponse", + "AsyncRegionsResourceWithStreamingResponse", + "RegionalHostnamesResource", + "AsyncRegionalHostnamesResource", + "RegionalHostnamesResourceWithRawResponse", + "AsyncRegionalHostnamesResourceWithRawResponse", + "RegionalHostnamesResourceWithStreamingResponse", + "AsyncRegionalHostnamesResourceWithStreamingResponse", +] diff --git a/src/cloudflare/resources/addressing/regional_hostnames/regional_hostnames.py b/src/cloudflare/resources/addressing/regional_hostnames/regional_hostnames.py new file mode 100644 index 00000000000..7145a5da939 --- /dev/null +++ b/src/cloudflare/resources/addressing/regional_hostnames/regional_hostnames.py @@ -0,0 +1,669 @@ +# 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 .regions import ( + RegionsResource, + AsyncRegionsResource, + RegionsResourceWithRawResponse, + AsyncRegionsResourceWithRawResponse, + RegionsResourceWithStreamingResponse, + AsyncRegionsResourceWithStreamingResponse, +) +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 ....pagination import SyncSinglePage, AsyncSinglePage +from ...._base_client import AsyncPaginator, make_request_options +from ....types.addressing import regional_hostname_edit_params, regional_hostname_create_params +from ....types.addressing.regional_hostname_get_response import RegionalHostnameGetResponse +from ....types.addressing.regional_hostname_edit_response import RegionalHostnameEditResponse +from ....types.addressing.regional_hostname_list_response import RegionalHostnameListResponse +from ....types.addressing.regional_hostname_create_response import RegionalHostnameCreateResponse +from ....types.addressing.regional_hostname_delete_response import RegionalHostnameDeleteResponse + +__all__ = ["RegionalHostnamesResource", "AsyncRegionalHostnamesResource"] + + +class RegionalHostnamesResource(SyncAPIResource): + @cached_property + def regions(self) -> RegionsResource: + return RegionsResource(self._client) + + @cached_property + def with_raw_response(self) -> RegionalHostnamesResourceWithRawResponse: + """ + 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 RegionalHostnamesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> RegionalHostnamesResourceWithStreamingResponse: + """ + 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 RegionalHostnamesResourceWithStreamingResponse(self) + + def create( + self, + *, + zone_id: str, + hostname: str, + region_key: str, + routing: 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[RegionalHostnameCreateResponse]: + """Create a new Regional Hostname entry. + + Cloudflare will only use data centers that + are physically located within the chosen region to decrypt and service HTTPS + traffic. Learn more about + [Regional Services](https://developers.cloudflare.com/data-localization/regional-services/get-started/). + + Args: + zone_id: Identifier. + + hostname: DNS hostname to be regionalized, must be a subdomain of the zone. Wildcards are + supported for one level, e.g `*.example.com` + + region_key: Identifying key for the region + + routing: Configure which routing method to use for the regional hostname + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return self._post( + path_template("/zones/{zone_id}/addressing/regional_hostnames", zone_id=zone_id), + body=maybe_transform( + { + "hostname": hostname, + "region_key": region_key, + "routing": routing, + }, + regional_hostname_create_params.RegionalHostnameCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[RegionalHostnameCreateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[RegionalHostnameCreateResponse]], ResultWrapper[RegionalHostnameCreateResponse]), + ) + + def list( + 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, + ) -> SyncSinglePage[RegionalHostnameListResponse]: + """ + List all Regional Hostnames within a zone. + + 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_api_list( + path_template("/zones/{zone_id}/addressing/regional_hostnames", zone_id=zone_id), + page=SyncSinglePage[RegionalHostnameListResponse], + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + model=RegionalHostnameListResponse, + ) + + def delete( + self, + hostname: str, + *, + 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, + ) -> RegionalHostnameDeleteResponse: + """ + Delete the region configuration for a specific Regional Hostname. + + Args: + zone_id: Identifier. + + hostname: DNS hostname to be regionalized, must be a subdomain of the zone. Wildcards are + supported for one level, e.g `*.example.com` + + 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}") + if not hostname: + raise ValueError(f"Expected a non-empty value for `hostname` but received {hostname!r}") + return self._delete( + path_template( + "/zones/{zone_id}/addressing/regional_hostnames/{hostname}", zone_id=zone_id, hostname=hostname + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=RegionalHostnameDeleteResponse, + ) + + def edit( + self, + hostname: str, + *, + zone_id: str, + region_key: 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[RegionalHostnameEditResponse]: + """Update the configuration for a specific Regional Hostname. + + Only the region_key + of a hostname is mutable. + + Args: + zone_id: Identifier. + + hostname: DNS hostname to be regionalized, must be a subdomain of the zone. Wildcards are + supported for one level, e.g `*.example.com` + + region_key: Identifying key for the region + + 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}") + if not hostname: + raise ValueError(f"Expected a non-empty value for `hostname` but received {hostname!r}") + return self._patch( + path_template( + "/zones/{zone_id}/addressing/regional_hostnames/{hostname}", zone_id=zone_id, hostname=hostname + ), + body=maybe_transform({"region_key": region_key}, regional_hostname_edit_params.RegionalHostnameEditParams), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[RegionalHostnameEditResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[RegionalHostnameEditResponse]], ResultWrapper[RegionalHostnameEditResponse]), + ) + + def get( + self, + hostname: str, + *, + 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[RegionalHostnameGetResponse]: + """ + Fetch the configuration for a specific Regional Hostname, within a zone. + + Args: + zone_id: Identifier. + + hostname: DNS hostname to be regionalized, must be a subdomain of the zone. Wildcards are + supported for one level, e.g `*.example.com` + + 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}") + if not hostname: + raise ValueError(f"Expected a non-empty value for `hostname` but received {hostname!r}") + return self._get( + path_template( + "/zones/{zone_id}/addressing/regional_hostnames/{hostname}", zone_id=zone_id, hostname=hostname + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[RegionalHostnameGetResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[RegionalHostnameGetResponse]], ResultWrapper[RegionalHostnameGetResponse]), + ) + + +class AsyncRegionalHostnamesResource(AsyncAPIResource): + @cached_property + def regions(self) -> AsyncRegionsResource: + return AsyncRegionsResource(self._client) + + @cached_property + def with_raw_response(self) -> AsyncRegionalHostnamesResourceWithRawResponse: + """ + 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 AsyncRegionalHostnamesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncRegionalHostnamesResourceWithStreamingResponse: + """ + 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 AsyncRegionalHostnamesResourceWithStreamingResponse(self) + + async def create( + self, + *, + zone_id: str, + hostname: str, + region_key: str, + routing: 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[RegionalHostnameCreateResponse]: + """Create a new Regional Hostname entry. + + Cloudflare will only use data centers that + are physically located within the chosen region to decrypt and service HTTPS + traffic. Learn more about + [Regional Services](https://developers.cloudflare.com/data-localization/regional-services/get-started/). + + Args: + zone_id: Identifier. + + hostname: DNS hostname to be regionalized, must be a subdomain of the zone. Wildcards are + supported for one level, e.g `*.example.com` + + region_key: Identifying key for the region + + routing: Configure which routing method to use for the regional hostname + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not zone_id: + raise ValueError(f"Expected a non-empty value for `zone_id` but received {zone_id!r}") + return await self._post( + path_template("/zones/{zone_id}/addressing/regional_hostnames", zone_id=zone_id), + body=await async_maybe_transform( + { + "hostname": hostname, + "region_key": region_key, + "routing": routing, + }, + regional_hostname_create_params.RegionalHostnameCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[RegionalHostnameCreateResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[RegionalHostnameCreateResponse]], ResultWrapper[RegionalHostnameCreateResponse]), + ) + + def list( + 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, + ) -> AsyncPaginator[RegionalHostnameListResponse, AsyncSinglePage[RegionalHostnameListResponse]]: + """ + List all Regional Hostnames within a zone. + + 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_api_list( + path_template("/zones/{zone_id}/addressing/regional_hostnames", zone_id=zone_id), + page=AsyncSinglePage[RegionalHostnameListResponse], + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + model=RegionalHostnameListResponse, + ) + + async def delete( + self, + hostname: str, + *, + 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, + ) -> RegionalHostnameDeleteResponse: + """ + Delete the region configuration for a specific Regional Hostname. + + Args: + zone_id: Identifier. + + hostname: DNS hostname to be regionalized, must be a subdomain of the zone. Wildcards are + supported for one level, e.g `*.example.com` + + 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}") + if not hostname: + raise ValueError(f"Expected a non-empty value for `hostname` but received {hostname!r}") + return await self._delete( + path_template( + "/zones/{zone_id}/addressing/regional_hostnames/{hostname}", zone_id=zone_id, hostname=hostname + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=RegionalHostnameDeleteResponse, + ) + + async def edit( + self, + hostname: str, + *, + zone_id: str, + region_key: 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[RegionalHostnameEditResponse]: + """Update the configuration for a specific Regional Hostname. + + Only the region_key + of a hostname is mutable. + + Args: + zone_id: Identifier. + + hostname: DNS hostname to be regionalized, must be a subdomain of the zone. Wildcards are + supported for one level, e.g `*.example.com` + + region_key: Identifying key for the region + + 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}") + if not hostname: + raise ValueError(f"Expected a non-empty value for `hostname` but received {hostname!r}") + return await self._patch( + path_template( + "/zones/{zone_id}/addressing/regional_hostnames/{hostname}", zone_id=zone_id, hostname=hostname + ), + body=await async_maybe_transform( + {"region_key": region_key}, regional_hostname_edit_params.RegionalHostnameEditParams + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[RegionalHostnameEditResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[RegionalHostnameEditResponse]], ResultWrapper[RegionalHostnameEditResponse]), + ) + + async def get( + self, + hostname: str, + *, + 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[RegionalHostnameGetResponse]: + """ + Fetch the configuration for a specific Regional Hostname, within a zone. + + Args: + zone_id: Identifier. + + hostname: DNS hostname to be regionalized, must be a subdomain of the zone. Wildcards are + supported for one level, e.g `*.example.com` + + 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}") + if not hostname: + raise ValueError(f"Expected a non-empty value for `hostname` but received {hostname!r}") + return await self._get( + path_template( + "/zones/{zone_id}/addressing/regional_hostnames/{hostname}", zone_id=zone_id, hostname=hostname + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + post_parser=ResultWrapper[Optional[RegionalHostnameGetResponse]]._unwrapper, + ), + cast_to=cast(Type[Optional[RegionalHostnameGetResponse]], ResultWrapper[RegionalHostnameGetResponse]), + ) + + +class RegionalHostnamesResourceWithRawResponse: + def __init__(self, regional_hostnames: RegionalHostnamesResource) -> None: + self._regional_hostnames = regional_hostnames + + self.create = to_raw_response_wrapper( + regional_hostnames.create, + ) + self.list = to_raw_response_wrapper( + regional_hostnames.list, + ) + self.delete = to_raw_response_wrapper( + regional_hostnames.delete, + ) + self.edit = to_raw_response_wrapper( + regional_hostnames.edit, + ) + self.get = to_raw_response_wrapper( + regional_hostnames.get, + ) + + @cached_property + def regions(self) -> RegionsResourceWithRawResponse: + return RegionsResourceWithRawResponse(self._regional_hostnames.regions) + + +class AsyncRegionalHostnamesResourceWithRawResponse: + def __init__(self, regional_hostnames: AsyncRegionalHostnamesResource) -> None: + self._regional_hostnames = regional_hostnames + + self.create = async_to_raw_response_wrapper( + regional_hostnames.create, + ) + self.list = async_to_raw_response_wrapper( + regional_hostnames.list, + ) + self.delete = async_to_raw_response_wrapper( + regional_hostnames.delete, + ) + self.edit = async_to_raw_response_wrapper( + regional_hostnames.edit, + ) + self.get = async_to_raw_response_wrapper( + regional_hostnames.get, + ) + + @cached_property + def regions(self) -> AsyncRegionsResourceWithRawResponse: + return AsyncRegionsResourceWithRawResponse(self._regional_hostnames.regions) + + +class RegionalHostnamesResourceWithStreamingResponse: + def __init__(self, regional_hostnames: RegionalHostnamesResource) -> None: + self._regional_hostnames = regional_hostnames + + self.create = to_streamed_response_wrapper( + regional_hostnames.create, + ) + self.list = to_streamed_response_wrapper( + regional_hostnames.list, + ) + self.delete = to_streamed_response_wrapper( + regional_hostnames.delete, + ) + self.edit = to_streamed_response_wrapper( + regional_hostnames.edit, + ) + self.get = to_streamed_response_wrapper( + regional_hostnames.get, + ) + + @cached_property + def regions(self) -> RegionsResourceWithStreamingResponse: + return RegionsResourceWithStreamingResponse(self._regional_hostnames.regions) + + +class AsyncRegionalHostnamesResourceWithStreamingResponse: + def __init__(self, regional_hostnames: AsyncRegionalHostnamesResource) -> None: + self._regional_hostnames = regional_hostnames + + self.create = async_to_streamed_response_wrapper( + regional_hostnames.create, + ) + self.list = async_to_streamed_response_wrapper( + regional_hostnames.list, + ) + self.delete = async_to_streamed_response_wrapper( + regional_hostnames.delete, + ) + self.edit = async_to_streamed_response_wrapper( + regional_hostnames.edit, + ) + self.get = async_to_streamed_response_wrapper( + regional_hostnames.get, + ) + + @cached_property + def regions(self) -> AsyncRegionsResourceWithStreamingResponse: + return AsyncRegionsResourceWithStreamingResponse(self._regional_hostnames.regions) diff --git a/src/cloudflare/resources/addressing/regional_hostnames/regions.py b/src/cloudflare/resources/addressing/regional_hostnames/regions.py new file mode 100644 index 00000000000..ec9ea7806d7 --- /dev/null +++ b/src/cloudflare/resources/addressing/regional_hostnames/regions.py @@ -0,0 +1,171 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from ...._types import Body, Query, Headers, NotGiven, not_given +from ...._utils import path_template +from ...._compat import cached_property +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ....pagination import SyncSinglePage, AsyncSinglePage +from ...._base_client import AsyncPaginator, make_request_options +from ....types.addressing.regional_hostnames.region_list_response import RegionListResponse + +__all__ = ["RegionsResource", "AsyncRegionsResource"] + + +class RegionsResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> RegionsResourceWithRawResponse: + """ + 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 RegionsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> RegionsResourceWithStreamingResponse: + """ + 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 RegionsResourceWithStreamingResponse(self) + + def list( + self, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncSinglePage[RegionListResponse]: + """ + List all Regional Services regions available for use by this account. + + Args: + account_id: Identifier. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/addressing/regional_hostnames/regions", account_id=account_id), + page=SyncSinglePage[RegionListResponse], + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + model=RegionListResponse, + ) + + +class AsyncRegionsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncRegionsResourceWithRawResponse: + """ + 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 AsyncRegionsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncRegionsResourceWithStreamingResponse: + """ + 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 AsyncRegionsResourceWithStreamingResponse(self) + + def list( + self, + *, + account_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[RegionListResponse, AsyncSinglePage[RegionListResponse]]: + """ + List all Regional Services regions available for use by this account. + + Args: + account_id: Identifier. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not account_id: + raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") + return self._get_api_list( + path_template("/accounts/{account_id}/addressing/regional_hostnames/regions", account_id=account_id), + page=AsyncSinglePage[RegionListResponse], + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + model=RegionListResponse, + ) + + +class RegionsResourceWithRawResponse: + def __init__(self, regions: RegionsResource) -> None: + self._regions = regions + + self.list = to_raw_response_wrapper( + regions.list, + ) + + +class AsyncRegionsResourceWithRawResponse: + def __init__(self, regions: AsyncRegionsResource) -> None: + self._regions = regions + + self.list = async_to_raw_response_wrapper( + regions.list, + ) + + +class RegionsResourceWithStreamingResponse: + def __init__(self, regions: RegionsResource) -> None: + self._regions = regions + + self.list = to_streamed_response_wrapper( + regions.list, + ) + + +class AsyncRegionsResourceWithStreamingResponse: + def __init__(self, regions: AsyncRegionsResource) -> None: + self._regions = regions + + self.list = async_to_streamed_response_wrapper( + regions.list, + ) diff --git a/src/cloudflare/types/addressing/__init__.py b/src/cloudflare/types/addressing/__init__.py index 2ea66f6d7f8..1c96d654c50 100644 --- a/src/cloudflare/types/addressing/__init__.py +++ b/src/cloudflare/types/addressing/__init__.py @@ -16,3 +16,10 @@ from .address_map_create_response import AddressMapCreateResponse as AddressMapCreateResponse from .address_map_delete_response import AddressMapDeleteResponse as AddressMapDeleteResponse from .loa_document_create_response import LOADocumentCreateResponse as LOADocumentCreateResponse +from .regional_hostname_edit_params import RegionalHostnameEditParams as RegionalHostnameEditParams +from .regional_hostname_get_response import RegionalHostnameGetResponse as RegionalHostnameGetResponse +from .regional_hostname_create_params import RegionalHostnameCreateParams as RegionalHostnameCreateParams +from .regional_hostname_edit_response import RegionalHostnameEditResponse as RegionalHostnameEditResponse +from .regional_hostname_list_response import RegionalHostnameListResponse as RegionalHostnameListResponse +from .regional_hostname_create_response import RegionalHostnameCreateResponse as RegionalHostnameCreateResponse +from .regional_hostname_delete_response import RegionalHostnameDeleteResponse as RegionalHostnameDeleteResponse diff --git a/src/cloudflare/types/addressing/regional_hostname_create_params.py b/src/cloudflare/types/addressing/regional_hostname_create_params.py new file mode 100644 index 00000000000..c462c98f63d --- /dev/null +++ b/src/cloudflare/types/addressing/regional_hostname_create_params.py @@ -0,0 +1,24 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["RegionalHostnameCreateParams"] + + +class RegionalHostnameCreateParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier.""" + + hostname: Required[str] + """DNS hostname to be regionalized, must be a subdomain of the zone. + + Wildcards are supported for one level, e.g `*.example.com` + """ + + region_key: Required[str] + """Identifying key for the region""" + + routing: str + """Configure which routing method to use for the regional hostname""" diff --git a/src/cloudflare/types/addressing/regional_hostname_create_response.py b/src/cloudflare/types/addressing/regional_hostname_create_response.py new file mode 100644 index 00000000000..6d6436a9b2c --- /dev/null +++ b/src/cloudflare/types/addressing/regional_hostname_create_response.py @@ -0,0 +1,24 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from datetime import datetime + +from ..._models import BaseModel + +__all__ = ["RegionalHostnameCreateResponse"] + + +class RegionalHostnameCreateResponse(BaseModel): + created_on: datetime + """When the regional hostname was created""" + + hostname: str + """DNS hostname to be regionalized, must be a subdomain of the zone. + + Wildcards are supported for one level, e.g `*.example.com` + """ + + region_key: str + """Identifying key for the region""" + + routing: str + """Configure which routing method to use for the regional hostname""" diff --git a/src/cloudflare/types/addressing/regional_hostname_delete_response.py b/src/cloudflare/types/addressing/regional_hostname_delete_response.py new file mode 100644 index 00000000000..f478054084e --- /dev/null +++ b/src/cloudflare/types/addressing/regional_hostname_delete_response.py @@ -0,0 +1,45 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["RegionalHostnameDeleteResponse", "Error", "ErrorSource", "Message", "MessageSource"] + + +class ErrorSource(BaseModel): + pointer: Optional[str] = None + + +class Error(BaseModel): + code: int + + message: str + + documentation_url: Optional[str] = None + + source: Optional[ErrorSource] = None + + +class MessageSource(BaseModel): + pointer: Optional[str] = None + + +class Message(BaseModel): + code: int + + message: str + + documentation_url: Optional[str] = None + + source: Optional[MessageSource] = None + + +class RegionalHostnameDeleteResponse(BaseModel): + errors: List[Error] + + messages: List[Message] + + success: Literal[True] + """Whether the API call was successful.""" diff --git a/src/cloudflare/types/addressing/regional_hostname_edit_params.py b/src/cloudflare/types/addressing/regional_hostname_edit_params.py new file mode 100644 index 00000000000..822196cf6af --- /dev/null +++ b/src/cloudflare/types/addressing/regional_hostname_edit_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__ = ["RegionalHostnameEditParams"] + + +class RegionalHostnameEditParams(TypedDict, total=False): + zone_id: Required[str] + """Identifier.""" + + region_key: Required[str] + """Identifying key for the region""" diff --git a/src/cloudflare/types/addressing/regional_hostname_edit_response.py b/src/cloudflare/types/addressing/regional_hostname_edit_response.py new file mode 100644 index 00000000000..dbfc847f34d --- /dev/null +++ b/src/cloudflare/types/addressing/regional_hostname_edit_response.py @@ -0,0 +1,24 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from datetime import datetime + +from ..._models import BaseModel + +__all__ = ["RegionalHostnameEditResponse"] + + +class RegionalHostnameEditResponse(BaseModel): + created_on: datetime + """When the regional hostname was created""" + + hostname: str + """DNS hostname to be regionalized, must be a subdomain of the zone. + + Wildcards are supported for one level, e.g `*.example.com` + """ + + region_key: str + """Identifying key for the region""" + + routing: str + """Configure which routing method to use for the regional hostname""" diff --git a/src/cloudflare/types/addressing/regional_hostname_get_response.py b/src/cloudflare/types/addressing/regional_hostname_get_response.py new file mode 100644 index 00000000000..8af646d5a44 --- /dev/null +++ b/src/cloudflare/types/addressing/regional_hostname_get_response.py @@ -0,0 +1,24 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from datetime import datetime + +from ..._models import BaseModel + +__all__ = ["RegionalHostnameGetResponse"] + + +class RegionalHostnameGetResponse(BaseModel): + created_on: datetime + """When the regional hostname was created""" + + hostname: str + """DNS hostname to be regionalized, must be a subdomain of the zone. + + Wildcards are supported for one level, e.g `*.example.com` + """ + + region_key: str + """Identifying key for the region""" + + routing: str + """Configure which routing method to use for the regional hostname""" diff --git a/src/cloudflare/types/addressing/regional_hostname_list_response.py b/src/cloudflare/types/addressing/regional_hostname_list_response.py new file mode 100644 index 00000000000..c995664571d --- /dev/null +++ b/src/cloudflare/types/addressing/regional_hostname_list_response.py @@ -0,0 +1,24 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from datetime import datetime + +from ..._models import BaseModel + +__all__ = ["RegionalHostnameListResponse"] + + +class RegionalHostnameListResponse(BaseModel): + created_on: datetime + """When the regional hostname was created""" + + hostname: str + """DNS hostname to be regionalized, must be a subdomain of the zone. + + Wildcards are supported for one level, e.g `*.example.com` + """ + + region_key: str + """Identifying key for the region""" + + routing: str + """Configure which routing method to use for the regional hostname""" diff --git a/src/cloudflare/types/addressing/regional_hostnames/__init__.py b/src/cloudflare/types/addressing/regional_hostnames/__init__.py index f8ee8b14b1c..cf8fe425ff5 100644 --- a/src/cloudflare/types/addressing/regional_hostnames/__init__.py +++ b/src/cloudflare/types/addressing/regional_hostnames/__init__.py @@ -1,3 +1,5 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from __future__ import annotations + +from .region_list_response import RegionListResponse as RegionListResponse diff --git a/src/cloudflare/types/addressing/regional_hostnames/region_list_response.py b/src/cloudflare/types/addressing/regional_hostnames/region_list_response.py new file mode 100644 index 00000000000..d17c6577e43 --- /dev/null +++ b/src/cloudflare/types/addressing/regional_hostnames/region_list_response.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from ...._models import BaseModel + +__all__ = ["RegionListResponse"] + + +class RegionListResponse(BaseModel): + key: Optional[str] = None + """Identifying key for the region""" + + label: Optional[str] = None + """Human-readable text label for the region""" diff --git a/tests/api_resources/addressing/regional_hostnames/__init__.py b/tests/api_resources/addressing/regional_hostnames/__init__.py new file mode 100644 index 00000000000..fd8019a9a1a --- /dev/null +++ b/tests/api_resources/addressing/regional_hostnames/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/addressing/regional_hostnames/test_regions.py b/tests/api_resources/addressing/regional_hostnames/test_regions.py new file mode 100644 index 00000000000..e06d39e8cf3 --- /dev/null +++ b/tests/api_resources/addressing/regional_hostnames/test_regions.py @@ -0,0 +1,101 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncSinglePage, AsyncSinglePage +from cloudflare.types.addressing.regional_hostnames import RegionListResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestRegions: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + region = client.addressing.regional_hostnames.regions.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(SyncSinglePage[RegionListResponse], region, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.addressing.regional_hostnames.regions.with_raw_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + region = response.parse() + assert_matches_type(SyncSinglePage[RegionListResponse], region, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.addressing.regional_hostnames.regions.with_streaming_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + region = response.parse() + assert_matches_type(SyncSinglePage[RegionListResponse], region, 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.addressing.regional_hostnames.regions.with_raw_response.list( + account_id="", + ) + + +class TestAsyncRegions: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + region = await async_client.addressing.regional_hostnames.regions.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(AsyncSinglePage[RegionListResponse], region, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.addressing.regional_hostnames.regions.with_raw_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + region = await response.parse() + assert_matches_type(AsyncSinglePage[RegionListResponse], region, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.addressing.regional_hostnames.regions.with_streaming_response.list( + account_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + region = await response.parse() + assert_matches_type(AsyncSinglePage[RegionListResponse], region, 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.addressing.regional_hostnames.regions.with_raw_response.list( + account_id="", + ) diff --git a/tests/api_resources/addressing/test_regional_hostnames.py b/tests/api_resources/addressing/test_regional_hostnames.py new file mode 100644 index 00000000000..6f9c356c87a --- /dev/null +++ b/tests/api_resources/addressing/test_regional_hostnames.py @@ -0,0 +1,517 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, Optional, cast + +import pytest + +from cloudflare import Cloudflare, AsyncCloudflare +from tests.utils import assert_matches_type +from cloudflare.pagination import SyncSinglePage, AsyncSinglePage +from cloudflare.types.addressing import ( + RegionalHostnameGetResponse, + RegionalHostnameEditResponse, + RegionalHostnameListResponse, + RegionalHostnameCreateResponse, + RegionalHostnameDeleteResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestRegionalHostnames: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_create(self, client: Cloudflare) -> None: + regional_hostname = client.addressing.regional_hostnames.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + hostname="foo.example.com", + region_key="ca", + ) + assert_matches_type(Optional[RegionalHostnameCreateResponse], regional_hostname, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: Cloudflare) -> None: + regional_hostname = client.addressing.regional_hostnames.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + hostname="foo.example.com", + region_key="ca", + routing="dns", + ) + assert_matches_type(Optional[RegionalHostnameCreateResponse], regional_hostname, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Cloudflare) -> None: + response = client.addressing.regional_hostnames.with_raw_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + hostname="foo.example.com", + region_key="ca", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + regional_hostname = response.parse() + assert_matches_type(Optional[RegionalHostnameCreateResponse], regional_hostname, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Cloudflare) -> None: + with client.addressing.regional_hostnames.with_streaming_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + hostname="foo.example.com", + region_key="ca", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + regional_hostname = response.parse() + assert_matches_type(Optional[RegionalHostnameCreateResponse], regional_hostname, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create(self, client: Cloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + client.addressing.regional_hostnames.with_raw_response.create( + zone_id="", + hostname="foo.example.com", + region_key="ca", + ) + + @parametrize + def test_method_list(self, client: Cloudflare) -> None: + regional_hostname = client.addressing.regional_hostnames.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(SyncSinglePage[RegionalHostnameListResponse], regional_hostname, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: Cloudflare) -> None: + response = client.addressing.regional_hostnames.with_raw_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + regional_hostname = response.parse() + assert_matches_type(SyncSinglePage[RegionalHostnameListResponse], regional_hostname, path=["response"]) + + @parametrize + def test_streaming_response_list(self, client: Cloudflare) -> None: + with client.addressing.regional_hostnames.with_streaming_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + regional_hostname = response.parse() + assert_matches_type(SyncSinglePage[RegionalHostnameListResponse], regional_hostname, 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.addressing.regional_hostnames.with_raw_response.list( + zone_id="", + ) + + @parametrize + def test_method_delete(self, client: Cloudflare) -> None: + regional_hostname = client.addressing.regional_hostnames.delete( + hostname="foo.example.com", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(RegionalHostnameDeleteResponse, regional_hostname, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: Cloudflare) -> None: + response = client.addressing.regional_hostnames.with_raw_response.delete( + hostname="foo.example.com", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + regional_hostname = response.parse() + assert_matches_type(RegionalHostnameDeleteResponse, regional_hostname, path=["response"]) + + @parametrize + def test_streaming_response_delete(self, client: Cloudflare) -> None: + with client.addressing.regional_hostnames.with_streaming_response.delete( + hostname="foo.example.com", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + regional_hostname = response.parse() + assert_matches_type(RegionalHostnameDeleteResponse, regional_hostname, 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 `zone_id` but received ''"): + client.addressing.regional_hostnames.with_raw_response.delete( + hostname="foo.example.com", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `hostname` but received ''"): + client.addressing.regional_hostnames.with_raw_response.delete( + hostname="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + def test_method_edit(self, client: Cloudflare) -> None: + regional_hostname = client.addressing.regional_hostnames.edit( + hostname="foo.example.com", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + region_key="ca", + ) + assert_matches_type(Optional[RegionalHostnameEditResponse], regional_hostname, path=["response"]) + + @parametrize + def test_raw_response_edit(self, client: Cloudflare) -> None: + response = client.addressing.regional_hostnames.with_raw_response.edit( + hostname="foo.example.com", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + region_key="ca", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + regional_hostname = response.parse() + assert_matches_type(Optional[RegionalHostnameEditResponse], regional_hostname, path=["response"]) + + @parametrize + def test_streaming_response_edit(self, client: Cloudflare) -> None: + with client.addressing.regional_hostnames.with_streaming_response.edit( + hostname="foo.example.com", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + region_key="ca", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + regional_hostname = response.parse() + assert_matches_type(Optional[RegionalHostnameEditResponse], regional_hostname, 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.addressing.regional_hostnames.with_raw_response.edit( + hostname="foo.example.com", + zone_id="", + region_key="ca", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `hostname` but received ''"): + client.addressing.regional_hostnames.with_raw_response.edit( + hostname="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + region_key="ca", + ) + + @parametrize + def test_method_get(self, client: Cloudflare) -> None: + regional_hostname = client.addressing.regional_hostnames.get( + hostname="foo.example.com", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[RegionalHostnameGetResponse], regional_hostname, path=["response"]) + + @parametrize + def test_raw_response_get(self, client: Cloudflare) -> None: + response = client.addressing.regional_hostnames.with_raw_response.get( + hostname="foo.example.com", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + regional_hostname = response.parse() + assert_matches_type(Optional[RegionalHostnameGetResponse], regional_hostname, path=["response"]) + + @parametrize + def test_streaming_response_get(self, client: Cloudflare) -> None: + with client.addressing.regional_hostnames.with_streaming_response.get( + hostname="foo.example.com", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + regional_hostname = response.parse() + assert_matches_type(Optional[RegionalHostnameGetResponse], regional_hostname, 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.addressing.regional_hostnames.with_raw_response.get( + hostname="foo.example.com", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `hostname` but received ''"): + client.addressing.regional_hostnames.with_raw_response.get( + hostname="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + +class TestAsyncRegionalHostnames: + 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: + regional_hostname = await async_client.addressing.regional_hostnames.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + hostname="foo.example.com", + region_key="ca", + ) + assert_matches_type(Optional[RegionalHostnameCreateResponse], regional_hostname, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncCloudflare) -> None: + regional_hostname = await async_client.addressing.regional_hostnames.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + hostname="foo.example.com", + region_key="ca", + routing="dns", + ) + assert_matches_type(Optional[RegionalHostnameCreateResponse], regional_hostname, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncCloudflare) -> None: + response = await async_client.addressing.regional_hostnames.with_raw_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + hostname="foo.example.com", + region_key="ca", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + regional_hostname = await response.parse() + assert_matches_type(Optional[RegionalHostnameCreateResponse], regional_hostname, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncCloudflare) -> None: + async with async_client.addressing.regional_hostnames.with_streaming_response.create( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + hostname="foo.example.com", + region_key="ca", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + regional_hostname = await response.parse() + assert_matches_type(Optional[RegionalHostnameCreateResponse], regional_hostname, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create(self, async_client: AsyncCloudflare) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `zone_id` but received ''"): + await async_client.addressing.regional_hostnames.with_raw_response.create( + zone_id="", + hostname="foo.example.com", + region_key="ca", + ) + + @parametrize + async def test_method_list(self, async_client: AsyncCloudflare) -> None: + regional_hostname = await async_client.addressing.regional_hostnames.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(AsyncSinglePage[RegionalHostnameListResponse], regional_hostname, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncCloudflare) -> None: + response = await async_client.addressing.regional_hostnames.with_raw_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + regional_hostname = await response.parse() + assert_matches_type(AsyncSinglePage[RegionalHostnameListResponse], regional_hostname, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncCloudflare) -> None: + async with async_client.addressing.regional_hostnames.with_streaming_response.list( + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + regional_hostname = await response.parse() + assert_matches_type(AsyncSinglePage[RegionalHostnameListResponse], regional_hostname, 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.addressing.regional_hostnames.with_raw_response.list( + zone_id="", + ) + + @parametrize + async def test_method_delete(self, async_client: AsyncCloudflare) -> None: + regional_hostname = await async_client.addressing.regional_hostnames.delete( + hostname="foo.example.com", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(RegionalHostnameDeleteResponse, regional_hostname, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, async_client: AsyncCloudflare) -> None: + response = await async_client.addressing.regional_hostnames.with_raw_response.delete( + hostname="foo.example.com", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + regional_hostname = await response.parse() + assert_matches_type(RegionalHostnameDeleteResponse, regional_hostname, path=["response"]) + + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncCloudflare) -> None: + async with async_client.addressing.regional_hostnames.with_streaming_response.delete( + hostname="foo.example.com", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + regional_hostname = await response.parse() + assert_matches_type(RegionalHostnameDeleteResponse, regional_hostname, 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 `zone_id` but received ''"): + await async_client.addressing.regional_hostnames.with_raw_response.delete( + hostname="foo.example.com", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `hostname` but received ''"): + await async_client.addressing.regional_hostnames.with_raw_response.delete( + hostname="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + @parametrize + async def test_method_edit(self, async_client: AsyncCloudflare) -> None: + regional_hostname = await async_client.addressing.regional_hostnames.edit( + hostname="foo.example.com", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + region_key="ca", + ) + assert_matches_type(Optional[RegionalHostnameEditResponse], regional_hostname, path=["response"]) + + @parametrize + async def test_raw_response_edit(self, async_client: AsyncCloudflare) -> None: + response = await async_client.addressing.regional_hostnames.with_raw_response.edit( + hostname="foo.example.com", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + region_key="ca", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + regional_hostname = await response.parse() + assert_matches_type(Optional[RegionalHostnameEditResponse], regional_hostname, path=["response"]) + + @parametrize + async def test_streaming_response_edit(self, async_client: AsyncCloudflare) -> None: + async with async_client.addressing.regional_hostnames.with_streaming_response.edit( + hostname="foo.example.com", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + region_key="ca", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + regional_hostname = await response.parse() + assert_matches_type(Optional[RegionalHostnameEditResponse], regional_hostname, 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.addressing.regional_hostnames.with_raw_response.edit( + hostname="foo.example.com", + zone_id="", + region_key="ca", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `hostname` but received ''"): + await async_client.addressing.regional_hostnames.with_raw_response.edit( + hostname="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + region_key="ca", + ) + + @parametrize + async def test_method_get(self, async_client: AsyncCloudflare) -> None: + regional_hostname = await async_client.addressing.regional_hostnames.get( + hostname="foo.example.com", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + assert_matches_type(Optional[RegionalHostnameGetResponse], regional_hostname, path=["response"]) + + @parametrize + async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: + response = await async_client.addressing.regional_hostnames.with_raw_response.get( + hostname="foo.example.com", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + regional_hostname = await response.parse() + assert_matches_type(Optional[RegionalHostnameGetResponse], regional_hostname, path=["response"]) + + @parametrize + async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + async with async_client.addressing.regional_hostnames.with_streaming_response.get( + hostname="foo.example.com", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + regional_hostname = await response.parse() + assert_matches_type(Optional[RegionalHostnameGetResponse], regional_hostname, 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.addressing.regional_hostnames.with_raw_response.get( + hostname="foo.example.com", + zone_id="", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `hostname` but received ''"): + await async_client.addressing.regional_hostnames.with_raw_response.get( + hostname="", + zone_id="023e105f4ecef8ad9ca31a8372d0c353", + )