diff --git a/.stats.yml b/.stats.yml index 330be9e14a4..0440ff0afac 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,2 +1,2 @@ configured_endpoints: 1343 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare%2Fcloudflare-0053e474edb7f838f2b1d38334a7ccb983db09216cca0173a3c3d5401cadcf82.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare%2Fcloudflare-d780b9eb98465e97c30112eb2c9e586883852508d23a6684bd28e5a9cb7da7a1.yml diff --git a/api.md b/api.md index 5295390d972..5d3170fce1e 100644 --- a/api.md +++ b/api.md @@ -3498,15 +3498,9 @@ Methods: ### Downloads -Types: - -```python -from cloudflare.types.addressing.loa_documents import DownloadGetResponse -``` - Methods: -- client.addressing.loa_documents.downloads.get(loa_document_id, \*, account_id) -> object +- client.addressing.loa_documents.downloads.get(loa_document_id, \*, account_id) -> BinaryAPIResponse ## Prefixes diff --git a/src/cloudflare/resources/addressing/address_maps/address_maps.py b/src/cloudflare/resources/addressing/address_maps/address_maps.py index bb2faee96ef..c92ddd937a3 100644 --- a/src/cloudflare/resources/addressing/address_maps/address_maps.py +++ b/src/cloudflare/resources/addressing/address_maps/address_maps.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Type, Optional, cast +from typing import List, Type, Iterable, Optional, cast import httpx @@ -85,6 +85,8 @@ def create( account_id: str, description: Optional[str] | NotGiven = NOT_GIVEN, enabled: Optional[bool] | NotGiven = NOT_GIVEN, + ips: List[str] | NotGiven = NOT_GIVEN, + memberships: Iterable[address_map_create_params.Membership] | NotGiven = NOT_GIVEN, # 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, @@ -104,6 +106,9 @@ def create( enabled: Whether the Address Map is enabled or not. Cloudflare's DNS will not respond with IP addresses on an Address Map until the map is enabled. + memberships: Zones and Accounts which will be assigned IPs on this Address Map. A zone + membership will take priority over an account membership. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -120,6 +125,8 @@ def create( { "description": description, "enabled": enabled, + "ips": ips, + "memberships": memberships, }, address_map_create_params.AddressMapCreateParams, ), @@ -354,6 +361,8 @@ async def create( account_id: str, description: Optional[str] | NotGiven = NOT_GIVEN, enabled: Optional[bool] | NotGiven = NOT_GIVEN, + ips: List[str] | NotGiven = NOT_GIVEN, + memberships: Iterable[address_map_create_params.Membership] | NotGiven = NOT_GIVEN, # 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, @@ -373,6 +382,9 @@ async def create( enabled: Whether the Address Map is enabled or not. Cloudflare's DNS will not respond with IP addresses on an Address Map until the map is enabled. + memberships: Zones and Accounts which will be assigned IPs on this Address Map. A zone + membership will take priority over an account membership. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -389,6 +401,8 @@ async def create( { "description": description, "enabled": enabled, + "ips": ips, + "memberships": memberships, }, address_map_create_params.AddressMapCreateParams, ), diff --git a/src/cloudflare/resources/addressing/loa_documents/downloads.py b/src/cloudflare/resources/addressing/loa_documents/downloads.py index b29d0888acd..e333bc3e986 100644 --- a/src/cloudflare/resources/addressing/loa_documents/downloads.py +++ b/src/cloudflare/resources/addressing/loa_documents/downloads.py @@ -10,10 +10,14 @@ 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, + BinaryAPIResponse, + AsyncBinaryAPIResponse, + StreamedBinaryAPIResponse, + AsyncStreamedBinaryAPIResponse, + to_custom_raw_response_wrapper, + to_custom_streamed_response_wrapper, + async_to_custom_raw_response_wrapper, + async_to_custom_streamed_response_wrapper, ) from ...._base_client import ( make_request_options, @@ -42,7 +46,7 @@ def get( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> object: + ) -> BinaryAPIResponse: """ Download specified LOA document under the account. @@ -63,12 +67,13 @@ def get( raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") if not loa_document_id: raise ValueError(f"Expected a non-empty value for `loa_document_id` but received {loa_document_id!r}") + extra_headers = {"Accept": "application/pdf", **(extra_headers or {})} return self._get( f"/accounts/{account_id}/addressing/loa_documents/{loa_document_id}/download", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - cast_to=object, + cast_to=BinaryAPIResponse, ) @@ -92,7 +97,7 @@ async def get( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, - ) -> object: + ) -> AsyncBinaryAPIResponse: """ Download specified LOA document under the account. @@ -113,12 +118,13 @@ async def get( raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}") if not loa_document_id: raise ValueError(f"Expected a non-empty value for `loa_document_id` but received {loa_document_id!r}") + extra_headers = {"Accept": "application/pdf", **(extra_headers or {})} return await self._get( f"/accounts/{account_id}/addressing/loa_documents/{loa_document_id}/download", options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - cast_to=object, + cast_to=AsyncBinaryAPIResponse, ) @@ -126,8 +132,9 @@ class DownloadsResourceWithRawResponse: def __init__(self, downloads: DownloadsResource) -> None: self._downloads = downloads - self.get = to_raw_response_wrapper( + self.get = to_custom_raw_response_wrapper( downloads.get, + BinaryAPIResponse, ) @@ -135,8 +142,9 @@ class AsyncDownloadsResourceWithRawResponse: def __init__(self, downloads: AsyncDownloadsResource) -> None: self._downloads = downloads - self.get = async_to_raw_response_wrapper( + self.get = async_to_custom_raw_response_wrapper( downloads.get, + AsyncBinaryAPIResponse, ) @@ -144,8 +152,9 @@ class DownloadsResourceWithStreamingResponse: def __init__(self, downloads: DownloadsResource) -> None: self._downloads = downloads - self.get = to_streamed_response_wrapper( + self.get = to_custom_streamed_response_wrapper( downloads.get, + StreamedBinaryAPIResponse, ) @@ -153,6 +162,7 @@ class AsyncDownloadsResourceWithStreamingResponse: def __init__(self, downloads: AsyncDownloadsResource) -> None: self._downloads = downloads - self.get = async_to_streamed_response_wrapper( + self.get = async_to_custom_streamed_response_wrapper( downloads.get, + AsyncStreamedBinaryAPIResponse, ) diff --git a/src/cloudflare/types/addressing/address_map_create_params.py b/src/cloudflare/types/addressing/address_map_create_params.py index 5ecc49b6e6e..ac313102d61 100644 --- a/src/cloudflare/types/addressing/address_map_create_params.py +++ b/src/cloudflare/types/addressing/address_map_create_params.py @@ -2,10 +2,12 @@ from __future__ import annotations -from typing import Optional +from typing import List, Iterable, Optional from typing_extensions import Required, TypedDict -__all__ = ["AddressMapCreateParams"] +from .kind import Kind + +__all__ = ["AddressMapCreateParams", "Membership"] class AddressMapCreateParams(TypedDict, total=False): @@ -24,3 +26,19 @@ class AddressMapCreateParams(TypedDict, total=False): Cloudflare's DNS will not respond with IP addresses on an Address Map until the map is enabled. """ + + ips: List[str] + + memberships: Iterable[Membership] + """Zones and Accounts which will be assigned IPs on this Address Map. + + A zone membership will take priority over an account membership. + """ + + +class Membership(TypedDict, total=False): + identifier: str + """The identifier for the membership (eg. a zone or account tag).""" + + kind: Kind + """The type of the membership.""" diff --git a/src/cloudflare/types/addressing/address_map_create_response.py b/src/cloudflare/types/addressing/address_map_create_response.py index d4eb788e2df..032e1166d18 100644 --- a/src/cloudflare/types/addressing/address_map_create_response.py +++ b/src/cloudflare/types/addressing/address_map_create_response.py @@ -23,7 +23,7 @@ class Membership(BaseModel): created_at: Optional[datetime] = None identifier: Optional[str] = None - """Identifier""" + """The identifier for the membership (eg. a zone or account tag).""" kind: Optional[Kind] = None """The type of the membership.""" diff --git a/src/cloudflare/types/addressing/address_map_get_response.py b/src/cloudflare/types/addressing/address_map_get_response.py index 06bdfc92ed8..0eb306ccdbd 100644 --- a/src/cloudflare/types/addressing/address_map_get_response.py +++ b/src/cloudflare/types/addressing/address_map_get_response.py @@ -23,7 +23,7 @@ class Membership(BaseModel): created_at: Optional[datetime] = None identifier: Optional[str] = None - """Identifier""" + """The identifier for the membership (eg. a zone or account tag).""" kind: Optional[Kind] = None """The type of the membership.""" diff --git a/tests/api_resources/addressing/loa_documents/test_downloads.py b/tests/api_resources/addressing/loa_documents/test_downloads.py index db82ee230fa..bd37633f548 100644 --- a/tests/api_resources/addressing/loa_documents/test_downloads.py +++ b/tests/api_resources/addressing/loa_documents/test_downloads.py @@ -5,10 +5,17 @@ import os from typing import Any, cast +import httpx import pytest +from respx import MockRouter from cloudflare import Cloudflare, AsyncCloudflare -from tests.utils import assert_matches_type +from cloudflare._response import ( + BinaryAPIResponse, + AsyncBinaryAPIResponse, + StreamedBinaryAPIResponse, + AsyncStreamedBinaryAPIResponse, +) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -17,40 +24,58 @@ class TestDownloads: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - def test_method_get(self, client: Cloudflare) -> None: + @pytest.mark.respx(base_url=base_url) + def test_method_get(self, client: Cloudflare, respx_mock: MockRouter) -> None: + respx_mock.get( + "/accounts/023e105f4ecef8ad9ca31a8372d0c353/addressing/loa_documents/d933b1530bc56c9953cf8ce166da8004/download" + ).mock(return_value=httpx.Response(200, json={"foo": "bar"})) download = client.addressing.loa_documents.downloads.get( "d933b1530bc56c9953cf8ce166da8004", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(object, download, path=["response"]) + assert download.is_closed + assert download.json() == {"foo": "bar"} + assert cast(Any, download.is_closed) is True + assert isinstance(download, BinaryAPIResponse) @parametrize - def test_raw_response_get(self, client: Cloudflare) -> None: - response = client.addressing.loa_documents.downloads.with_raw_response.get( + @pytest.mark.respx(base_url=base_url) + def test_raw_response_get(self, client: Cloudflare, respx_mock: MockRouter) -> None: + respx_mock.get( + "/accounts/023e105f4ecef8ad9ca31a8372d0c353/addressing/loa_documents/d933b1530bc56c9953cf8ce166da8004/download" + ).mock(return_value=httpx.Response(200, json={"foo": "bar"})) + + download = client.addressing.loa_documents.downloads.with_raw_response.get( "d933b1530bc56c9953cf8ce166da8004", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - download = response.parse() - assert_matches_type(object, download, path=["response"]) + assert download.is_closed is True + assert download.http_request.headers.get("X-Stainless-Lang") == "python" + assert download.json() == {"foo": "bar"} + assert isinstance(download, BinaryAPIResponse) @parametrize - def test_streaming_response_get(self, client: Cloudflare) -> None: + @pytest.mark.respx(base_url=base_url) + def test_streaming_response_get(self, client: Cloudflare, respx_mock: MockRouter) -> None: + respx_mock.get( + "/accounts/023e105f4ecef8ad9ca31a8372d0c353/addressing/loa_documents/d933b1530bc56c9953cf8ce166da8004/download" + ).mock(return_value=httpx.Response(200, json={"foo": "bar"})) with client.addressing.loa_documents.downloads.with_streaming_response.get( "d933b1530bc56c9953cf8ce166da8004", account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" + ) as download: + assert not download.is_closed + assert download.http_request.headers.get("X-Stainless-Lang") == "python" - download = response.parse() - assert_matches_type(object, download, path=["response"]) + assert download.json() == {"foo": "bar"} + assert cast(Any, download.is_closed) is True + assert isinstance(download, StreamedBinaryAPIResponse) - assert cast(Any, response.is_closed) is True + assert cast(Any, download.is_closed) is True @parametrize + @pytest.mark.respx(base_url=base_url) 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.addressing.loa_documents.downloads.with_raw_response.get( @@ -69,40 +94,58 @@ class TestAsyncDownloads: parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) @parametrize - async def test_method_get(self, async_client: AsyncCloudflare) -> None: + @pytest.mark.respx(base_url=base_url) + async def test_method_get(self, async_client: AsyncCloudflare, respx_mock: MockRouter) -> None: + respx_mock.get( + "/accounts/023e105f4ecef8ad9ca31a8372d0c353/addressing/loa_documents/d933b1530bc56c9953cf8ce166da8004/download" + ).mock(return_value=httpx.Response(200, json={"foo": "bar"})) download = await async_client.addressing.loa_documents.downloads.get( "d933b1530bc56c9953cf8ce166da8004", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert_matches_type(object, download, path=["response"]) + assert download.is_closed + assert await download.json() == {"foo": "bar"} + assert cast(Any, download.is_closed) is True + assert isinstance(download, AsyncBinaryAPIResponse) @parametrize - async def test_raw_response_get(self, async_client: AsyncCloudflare) -> None: - response = await async_client.addressing.loa_documents.downloads.with_raw_response.get( + @pytest.mark.respx(base_url=base_url) + async def test_raw_response_get(self, async_client: AsyncCloudflare, respx_mock: MockRouter) -> None: + respx_mock.get( + "/accounts/023e105f4ecef8ad9ca31a8372d0c353/addressing/loa_documents/d933b1530bc56c9953cf8ce166da8004/download" + ).mock(return_value=httpx.Response(200, json={"foo": "bar"})) + + download = await async_client.addressing.loa_documents.downloads.with_raw_response.get( "d933b1530bc56c9953cf8ce166da8004", account_id="023e105f4ecef8ad9ca31a8372d0c353", ) - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - download = await response.parse() - assert_matches_type(object, download, path=["response"]) + assert download.is_closed is True + assert download.http_request.headers.get("X-Stainless-Lang") == "python" + assert await download.json() == {"foo": "bar"} + assert isinstance(download, AsyncBinaryAPIResponse) @parametrize - async def test_streaming_response_get(self, async_client: AsyncCloudflare) -> None: + @pytest.mark.respx(base_url=base_url) + async def test_streaming_response_get(self, async_client: AsyncCloudflare, respx_mock: MockRouter) -> None: + respx_mock.get( + "/accounts/023e105f4ecef8ad9ca31a8372d0c353/addressing/loa_documents/d933b1530bc56c9953cf8ce166da8004/download" + ).mock(return_value=httpx.Response(200, json={"foo": "bar"})) async with async_client.addressing.loa_documents.downloads.with_streaming_response.get( "d933b1530bc56c9953cf8ce166da8004", account_id="023e105f4ecef8ad9ca31a8372d0c353", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" + ) as download: + assert not download.is_closed + assert download.http_request.headers.get("X-Stainless-Lang") == "python" - download = await response.parse() - assert_matches_type(object, download, path=["response"]) + assert await download.json() == {"foo": "bar"} + assert cast(Any, download.is_closed) is True + assert isinstance(download, AsyncStreamedBinaryAPIResponse) - assert cast(Any, response.is_closed) is True + assert cast(Any, download.is_closed) is True @parametrize + @pytest.mark.respx(base_url=base_url) 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.addressing.loa_documents.downloads.with_raw_response.get( diff --git a/tests/api_resources/addressing/test_address_maps.py b/tests/api_resources/addressing/test_address_maps.py index 1a4e0b0a57c..a883e9dfd4b 100644 --- a/tests/api_resources/addressing/test_address_maps.py +++ b/tests/api_resources/addressing/test_address_maps.py @@ -36,6 +36,21 @@ def test_method_create_with_all_params(self, client: Cloudflare) -> None: account_id="023e105f4ecef8ad9ca31a8372d0c353", description="My Ecommerce zones", enabled=True, + ips=["192.0.2.1", "192.0.2.1", "192.0.2.1"], + memberships=[ + { + "identifier": "023e105f4ecef8ad9ca31a8372d0c353", + "kind": "zone", + }, + { + "identifier": "023e105f4ecef8ad9ca31a8372d0c353", + "kind": "zone", + }, + { + "identifier": "023e105f4ecef8ad9ca31a8372d0c353", + "kind": "zone", + }, + ], ) assert_matches_type(Optional[AddressMapCreateResponse], address_map, path=["response"]) @@ -280,6 +295,21 @@ async def test_method_create_with_all_params(self, async_client: AsyncCloudflare account_id="023e105f4ecef8ad9ca31a8372d0c353", description="My Ecommerce zones", enabled=True, + ips=["192.0.2.1", "192.0.2.1", "192.0.2.1"], + memberships=[ + { + "identifier": "023e105f4ecef8ad9ca31a8372d0c353", + "kind": "zone", + }, + { + "identifier": "023e105f4ecef8ad9ca31a8372d0c353", + "kind": "zone", + }, + { + "identifier": "023e105f4ecef8ad9ca31a8372d0c353", + "kind": "zone", + }, + ], ) assert_matches_type(Optional[AddressMapCreateResponse], address_map, path=["response"])