Skip to content

Commit 2429959

Browse files
committed
1. "async" parameter for templates
2. hand written tests for python-httpx 3. CI workflow updated
1 parent 9050b8b commit 2429959

23 files changed

Lines changed: 822 additions & 74 deletions

File tree

.github/workflows/samples-python-petstore.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ jobs:
3434
- "3.13"
3535
sample:
3636
- samples/openapi3/client/petstore/python-aiohttp
37+
- samples/openapi3/client/petstore/python-httpx
3738
- samples/openapi3/client/petstore/python
3839
- samples/openapi3/client/petstore/python-lazyImports
3940
services:

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,13 +331,14 @@ public void processOpts() {
331331

332332
if ("asyncio".equals(getLibrary())) {
333333
supportingFiles.add(new SupportingFile("asyncio/rest.mustache", packagePath(), "rest.py"));
334+
additionalProperties.put("async", "true");
334335
additionalProperties.put("asyncio", "true");
335336
} else if ("tornado".equals(getLibrary())) {
336337
supportingFiles.add(new SupportingFile("tornado/rest.mustache", packagePath(), "rest.py"));
337338
additionalProperties.put("tornado", "true");
338339
} else if ("httpx".equals(getLibrary())) {
339340
supportingFiles.add(new SupportingFile("httpx/rest.mustache", packagePath(), "rest.py"));
340-
additionalProperties.put("asyncio", "true");
341+
additionalProperties.put("async", "true");
341342
additionalProperties.put("httpx", "true");
342343
} else {
343344
supportingFiles.add(new SupportingFile("rest.mustache", packagePath(), "rest.py"));

modules/openapi-generator/src/main/resources/python/README_onlypackage.mustache

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ To be able to use it, you will need these dependencies in your own package that
2828

2929
* urllib3 >= 2.1.0, < 3.0.0
3030
* python-dateutil >= 2.8.2
31-
{{#asyncio}}
31+
{{#async}}
3232
* aiohttp >= 3.8.4
3333
* aiohttp-retry >= 2.8.3
34-
{{/asyncio}}
34+
{{/async}}
3535
{{#tornado}}
3636
* tornado >= 4.2, < 5
3737
{{/tornado}}

modules/openapi-generator/src/main/resources/python/api.mustache

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,40 +32,40 @@ class {{classname}}:
3232

3333

3434
@validate_call
35-
{{#asyncio}}async {{/asyncio}}def {{operationId}}{{>partial_api_args}} -> {{{returnType}}}{{^returnType}}None{{/returnType}}:
35+
{{#async}}async {{/async}}def {{operationId}}{{>partial_api_args}} -> {{{returnType}}}{{^returnType}}None{{/returnType}}:
3636
{{>partial_api}}
3737

38-
response_data = {{#asyncio}}await {{/asyncio}}self.api_client.call_api(
38+
response_data = {{#async}}await {{/async}}self.api_client.call_api(
3939
*_param,
4040
_request_timeout=_request_timeout
4141
)
42-
{{#asyncio}}await {{/asyncio}}response_data.read()
42+
{{#async}}await {{/async}}response_data.read()
4343
return self.api_client.response_deserialize(
4444
response_data=response_data,
4545
response_types_map=_response_types_map,
4646
).data
4747

4848

4949
@validate_call
50-
{{#asyncio}}async {{/asyncio}}def {{operationId}}_with_http_info{{>partial_api_args}} -> ApiResponse[{{{returnType}}}{{^returnType}}None{{/returnType}}]:
50+
{{#async}}async {{/async}}def {{operationId}}_with_http_info{{>partial_api_args}} -> ApiResponse[{{{returnType}}}{{^returnType}}None{{/returnType}}]:
5151
{{>partial_api}}
5252

53-
response_data = {{#asyncio}}await {{/asyncio}}self.api_client.call_api(
53+
response_data = {{#async}}await {{/async}}self.api_client.call_api(
5454
*_param,
5555
_request_timeout=_request_timeout
5656
)
57-
{{#asyncio}}await {{/asyncio}}response_data.read()
57+
{{#async}}await {{/async}}response_data.read()
5858
return self.api_client.response_deserialize(
5959
response_data=response_data,
6060
response_types_map=_response_types_map,
6161
)
6262

6363

6464
@validate_call
65-
{{#asyncio}}async {{/asyncio}}def {{operationId}}_without_preload_content{{>partial_api_args}} -> RESTResponseType:
65+
{{#async}}async {{/async}}def {{operationId}}_without_preload_content{{>partial_api_args}} -> RESTResponseType:
6666
{{>partial_api}}
6767

68-
response_data = {{#asyncio}}await {{/asyncio}}self.api_client.call_api(
68+
response_data = {{#async}}await {{/async}}self.api_client.call_api(
6969
*_param,
7070
_request_timeout=_request_timeout
7171
)

modules/openapi-generator/src/main/resources/python/api_client.mustache

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class ApiClient:
8888
self.user_agent = '{{{httpUserAgent}}}{{^httpUserAgent}}OpenAPI-Generator/{{{packageVersion}}}/python{{/httpUserAgent}}'
8989
self.client_side_validation = configuration.client_side_validation
9090

91-
{{#asyncio}}
91+
{{#async}}
9292
async def __aenter__(self):
9393
return self
9494

@@ -97,14 +97,14 @@ class ApiClient:
9797

9898
async def close(self):
9999
await self.rest_client.close()
100-
{{/asyncio}}
101-
{{^asyncio}}
100+
{{/async}}
101+
{{^async}}
102102
def __enter__(self):
103103
return self
104104

105105
def __exit__(self, exc_type, exc_value, traceback):
106106
pass
107-
{{/asyncio}}
107+
{{/async}}
108108

109109
@property
110110
def user_agent(self):
@@ -257,7 +257,7 @@ class ApiClient:
257257
{{#tornado}}
258258
@tornado.gen.coroutine
259259
{{/tornado}}
260-
{{#asyncio}}async {{/asyncio}}def call_api(
260+
{{#async}}async {{/async}}def call_api(
261261
self,
262262
method,
263263
url,
@@ -280,7 +280,7 @@ class ApiClient:
280280

281281
try:
282282
# perform request and return response
283-
response_data = {{#asyncio}}await {{/asyncio}}{{#tornado}}yield {{/tornado}}self.rest_client.request(
283+
response_data = {{#async}}await {{/async}}{{#tornado}}yield {{/tornado}}self.rest_client.request(
284284
method, url,
285285
headers=header_params,
286286
body=body, post_params=post_params,

modules/openapi-generator/src/main/resources/python/api_doc_example.mustache

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ from pprint import pprint
1010
{{> python_doc_auth_partial}}
1111

1212
# Enter a context with an instance of the API client
13-
{{#asyncio}}async {{/asyncio}}with {{{packageName}}}.ApiClient(configuration) as api_client:
13+
{{#async}}async {{/async}}with {{{packageName}}}.ApiClient(configuration) as api_client:
1414
# Create an instance of the API class
1515
api_instance = {{{packageName}}}.{{{classname}}}(api_client)
1616
{{#allParams}}
@@ -21,7 +21,7 @@ from pprint import pprint
2121
{{#summary}}
2222
# {{{.}}}
2323
{{/summary}}
24-
{{#returnType}}api_response = {{/returnType}}{{#asyncio}}await {{/asyncio}}api_instance.{{{operationId}}}({{#allParams}}{{#required}}{{paramName}}{{/required}}{{^required}}{{paramName}}={{paramName}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}})
24+
{{#returnType}}api_response = {{/returnType}}{{#async}}await {{/async}}api_instance.{{{operationId}}}({{#allParams}}{{#required}}{{paramName}}{{/required}}{{^required}}{{paramName}}={{paramName}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}})
2525
{{#returnType}}
2626
print("The response of {{classname}}->{{operationId}}:\n")
2727
pprint(api_response)

modules/openapi-generator/src/main/resources/python/api_test.mustache

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,31 @@ import unittest
88
from {{apiPackage}}.{{classFilename}} import {{classname}}
99

1010

11-
class {{#operations}}Test{{classname}}(unittest.{{#asyncio}}IsolatedAsyncio{{/asyncio}}TestCase):
11+
class {{#operations}}Test{{classname}}(unittest.{{#async}}IsolatedAsyncio{{/async}}TestCase):
1212
"""{{classname}} unit test stubs"""
1313

14-
{{#asyncio}}
14+
{{#async}}
1515
async def asyncSetUp(self) -> None:
1616
self.api = {{classname}}()
1717

1818
async def asyncTearDown(self) -> None:
1919
await self.api.api_client.close()
20-
{{/asyncio}}
21-
{{^asyncio}}
20+
{{/async}}
21+
{{^async}}
2222
def setUp(self) -> None:
2323
self.api = {{classname}}()
2424

2525
def tearDown(self) -> None:
2626
pass
27-
{{/asyncio}}
27+
{{/async}}
2828

2929
{{#operation}}
30-
{{#asyncio}}
30+
{{#async}}
3131
async def test_{{operationId}}(self) -> None:
32-
{{/asyncio}}
33-
{{^asyncio}}
32+
{{/async}}
33+
{{^async}}
3434
def test_{{operationId}}(self) -> None:
35-
{{/asyncio}}
35+
{{/async}}
3636
"""Test case for {{{operationId}}}
3737

3838
{{#summary}}

modules/openapi-generator/src/main/resources/python/common_README.mustache

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ from pprint import pprint
88

99

1010
# Enter a context with an instance of the API client
11-
{{#asyncio}}async {{/asyncio}}with {{{packageName}}}.ApiClient(configuration) as api_client:
11+
{{#async}}async {{/async}}with {{{packageName}}}.ApiClient(configuration) as api_client:
1212
# Create an instance of the API class
1313
api_instance = {{{packageName}}}.{{{classname}}}(api_client)
1414
{{#allParams}}
@@ -19,7 +19,7 @@ from pprint import pprint
1919
{{#summary}}
2020
# {{{.}}}
2121
{{/summary}}
22-
{{#returnType}}api_response = {{/returnType}}{{#asyncio}}await {{/asyncio}}api_instance.{{{operationId}}}({{#allParams}}{{#required}}{{paramName}}{{/required}}{{^required}}{{paramName}}={{paramName}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}})
22+
{{#returnType}}api_response = {{/returnType}}{{#async}}await {{/async}}api_instance.{{{operationId}}}({{#allParams}}{{#required}}{{paramName}}{{/required}}{{^required}}{{paramName}}={{paramName}}{{/required}}{{^-last}}, {{/-last}}{{/allParams}})
2323
{{#returnType}}
2424
print("The response of {{classname}}->{{operationId}}:\n")
2525
pprint(api_response)

modules/openapi-generator/src/main/resources/python/configuration.mustache

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ import copy
77
import http.client as httplib
88
import logging
99
from logging import FileHandler
10-
{{^asyncio}}
10+
{{^async}}
1111
import multiprocessing
12-
{{/asyncio}}
12+
{{/async}}
1313
import sys
1414
from typing import Any, ClassVar, Dict, List, Literal, Optional, TypedDict, Union
1515
from typing_extensions import NotRequired, Self
@@ -395,21 +395,21 @@ conf = {{{packageName}}}.Configuration(
395395
Set this to the SNI value expected by the server.
396396
"""
397397

398-
{{#asyncio}}
398+
{{#async}}
399399
self.connection_pool_maxsize = 100
400400
"""This value is passed to the aiohttp to limit simultaneous connections.
401401
Default values is 100, None means no-limit.
402402
"""
403-
{{/asyncio}}
404-
{{^asyncio}}
403+
{{/async}}
404+
{{^async}}
405405
self.connection_pool_maxsize = multiprocessing.cpu_count() * 5
406406
"""urllib3 connection pool's maximum number of connections saved
407407
per pool. urllib3 uses 1 connection as default value, but this is
408408
not the best value when you are making a lot of possibly parallel
409409
requests to the same host, which is often the case here.
410410
cpu_count * 5 is used as default value to increase performance.
411411
"""
412-
{{/asyncio}}
412+
{{/async}}
413413

414414
self.proxy: Optional[str] = None
415415
"""Proxy URL

modules/openapi-generator/src/main/resources/python/httpx/rest.mustache

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ class RESTClientObject:
6363
self.pool_manager: Optional[httpx.AsyncClient] = None
6464

6565
async def close(self):
66-
await self.pool_manager.aclose()
66+
if self.pool_manager is not None:
67+
await self.pool_manager.aclose()
6768

6869
async def request(
6970
self,

0 commit comments

Comments
 (0)