ab-openapi-python-generator 2.1.4__py3-none-any.whl → 2.1.4.dev1768280320__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 (36) hide show
  1. ab_openapi_python_generator/__init__.py +10 -14
  2. {ab_openapi_python_generator-2.1.4.dist-info → ab_openapi_python_generator-2.1.4.dev1768280320.dist-info}/METADATA +27 -21
  3. ab_openapi_python_generator-2.1.4.dev1768280320.dist-info/RECORD +6 -0
  4. {ab_openapi_python_generator-2.1.4.dist-info → ab_openapi_python_generator-2.1.4.dev1768280320.dist-info}/WHEEL +1 -1
  5. ab_openapi_python_generator-2.1.4.dev1768280320.dist-info/entry_points.txt +3 -0
  6. ab_openapi_python_generator/__main__.py +0 -85
  7. ab_openapi_python_generator/common.py +0 -58
  8. ab_openapi_python_generator/generate_data.py +0 -235
  9. ab_openapi_python_generator/language_converters/__init__.py +0 -0
  10. ab_openapi_python_generator/language_converters/python/__init__.py +0 -0
  11. ab_openapi_python_generator/language_converters/python/api_config_generator.py +0 -35
  12. ab_openapi_python_generator/language_converters/python/common.py +0 -58
  13. ab_openapi_python_generator/language_converters/python/generator.py +0 -54
  14. ab_openapi_python_generator/language_converters/python/jinja_config.py +0 -38
  15. ab_openapi_python_generator/language_converters/python/model_generator.py +0 -896
  16. ab_openapi_python_generator/language_converters/python/service_generator.py +0 -540
  17. ab_openapi_python_generator/language_converters/python/templates/aiohttp.jinja2 +0 -49
  18. ab_openapi_python_generator/language_converters/python/templates/alias_union.jinja2 +0 -17
  19. ab_openapi_python_generator/language_converters/python/templates/apiconfig.jinja2 +0 -38
  20. ab_openapi_python_generator/language_converters/python/templates/apiconfig_pydantic_2.jinja2 +0 -42
  21. ab_openapi_python_generator/language_converters/python/templates/discriminator_enum.jinja2 +0 -7
  22. ab_openapi_python_generator/language_converters/python/templates/enum.jinja2 +0 -11
  23. ab_openapi_python_generator/language_converters/python/templates/httpx.jinja2 +0 -126
  24. ab_openapi_python_generator/language_converters/python/templates/models.jinja2 +0 -24
  25. ab_openapi_python_generator/language_converters/python/templates/models_pydantic_2.jinja2 +0 -28
  26. ab_openapi_python_generator/language_converters/python/templates/requests.jinja2 +0 -50
  27. ab_openapi_python_generator/language_converters/python/templates/service.jinja2 +0 -12
  28. ab_openapi_python_generator/models.py +0 -101
  29. ab_openapi_python_generator/parsers/__init__.py +0 -13
  30. ab_openapi_python_generator/parsers/openapi_30.py +0 -65
  31. ab_openapi_python_generator/parsers/openapi_31.py +0 -65
  32. ab_openapi_python_generator/py.typed +0 -0
  33. ab_openapi_python_generator/version_detector.py +0 -70
  34. ab_openapi_python_generator-2.1.4.dist-info/RECORD +0 -34
  35. ab_openapi_python_generator-2.1.4.dist-info/entry_points.txt +0 -2
  36. {ab_openapi_python_generator-2.1.4.dist-info/licenses → ab_openapi_python_generator-2.1.4.dev1768280320.dist-info}/LICENSE +0 -0
