Skip to content

Commit f385be8

Browse files
committed
Added detailed response functions, updated Black version.
1 parent 98a5aa1 commit f385be8

29 files changed

+739
-356
lines changed

CHANGELOG.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99
- Reorganized api calls in generated clients. `async_api` will no longer be generated. Each path operation will now
1010
have it's own module under its tag. For example, if there was a generated function `api.my_tag.my_function()` it is
1111
replaced with `api.my_tag.my_function.sync()`. The async version can be called with `asyncio()` instead of `sync()`.
12+
(#167)
1213
- Removed support for mutable default values (e.g. dicts, lists). They may be added back in a future version given enough
13-
demand, but the existing implementation was not up to this project's standards.
14+
demand, but the existing implementation was not up to this project's standards. (#170)
15+
- Removed generated `errors` module (and the `ApiResponseError` therein). Instead of raising an exception on failure,
16+
the `sync()` and `asyncio()` functions for a path operation will return `None`. This means all return types are now
17+
`Optional`, so mypy will require you to handle potential errors (or explicitly ignore them).
18+
- Moved `models.types` generated module up a level, so just `types`.
19+
20+
### Additions
21+
- Every generated API module will have a `sync_detailed()` and `asyncio_detailed()` function which work like their
22+
non-detailed counterparts, but return a `types.Response[T]` instead of an `Optional[T]` (where T is the parsed body type).
23+
`types.Response` contains `status_code`, `content` (bytes of returned content), `headers`, and `parsed` (the
24+
parsed return type you would get from the non-detailed function). (#115)
1425

1526

1627
## 0.5.4 - Unreleased

end_to_end_tests/fastapi_app/__init__.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
from pydantic import BaseModel
1010
from starlette.responses import FileResponse
1111

12-
app = FastAPI(title="My Test API", description="An API for testing openapi-python-client",)
12+
app = FastAPI(
13+
title="My Test API",
14+
description="An API for testing openapi-python-client",
15+
)
1316

1417

1518
@app.get("/ping", response_model=bool)
@@ -51,7 +54,8 @@ class AModel(BaseModel):
5154

5255
@test_router.get("/", response_model=List[AModel], operation_id="getUserList")
5356
def get_list(
54-
an_enum_value: List[AnEnum] = Query(...), some_date: Union[date, datetime] = Query(...),
57+
an_enum_value: List[AnEnum] = Query(...),
58+
some_date: Union[date, datetime] = Query(...),
5559
):
5660
""" Get a list of things """
5761
return

end_to_end_tests/golden-master/my_test_api_client/api/default/ping_ping_get.py

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
44
import httpx
55

66
from ...client import AuthenticatedClient, Client
7-
from ...errors import ApiResponseError
7+
from ...types import Response
88

99

10-
def _get_kwargs(*, client: Client,) -> Dict[str, Any]:
10+
def _get_kwargs(
11+
*,
12+
client: Client,
13+
) -> Dict[str, Any]:
1114
url = "{}/ping".format(client.base_url)
1215

1316
headers: Dict[str, Any] = client.get_headers()
@@ -18,31 +21,69 @@ def _get_kwargs(*, client: Client,) -> Dict[str, Any]:
1821
}
1922

2023

21-
def _parse_response(*, response: httpx.Response) -> bool:
22-
24+
def _parse_response(*, response: httpx.Response) -> Optional[bool]:
2325
if response.status_code == 200:
2426
return bool(response.text)
25-
else:
26-
raise ApiResponseError(response=response)
27-
27+
return None
2828

29-
def sync(*, client: Client,) -> bool:
3029

31-
""" A quick check to see if the system is running """
30+
def _build_response(*, response: httpx.Response) -> Response[bool]:
31+
return Response(
32+
status_code=response.status_code,
33+
content=response.content,
34+
headers=response.headers,
35+
parsed=_parse_response(response=response),
36+
)
3237

33-
kwargs = _get_kwargs(client=client,)
3438

35-
response = httpx.get(**kwargs,)
39+
def sync_detailed(
40+
*,
41+
client: Client,
42+
) -> Response[bool]:
43+
kwargs = _get_kwargs(
44+
client=client,
45+
)
3646

37-
return _parse_response(response=response)
47+
response = httpx.get(
48+
**kwargs,
49+
)
3850

51+
return _build_response(response=response)
3952

40-
async def asyncio(*, client: Client,) -> bool:
4153

54+
def sync(
55+
*,
56+
client: Client,
57+
) -> Optional[bool]:
4258
""" A quick check to see if the system is running """
43-
kwargs = _get_kwargs(client=client,)
59+
60+
return sync_detailed(
61+
client=client,
62+
).parsed
63+
64+
65+
async def asyncio_detailed(
66+
*,
67+
client: Client,
68+
) -> Response[bool]:
69+
kwargs = _get_kwargs(
70+
client=client,
71+
)
4472

4573
async with httpx.AsyncClient() as _client:
4674
response = await _client.get(**kwargs)
4775

48-
return _parse_response(response=response)
76+
return _build_response(response=response)
77+
78+
79+
async def asyncio(
80+
*,
81+
client: Client,
82+
) -> Optional[bool]:
83+
""" A quick check to see if the system is running """
84+
85+
return (
86+
await asyncio_detailed(
87+
client=client,
88+
)
89+
).parsed

end_to_end_tests/golden-master/my_test_api_client/api/tests/get_user_list.py

Lines changed: 75 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@
55
import httpx
66

77
from ...client import AuthenticatedClient, Client
8-
from ...errors import ApiResponseError
98
from ...models.a_model import AModel
109
from ...models.an_enum import AnEnum
1110
from ...models.http_validation_error import HTTPValidationError
11+
from ...types import Response
1212

1313

1414
def _get_kwargs(
15-
*, client: Client, an_enum_value: List[AnEnum], some_date: Union[datetime.date, datetime.datetime],
15+
*,
16+
client: Client,
17+
an_enum_value: List[AnEnum],
18+
some_date: Union[datetime.date, datetime.datetime],
1619
) -> Dict[str, Any]:
1720
url = "{}/tests/".format(client.base_url)
1821

@@ -44,40 +47,89 @@ def _get_kwargs(
4447

4548
def _parse_response(
4649
*, response: httpx.Response
47-
) -> Union[
48-
List[AModel], HTTPValidationError,
49-
]:
50+
) -> Optional[Union[List[AModel], HTTPValidationError,]]:
5051
if response.status_code == 200:
5152
return [AModel.from_dict(item) for item in cast(List[Dict[str, Any]], response.json())]
5253
if response.status_code == 422:
5354
return HTTPValidationError.from_dict(cast(Dict[str, Any], response.json()))
54-
else:
55-
raise ApiResponseError(response=response)
55+
return None
56+
57+
58+
def _build_response(
59+
*, response: httpx.Response
60+
) -> Response[Union[List[AModel], HTTPValidationError,]]:
61+
return Response(
62+
status_code=response.status_code,
63+
content=response.content,
64+
headers=response.headers,
65+
parsed=_parse_response(response=response),
66+
)
67+
68+
69+
def sync_detailed(
70+
*,
71+
client: Client,
72+
an_enum_value: List[AnEnum],
73+
some_date: Union[datetime.date, datetime.datetime],
74+
) -> Response[Union[List[AModel], HTTPValidationError,]]:
75+
kwargs = _get_kwargs(
76+
client=client,
77+
an_enum_value=an_enum_value,
78+
some_date=some_date,
79+
)
80+
81+
response = httpx.get(
82+
**kwargs,
83+
)
84+
85+
return _build_response(response=response)
5686

5787

5888
def sync(
59-
*, client: Client, an_enum_value: List[AnEnum], some_date: Union[datetime.date, datetime.datetime],
60-
) -> Union[
61-
List[AModel], HTTPValidationError,
62-
]:
89+
*,
90+
client: Client,
91+
an_enum_value: List[AnEnum],
92+
some_date: Union[datetime.date, datetime.datetime],
93+
) -> Optional[Union[List[AModel], HTTPValidationError,]]:
6394
""" Get a list of things """
6495

