diff --git a/end_to_end_tests/golden-record/my_test_api_client/api/tests/post_form_data.py b/end_to_end_tests/golden-record/my_test_api_client/api/tests/post_form_data.py new file mode 100644 index 000000000..8152214c1 --- /dev/null +++ b/end_to_end_tests/golden-record/my_test_api_client/api/tests/post_form_data.py @@ -0,0 +1,68 @@ +from typing import Any, Dict + +import httpx + +from ...client import Client +from ...models.a_form_data import AFormData +from ...types import Response + + +def _get_kwargs( + *, + client: Client, + form_data: AFormData, +) -> Dict[str, Any]: + url = "{}/tests/post_form_data".format(client.base_url) + + headers: Dict[str, Any] = client.get_headers() + cookies: Dict[str, Any] = client.get_cookies() + + return { + "url": url, + "headers": headers, + "cookies": cookies, + "timeout": client.get_timeout(), + "data": form_data.to_dict(), + } + + +def _build_response(*, response: httpx.Response) -> Response[None]: + return Response( + status_code=response.status_code, + content=response.content, + headers=response.headers, + parsed=None, + ) + + +def sync_detailed( + *, + client: Client, + form_data: AFormData, +) -> Response[None]: + kwargs = _get_kwargs( + client=client, + form_data=form_data, + ) + + response = httpx.post( + **kwargs, + ) + + return _build_response(response=response) + + +async def asyncio_detailed( + *, + client: Client, + form_data: AFormData, +) -> Response[None]: + kwargs = _get_kwargs( + client=client, + form_data=form_data, + ) + + async with httpx.AsyncClient() as _client: + response = await _client.post(**kwargs) + + return _build_response(response=response) diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py b/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py index ea210a41f..0f7516048 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/__init__.py @@ -1,5 +1,6 @@ """ Contains all the data models used in inputs/outputs """ +from .a_form_data import AFormData from .a_model import AModel from .a_model_with_properties_reference_that_are_not_object import AModelWithPropertiesReferenceThatAreNotObject from .all_of_sub_model import AllOfSubModel diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/a_form_data.py b/end_to_end_tests/golden-record/my_test_api_client/models/a_form_data.py new file mode 100644 index 000000000..f5c34f5be --- /dev/null +++ b/end_to_end_tests/golden-record/my_test_api_client/models/a_form_data.py @@ -0,0 +1,63 @@ +from typing import Any, Dict, List, Type, TypeVar, Union + +import attr + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="AFormData") + + +@attr.s(auto_attribs=True) +class AFormData: + """ """ + + an_required_field: str + an_optional_field: Union[Unset, str] = UNSET + additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + an_required_field = self.an_required_field + an_optional_field = self.an_optional_field + + field_dict: Dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "an_required_field": an_required_field, + } + ) + if an_optional_field is not UNSET: + field_dict["an_optional_field"] = an_optional_field + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + an_required_field = d.pop("an_required_field") + + an_optional_field = d.pop("an_optional_field", UNSET) + + a_form_data = cls( + an_required_field=an_required_field, + an_optional_field=an_optional_field, + ) + + a_form_data.additional_properties = d + return a_form_data + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/end_to_end_tests/openapi.json b/end_to_end_tests/openapi.json index 64ccfdbc9..bbd227358 100644 --- a/end_to_end_tests/openapi.json +++ b/end_to_end_tests/openapi.json @@ -188,6 +188,36 @@ } } }, + "/tests/post_form_data": { + "post": { + "tags": [ + "tests" + ], + "sumnary": "Post from data", + "description": "Post form data", + "operationId": "post_form_data", + "requestBody": { + "content": { + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/AFormData" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + } + } + } + }, "/tests/upload": { "post": { "tags": [ @@ -797,6 +827,20 @@ }, "components": { "schemas": { + "AFormData": { + "type": "object", + "properties": { + "an_optional_field": { + "type": "string" + }, + "an_required_field": { + "type": "string" + } + }, + "required": [ + "an_required_field" + ] + }, "AModel": { "title": "AModel", "required": [ diff --git a/openapi_python_client/templates/endpoint_module.py.jinja b/openapi_python_client/templates/endpoint_module.py.jinja index 06876141a..687705def 100644 --- a/openapi_python_client/templates/endpoint_module.py.jinja +++ b/openapi_python_client/templates/endpoint_module.py.jinja @@ -1,7 +1,6 @@ from typing import Any, Dict, List, Optional, Union, cast import httpx -from attr import asdict from ...client import AuthenticatedClient, Client from ...types import Response, UNSET{% if endpoint.multipart_body_class %}, File {% endif %} @@ -52,7 +51,7 @@ def _get_kwargs( "cookies": cookies, "timeout": client.get_timeout(), {% if endpoint.form_body_class %} - "data": asdict(form_data), + "data": form_data.to_dict(), {% elif endpoint.multipart_body_class %} "files": files, "data": data,