diff --git a/end_to_end_tests/golden-record/my_test_api_client/client.py b/end_to_end_tests/golden-record/my_test_api_client/client.py index e80446f10..9b01a2795 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/client.py +++ b/end_to_end_tests/golden-record/my_test_api_client/client.py @@ -1,4 +1,5 @@ import ssl +import urllib.parse from typing import Any, Optional, Union import httpx @@ -266,3 +267,27 @@ async def __aenter__(self) -> "AuthenticatedClient": async def __aexit__(self, *args: Any, **kwargs: Any) -> None: """Exit a context manager for underlying httpx.AsyncClient (see httpx docs)""" await self.get_async_httpx_client().__aexit__(*args, **kwargs) + + +def replace_client_path(client: Client, base_path: str) -> Client: + """Override a client's base URL with a new path. Does not update scheme, host, or other URL parts.""" + parsed = urllib.parse.urlparse(client._base_url) + # _replace is not private, it's part of the NamedTuple API but prefixed _ to avoid conflicts + updated_url = parsed._replace(path=base_path) + client._base_url = updated_url.geturl() + return client + + +def v3_stable_client(client: Client) -> Client: + """Override a client's base URL with a v2 stable path.""" + return replace_client_path(client, "api/v3-draft") + + +def v3_alpha_client(client: Client) -> Client: + """Override a client's base URL with a v2-alpha path.""" + return replace_client_path(client, "api/v3-alpha") + + +def v3_beta_client(client: Client) -> Client: + """Override a client's base URL with a v2-beta path.""" + return replace_client_path(client, "api/v3-beta") diff --git a/end_to_end_tests/literal-enums-golden-record/my_enum_api_client/client.py b/end_to_end_tests/literal-enums-golden-record/my_enum_api_client/client.py index e80446f10..9b01a2795 100644 --- a/end_to_end_tests/literal-enums-golden-record/my_enum_api_client/client.py +++ b/end_to_end_tests/literal-enums-golden-record/my_enum_api_client/client.py @@ -1,4 +1,5 @@ import ssl +import urllib.parse from typing import Any, Optional, Union import httpx @@ -266,3 +267,27 @@ async def __aenter__(self) -> "AuthenticatedClient": async def __aexit__(self, *args: Any, **kwargs: Any) -> None: """Exit a context manager for underlying httpx.AsyncClient (see httpx docs)""" await self.get_async_httpx_client().__aexit__(*args, **kwargs) + + +def replace_client_path(client: Client, base_path: str) -> Client: + """Override a client's base URL with a new path. Does not update scheme, host, or other URL parts.""" + parsed = urllib.parse.urlparse(client._base_url) + # _replace is not private, it's part of the NamedTuple API but prefixed _ to avoid conflicts + updated_url = parsed._replace(path=base_path) + client._base_url = updated_url.geturl() + return client + + +def v3_stable_client(client: Client) -> Client: + """Override a client's base URL with a v2 stable path.""" + return replace_client_path(client, "api/v3-draft") + + +def v3_alpha_client(client: Client) -> Client: + """Override a client's base URL with a v2-alpha path.""" + return replace_client_path(client, "api/v3-alpha") + + +def v3_beta_client(client: Client) -> Client: + """Override a client's base URL with a v2-beta path.""" + return replace_client_path(client, "api/v3-beta") diff --git a/end_to_end_tests/test-3-1-golden-record/test_3_1_features_client/client.py b/end_to_end_tests/test-3-1-golden-record/test_3_1_features_client/client.py index e80446f10..9b01a2795 100644 --- a/end_to_end_tests/test-3-1-golden-record/test_3_1_features_client/client.py +++ b/end_to_end_tests/test-3-1-golden-record/test_3_1_features_client/client.py @@ -1,4 +1,5 @@ import ssl +import urllib.parse from typing import Any, Optional, Union import httpx @@ -266,3 +267,27 @@ async def __aenter__(self) -> "AuthenticatedClient": async def __aexit__(self, *args: Any, **kwargs: Any) -> None: """Exit a context manager for underlying httpx.AsyncClient (see httpx docs)""" await self.get_async_httpx_client().__aexit__(*args, **kwargs) + + +def replace_client_path(client: Client, base_path: str) -> Client: + """Override a client's base URL with a new path. Does not update scheme, host, or other URL parts.""" + parsed = urllib.parse.urlparse(client._base_url) + # _replace is not private, it's part of the NamedTuple API but prefixed _ to avoid conflicts + updated_url = parsed._replace(path=base_path) + client._base_url = updated_url.geturl() + return client + + +def v3_stable_client(client: Client) -> Client: + """Override a client's base URL with a v2 stable path.""" + return replace_client_path(client, "api/v3-draft") + + +def v3_alpha_client(client: Client) -> Client: + """Override a client's base URL with a v2-alpha path.""" + return replace_client_path(client, "api/v3-alpha") + + +def v3_beta_client(client: Client) -> Client: + """Override a client's base URL with a v2-beta path.""" + return replace_client_path(client, "api/v3-beta") diff --git a/integration-tests/integration_tests/client.py b/integration-tests/integration_tests/client.py index e80446f10..9b01a2795 100644 --- a/integration-tests/integration_tests/client.py +++ b/integration-tests/integration_tests/client.py @@ -1,4 +1,5 @@ import ssl +import urllib.parse from typing import Any, Optional, Union import httpx @@ -266,3 +267,27 @@ async def __aenter__(self) -> "AuthenticatedClient": async def __aexit__(self, *args: Any, **kwargs: Any) -> None: """Exit a context manager for underlying httpx.AsyncClient (see httpx docs)""" await self.get_async_httpx_client().__aexit__(*args, **kwargs) + + +def replace_client_path(client: Client, base_path: str) -> Client: + """Override a client's base URL with a new path. Does not update scheme, host, or other URL parts.""" + parsed = urllib.parse.urlparse(client._base_url) + # _replace is not private, it's part of the NamedTuple API but prefixed _ to avoid conflicts + updated_url = parsed._replace(path=base_path) + client._base_url = updated_url.geturl() + return client + + +def v3_stable_client(client: Client) -> Client: + """Override a client's base URL with a v2 stable path.""" + return replace_client_path(client, "api/v3-draft") + + +def v3_alpha_client(client: Client) -> Client: + """Override a client's base URL with a v2-alpha path.""" + return replace_client_path(client, "api/v3-alpha") + + +def v3_beta_client(client: Client) -> Client: + """Override a client's base URL with a v2-beta path.""" + return replace_client_path(client, "api/v3-beta") diff --git a/openapi_python_client/templates/client.py.jinja b/openapi_python_client/templates/client.py.jinja index cf0301a9a..3a0df0a7b 100644 --- a/openapi_python_client/templates/client.py.jinja +++ b/openapi_python_client/templates/client.py.jinja @@ -1,4 +1,5 @@ import ssl +import urllib.parse from typing import Any, Union, Optional from attrs import define, field, evolve @@ -189,3 +190,26 @@ class AuthenticatedClient: {{ builders("AuthenticatedClient") }} {{ httpx_stuff("AuthenticatedClient", "self._headers[self.auth_header_name] = f\"{self.prefix} {self.token}\" if self.prefix else self.token") }} + +def replace_client_path(client: Client, base_path: str) -> Client: + """Override a client's base URL with a new path. Does not update scheme, host, or other URL parts.""" + parsed = urllib.parse.urlparse(client._base_url) + # _replace is not private, it's part of the NamedTuple API but prefixed _ to avoid conflicts + updated_url = parsed._replace(path=base_path) + client._base_url = updated_url.geturl() + return client + + +def v3_stable_client(client: Client) -> Client: + """Override a client's base URL with a v2 stable path.""" + return replace_client_path(client, "api/v3-draft") + + +def v3_alpha_client(client: Client) -> Client: + """Override a client's base URL with a v2-alpha path.""" + return replace_client_path(client, "api/v3-alpha") + + +def v3_beta_client(client: Client) -> Client: + """Override a client's base URL with a v2-beta path.""" + return replace_client_path(client, "api/v3-beta")