@@ -1,540 +0,0 @@
1
- import re
2
- from typing import Any, Dict, List, Literal, Optional, Tuple, Union
3
-
4
- import click
5
- from openapi_pydantic.v3 import (
6
- Operation,
7
- PathItem,
8
- Reference,
9
- Response,
10
- Schema,
11
- )
12
- from openapi_pydantic.v3.v3_0 import (
13
- MediaType as MediaType30,
14
- )
15
-
16
- # Import version-specific types for isinstance checks
17
- from openapi_pydantic.v3.v3_0 import (
18
- Reference as Reference30,
19
- )
20
- from openapi_pydantic.v3.v3_0 import (
21
- Response as Response30,
22
- )
23
- from openapi_pydantic.v3.v3_0 import (
24
- Schema as Schema30,
25
- )
26
- from openapi_pydantic.v3.v3_0.parameter import Parameter as Parameter30
27
- from openapi_pydantic.v3.v3_1 import (
28
- MediaType as MediaType31,
29
- )
30
- from openapi_pydantic.v3.v3_1 import (
31
- Reference as Reference31,
32
- )
33
- from openapi_pydantic.v3.v3_1 import (
34
- Response as Response31,
35
- )
36
- from openapi_pydantic.v3.v3_1 import (
37
- Schema as Schema31,
38
- )
39
- from openapi_pydantic.v3.v3_1.parameter import Parameter as Parameter31
40
-
41
- from ab_openapi_python_generator.language_converters.python import common
42
- from ab_openapi_python_generator.language_converters.python.common import normalize_symbol
43
- from ab_openapi_python_generator.language_converters.python.jinja_config import (
44
- create_jinja_env,
45
- )
46
- from ab_openapi_python_generator.language_converters.python.model_generator import (
47
- type_converter,
48
- )
49
- from ab_openapi_python_generator.models import (
50
- LibraryConfig,
51
- OpReturnType,
52
- Service,
53
- ServiceOperation,
54
- TypeConversion,
55
- )
56
-
57
-
58
- # Helper functions for isinstance checks across OpenAPI versions
59
- def is_response_type(obj) -> bool:
60
- """Check if object is a Response from any OpenAPI version"""
61
- return isinstance(obj, (Response30, Response31))
62
-
63
-
64
- def create_media_type_for_reference(
65
- reference_obj: Union[Response30, Reference30, Response31, Reference31],
66
- ):
67
- """Create a MediaType wrapper for a reference object, using the correct version"""
68
- # Check which version the reference object belongs to
69
- if isinstance(reference_obj, Reference30):
70
- return MediaType30(schema=reference_obj) # type: ignore - pydantic issue with generics
71
- elif isinstance(reference_obj, Reference31):
72
- return MediaType31(schema=reference_obj) # type: ignore - pydantic issue with generics
73
- else:
74
- # Fallback to v3.0 for generic Reference
75
- return MediaType30(schema=reference_obj) # type: ignore - pydantic issue with generics
76
-
77
-
78
- def is_media_type(obj) -> bool:
79
- """Check if object is a MediaType from any OpenAPI version"""
80
- return isinstance(obj, (MediaType30, MediaType31))
81
-
82
-
83
- def is_reference_type(obj: Any) -> bool:
84
- """Check if object is a Reference type across different versions."""
85
- return isinstance(obj, (Reference, Reference30, Reference31))
86
-
87
-
88
- def is_schema_type(obj: Any) -> bool:
89
- """Check if object is a Schema from any OpenAPI version"""
90
- return isinstance(obj, (Schema30, Schema31))
91
-
92
-
93
- def operation_is_sse(op: Operation) -> bool:
94
- """Detect if an Operation advertises Server-Sent-Events (text/event-stream) in any 2xx response."""
95
- if not getattr(op, "responses", None):
96
- return False
97
-
98
- for status_code, resp in op.responses.items():
99
- try:
100
- if not str(status_code).startswith("2"):
101
- continue
102
- except Exception:
103
- continue
104
-
105
- # Concrete Response object
106
- if is_response_type(resp):
107
- content = getattr(resp, "content", None)
108
- if isinstance(content, dict) and "text/event-stream" in content:
109
- return True
110
-
111
- # Reference responses could be resolved externally; skip for now
112
- if is_reference_type(resp):
113
- # If you need supporting $ref'ed SSE responses, resolve via components
114
- pass
115
-
116
- return False
117
-
118
-
119
- HTTP_OPERATIONS = ["get", "post", "put", "delete", "options", "head", "patch", "trace"]
120
-
121
-
122
- def generate_body_param(operation: Operation) -> Union[str, None]:
123
- if operation.requestBody is None:
124
- return None
125
- else:
126
- if isinstance(operation.requestBody, Reference30) or isinstance(
127
- operation.requestBody, Reference31
128
- ):
129
- return "data.dict()"
130
-
131
- if operation.requestBody.content is None:
132
- return None # pragma: no cover
133
-
134
- if operation.requestBody.content.get("application/json") is None:
135
- return None # pragma: no cover
136
-
137
- media_type = operation.requestBody.content.get("application/json")
138
-
139
- if media_type is None:
140
- return None # pragma: no cover
141
-
142
- if isinstance(
143
- media_type.media_type_schema, (Reference, Reference30, Reference31)
144
- ):
145
- return "data.dict()"
146
- elif hasattr(media_type.media_type_schema, "ref"):
147
- # Handle Reference objects from different OpenAPI versions
148
- return "data.dict()"
149
- elif isinstance(media_type.media_type_schema, (Schema, Schema30, Schema31)):
150
- schema = media_type.media_type_schema
151
- if schema.type == "array":
152
- return "[i.dict() for i in data]"
153
- elif schema.type == "object":
154
- return "data"
155
- else:
156
- raise Exception(
157
- f"Unsupported schema type for request body: {schema.type}"
158
- ) # pragma: no cover
159
- else:
160
- raise Exception(
161
- f"Unsupported schema type for request body: {type(media_type.media_type_schema)}"
162
- ) # pragma: no cover
163
-
164
-
165
- def generate_params(operation: Operation) -> str:
166
- def _generate_params_from_content(content: Any):
167
- # Accept reference from either 3.0 or 3.1
168
- if isinstance(content, (Reference, Reference30, Reference31)):
169
- return f"data : {content.ref.split('/')[-1]}" # type: ignore
170
- elif isinstance(content, (Schema, Schema30, Schema31)):
171
- return f"data : {type_converter(content, True).converted_type}" # type: ignore
172
- else: # pragma: no cover
173
- raise Exception(f"Unsupported request body schema type: {type(content)}")
174
-
175
- if operation.parameters is None and operation.requestBody is None:
176
- return ""
177
-
178
- params = ""
179
- default_params = ""
180
- if operation.parameters is not None:
181
- for param in operation.parameters:
182
- if not isinstance(param, (Parameter30, Parameter31)):
183
- continue # pragma: no cover
184
- converted_result = ""
185
- required = False
186
- param_name_cleaned = common.normalize_symbol(param.name)
187
-
188
- if isinstance(param.param_schema, Schema30) or isinstance(
189
- param.param_schema, Schema31
190
- ):
191
- converted_result = (
192
- f"{param_name_cleaned} : {type_converter(param.param_schema, param.required).converted_type}"
193
- + ("" if param.required else " = None")
194
- )
195
- required = param.required
196
- elif isinstance(param.param_schema, Reference30) or isinstance(
197
- param.param_schema, Reference31
198
- ):
199
- converted_result = (
200
- f"{param_name_cleaned} : {param.param_schema.ref.split('/')[-1] }"
201
- + (
202
- ""
203
- if isinstance(param, Reference30)
204
- or isinstance(param, Reference31)
205
- or param.required
206
- else " = None"
207
- )
208
- )
209
- required = isinstance(param, Reference) or param.required
210
-
211
- if required:
212
- params += f"{converted_result}, "
213
- else:
214
- default_params += f"{converted_result}, "
215
-
216
- operation_request_body_types = [
217
- "application/json",
218
- "text/plain",
219
- "multipart/form-data",
220
- "application/octet-stream",
221
- ]
222
-
223
- if operation.requestBody is not None and not is_reference_type(
224
- operation.requestBody
225
- ):
226
- # Safe access only if it's a concrete RequestBody object
227
- rb_content = getattr(operation.requestBody, "content", None)
228
- if isinstance(rb_content, dict) and any(
229
- rb_content.get(i) is not None for i in operation_request_body_types
230
- ):
231
- get_keyword = [
232
- i for i in operation_request_body_types if rb_content.get(i)
233
- ][0]
234
- content = rb_content.get(get_keyword)
235
- if content is not None and hasattr(content, "media_type_schema"):
236
- mts = getattr(content, "media_type_schema", None)
237
- if isinstance(
238
- mts,
239
- (Reference, Reference30, Reference31, Schema, Schema30, Schema31),
240
- ):
241
- params += f"{_generate_params_from_content(mts)}, "
242
- else: # pragma: no cover
243
- raise Exception(
244
- f"Unsupported media type schema for {str(operation)}: {type(mts)}"
245
- )
246
- # else: silently ignore unsupported body shapes (could extend later)
247
- # Replace - with _ in params
248
- params = params.replace("-", "_")
249
- default_params = default_params.replace("-", "_")
250
-
251
- return params + default_params
252
-
253
-
254
- def generate_operation_id(
255
- operation: Operation, http_op: str, path_name: Optional[str] = None
256
- ) -> str:
257
- if operation.operationId is not None:
258
- return common.normalize_symbol(operation.operationId)
259
- elif path_name is not None:
260
- return common.normalize_symbol(f"{http_op}_{path_name}")
261
- else:
262
- raise Exception(
263
- f"OperationId is not defined for {http_op} of path_name {path_name} --> {operation.summary}"
264
- ) # pragma: no cover
265
-
266
-
267
- def _generate_params(
268
- operation: Operation, param_in: Literal["query", "header"] = "query"
269
- ):
270
- if operation.parameters is None:
271
- return []
272
-
273
- params = []
274
- for param in operation.parameters:
275
- if isinstance(param, (Parameter30, Parameter31)) and param.param_in == param_in:
276
- param_name_cleaned = common.normalize_symbol(param.name)
277
- params.append(f"{param.name!r} : {param_name_cleaned}")
278
-
279
- return params
280
-
281
-
282
- def generate_query_params(operation: Operation) -> List[str]:
283
- return _generate_params(operation, "query")
284
-
285
-
286
- def generate_header_params(operation: Operation) -> List[str]:
287
- return _generate_params(operation, "header")
288
-
289
-
290
- def generate_return_type(operation: Operation) -> OpReturnType:
291
- if operation.responses is None:
292
- return OpReturnType(type=None, status_code=200, complex_type=False)
293
-
294
- good_responses: List[Tuple[int, Union[Response, Reference]]] = [
295
- (int(status_code), response)
296
- for status_code, response in operation.responses.items()
297
- if status_code.startswith("2")
298
- ]
299
- if len(good_responses) == 0:
300
- return OpReturnType(type=None, status_code=200, complex_type=False)
301
-
302
- chosen_response = good_responses[0][1]
303
- media_type_schema = None
304
-
305
- if is_response_type(chosen_response):
306
- # It's a Response type, access content safely
307
- if hasattr(chosen_response, "content") and chosen_response.content is not None: # type: ignore
308
- content = chosen_response.content # type: ignore
309
- # Prefer application/json, then text/event-stream, then first available
310
- if isinstance(content, dict):
311
- media_type_schema = (
312
- content.get("application/json")
313
- or content.get("text/event-stream")
314
- or next(iter(content.values()), None)
315
- )
316
- else:
317
- media_type_schema = None
318
- elif is_reference_type(chosen_response):
319
- media_type_schema = create_media_type_for_reference(chosen_response)
320
-
321
- if media_type_schema is None:
322
- return OpReturnType(
323
- type=None, status_code=good_responses[0][0], complex_type=False
324
- )
325
-
326
- if is_media_type(media_type_schema):
327
- inner_schema = getattr(media_type_schema, "media_type_schema", None)
328
- if is_reference_type(inner_schema):
329
- type_conv = TypeConversion(
330
- original_type=inner_schema.ref, # type: ignore
331
- converted_type=inner_schema.ref.split("/")[-1], # type: ignore
332
- import_types=[inner_schema.ref.split("/")[-1]], # type: ignore
333
- )
334
- return OpReturnType(
335
- type=type_conv,
336
- status_code=good_responses[0][0],
337
- complex_type=True,
338
- )
339
- elif is_schema_type(inner_schema):
340
- converted_result = type_converter(inner_schema, True) # type: ignore
341
- if "array" in converted_result.original_type and isinstance(
342
- converted_result.import_types, list
343
- ):
344
- matched = re.findall(r"List\[(.+)\]", converted_result.converted_type)
345
- if len(matched) > 0:
346
- list_type = matched[0]
347
- else: # pragma: no cover
348
- raise Exception(
349
- f"Unable to parse list type from {converted_result.converted_type}"
350
- )
351
- else:
352
- list_type = None
353
- return OpReturnType(
354
- type=converted_result,
355
- status_code=good_responses[0][0],
356
- complex_type=bool(
357
- converted_result.import_types
358
- and len(converted_result.import_types) > 0
359
- ),
360
- list_type=list_type,
361
- )
362
- else: # pragma: no cover
363
- raise Exception("Unknown media type schema type")
364
- elif media_type_schema is None:
365
- return OpReturnType(
366
- type=None,
367
- status_code=good_responses[0][0],
368
- complex_type=False,
369
- )
370
- else:
371
- raise Exception("Unknown media type schema type") # pragma: no cover
372
-
373
-
374
- def generate_services(
375
- paths: Dict[str, PathItem], library_config: LibraryConfig
376
- ) -> List[Service]:
377
- """
378
- Generates services from a paths object.
379
- :param paths: paths object to be converted
380
- :return: List of services
381
- """
382
- jinja_env = create_jinja_env()
383
-
384
- def generate_service_operation(
385
- op: Operation, path_name: str, async_type: bool
386
- ) -> ServiceOperation:
387
- # Merge path-level parameters (always required by spec) into the
388
- # operation-level parameters so they get turned into function args.
389
- try:
390
- path_level_params = []
391
- if hasattr(path, "parameters") and path.parameters is not None: # type: ignore
392
- path_level_params = [p for p in path.parameters if p is not None] # type: ignore
393
- if path_level_params:
394
- existing_names = set()
395
- if op.parameters is not None:
396
- for p in op.parameters: # type: ignore
397
- if isinstance(p, (Parameter30, Parameter31)):
398
- existing_names.add(p.name)
399
- for p in path_level_params:
400
- if (
401
- isinstance(p, (Parameter30, Parameter31))
402
- and p.name not in existing_names
403
- ):
404
- if op.parameters is None:
405
- op.parameters = [] # type: ignore
406
- op.parameters.append(p) # type: ignore
407
- except Exception: # pragma: no cover
408
- print(
409
- f"Error merging path-level parameters for {path_name}"
410
- ) # pragma: no cover
411
- pass
412
-
413
- params = generate_params(op)
414
- # Fallback: ensure all {placeholders} in path are present as function params
415
- try:
416
- placeholder_names = [
417
- m.group(1) for m in re.finditer(r"\{([^}/]+)\}", path_name)
418
- ]
419
- existing_param_names = {
420
- p.split(":")[0].strip() for p in params.split(",") if ":" in p
421
- }
422
- for ph in placeholder_names:
423
- norm_ph = common.normalize_symbol(ph)
424
- if norm_ph not in existing_param_names and norm_ph:
425
- params = f"{norm_ph}: Any, " + params
426
- except Exception: # pragma: no cover
427
- print(
428
- f"Error ensuring path placeholders in params for {path_name}"
429
- ) # pragma: no cover
430
- pass
431
- operation_id = generate_operation_id(op, http_operation, path_name)
432
- query_params = generate_query_params(op)
433
- header_params = generate_header_params(op)
434
- return_type = generate_return_type(op)
435
- body_param = generate_body_param(op)
436
-
437
- so = ServiceOperation(
438
- params=params,
439
- operation_id=operation_id,
440
- query_params=query_params,
441
- header_params=header_params,
442
- return_type=return_type,
443
- operation=op,
444
- pathItem=path,
445
- content="",
446
- async_client=async_type,
447
- body_param=body_param,
448
- path_name=path_name,
449
- method=http_operation,
450
- is_sse=operation_is_sse(op),
451
- use_orjson=common.get_use_orjson(),
452
- )
453
-
454
- so.content = jinja_env.get_template(library_config.template_name).render(
455
- **so.model_dump()
456
- )
457
-
458
- if op.tags is not None and len(op.tags) > 0:
459
- so.tag = normalize_symbol(op.tags[0])
460
-
461
- try:
462
- compile(so.content, "<string>", "exec")
463
- except SyntaxError as e: # pragma: no cover
464
- click.echo(f"Error in service {so.operation_id}: {e}") # pragma: no cover
465
-
466
- return so
467
-
468
- services = []
469
- service_ops = []
470
- for path_name, path in paths.items():
471
- clean_path_name = clean_up_path_name(path_name)
472
- for http_operation in HTTP_OPERATIONS:
473
- op = path.__getattribute__(http_operation)
474
- if op is None:
475
- continue
476
-
477
- if library_config.include_sync:
478
- sync_so = generate_service_operation(op, clean_path_name, False)
479
- service_ops.append(sync_so)
480
-
481
- if library_config.include_async:
482
- async_so = generate_service_operation(op, clean_path_name, True)
483
- service_ops.append(async_so)
484
-
485
- # Ensure every operation has a tag; fallback to "default" for untagged operations
486
- for so in service_ops:
487
- if not so.tag:
488
- so.tag = "default"
489
-
490
- tags = list({so.tag for so in service_ops})
491
-
492
- for tag in tags:
493
- services.append(
494
- Service(
495
- file_name=f"{tag}_service",
496
- operations=[
497
- so for so in service_ops if so.tag == tag and not so.async_client
498
- ],
499
- content="\n".join(
500
- [
501
- so.content
502
- for so in service_ops
503
- if so.tag == tag and not so.async_client
504
- ]
505
- ),
506
- async_client=False,
507
- library_import=library_config.library_name,
508
- use_orjson=common.get_use_orjson(),
509
- )
510
- )
511
-
512
- for tag in tags:
513
- services.append(
514
- Service(
515
- file_name=f"async_{tag}_service",
516
- operations=[
517
- so for so in service_ops if so.tag == tag and so.async_client
518
- ],
519
- content="\n".join(
520
- [
521
- so.content
522
- for so in service_ops
523
- if so.tag == tag and so.async_client
524
- ]
525
- ),
526
- async_client=True,
527
- library_import=library_config.library_name,
528
- use_orjson=common.get_use_orjson(),
529
- )
530
- )
531
-
532
- return services
533
-
534
-
535
- def clean_up_path_name(path_name: str) -> str:
536
- # Clean up path name: only replace dashes inside curly brackets for f-string compatibility, keep other dashes
537
- def _replace_bracket_dashes(match):
538
- return "{" + match.group(1).replace("-", "_") + "}"
539
-
540
- return re.sub(r"\{([^}/]+)\}", _replace_bracket_dashes, path_name)
@@ -1,49 +0,0 @@
1
- async 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
-
13
- query_params : Dict[str,Any] = {
14
- {% if query_params|length > 0 %}
15
- {{ query_params | join(',\n') | safe }}
16
- {% endif %}
17
- }
18
-
19
- query_params = {key:value for (key,value) in query_params.items() if value is not None}
20
-
21
- async with aiohttp.ClientSession(headers=headers) as session:
22
- async with session.request(
23
- '{{ method }}',
24
- base_path + path,
25
- params=query_params,
26
- {% if body_param %}
27
- {% if use_orjson %}
28
- data=orjson.dumps({{ body_param }})
29
- {% else %}
30
- json = {{ body_param }}
31
- {% endif %}
32
- {% endif %}
33
- ) as initial_response:
34
- if initial_response.status != {{ return_type.status_code }}:
35
- raise HTTPException(initial_response.status, f'{{ operation_id }} failed with status code: {initial_response.status}')
36
- # Only parse JSON when a body is expected (avoid errors on 204 No Content)
37
- body = None if {{ return_type.status_code }} == 204 else await initial_response.json()
38
-
39
- {% if return_type.type is none or return_type.type.converted_type is none %}
40
- return None
41
- {% elif return_type.complex_type %}
42
- {%- if return_type.list_type is none %}
43
- return {{ return_type.type.converted_type }}(**body) if body is not None else {{ return_type.type.converted_type }}()
44
- {%- else %}
45
- return [{{ return_type.list_type }}(**item) for item in body]
46
- {%- endif %}
47
- {% else %}
48
- return body
49
- {% endif %}
@@ -1,17 +0,0 @@
1
- {# Renders ONE standalone python module that defines a named Union/Annotated alias #}
2
- {% if discriminator_key -%}
3
- from typing import Annotated, Union
4
- from pydantic import Field
5
- {% else -%}
6
- from typing import Union
7
- {% endif %}
8
-
9
- {% for imp in member_imports -%}
10
- {{ imp }}
11
- {% endfor %}
12
-
13
- {% if discriminator_key -%}
14
- {{ alias_name }} = Annotated[{{ union_type }}, Field(discriminator="{{ discriminator_key }}")]
15
- {% else -%}
16
- {{ alias_name }} = {{ union_type }}
17
- {% endif -%}
@@ -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,7 +0,0 @@
1
- from enum import Enum
2
-
3
-
4
- class {{ enum_name }}(str, Enum):
5
- {% for member_name, member_value in members %}
6
- {{ member_name }} = "{{ member_value }}"
7
- {% endfor %}