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.
Files changed (23) hide show
  1. ab_openapi_python_generator/generate_data.py +60 -60
  2. ab_openapi_python_generator/language_converters/python/{service_generator.py → client_generator.py} +83 -167
  3. ab_openapi_python_generator/language_converters/python/exception_generator.py +23 -0
  4. ab_openapi_python_generator/language_converters/python/generator.py +9 -11
  5. ab_openapi_python_generator/language_converters/python/jinja_config.py +3 -4
  6. ab_openapi_python_generator/language_converters/python/model_generator.py +33 -91
  7. ab_openapi_python_generator/language_converters/python/templates/async_client_httpx_pydantic_2.jinja2 +80 -0
  8. ab_openapi_python_generator/language_converters/python/templates/http_exception.jinja2 +8 -0
  9. ab_openapi_python_generator/language_converters/python/templates/sync_client_httpx_pydantic_2.jinja2 +80 -0
  10. ab_openapi_python_generator/models.py +5 -5
  11. ab_openapi_python_generator/version_detector.py +1 -4
  12. {ab_openapi_python_generator-2.1.4.dist-info → ab_openapi_python_generator-2.2.0.dist-info}/METADATA +1 -1
  13. {ab_openapi_python_generator-2.1.4.dist-info → ab_openapi_python_generator-2.2.0.dist-info}/RECORD +16 -19
  14. ab_openapi_python_generator/language_converters/python/api_config_generator.py +0 -35
  15. ab_openapi_python_generator/language_converters/python/templates/aiohttp.jinja2 +0 -49
  16. ab_openapi_python_generator/language_converters/python/templates/apiconfig.jinja2 +0 -38
  17. ab_openapi_python_generator/language_converters/python/templates/apiconfig_pydantic_2.jinja2 +0 -42
  18. ab_openapi_python_generator/language_converters/python/templates/httpx.jinja2 +0 -126
  19. ab_openapi_python_generator/language_converters/python/templates/requests.jinja2 +0 -50
  20. ab_openapi_python_generator/language_converters/python/templates/service.jinja2 +0 -12
  21. {ab_openapi_python_generator-2.1.4.dist-info → ab_openapi_python_generator-2.2.0.dist-info}/WHEEL +0 -0
  22. {ab_openapi_python_generator-2.1.4.dist-info → ab_openapi_python_generator-2.2.0.dist-info}/entry_points.txt +0 -0
  23. {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}"
@@ -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 %}
@@ -1,12 +0,0 @@
1
- from typing import *
2
- import {{ library_import }}
3
-
4
- {% if use_orjson %}
5
- import orjson
6
- from uuid import UUID
7
- {% endif %}
8
-
9
- from ..models import *
10
- from ..api_config import APIConfig, HTTPException
11
-
12
- {{ content | safe}}