ab-openapi-python-generator 2.1.4__py3-none-any.whl → 2.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ab_openapi_python_generator/generate_data.py +60 -60
- ab_openapi_python_generator/language_converters/python/{service_generator.py → client_generator.py} +83 -167
- ab_openapi_python_generator/language_converters/python/exception_generator.py +23 -0
- ab_openapi_python_generator/language_converters/python/generator.py +9 -11
- ab_openapi_python_generator/language_converters/python/jinja_config.py +3 -4
- ab_openapi_python_generator/language_converters/python/model_generator.py +33 -91
- ab_openapi_python_generator/language_converters/python/templates/async_client_httpx_pydantic_2.jinja2 +80 -0
- ab_openapi_python_generator/language_converters/python/templates/http_exception.jinja2 +8 -0
- ab_openapi_python_generator/language_converters/python/templates/sync_client_httpx_pydantic_2.jinja2 +80 -0
- ab_openapi_python_generator/models.py +5 -5
- ab_openapi_python_generator/version_detector.py +1 -4
- {ab_openapi_python_generator-2.1.4.dist-info → ab_openapi_python_generator-2.2.0.dist-info}/METADATA +1 -1
- {ab_openapi_python_generator-2.1.4.dist-info → ab_openapi_python_generator-2.2.0.dist-info}/RECORD +16 -19
- ab_openapi_python_generator/language_converters/python/api_config_generator.py +0 -35
- ab_openapi_python_generator/language_converters/python/templates/aiohttp.jinja2 +0 -49
- ab_openapi_python_generator/language_converters/python/templates/apiconfig.jinja2 +0 -38
- ab_openapi_python_generator/language_converters/python/templates/apiconfig_pydantic_2.jinja2 +0 -42
- ab_openapi_python_generator/language_converters/python/templates/httpx.jinja2 +0 -126
- ab_openapi_python_generator/language_converters/python/templates/requests.jinja2 +0 -50
- ab_openapi_python_generator/language_converters/python/templates/service.jinja2 +0 -12
- {ab_openapi_python_generator-2.1.4.dist-info → ab_openapi_python_generator-2.2.0.dist-info}/WHEEL +0 -0
- {ab_openapi_python_generator-2.1.4.dist-info → ab_openapi_python_generator-2.2.0.dist-info}/entry_points.txt +0 -0
- {ab_openapi_python_generator-2.1.4.dist-info → ab_openapi_python_generator-2.2.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
{% if env_token_name is not none %}import os{% endif %}
|
|
2
|
-
|
|
3
|
-
from pydantic import BaseModel, Field
|
|
4
|
-
from typing import Optional, Union
|
|
5
|
-
|
|
6
|
-
class APIConfig(BaseModel):
|
|
7
|
-
base_path: str = {% if servers|length > 0 %} '{{ servers[0].url }}' {% else %} 'NO SERVER' {% endif %}
|
|
8
|
-
|
|
9
|
-
verify: Union[bool, str] = True
|
|
10
|
-
{% if env_token_name is none %}
|
|
11
|
-
access_token : Optional[str] = None
|
|
12
|
-
{% endif %}
|
|
13
|
-
|
|
14
|
-
def get_access_token(self) -> Optional[str]:
|
|
15
|
-
{% if env_token_name is not none %}
|
|
16
|
-
try:
|
|
17
|
-
return os.environ['{{ env_token_name }}']
|
|
18
|
-
except KeyError:
|
|
19
|
-
return None
|
|
20
|
-
{% else %}
|
|
21
|
-
return self.access_token
|
|
22
|
-
{% endif %}
|
|
23
|
-
|
|
24
|
-
def set_access_token(self, value : str):
|
|
25
|
-
{% if env_token_name is not none %}
|
|
26
|
-
raise Exception("This client was generated with an environment variable for the access token. Please set the environment variable '{{ env_token_name }}' to the access token.")
|
|
27
|
-
{% else %}
|
|
28
|
-
self.access_token = value
|
|
29
|
-
{% endif %}
|
|
30
|
-
|
|
31
|
-
class HTTPException(Exception):
|
|
32
|
-
def __init__(self, status_code: int, message: str):
|
|
33
|
-
self.status_code = status_code
|
|
34
|
-
self.message = message
|
|
35
|
-
super().__init__(f"{status_code} {message}")
|
|
36
|
-
|
|
37
|
-
def __str__(self):
|
|
38
|
-
return f"{self.status_code} {self.message}"
|
ab_openapi_python_generator/language_converters/python/templates/apiconfig_pydantic_2.jinja2
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
{% if env_token_name is not none %}import os{% endif %}
|
|
2
|
-
|
|
3
|
-
from pydantic import BaseModel, Field
|
|
4
|
-
from typing import Optional, Union
|
|
5
|
-
|
|
6
|
-
class APIConfig(BaseModel):
|
|
7
|
-
model_config = {
|
|
8
|
-
"validate_assignment": True
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
base_path: str = {% if servers|length > 0 %} '{{ servers[0].url }}' {% else %} 'NO SERVER' {% endif %}
|
|
12
|
-
|
|
13
|
-
verify: Union[bool, str] = True
|
|
14
|
-
{% if env_token_name is none %}
|
|
15
|
-
access_token : Optional[str] = None
|
|
16
|
-
{% endif %}
|
|
17
|
-
|
|
18
|
-
def get_access_token(self) -> Optional[str]:
|
|
19
|
-
{% if env_token_name is not none %}
|
|
20
|
-
try:
|
|
21
|
-
return os.environ['{{ env_token_name }}']
|
|
22
|
-
except KeyError:
|
|
23
|
-
return None
|
|
24
|
-
{% else %}
|
|
25
|
-
return self.access_token
|
|
26
|
-
{% endif %}
|
|
27
|
-
|
|
28
|
-
def set_access_token(self, value : str):
|
|
29
|
-
{% if env_token_name is not none %}
|
|
30
|
-
raise Exception("This client was generated with an environment variable for the access token. Please set the environment variable '{{ env_token_name }}' to the access token.")
|
|
31
|
-
{% else %}
|
|
32
|
-
self.access_token = value
|
|
33
|
-
{% endif %}
|
|
34
|
-
|
|
35
|
-
class HTTPException(Exception):
|
|
36
|
-
def __init__(self, status_code: int, message: str):
|
|
37
|
-
self.status_code = status_code
|
|
38
|
-
self.message = message
|
|
39
|
-
super().__init__(f"{status_code} {message}")
|
|
40
|
-
|
|
41
|
-
def __str__(self):
|
|
42
|
-
return f"{self.status_code} {self.message}"
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
{# NOTE: this template renders ONE function. It must be valid standalone python. #}
|
|
2
|
-
|
|
3
|
-
{% if async_client %}async {% endif %}def {{ operation_id }}(
|
|
4
|
-
api_config_override: Optional[APIConfig] = None{% if params.strip() %}, *, {{ params.rstrip(', ') }}{% endif %}
|
|
5
|
-
) -> {% if is_sse %}{% if async_client %}AsyncGenerator[Any, None]{% else %}Iterator[Any]{% endif %}{% else %}{% if return_type.type is none or return_type.type.converted_type is none %}None{% else %}{{ return_type.type.converted_type }}{% endif %}{% endif %}:
|
|
6
|
-
api_config = api_config_override if api_config_override else APIConfig()
|
|
7
|
-
|
|
8
|
-
base_path = api_config.base_path
|
|
9
|
-
path = f'{{ path_name }}'
|
|
10
|
-
|
|
11
|
-
headers = {
|
|
12
|
-
"Content-Type": "application/json",
|
|
13
|
-
{% if is_sse %}
|
|
14
|
-
"Accept": "text/event-stream",
|
|
15
|
-
{% else %}
|
|
16
|
-
"Accept": "application/json",
|
|
17
|
-
{% endif %}
|
|
18
|
-
"Authorization": f"Bearer { api_config.get_access_token() }",
|
|
19
|
-
{{ header_params | join(',\n') | safe }}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
query_params: Dict[str, Any] = {}
|
|
23
|
-
query_params = {key: value for (key, value) in query_params.items() if value is not None}
|
|
24
|
-
|
|
25
|
-
{% if is_sse %}
|
|
26
|
-
import json
|
|
27
|
-
|
|
28
|
-
{% if async_client %}
|
|
29
|
-
async with httpx.AsyncClient(base_url=base_path, verify=api_config.verify) as client:
|
|
30
|
-
async with client.stream(
|
|
31
|
-
"{{ method }}",
|
|
32
|
-
httpx.URL(path),
|
|
33
|
-
headers=headers,
|
|
34
|
-
params=query_params,
|
|
35
|
-
{% if body_param %}
|
|
36
|
-
json={{ body_param }},
|
|
37
|
-
{% endif %}
|
|
38
|
-
) as response:
|
|
39
|
-
if response.status_code != {{ return_type.status_code }}:
|
|
40
|
-
raise HTTPException(
|
|
41
|
-
response.status_code,
|
|
42
|
-
f"{{ operation_id }} failed with status code: {response.status_code}",
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
async for line in response.aiter_lines():
|
|
46
|
-
if not line:
|
|
47
|
-
continue
|
|
48
|
-
if line.startswith("data:"):
|
|
49
|
-
payload = line[len("data:"):].strip()
|
|
50
|
-
if not payload:
|
|
51
|
-
continue
|
|
52
|
-
if payload == "[DONE]":
|
|
53
|
-
break
|
|
54
|
-
try:
|
|
55
|
-
yield json.loads(payload)
|
|
56
|
-
except Exception:
|
|
57
|
-
yield payload
|
|
58
|
-
{% else %}
|
|
59
|
-
with httpx.Client(base_url=base_path, verify=api_config.verify) as client:
|
|
60
|
-
with client.stream(
|
|
61
|
-
"{{ method }}",
|
|
62
|
-
httpx.URL(path),
|
|
63
|
-
headers=headers,
|
|
64
|
-
params=query_params,
|
|
65
|
-
{% if body_param %}
|
|
66
|
-
json={{ body_param }},
|
|
67
|
-
{% endif %}
|
|
68
|
-
) as response:
|
|
69
|
-
if response.status_code != {{ return_type.status_code }}:
|
|
70
|
-
raise HTTPException(
|
|
71
|
-
response.status_code,
|
|
72
|
-
f"{{ operation_id }} failed with status code: {response.status_code}",
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
for line in response.iter_lines():
|
|
76
|
-
if not line:
|
|
77
|
-
continue
|
|
78
|
-
if line.startswith("data:"):
|
|
79
|
-
payload = line[len("data:"):].strip()
|
|
80
|
-
if not payload:
|
|
81
|
-
continue
|
|
82
|
-
if payload == "[DONE]":
|
|
83
|
-
break
|
|
84
|
-
try:
|
|
85
|
-
yield json.loads(payload)
|
|
86
|
-
except Exception:
|
|
87
|
-
yield payload
|
|
88
|
-
{% endif %}
|
|
89
|
-
|
|
90
|
-
{% else %}
|
|
91
|
-
{% if async_client %}
|
|
92
|
-
async with httpx.AsyncClient(base_url=base_path, verify=api_config.verify) as client:
|
|
93
|
-
response = await client.request(
|
|
94
|
-
{% else %}
|
|
95
|
-
with httpx.Client(base_url=base_path, verify=api_config.verify) as client:
|
|
96
|
-
response = client.request(
|
|
97
|
-
{% endif %}
|
|
98
|
-
"{{ method }}",
|
|
99
|
-
httpx.URL(path),
|
|
100
|
-
headers=headers,
|
|
101
|
-
params=query_params,
|
|
102
|
-
{% if body_param %}
|
|
103
|
-
json={{ body_param }},
|
|
104
|
-
{% endif %}
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
if response.status_code != {{ return_type.status_code }}:
|
|
108
|
-
raise HTTPException(
|
|
109
|
-
response.status_code,
|
|
110
|
-
f"{{ operation_id }} failed with status code: {response.status_code}",
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
body = None if {{ return_type.status_code }} == 204 else response.json()
|
|
114
|
-
|
|
115
|
-
{% if return_type.type is none or return_type.type.converted_type is none %}
|
|
116
|
-
return None
|
|
117
|
-
{% elif return_type.complex_type %}
|
|
118
|
-
{% if return_type.list_type is none %}
|
|
119
|
-
return {{ return_type.type.converted_type }}(**body) if body is not None else {{ return_type.type.converted_type }}()
|
|
120
|
-
{% else %}
|
|
121
|
-
return [{{ return_type.list_type }}(**item) for item in body]
|
|
122
|
-
{% endif %}
|
|
123
|
-
{% else %}
|
|
124
|
-
return body
|
|
125
|
-
{% endif %}
|
|
126
|
-
{% endif %}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
def {{ operation_id }}(api_config_override : Optional[APIConfig] = None{% if params.strip() %}, *, {{ params.rstrip(', ') }}{% endif %}) -> {% if return_type.type is none or return_type.type.converted_type is none %}None{% else %}{{ return_type.type.converted_type}}{% endif %}:
|
|
2
|
-
api_config = api_config_override if api_config_override else APIConfig()
|
|
3
|
-
|
|
4
|
-
base_path = api_config.base_path
|
|
5
|
-
path = f'{{ path_name }}'
|
|
6
|
-
headers = {
|
|
7
|
-
'Content-Type': 'application/json',
|
|
8
|
-
'Accept': 'application/json',
|
|
9
|
-
'Authorization': f'Bearer { api_config.get_access_token() }',
|
|
10
|
-
{{ header_params | join(',\n') | safe }}
|
|
11
|
-
}
|
|
12
|
-
query_params : Dict[str,Any] = {
|
|
13
|
-
{% if query_params|length > 0 %}
|
|
14
|
-
{{ query_params | join(',\n') | safe }}
|
|
15
|
-
{% endif %}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
query_params = {key:value for (key,value) in query_params.items() if value is not None}
|
|
19
|
-
|
|
20
|
-
response = requests.request(
|
|
21
|
-
'{{ method }}',
|
|
22
|
-
f'{base_path}{path}',
|
|
23
|
-
headers=headers,
|
|
24
|
-
params=query_params,
|
|
25
|
-
verify=api_config.verify,
|
|
26
|
-
{% if body_param %}
|
|
27
|
-
{% if use_orjson %}
|
|
28
|
-
content=orjson.dumps({{ body_param }})
|
|
29
|
-
{% else %}
|
|
30
|
-
json = {{ body_param }}
|
|
31
|
-
{% endif %}
|
|
32
|
-
{% endif %}
|
|
33
|
-
)
|
|
34
|
-
if response.status_code != {{ return_type.status_code }}:
|
|
35
|
-
raise HTTPException(response.status_code, f'{{ operation_id }} failed with status code: {response.status_code}')
|
|
36
|
-
else:
|
|
37
|
-
{# Conditional body parsing: avoid calling .json() for 204 #}
|
|
38
|
-
body = None if {{ return_type.status_code }} == 204 else response.json()
|
|
39
|
-
|
|
40
|
-
{% if return_type.type is none or return_type.type.converted_type is none %}
|
|
41
|
-
return None
|
|
42
|
-
{% elif return_type.complex_type %}
|
|
43
|
-
{%- if return_type.list_type is none %}
|
|
44
|
-
return {{ return_type.type.converted_type }}(**body) if body is not None else {{ return_type.type.converted_type }}()
|
|
45
|
-
{%- else %}
|
|
46
|
-
return [{{ return_type.list_type }}(**item) for item in body]
|
|
47
|
-
{%- endif %}
|
|
48
|
-
{% else %}
|
|
49
|
-
return body
|
|
50
|
-
{% endif %}
|
{ab_openapi_python_generator-2.1.4.dist-info → ab_openapi_python_generator-2.2.0.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|