Skip to content

Commit 03bc946

Browse files
committed
Merge branch 'main' into release/0.6.0
2 parents 2108907 + c0557f1 commit 03bc946

File tree

11 files changed

+38
-47
lines changed

11 files changed

+38
-47
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3838

3939
- The format of any errors/warnings has been spaced out a bit.
4040

41+
## 0.5.5 - 2020-09-04
42+
### Fixes
43+
- Improved trailing comma handling in endpoint generation (#178 & #179). Thanks @dtkav!
44+
- `Optional` is now properly imported for `nullable` fields (#177 & #180). Thanks @dtkav!
45+
46+
4147
## 0.5.4 - 2020-08-29
4248

4349
### Additions

end_to_end_tests/fastapi_app/__init__.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from typing import Dict, List, Union
77

88
from fastapi import APIRouter, Body, FastAPI, File, Header, Query, UploadFile
9-
from pydantic import BaseModel
9+
from pydantic import BaseModel, Field
1010
from starlette.responses import FileResponse
1111

1212
app = FastAPI(
@@ -47,7 +47,7 @@ class AModel(BaseModel):
4747

4848
an_enum_value: AnEnum
4949
nested_list_of_enums: List[List[DifferentEnum]] = []
50-
some_dict: Dict[str, str]
50+
some_dict: Dict[str, str] = Field(..., nullable=True)
5151
aCamelDateTime: Union[datetime, date]
5252
a_date: date
5353

end_to_end_tests/fastapi_app/openapi.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,8 @@
537537
"type": "object",
538538
"additionalProperties": {
539539
"type": "string"
540-
}
540+
},
541+
"nullable": true
541542
},
542543
"aCamelDateTime": {
543544
"title": "Acameldatetime",

end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py

+6-10
Original file line numberDiff line numberDiff line change
@@ -82,19 +82,15 @@ def _get_kwargs(
8282
}
8383

8484

85-
def _parse_response(
86-
*, response: httpx.Response
87-
) -> Optional[Union[None, HTTPValidationError,]]:
85+
def _parse_response(*, response: httpx.Response) -> Optional[Union[None, HTTPValidationError]]:
8886
if response.status_code == 200:
8987
return None
9088
if response.status_code == 422:
9189
return HTTPValidationError.from_dict(cast(Dict[str, Any], response.json()))
9290
return None
9391

9492

95-
def _build_response(
96-
*, response: httpx.Response
97-
) -> Response[Union[None, HTTPValidationError,]]:
93+
def _build_response(*, response: httpx.Response) -> Response[Union[None, HTTPValidationError]]:
9894
return Response(
9995
status_code=response.status_code,
10096
content=response.content,
@@ -116,7 +112,7 @@ def sync_detailed(
116112
list_prop: Optional[List[AnEnum]] = None,
117113
union_prop: Optional[Union[Optional[float], Optional[str]]] = "not a float",
118114
enum_prop: Optional[AnEnum] = None,
119-
) -> Response[Union[None, HTTPValidationError,]]:
115+
) -> Response[Union[None, HTTPValidationError]]:
120116
kwargs = _get_kwargs(
121117
client=client,
122118
json_body=json_body,
@@ -151,7 +147,7 @@ def sync(
151147
list_prop: Optional[List[AnEnum]] = None,
152148
union_prop: Optional[Union[Optional[float], Optional[str]]] = "not a float",
153149
enum_prop: Optional[AnEnum] = None,
154-
) -> Optional[Union[None, HTTPValidationError,]]:
150+
) -> Optional[Union[None, HTTPValidationError]]:
155151
""" """
156152

157153
return sync_detailed(
@@ -182,7 +178,7 @@ async def asyncio_detailed(
182178
list_prop: Optional[List[AnEnum]] = None,
183179
union_prop: Optional[Union[Optional[float], Optional[str]]] = "not a float",
184180
enum_prop: Optional[AnEnum] = None,
185-
) -> Response[Union[None, HTTPValidationError,]]:
181+
) -> Response[Union[None, HTTPValidationError]]:
186182
kwargs = _get_kwargs(
187183
client=client,
188184
json_body=json_body,
@@ -216,7 +212,7 @@ async def asyncio(
216212
list_prop: Optional[List[AnEnum]] = None,
217213
union_prop: Optional[Union[Optional[float], Optional[str]]] = "not a float",
218214
enum_prop: Optional[AnEnum] = None,
219-
) -> Optional[Union[None, HTTPValidationError,]]:
215+
) -> Optional[Union[None, HTTPValidationError]]:
220216
""" """
221217

222218
return (

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

+6-10
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,15 @@ def _get_kwargs(
4747
}
4848

4949

50-
def _parse_response(
51-
*, response: httpx.Response
52-
) -> Optional[Union[List[AModel], HTTPValidationError,]]:
50+
def _parse_response(*, response: httpx.Response) -> Optional[Union[List[AModel], HTTPValidationError]]:
5351
if response.status_code == 200:
5452
return [AModel.from_dict(item) for item in cast(List[Dict[str, Any]], response.json())]
5553
if response.status_code == 422:
5654
return HTTPValidationError.from_dict(cast(Dict[str, Any], response.json()))
5755
return None
5856

5957

60-
def _build_response(
61-
*, response: httpx.Response
62-
) -> Response[Union[List[AModel], HTTPValidationError,]]:
58+
def _build_response(*, response: httpx.Response) -> Response[Union[List[AModel], HTTPValidationError]]:
6359
return Response(
6460
status_code=response.status_code,
6561
content=response.content,
@@ -73,7 +69,7 @@ def sync_detailed(
7369
client: Client,
7470
an_enum_value: List[AnEnum],
7571
some_date: Union[datetime.date, datetime.datetime],
76-
) -> Response[Union[List[AModel], HTTPValidationError,]]:
72+
) -> Response[Union[List[AModel], HTTPValidationError]]:
7773
kwargs = _get_kwargs(
7874
client=client,
7975
an_enum_value=an_enum_value,
@@ -92,7 +88,7 @@ def sync(
9288
client: Client,
9389
an_enum_value: List[AnEnum],
9490
some_date: Union[datetime.date, datetime.datetime],
95-
) -> Optional[Union[List[AModel], HTTPValidationError,]]:
91+
) -> Optional[Union[List[AModel], HTTPValidationError]]:
9692
""" Get a list of things """
9793

9894
return sync_detailed(
@@ -107,7 +103,7 @@ async def asyncio_detailed(
107103
client: Client,
108104
an_enum_value: List[AnEnum],
109105
some_date: Union[datetime.date, datetime.datetime],
110-
) -> Response[Union[List[AModel], HTTPValidationError,]]:
106+
) -> Response[Union[List[AModel], HTTPValidationError]]:
111107
kwargs = _get_kwargs(
112108
client=client,
113109
an_enum_value=an_enum_value,
@@ -125,7 +121,7 @@ async def asyncio(
125121
client: Client,
126122
an_enum_value: List[AnEnum],
127123
some_date: Union[datetime.date, datetime.datetime],
128-
) -> Optional[Union[List[AModel], HTTPValidationError,]]:
124+
) -> Optional[Union[List[AModel], HTTPValidationError]]:
129125
""" Get a list of things """
130126

131127
return (

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

+6-10
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,15 @@ def _get_kwargs(
2929
}
3030

3131

32-
def _parse_response(
33-
*, response: httpx.Response
34-
) -> Optional[Union[None, HTTPValidationError,]]:
32+
def _parse_response(*, response: httpx.Response) -> Optional[Union[None, HTTPValidationError]]:
3533
if response.status_code == 200:
3634
return None
3735
if response.status_code == 422:
3836
return HTTPValidationError.from_dict(cast(Dict[str, Any], response.json()))
3937
return None
4038

4139

42-
def _build_response(
43-
*, response: httpx.Response
44-
) -> Response[Union[None, HTTPValidationError,]]:
40+
def _build_response(*, response: httpx.Response) -> Response[Union[None, HTTPValidationError]]:
4541
return Response(
4642
status_code=response.status_code,
4743
content=response.content,
@@ -54,7 +50,7 @@ def sync_detailed(
5450
*,
5551
client: Client,
5652
json_body: AModel,
57-
) -> Response[Union[None, HTTPValidationError,]]:
53+
) -> Response[Union[None, HTTPValidationError]]:
5854
kwargs = _get_kwargs(
5955
client=client,
6056
json_body=json_body,
@@ -71,7 +67,7 @@ def sync(
7167
*,
7268
client: Client,
7369
json_body: AModel,
74-
) -> Optional[Union[None, HTTPValidationError,]]:
70+
) -> Optional[Union[None, HTTPValidationError]]:
7571
""" Try sending a JSON body """
7672

7773
return sync_detailed(
@@ -84,7 +80,7 @@ async def asyncio_detailed(
8480
*,
8581
client: Client,
8682
json_body: AModel,
87-
) -> Response[Union[None, HTTPValidationError,]]:
83+
) -> Response[Union[None, HTTPValidationError]]:
8884
kwargs = _get_kwargs(
8985
client=client,
9086
json_body=json_body,
@@ -100,7 +96,7 @@ async def asyncio(
10096
*,
10197
client: Client,
10298
json_body: AModel,
103-
) -> Optional[Union[None, HTTPValidationError,]]:
99+
) -> Optional[Union[None, HTTPValidationError]]:
104100
""" Try sending a JSON body """
105101

106102
return (

end_to_end_tests/golden-record/my_test_api_client/api/tests/upload_file_tests_upload_post.py

+6-10
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,15 @@ def _get_kwargs(
3131
}
3232

3333

34-
def _parse_response(
35-
*, response: httpx.Response
36-
) -> Optional[Union[None, HTTPValidationError,]]:
34+
def _parse_response(*, response: httpx.Response) -> Optional[Union[None, HTTPValidationError]]:
3735
if response.status_code == 200:
3836
return None
3937
if response.status_code == 422:
4038
return HTTPValidationError.from_dict(cast(Dict[str, Any], response.json()))
4139
return None
4240

4341

44-
def _build_response(
45-
*, response: httpx.Response
46-
) -> Response[Union[None, HTTPValidationError,]]:
42+
def _build_response(*, response: httpx.Response) -> Response[Union[None, HTTPValidationError]]:
4743
return Response(
4844
status_code=response.status_code,
4945
content=response.content,
@@ -57,7 +53,7 @@ def sync_detailed(
5753
client: Client,
5854
multipart_data: BodyUploadFileTestsUploadPost,
5955
keep_alive: Optional[bool] = None,
60-
) -> Response[Union[None, HTTPValidationError,]]:
56+
) -> Response[Union[None, HTTPValidationError]]:
6157
kwargs = _get_kwargs(
6258
client=client,
6359
multipart_data=multipart_data,
@@ -76,7 +72,7 @@ def sync(
7672
client: Client,
7773
multipart_data: BodyUploadFileTestsUploadPost,
7874
keep_alive: Optional[bool] = None,
79-
) -> Optional[Union[None, HTTPValidationError,]]:
75+
) -> Optional[Union[None, HTTPValidationError]]:
8076
""" Upload a file """
8177

8278
return sync_detailed(
@@ -91,7 +87,7 @@ async def asyncio_detailed(
9187
client: Client,
9288
multipart_data: BodyUploadFileTestsUploadPost,
9389
keep_alive: Optional[bool] = None,
94-
) -> Response[Union[None, HTTPValidationError,]]:
90+
) -> Response[Union[None, HTTPValidationError]]:
9591
kwargs = _get_kwargs(
9692
client=client,
9793
multipart_data=multipart_data,
@@ -109,7 +105,7 @@ async def asyncio(
109105
client: Client,
110106
multipart_data: BodyUploadFileTestsUploadPost,
111107
keep_alive: Optional[bool] = None,
112-
) -> Optional[Union[None, HTTPValidationError,]]:
108+
) -> Optional[Union[None, HTTPValidationError]]:
113109
""" Upload a file """
114110

115111
return (

end_to_end_tests/golden-record/my_test_api_client/models/a_model.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class AModel:
1313
""" A Model for testing all the ways custom objects can be used """
1414

1515
an_enum_value: AnEnum
16-
some_dict: Dict[Any, Any]
16+
some_dict: Optional[Dict[Any, Any]]
1717
a_camel_date_time: Union[datetime.datetime, datetime.date]
1818
a_date: datetime.date
1919
nested_list_of_enums: Optional[List[List[DifferentEnum]]] = None

openapi_python_client/parser/properties.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def get_imports(self, *, prefix: str) -> Set[str]:
6363
Args:
6464
prefix: A prefix to put before any relative (local) module names.
6565
"""
66-
if not self.required:
66+
if self.nullable or not self.required:
6767
return {"from typing import Optional"}
6868
return set()
6969

openapi_python_client/templates/endpoint_macros.pyi

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ None
6363
{%- else %}
6464
Union[
6565
{% for response in endpoint.responses %}
66-
{{ response.return_string() }},
66+
{{ response.return_string() }}{{ "," if not loop.last }}
6767
{% endfor %}
6868
]
6969
{%- endif %}

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "openapi-python-client"
3-
version = "0.6.0-alpha.1"
3+
version = "0.6.0-alpha.2"
44
description = "Generate modern Python clients from OpenAPI"
55
repository = "https://github.com/triaxtec/openapi-python-client"
66
license = "MIT"

0 commit comments

Comments
 (0)