pyopenapi-gen 0.8.7__py3-none-any.whl → 0.10.1__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.
- pyopenapi_gen/__init__.py +2 -2
- pyopenapi_gen/context/CLAUDE.md +284 -0
- pyopenapi_gen/context/import_collector.py +8 -8
- pyopenapi_gen/core/CLAUDE.md +224 -0
- pyopenapi_gen/core/loader/operations/parser.py +1 -1
- pyopenapi_gen/core/parsing/cycle_helpers.py +1 -1
- pyopenapi_gen/core/parsing/keywords/properties_parser.py +4 -4
- pyopenapi_gen/core/parsing/schema_parser.py +4 -4
- pyopenapi_gen/core/parsing/transformers/inline_enum_extractor.py +1 -1
- pyopenapi_gen/core/writers/python_construct_renderer.py +2 -2
- pyopenapi_gen/emitters/CLAUDE.md +286 -0
- pyopenapi_gen/emitters/endpoints_emitter.py +1 -1
- pyopenapi_gen/generator/CLAUDE.md +352 -0
- pyopenapi_gen/helpers/CLAUDE.md +325 -0
- pyopenapi_gen/helpers/endpoint_utils.py +2 -2
- pyopenapi_gen/helpers/type_cleaner.py +1 -1
- pyopenapi_gen/helpers/type_resolution/composition_resolver.py +1 -1
- pyopenapi_gen/helpers/type_resolution/finalizer.py +1 -1
- pyopenapi_gen/types/CLAUDE.md +140 -0
- pyopenapi_gen/types/resolvers/schema_resolver.py +2 -2
- pyopenapi_gen/visit/CLAUDE.md +272 -0
- pyopenapi_gen/visit/endpoint/generators/docstring_generator.py +1 -1
- pyopenapi_gen/visit/endpoint/generators/signature_generator.py +1 -1
- pyopenapi_gen/visit/endpoint/processors/parameter_processor.py +1 -1
- {pyopenapi_gen-0.8.7.dist-info → pyopenapi_gen-0.10.1.dist-info}/METADATA +18 -4
- {pyopenapi_gen-0.8.7.dist-info → pyopenapi_gen-0.10.1.dist-info}/RECORD +29 -22
- {pyopenapi_gen-0.8.7.dist-info → pyopenapi_gen-0.10.1.dist-info}/WHEEL +0 -0
- {pyopenapi_gen-0.8.7.dist-info → pyopenapi_gen-0.10.1.dist-info}/entry_points.txt +0 -0
- {pyopenapi_gen-0.8.7.dist-info → pyopenapi_gen-0.10.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,272 @@
|
|
1
|
+
# visit/ - Code Generation Visitor Pattern
|
2
|
+
|
3
|
+
## Why This Folder?
|
4
|
+
Transform IR objects into Python code strings using visitor pattern. Each visitor specializes in generating one aspect of the client (models, endpoints, exceptions, etc.).
|
5
|
+
|
6
|
+
## Key Dependencies
|
7
|
+
- **Input**: `IRSpec`, `IRSchema`, `IROperation` from `../ir.py`
|
8
|
+
- **Output**: Python code strings for emitters
|
9
|
+
- **Services**: `UnifiedTypeService` from `../types/services/`
|
10
|
+
- **Context**: `RenderContext` from `../context/render_context.py`
|
11
|
+
|
12
|
+
## Essential Architecture
|
13
|
+
|
14
|
+
### 1. Visitor Pattern Hierarchy
|
15
|
+
```python
|
16
|
+
# visitor.py - Base visitor
|
17
|
+
class Visitor(Generic[tNode, tRet]):
|
18
|
+
def visit(self, node: tNode, context: RenderContext) -> tRet:
|
19
|
+
# Dispatch to specific visit methods
|
20
|
+
|
21
|
+
# Concrete visitors
|
22
|
+
class ModelVisitor(Visitor[IRSchema, str]):
|
23
|
+
def visit_schema(self, schema: IRSchema, context: RenderContext) -> str:
|
24
|
+
# Generate dataclass/enum code
|
25
|
+
```
|
26
|
+
|
27
|
+
### 2. Generators vs Visitors
|
28
|
+
- **Visitors**: High-level orchestration, traverse IR structure
|
29
|
+
- **Generators**: Low-level code generation, create specific code blocks
|
30
|
+
|
31
|
+
```python
|
32
|
+
# endpoint/endpoint_visitor.py
|
33
|
+
class EndpointVisitor:
|
34
|
+
def __init__(self):
|
35
|
+
self.signature_generator = SignatureGenerator()
|
36
|
+
self.request_generator = RequestGenerator()
|
37
|
+
self.response_generator = ResponseHandlerGenerator()
|
38
|
+
```
|
39
|
+
|
40
|
+
## Critical Components
|
41
|
+
|
42
|
+
### model/model_visitor.py
|
43
|
+
**Purpose**: Generate dataclass and enum code from schemas
|
44
|
+
```python
|
45
|
+
def visit_schema(self, schema: IRSchema, context: RenderContext) -> str:
|
46
|
+
if schema.enum:
|
47
|
+
return self.enum_generator.generate_enum(schema, context)
|
48
|
+
elif schema.type == "object":
|
49
|
+
return self.dataclass_generator.generate_dataclass(schema, context)
|
50
|
+
else:
|
51
|
+
return self.alias_generator.generate_alias(schema, context)
|
52
|
+
```
|
53
|
+
|
54
|
+
### endpoint/endpoint_visitor.py
|
55
|
+
**Purpose**: Generate async method code from operations
|
56
|
+
```python
|
57
|
+
def visit_operation(self, operation: IROperation, context: RenderContext) -> str:
|
58
|
+
# 1. Generate method signature
|
59
|
+
signature = self.signature_generator.generate(operation, context)
|
60
|
+
|
61
|
+
# 2. Generate request construction
|
62
|
+
request_code = self.request_generator.generate(operation, context)
|
63
|
+
|
64
|
+
# 3. Generate response handling
|
65
|
+
response_code = self.response_generator.generate(operation, context)
|
66
|
+
|
67
|
+
# 4. Combine into complete method
|
68
|
+
return self.combine_method_parts(signature, request_code, response_code)
|
69
|
+
```
|
70
|
+
|
71
|
+
### client_visitor.py
|
72
|
+
**Purpose**: Generate main client class with tag-grouped methods
|
73
|
+
```python
|
74
|
+
def visit_spec(self, spec: IRSpec, context: RenderContext) -> str:
|
75
|
+
# 1. Group operations by tag
|
76
|
+
operations_by_tag = self.group_operations_by_tag(spec.operations)
|
77
|
+
|
78
|
+
# 2. Generate client class
|
79
|
+
# 3. Generate tag-based property methods
|
80
|
+
# 4. Generate context manager methods
|
81
|
+
```
|
82
|
+
|
83
|
+
## Code Generation Patterns
|
84
|
+
|
85
|
+
### 1. Template-Based Generation
|
86
|
+
```python
|
87
|
+
# Use string templates for consistent formatting
|
88
|
+
METHOD_TEMPLATE = '''
|
89
|
+
async def {method_name}(self, {parameters}) -> {return_type}:
|
90
|
+
"""
|
91
|
+
{docstring}
|
92
|
+
"""
|
93
|
+
{body}
|
94
|
+
'''
|
95
|
+
|
96
|
+
# Fill template with generated content
|
97
|
+
method_code = METHOD_TEMPLATE.format(
|
98
|
+
method_name=operation.operation_id,
|
99
|
+
parameters=self.signature_generator.generate_parameters(operation),
|
100
|
+
return_type=self.get_return_type(operation),
|
101
|
+
docstring=self.docstring_generator.generate(operation),
|
102
|
+
body=self.generate_method_body(operation)
|
103
|
+
)
|
104
|
+
```
|
105
|
+
|
106
|
+
### 2. Type Resolution Integration
|
107
|
+
```python
|
108
|
+
# endpoint/generators/signature_generator.py
|
109
|
+
def generate_parameters(self, operation: IROperation, context: RenderContext) -> str:
|
110
|
+
params = []
|
111
|
+
for param in operation.parameters:
|
112
|
+
# Use unified type service for parameter types
|
113
|
+
param_type = self.type_service.resolve_schema_type(
|
114
|
+
param.schema, context, required=param.required
|
115
|
+
)
|
116
|
+
params.append(f"{param.name}: {param_type}")
|
117
|
+
return ", ".join(params)
|
118
|
+
```
|
119
|
+
|
120
|
+
### 3. Import Management
|
121
|
+
```python
|
122
|
+
# Always register imports when using complex types
|
123
|
+
def generate_dataclass(self, schema: IRSchema, context: RenderContext) -> str:
|
124
|
+
imports = []
|
125
|
+
|
126
|
+
for prop_name, prop_schema in schema.properties.items():
|
127
|
+
prop_type = self.type_service.resolve_schema_type(prop_schema, context)
|
128
|
+
|
129
|
+
# Type service handles import registration
|
130
|
+
# context.add_import() called internally
|
131
|
+
|
132
|
+
return dataclass_code
|
133
|
+
```
|
134
|
+
|
135
|
+
## Specialized Generators
|
136
|
+
|
137
|
+
### endpoint/generators/
|
138
|
+
**Purpose**: Generate specific parts of endpoint methods
|
139
|
+
|
140
|
+
#### docstring_generator.py
|
141
|
+
```python
|
142
|
+
def generate_docstring(self, operation: IROperation, context: RenderContext) -> str:
|
143
|
+
# Generate Google-style docstrings
|
144
|
+
# Include parameter descriptions
|
145
|
+
# Include return type information
|
146
|
+
# Include raises information
|
147
|
+
```
|
148
|
+
|
149
|
+
#### request_generator.py
|
150
|
+
```python
|
151
|
+
def generate_request_construction(self, operation: IROperation, context: RenderContext) -> str:
|
152
|
+
# Generate httpx.Request construction
|
153
|
+
# Handle query parameters, headers, body
|
154
|
+
# Apply authentication
|
155
|
+
```
|
156
|
+
|
157
|
+
#### response_handler_generator.py
|
158
|
+
```python
|
159
|
+
def generate_response_handling(self, operation: IROperation, context: RenderContext) -> str:
|
160
|
+
# Generate match/case for status codes
|
161
|
+
# Handle response deserialization
|
162
|
+
# Generate exception raising
|
163
|
+
```
|
164
|
+
|
165
|
+
## Dependencies on Other Systems
|
166
|
+
|
167
|
+
### From types/
|
168
|
+
- `UnifiedTypeService` for all type resolution
|
169
|
+
- Response unwrapping detection
|
170
|
+
- Forward reference handling
|
171
|
+
|
172
|
+
### From context/
|
173
|
+
- `RenderContext` for import management
|
174
|
+
- Template rendering utilities
|
175
|
+
- Path resolution
|
176
|
+
|
177
|
+
### To emitters/
|
178
|
+
- Visitors produce code strings
|
179
|
+
- Emitters organize code into files
|
180
|
+
|
181
|
+
## Testing Requirements
|
182
|
+
|
183
|
+
### Visitor Tests
|
184
|
+
```python
|
185
|
+
def test_model_visitor__dataclass_schema__generates_correct_code():
|
186
|
+
# Arrange
|
187
|
+
schema = IRSchema(type="object", properties={"name": {"type": "string"}})
|
188
|
+
context = RenderContext()
|
189
|
+
visitor = ModelVisitor()
|
190
|
+
|
191
|
+
# Act
|
192
|
+
code = visitor.visit_schema(schema, context)
|
193
|
+
|
194
|
+
# Assert
|
195
|
+
assert "@dataclass" in code
|
196
|
+
assert "name: str" in code
|
197
|
+
```
|
198
|
+
|
199
|
+
### Generator Tests
|
200
|
+
```python
|
201
|
+
def test_signature_generator__operation_with_params__generates_correct_signature():
|
202
|
+
# Test specific code generation components
|
203
|
+
operation = IROperation(parameters=[...])
|
204
|
+
generator = SignatureGenerator()
|
205
|
+
|
206
|
+
signature = generator.generate(operation, context)
|
207
|
+
|
208
|
+
# Verify parameter types, defaults, etc.
|
209
|
+
```
|
210
|
+
|
211
|
+
## Extension Points
|
212
|
+
|
213
|
+
### Adding New Visitors
|
214
|
+
```python
|
215
|
+
# Create new visitor for new code aspects
|
216
|
+
class CustomVisitor(Visitor[IRCustomNode, str]):
|
217
|
+
def visit_custom_node(self, node: IRCustomNode, context: RenderContext) -> str:
|
218
|
+
# Custom code generation logic
|
219
|
+
pass
|
220
|
+
```
|
221
|
+
|
222
|
+
### Adding New Generators
|
223
|
+
```python
|
224
|
+
# endpoint/generators/custom_generator.py
|
225
|
+
class CustomGenerator:
|
226
|
+
def __init__(self, type_service: UnifiedTypeService):
|
227
|
+
self.type_service = type_service
|
228
|
+
|
229
|
+
def generate(self, operation: IROperation, context: RenderContext) -> str:
|
230
|
+
# Custom code generation logic
|
231
|
+
pass
|
232
|
+
```
|
233
|
+
|
234
|
+
## Critical Implementation Details
|
235
|
+
|
236
|
+
### Error Handling in Visitors
|
237
|
+
```python
|
238
|
+
def visit_schema(self, schema: IRSchema, context: RenderContext) -> str:
|
239
|
+
try:
|
240
|
+
return self.generate_code(schema, context)
|
241
|
+
except Exception as e:
|
242
|
+
# Add context to errors
|
243
|
+
raise CodeGenerationError(f"Failed to generate code for schema {schema.name}: {e}")
|
244
|
+
```
|
245
|
+
|
246
|
+
### Context Management
|
247
|
+
```python
|
248
|
+
# Always use context for imports and state
|
249
|
+
def generate_method(self, operation: IROperation, context: RenderContext) -> str:
|
250
|
+
# Register imports
|
251
|
+
context.add_import("from typing import Optional")
|
252
|
+
|
253
|
+
# Use context for type resolution
|
254
|
+
return_type = self.type_service.resolve_operation_response_type(operation, context)
|
255
|
+
|
256
|
+
# Return code string
|
257
|
+
return method_code
|
258
|
+
```
|
259
|
+
|
260
|
+
### Code Formatting
|
261
|
+
```python
|
262
|
+
# Use consistent indentation and formatting
|
263
|
+
def format_method_body(self, lines: List[str]) -> str:
|
264
|
+
# Ensure proper indentation
|
265
|
+
formatted_lines = []
|
266
|
+
for line in lines:
|
267
|
+
if line.strip():
|
268
|
+
formatted_lines.append(f" {line}") # 4-space indent
|
269
|
+
else:
|
270
|
+
formatted_lines.append("")
|
271
|
+
return "\n".join(formatted_lines)
|
272
|
+
```
|
@@ -99,7 +99,7 @@ class EndpointDocstringGenerator:
|
|
99
99
|
for resp in error_codes:
|
100
100
|
# Using a generic HTTPError, specific error classes could be mapped later
|
101
101
|
code_to_raise = "HTTPError"
|
102
|
-
desc = f"{resp.status_code}: {resp.description.strip() if resp.description else
|
102
|
+
desc = f"{resp.status_code}: {resp.description.strip() if resp.description else 'HTTP error.'}"
|
103
103
|
raises.append((code_to_raise, desc))
|
104
104
|
else:
|
105
105
|
raises.append(("HTTPError", "If the server returns a non-2xx HTTP response."))
|
@@ -66,7 +66,7 @@ class EndpointMethodSignatureGenerator:
|
|
66
66
|
args = ["self"]
|
67
67
|
for p_orig in ordered_params:
|
68
68
|
p = p_orig.copy() # Work with a copy
|
69
|
-
arg_str = f"{NameSanitizer.sanitize_method_name(p[
|
69
|
+
arg_str = f"{NameSanitizer.sanitize_method_name(p['name'])}: {p['type']}" # Ensure param name is sanitized
|
70
70
|
if not p.get("required", False):
|
71
71
|
# Default value handling: if default is None, it should be ' = None'
|
72
72
|
# If default is a string, it should be ' = "default_value"'
|
@@ -123,7 +123,7 @@ class EndpointParameterProcessor:
|
|
123
123
|
param_details_map[body_specific_param_info["name"]] = body_specific_param_info
|
124
124
|
else:
|
125
125
|
logger.warning(
|
126
|
-
f"Request body parameter name '{body_specific_param_info[
|
126
|
+
f"Request body parameter name '{body_specific_param_info['name']}' "
|
127
127
|
f"for operation '{op.operation_id}'"
|
128
128
|
f"collides with an existing path/query/header parameter. Check OpenAPI spec."
|
129
129
|
)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: pyopenapi-gen
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.10.1
|
4
4
|
Summary: Modern, async-first Python client generator for OpenAPI specifications with advanced cycle detection and unified type resolution
|
5
5
|
Project-URL: Homepage, https://github.com/your-org/pyopenapi-gen
|
6
6
|
Project-URL: Documentation, https://github.com/your-org/pyopenapi-gen/blob/main/README.md
|
@@ -99,7 +99,7 @@ poetry add pyopenapi-gen
|
|
99
99
|
|
100
100
|
### 1. Generate Your First Client
|
101
101
|
```bash
|
102
|
-
pyopenapi-gen
|
102
|
+
pyopenapi-gen openapi.yaml \
|
103
103
|
--project-root . \
|
104
104
|
--output-package my_api_client
|
105
105
|
```
|
@@ -127,7 +127,7 @@ asyncio.run(main())
|
|
127
127
|
|
128
128
|
### Standalone Client (Default)
|
129
129
|
```bash
|
130
|
-
pyopenapi-gen
|
130
|
+
pyopenapi-gen openapi.yaml \
|
131
131
|
--project-root . \
|
132
132
|
--output-package my_api_client
|
133
133
|
```
|
@@ -135,7 +135,7 @@ Creates self-contained client with embedded core dependencies.
|
|
135
135
|
|
136
136
|
### Shared Core (Multiple Clients)
|
137
137
|
```bash
|
138
|
-
pyopenapi-gen
|
138
|
+
pyopenapi-gen openapi.yaml \
|
139
139
|
--project-root . \
|
140
140
|
--output-package clients.api_client \
|
141
141
|
--core-package clients.core
|
@@ -358,6 +358,20 @@ make typecheck # Type checking with mypy
|
|
358
358
|
make security # Security scanning with Bandit
|
359
359
|
```
|
360
360
|
|
361
|
+
### Release Process
|
362
|
+
The project uses **automated semantic versioning** with conventional commits:
|
363
|
+
|
364
|
+
```bash
|
365
|
+
# Conventional commit format triggers automatic releases
|
366
|
+
git commit -m "feat(auth): add OAuth2 support" # → Minor version bump
|
367
|
+
git commit -m "fix(parser): resolve memory leak" # → Patch version bump
|
368
|
+
|
369
|
+
# Push to main triggers automatic PyPI release
|
370
|
+
git push origin main
|
371
|
+
```
|
372
|
+
|
373
|
+
All releases are automatically published to PyPI with generated changelogs. See [Release Management](CLAUDE.md#release-management--semantic-versioning) for complete details.
|
374
|
+
|
361
375
|
See our [Contributing Guide](CONTRIBUTING.md) for detailed information on:
|
362
376
|
- 📋 Development setup and workflow
|
363
377
|
- 🧪 Testing guidelines and standards
|
@@ -1,12 +1,14 @@
|
|
1
|
-
pyopenapi_gen/__init__.py,sha256=
|
1
|
+
pyopenapi_gen/__init__.py,sha256=9DJOZ8R4qQ3tHN0XxuSOK0PWXBtbpjaNEJAgzfUVTeE,3016
|
2
2
|
pyopenapi_gen/__main__.py,sha256=4-SCaCNhBd7rtyRK58uoDbdl93J0KhUeajP_b0CPpLE,110
|
3
3
|
pyopenapi_gen/cli.py,sha256=_ewksNDaA5st3TJJMZJWgCZdBGOQp__tkMVqr_6U3vs,2339
|
4
4
|
pyopenapi_gen/http_types.py,sha256=EMMYZBt8PNVZKPFu77TQija-JI-nOKyXvpiQP9-VSWE,467
|
5
5
|
pyopenapi_gen/ir.py,sha256=OWQk53_iVi9JZxVeKRjagF0nhw57skkNPd-4jDsyD7M,7354
|
6
6
|
pyopenapi_gen/py.typed,sha256=Nqnn8clbgv-5l0PgxcTOldg8mkMKrFn4TvPL-rYUUGg,1
|
7
|
+
pyopenapi_gen/context/CLAUDE.md,sha256=eUPvSY2ADQK21i52bWfzyBcDPVvvepErMiQrq6ndwlU,9004
|
7
8
|
pyopenapi_gen/context/file_manager.py,sha256=vpbRByO5SH6COdjb6C-pXkdSIRu7QFqrXxi69VLKBnM,1691
|
8
|
-
pyopenapi_gen/context/import_collector.py,sha256=
|
9
|
+
pyopenapi_gen/context/import_collector.py,sha256=rnOgR5-GsHs_oS1iUVbOF3tagcH5namNWvp7k44kugw,15262
|
9
10
|
pyopenapi_gen/context/render_context.py,sha256=AS08ha9WVjgRUsM1LFPjMCgrsHbczHH7c60Z5PbojhY,30320
|
11
|
+
pyopenapi_gen/core/CLAUDE.md,sha256=bz48K-PSrhxCq5ScmiLiU9kfpVVzSWRKOA9RdKk_pbg,6482
|
10
12
|
pyopenapi_gen/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
13
|
pyopenapi_gen/core/exceptions.py,sha256=KemyLDXl8pBgzxxV6ZhsGi7WjwKGooKU6Idy63eC2ko,553
|
12
14
|
pyopenapi_gen/core/http_transport.py,sha256=77ZOTyl0_CLuDtSCOVDQoxHDQBnclJgz6f3Hs6cy7hY,9675
|
@@ -22,7 +24,7 @@ pyopenapi_gen/core/auth/plugins.py,sha256=bDWx4MTRFsCKp1i__BsQtZEvQPGU-NKI137-zo
|
|
22
24
|
pyopenapi_gen/core/loader/__init__.py,sha256=bt-MQ35fbq-f1YnCcopPg53TuXCI9_7wcMzQZoWVpjU,391
|
23
25
|
pyopenapi_gen/core/loader/loader.py,sha256=bogAgDr2XvJWmMAFE006b3K_5AmC8eg2uj_TpYtLAfg,5591
|
24
26
|
pyopenapi_gen/core/loader/operations/__init__.py,sha256=7se21D-BOy7Qw6C9auJ9v6D3NCuRiDpRlhqxGq11fJs,366
|
25
|
-
pyopenapi_gen/core/loader/operations/parser.py,sha256=
|
27
|
+
pyopenapi_gen/core/loader/operations/parser.py,sha256=ai5iZZA2nicouC77iEvo8jKGXbHKbX_NcTy44lkwOVQ,6896
|
26
28
|
pyopenapi_gen/core/loader/operations/post_processor.py,sha256=3FZ5o59J2bSpZP-tNIec0A2hw095cC27GKqkhGrgHZA,2437
|
27
29
|
pyopenapi_gen/core/loader/operations/request_body.py,sha256=qz-wh014ejb1SGTuVRNODSXc95_iOLAjw05aDRhbXoo,3099
|
28
30
|
pyopenapi_gen/core/loader/parameters/__init__.py,sha256=p13oSibCRC5RCfsP6w7yD9MYs5TXcdI4WwPv7oGUYKk,284
|
@@ -33,9 +35,9 @@ pyopenapi_gen/core/loader/schemas/__init__.py,sha256=rlhujYfw_IzWgzhVhYMJ3eIhE6C
|
|
33
35
|
pyopenapi_gen/core/loader/schemas/extractor.py,sha256=7-lpDhs9W9wVhG1OCASdyft_V1kUH7NdP8D4x-raGjk,8364
|
34
36
|
pyopenapi_gen/core/parsing/__init__.py,sha256=RJsIR6cHaNoI4tBcpMlAa0JsY64vsHb9sPxPg6rd8FQ,486
|
35
37
|
pyopenapi_gen/core/parsing/context.py,sha256=crn5oTkzEvnSzYdPuHBA_s72kmq0RKzXpyaqNh67k68,7947
|
36
|
-
pyopenapi_gen/core/parsing/cycle_helpers.py,sha256=
|
38
|
+
pyopenapi_gen/core/parsing/cycle_helpers.py,sha256=nG5ysNavL_6lpnHWFUZR9qraBxqOzuNfI6NgSEa8a5M,5939
|
37
39
|
pyopenapi_gen/core/parsing/schema_finalizer.py,sha256=fsyuOenLJA3TndzYVETqKkSlo2Qz3TsD1YDtlbyOATQ,6839
|
38
|
-
pyopenapi_gen/core/parsing/schema_parser.py,sha256=
|
40
|
+
pyopenapi_gen/core/parsing/schema_parser.py,sha256=qFdan2djgdRBtzVCLiDBooVqXgcuWy_JbzDGLTJpPeE,30502
|
39
41
|
pyopenapi_gen/core/parsing/unified_cycle_detection.py,sha256=3nplaCVh2dFwBPbmDc2kiU0SzTPXXktdQ5Rc0Q9Uu9s,10873
|
40
42
|
pyopenapi_gen/core/parsing/common/__init__.py,sha256=U3sHMO-l6S3Cm04CVOYmBCpqLEZvCylUI7yQfcTwxYU,27
|
41
43
|
pyopenapi_gen/core/parsing/common/type_parser.py,sha256=cK7xtxhoD43K2WjLP9TGip3As3akYeYW7L2XztXCecg,2562
|
@@ -54,36 +56,40 @@ pyopenapi_gen/core/parsing/keywords/all_of_parser.py,sha256=s0aav49R4LYAwfEimWa0
|
|
54
56
|
pyopenapi_gen/core/parsing/keywords/any_of_parser.py,sha256=r9_0opPM75p0rPgdcRTBmae7Td3jPkJouuL_ksuFWtM,2856
|
55
57
|
pyopenapi_gen/core/parsing/keywords/array_items_parser.py,sha256=dIb3_VsEkqsR9W4rwXoTT9IW313TnH66sQzJL4K7EQQ,2645
|
56
58
|
pyopenapi_gen/core/parsing/keywords/one_of_parser.py,sha256=82SUPd0hk0QF4-hMr0QJmRSFa9nnJL8ncYmvgkIKKXs,2601
|
57
|
-
pyopenapi_gen/core/parsing/keywords/properties_parser.py,sha256=
|
59
|
+
pyopenapi_gen/core/parsing/keywords/properties_parser.py,sha256=bm248ApsNskFPQF4fXq7mT5oJf6FF9yAcdVLmK6el3E,4426
|
58
60
|
pyopenapi_gen/core/parsing/transformers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
59
|
-
pyopenapi_gen/core/parsing/transformers/inline_enum_extractor.py,sha256=
|
61
|
+
pyopenapi_gen/core/parsing/transformers/inline_enum_extractor.py,sha256=hXuht-t0Syi5vPO8qn9GcjEpyDcZnfFVHVIlwfMa8L0,13461
|
60
62
|
pyopenapi_gen/core/parsing/transformers/inline_object_promoter.py,sha256=4njv5raMVtspL6DoU9mxabU3yhgXHLTEhR8KmI9YMoA,5083
|
61
63
|
pyopenapi_gen/core/writers/code_writer.py,sha256=uWH5tRFIdT3RHsRV1haWQxESwhwMoM2G_CxnKB8uP88,4776
|
62
64
|
pyopenapi_gen/core/writers/documentation_writer.py,sha256=Vce-_kD4XDm3HfZb_ibSEKAu2fbTZCzzdojn9TPgFhU,8706
|
63
65
|
pyopenapi_gen/core/writers/line_writer.py,sha256=uhysxO6bh_9POUQHhoqYI4_savfAgjH4EcwBdNrVtPc,7759
|
64
|
-
pyopenapi_gen/core/writers/python_construct_renderer.py,sha256=
|
66
|
+
pyopenapi_gen/core/writers/python_construct_renderer.py,sha256=H2-dbUoc0wgI5Ll2OiRIRkfaDVBG_rFB4j44NXvF7Fk,12602
|
65
67
|
pyopenapi_gen/core_package_template/README.md,sha256=8YP-MS0KxphRbCGBf7kV3dYIFLU9piOJ3IMm3K_0hcI,1488
|
66
68
|
pyopenapi_gen/emit/models_emitter.py,sha256=Ty5yHGzvBDYa_qQwbyPNRLWPnHaWR_KLh6pYxT7uePY,7193
|
69
|
+
pyopenapi_gen/emitters/CLAUDE.md,sha256=iZYEZq1a1h033rxuh97cMpsKUElv72ysvTm3-QQUvrs,9323
|
67
70
|
pyopenapi_gen/emitters/client_emitter.py,sha256=kmMVnG-wAOJm7TUm0xOQ5YnSJfYxz1SwtpiyoUCbcCA,1939
|
68
71
|
pyopenapi_gen/emitters/core_emitter.py,sha256=RcBsAYQ3ZKcWwtkzQmyHkL7VtDQjbIObFLXD9M_GdpI,8020
|
69
72
|
pyopenapi_gen/emitters/docs_emitter.py,sha256=aouKqhRdtVvYfGVsye_uqM80nONRy0SqN06cr1l3OgA,1137
|
70
|
-
pyopenapi_gen/emitters/endpoints_emitter.py,sha256=
|
73
|
+
pyopenapi_gen/emitters/endpoints_emitter.py,sha256=2VuJJF0hpzyN-TqY9XVLQtTJ-QgedZe5Vj8ITBGsJYE,9558
|
71
74
|
pyopenapi_gen/emitters/exceptions_emitter.py,sha256=qPTIPXDyqSUtpmBIp-V4ap1uMHUPmYziCSN62t7qcAE,1918
|
72
75
|
pyopenapi_gen/emitters/models_emitter.py,sha256=I3IKwtKVocD3UVrI7cINXI8NjLwUZqHuGgvS3hjWUJ8,22192
|
76
|
+
pyopenapi_gen/generator/CLAUDE.md,sha256=BS9KkmLvk2WD-Io-_apoWjGNeMU4q4LKy4UOxYF9WxM,10870
|
73
77
|
pyopenapi_gen/generator/client_generator.py,sha256=avYz5GCp7t6vRAFJCvXw0ipLQGX2QfgWtfOwr3QlOqY,28880
|
78
|
+
pyopenapi_gen/helpers/CLAUDE.md,sha256=GyIJ0grp4SkD3plAUzyycW4nTUZf9ewtvvsdAGkmIZw,10609
|
74
79
|
pyopenapi_gen/helpers/__init__.py,sha256=m4jSQ1sDH6CesIcqIl_kox4LcDFabGxBpSIWVwbHK0M,39
|
75
|
-
pyopenapi_gen/helpers/endpoint_utils.py,sha256=
|
76
|
-
pyopenapi_gen/helpers/type_cleaner.py,sha256=
|
80
|
+
pyopenapi_gen/helpers/endpoint_utils.py,sha256=bkRu6YddIPQQD3rZLbB8L5WYzG-2Bd_JgMbxMUYY2wY,22198
|
81
|
+
pyopenapi_gen/helpers/type_cleaner.py,sha256=PRBqeEUPyEKHwedB4RZPrEDxUJ6q_h5ANains0WHIwg,13613
|
77
82
|
pyopenapi_gen/helpers/type_helper.py,sha256=uWLmJ25FHnqPf0-Pqakk4-lJ4xr5VBOF6gQP26KBAms,4276
|
78
83
|
pyopenapi_gen/helpers/url_utils.py,sha256=IflBiOcCzLrOvC5P25y12pk88Zu3X071hq4bCeDDxK0,340
|
79
84
|
pyopenapi_gen/helpers/type_resolution/__init__.py,sha256=TbaQZp7jvBiYgmuzuG8Wp56xZq32xEKtpunHqZVG1VA,85
|
80
85
|
pyopenapi_gen/helpers/type_resolution/array_resolver.py,sha256=dFppBtA6CxmiWAMR6rwGnQPv4AibL3nxtzw1LbeXVn4,2023
|
81
|
-
pyopenapi_gen/helpers/type_resolution/composition_resolver.py,sha256=
|
82
|
-
pyopenapi_gen/helpers/type_resolution/finalizer.py,sha256=
|
86
|
+
pyopenapi_gen/helpers/type_resolution/composition_resolver.py,sha256=wq6CRGxGgOKK470ln5Tpk9SzHtMuwB22TXHsRLtUFyw,3015
|
87
|
+
pyopenapi_gen/helpers/type_resolution/finalizer.py,sha256=_BcOBmOvadhBTUAvIc0Ak8FNxFw1uYL4rkKWtU68_m4,4332
|
83
88
|
pyopenapi_gen/helpers/type_resolution/named_resolver.py,sha256=akHVthcD7cp9lHI-TCeABMacwQ2Z1gGp8zMGNsI_b5A,9403
|
84
89
|
pyopenapi_gen/helpers/type_resolution/object_resolver.py,sha256=jayEjBr4evzIVMMAPc7g_gKb6BShFbAXG1oHMgskOcI,12373
|
85
90
|
pyopenapi_gen/helpers/type_resolution/primitive_resolver.py,sha256=qTshZaye5ohibVfcJYCzh4v3CAshguMGWPt2FgvQeNM,1960
|
86
91
|
pyopenapi_gen/helpers/type_resolution/resolver.py,sha256=qQY6wAitBluA-tofiyJ67Gxx8ol1W528zDWd9izYN5s,1982
|
92
|
+
pyopenapi_gen/types/CLAUDE.md,sha256=xRYlHdLhw3QGIfIlWqPt9pewRs736H1YCzwmslKtzZc,4255
|
87
93
|
pyopenapi_gen/types/__init__.py,sha256=Tv4xouOXp1CeOcnhDdh_wWF9PBHAeZmCeVPSm71kouI,359
|
88
94
|
pyopenapi_gen/types/contracts/__init__.py,sha256=qf5kJbbZ8TuH79UQSHBvjE1odKfNJrt5NrBEmurFlSU,358
|
89
95
|
pyopenapi_gen/types/contracts/protocols.py,sha256=eyjsrvHQv1viNON9itrHO5TA-PtWUZERdK3aPO_3uXM,2887
|
@@ -91,11 +97,12 @@ pyopenapi_gen/types/contracts/types.py,sha256=-Qvbx3N_14AaN-1BeyocrvsjiwXPn_eWQh
|
|
91
97
|
pyopenapi_gen/types/resolvers/__init__.py,sha256=_5kA49RvyOTyXgt0GbbOfHJcdQw2zHxvU9af8GGyNWc,295
|
92
98
|
pyopenapi_gen/types/resolvers/reference_resolver.py,sha256=qnaZeLmtyh4_NBMcKib58s6o5ycUJaattYt8F38_qIo,2053
|
93
99
|
pyopenapi_gen/types/resolvers/response_resolver.py,sha256=Kb1a2803lyoukoZy06ztPBlUw-A1lHiZ6NlJmsixxA8,6500
|
94
|
-
pyopenapi_gen/types/resolvers/schema_resolver.py,sha256=
|
100
|
+
pyopenapi_gen/types/resolvers/schema_resolver.py,sha256=R0N03MDLVzaFBQcrFOOTre1zqIg6APiWdHAT96ldgQ0,16898
|
95
101
|
pyopenapi_gen/types/services/__init__.py,sha256=inSUKmY_Vnuym6tC-AhvjCTj16GbkfxCGLESRr_uQPE,123
|
96
102
|
pyopenapi_gen/types/services/type_service.py,sha256=-LQj7oSx1mxb10Zi6DpawS8uyoUrUbnYhmUA0GuKZTc,4402
|
97
103
|
pyopenapi_gen/types/strategies/__init__.py,sha256=bju8_KEPNIow1-woMO-zJCgK_E0M6JnFq0NFsK1R4Ss,171
|
98
104
|
pyopenapi_gen/types/strategies/response_strategy.py,sha256=Y6E3O5xvCrJ2Y6IGn4BWlaGiQCC8Uk1a7BRJxfBkqrM,7387
|
105
|
+
pyopenapi_gen/visit/CLAUDE.md,sha256=Rq2e4S74TXv0ua2ZcCrO6cwCCccf3Yph44oVdj1yFPY,8297
|
99
106
|
pyopenapi_gen/visit/client_visitor.py,sha256=vpLCGF353XtBjfS7W69-1b1d79opTb1i6qBue6vSz5g,11152
|
100
107
|
pyopenapi_gen/visit/docs_visitor.py,sha256=hqgd4DAoy7T5Bap4mpH4R-nIZSyAWwFYmrIuNHM03Rg,1644
|
101
108
|
pyopenapi_gen/visit/exception_visitor.py,sha256=6gWkjEWMYM35_rBNCgB-xdE0RvYwbj49wytAorLHK9k,2097
|
@@ -103,22 +110,22 @@ pyopenapi_gen/visit/visitor.py,sha256=PANoV9zXMUrefr0pBLXIKkDOaTIjQ2hyL82cidVBCL
|
|
103
110
|
pyopenapi_gen/visit/endpoint/__init__.py,sha256=DftIZSWp6Z8jKWoJE2VGKL4G_5cqwFXe9v-PALMmsGk,73
|
104
111
|
pyopenapi_gen/visit/endpoint/endpoint_visitor.py,sha256=1aS0i2D_Y-979_7aBd0W6IS2UVO6wMujsMMw8Qt8PRE,3574
|
105
112
|
pyopenapi_gen/visit/endpoint/generators/__init__.py,sha256=-X-GYnJZ9twiEBr_U0obW8VuSoY6IJmYaxinn-seMzA,50
|
106
|
-
pyopenapi_gen/visit/endpoint/generators/docstring_generator.py,sha256=
|
113
|
+
pyopenapi_gen/visit/endpoint/generators/docstring_generator.py,sha256=U02qvuYtFElQNEtOHuTNXFl2NxUriIiuZMkmUsapOg4,5913
|
107
114
|
pyopenapi_gen/visit/endpoint/generators/endpoint_method_generator.py,sha256=wUJ4_gaA1gRrFCHYFCObBIankxGQu0MNqiOSoZOZmoA,4352
|
108
115
|
pyopenapi_gen/visit/endpoint/generators/request_generator.py,sha256=OnkrkRk39_BrK9ZDvyWqJYLz1mocD2zY7j70yIpS0J4,5374
|
109
116
|
pyopenapi_gen/visit/endpoint/generators/response_handler_generator.py,sha256=VuyYpUUQ3hIOwM0X_hrMk9qmQTC0P6xRQdC2HTTIyQw,22828
|
110
|
-
pyopenapi_gen/visit/endpoint/generators/signature_generator.py,sha256=
|
117
|
+
pyopenapi_gen/visit/endpoint/generators/signature_generator.py,sha256=VC9Q_exZMpUh46hn1JXaDRlgVm3Gb-D2v36h9SDF10k,4390
|
111
118
|
pyopenapi_gen/visit/endpoint/generators/url_args_generator.py,sha256=EsmNuVSkGfUqrmV7-1GiLPzdN86V5UqLfs1SVY0jsf0,9590
|
112
119
|
pyopenapi_gen/visit/endpoint/processors/__init__.py,sha256=_6RqpOdDuDheArqDBi3ykhsaetACny88WUuuAJvr_ME,29
|
113
120
|
pyopenapi_gen/visit/endpoint/processors/import_analyzer.py,sha256=tNmhgWwt-CjLE774TC8sPVH1-yaTKKm6JmfgBT2-iRk,3386
|
114
|
-
pyopenapi_gen/visit/endpoint/processors/parameter_processor.py,sha256=
|
121
|
+
pyopenapi_gen/visit/endpoint/processors/parameter_processor.py,sha256=BygP8yzSTrxfvNpEQIHERjd2NpEXDiwpCtmMseJKRq0,7700
|
115
122
|
pyopenapi_gen/visit/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
116
123
|
pyopenapi_gen/visit/model/alias_generator.py,sha256=3iPFDjCXU0Vm59Hfp64jTDfHoUL8ouXTTfoEwiOVm4Q,3558
|
117
124
|
pyopenapi_gen/visit/model/dataclass_generator.py,sha256=WtcQNx6l2sxVyTlH1MdQ-UFYWVMsxQk5nyJr1Mk02iM,9999
|
118
125
|
pyopenapi_gen/visit/model/enum_generator.py,sha256=QWsD-IAxGOxKQuC6LLNUvbT8Ot3NWrLFsaYT0DI16DU,9670
|
119
126
|
pyopenapi_gen/visit/model/model_visitor.py,sha256=PZeQd7-dlxZf5gY10BW-DhswmAGF903NccV6L56mjoE,9439
|
120
|
-
pyopenapi_gen-0.
|
121
|
-
pyopenapi_gen-0.
|
122
|
-
pyopenapi_gen-0.
|
123
|
-
pyopenapi_gen-0.
|
124
|
-
pyopenapi_gen-0.
|
127
|
+
pyopenapi_gen-0.10.1.dist-info/METADATA,sha256=dmrKeU6KlcuRSdXhM2caLE5mbVqlcdt6y2SYbJcNpBI,14040
|
128
|
+
pyopenapi_gen-0.10.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
129
|
+
pyopenapi_gen-0.10.1.dist-info/entry_points.txt,sha256=gxSlNiwom50T3OEZnlocA6qRjGdV0bn6hN_Xr-Ub5wA,56
|
130
|
+
pyopenapi_gen-0.10.1.dist-info/licenses/LICENSE,sha256=UFAyTWKa4w10-QerlJaHJeep7G2gcwpf-JmvI2dS2Gc,1088
|
131
|
+
pyopenapi_gen-0.10.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|