65-
kwargs = _get_kwargs(client=client, an_enum_value=an_enum_value, some_date=some_date,)
96+
return sync_detailed(
97+
client=client,
98+
an_enum_value=an_enum_value,
99+
some_date=some_date,
100+
).parsed
101+
102+
103+
async def asyncio_detailed(
104+
*,
105+
client: Client,
106+
an_enum_value: List[AnEnum],
107+
some_date: Union[datetime.date, datetime.datetime],
108+
) -> Response[Union[List[AModel], HTTPValidationError,]]:
109+
kwargs = _get_kwargs(
110+
client=client,
111+
an_enum_value=an_enum_value,
112+
some_date=some_date,
113+
)
66114

67-
response = httpx.get(**kwargs,)
115+
async with httpx.AsyncClient() as _client:
116+
response = await _client.get(**kwargs)
68117

69-
return _parse_response(response=response)
118+
return _build_response(response=response)
70119

71120

72121
async def asyncio(
73-
*, client: Client, an_enum_value: List[AnEnum], some_date: Union[datetime.date, datetime.datetime],
74-
) -> Union[
75-
List[AModel], HTTPValidationError,
76-
]:
122+
*,
123+
client: Client,
124+
an_enum_value: List[AnEnum],
125+
some_date: Union[datetime.date, datetime.datetime],
126+
) -> Optional[Union[List[AModel], HTTPValidationError,]]:
77127
""" Get a list of things """
78-
kwargs = _get_kwargs(client=client, an_enum_value=an_enum_value, some_date=some_date,)
79-
80-
async with httpx.AsyncClient() as _client:
81-
response = await _client.get(**kwargs)
82128

83-
return _parse_response(response=response)
129+
return (
130+
await asyncio_detailed(
131+
client=client,
132+
an_enum_value=an_enum_value,
133+
some_date=some_date,
134+
)
135+
).parsed

end_to_end_tests/golden-master/my_test_api_client/api/tests/json_body_tests_json_body_post.py

Lines changed: 68 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@
44
import httpx
55

66
from ...client import AuthenticatedClient, Client
7-
from ...errors import ApiResponseError
87
from ...models.a_model import AModel
98
from ...models.http_validation_error import HTTPValidationError
9+
from ...types import Response
1010

1111

12-
def _get_kwargs(*, client: Client, json_body: AModel,) -> Dict[str, Any]:
12+
def _get_kwargs(
13+
*,
14+
client: Client,
15+
json_body: AModel,
16+
) -> Dict[str, Any]:
1317
url = "{}/tests/json_body".format(client.base_url)
1418

1519
headers: Dict[str, Any] = client.get_headers()
@@ -25,40 +29,81 @@ def _get_kwargs(*, client: Client, json_body: AModel,) -> Dict[str, Any]:
2529

2630
def _parse_response(
2731
*, response: httpx.Response
28-
) -> Union[
29-
None, HTTPValidationError,
30-
]:
32+
) -> Optional[Union[None, HTTPValidationError,]]:
3133
if response.status_code == 200:
3234
return None
3335
if response.status_code == 422:
3436
return HTTPValidationError.from_dict(cast(Dict[str, Any], response.json()))
35-
else:
36-
raise ApiResponseError(response=response)
37+
return None
3738

3839

39-
def sync(
40-
*, client: Client, json_body: AModel,
41-
) -> Union[
42-
None, HTTPValidationError,
43-
]:
44-
""" Try sending a JSON body """
40+
def _build_response(
41+
*, response: httpx.Response
42+
) -> Response[Union[None, HTTPValidationError,]]:
43+
return Response(
44+
status_code=response.status_code,
45+
content=response.content,
46+
headers=response.headers,
47+
parsed=_parse_response(response=response),
48+
)
4549

46-
kwargs = _get_kwargs(client=client, json_body=json_body,)
4750

48-
response = httpx.post(**kwargs,)
51+
def sync_detailed(
52+
*,
53+
client: Client,
54+
json_body: AModel,
55+
) -> Response[Union[None, HTTPValidationError,]]:
56+
kwargs = _get_kwargs(
57+
client=client,
58+
json_body=json_body,
59+
)
4960

50-
return _parse_response(response=response)
61+
response = httpx.post(
62+
**kwargs,
63+
)
5164

65+
return _build_response(response=response)
5266

53-
async def asyncio(
54-
*, client: Client, json_body: AModel,
55-
) -> Union[
56-
None, HTTPValidationError,
57-
]:
67+
68+
def sync(
69+
*,
70+
client: Client,
71+
json_body: AModel,
72+
) -> Optional[Union[None, HTTPValidationError,]]:
5873
""" Try sending a JSON body """
59-
kwargs = _get_kwargs(client=client, json_body=json_body,)
74+
75+
return sync_detailed(
76+
client=client,
77+
json_body=json_body,
78+
).parsed
79+
80+
81+
async def asyncio_detailed(
82+
*,
83+
client: Client,
84+
json_body: AModel,
85+
) -> Response[Union[None, HTTPValidationError,]]:
86+
kwargs = _get_kwargs(
87+
client=client,
88+
json_body=json_body,
89+
)
6090

6191
async with httpx.AsyncClient() as _client:
6292
response = await _client.post(**kwargs)
6393

64-
return _parse_response(response=response)
94+
return _build_response(response=response)
95+
96+
97+
async def asyncio(
98+
*,
99+
client: Client,
100+
json_body: AModel,
101+
) -> Optional[Union[None, HTTPValidationError,]]:
102+
""" Try sending a JSON body """
103+
104+
return (
105+
await asyncio_detailed(
106+
client=client,
107+
json_body=json_body,
108+
)
109+
).parsed

0 commit comments

Comments
 (0)