Skip to content

Commit 96bbafc

Browse files
author
Doug Borg
committed
Add static file infrastructure for generated clients
This commit adds the ability to include static Python files in generated clients, which is essential for implementing shared utilities and modules that don't need to be templated. Changes: - Add StaticFile model to represent static content - Extend ConversionResult to include static_files list - Create static_file_generator.py module (currently returns empty list) - Update write_data() to write static files to output directory - Add comprehensive tests for static file generation This infrastructure will be used for Issue #100 enhanced error handling: - errors.py: Exception hierarchy (APIError, ClientError, ServerError) - response.py: DetailedResponse wrapper with fluent API - utils.py: Helper functions (unwrap, expect, match, type guards) All tests passing. Ready for static file content in follow-up PRs. Related to #100
1 parent f356cf0 commit 96bbafc

File tree

5 files changed

+101
-0
lines changed

5 files changed

+101
-0
lines changed

src/openapi_python_generator/generate_data.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,10 @@ def write_data(
186186
# Write the api_config.py file.
187187
write_code(Path(output) / "api_config.py", data.api_config.content, formatter)
188188

189+
# Write static files (if any).
190+
for static_file in data.static_files:
191+
write_code(Path(output) / f"{static_file.file_name}.py", static_file.content, formatter)
192+
189193
# Write the __init__.py file.
190194
write_code(
191195
Path(output) / "__init__.py",

src/openapi_python_generator/language_converters/python/generator.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
from openapi_python_generator.language_converters.python.service_generator import (
1515
generate_services,
1616
)
17+
from openapi_python_generator.language_converters.python.static_file_generator import (
18+
generate_static_files,
19+
)
1720
from openapi_python_generator.models import ConversionResult, LibraryConfig
1821

1922
# Type alias for both OpenAPI versions
@@ -46,9 +49,11 @@ def generator(
4649
services = []
4750

4851
api_config = generate_api_config(data, env_token_name, pydantic_version)
52+
static_files = generate_static_files()
4953

5054
return ConversionResult(
5155
models=models,
5256
services=services,
5357
api_config=api_config,
58+
static_files=static_files,
5459
)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
"""Generator for static files that are copied to the generated client."""
2+
from typing import List
3+
4+
from ...models import StaticFile
5+
6+
7+
def generate_static_files() -> List[StaticFile]:
8+
"""
9+
Generate static files that will be copied to the generated client.
10+
11+
Returns:
12+
List of StaticFile objects containing file names and content.
13+
"""
14+
return []

src/openapi_python_generator/models.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,13 @@ class APIConfig(BaseModel):
9494
content: str
9595

9696

97+
class StaticFile(BaseModel):
98+
file_name: str
99+
content: str
100+
101+
97102
class ConversionResult(BaseModel):
98103
models: List[Model]
99104
services: List[Service]
100105
api_config: APIConfig
106+
static_files: List[StaticFile] = []

tests/test_static_files.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
"""Test static file generation and inclusion."""
2+
import tempfile
3+
from pathlib import Path
4+
5+
from openapi_python_generator.common import Formatter
6+
from openapi_python_generator.generate_data import write_data
7+
from openapi_python_generator.models import ConversionResult, APIConfig, StaticFile
8+
9+
10+
def test_static_files_are_written():
11+
"""Test that static files are written to the output directory."""
12+
# Create a minimal ConversionResult with static files
13+
result = ConversionResult(
14+
models=[],
15+
services=[],
16+
api_config=APIConfig(
17+
file_name="api_config",
18+
base_url="https://api.example.com",
19+
content='class APIConfig:\n pass\n',
20+
),
21+
static_files=[
22+
StaticFile(
23+
file_name="errors",
24+
content='"""Error types."""\nclass APIError(Exception):\n pass\n',
25+
),
26+
StaticFile(
27+
file_name="response",
28+
content='"""Response wrapper."""\nclass DetailedResponse:\n pass\n',
29+
),
30+
],
31+
)
32+
33+
# Write to temp directory
34+
with tempfile.TemporaryDirectory() as tmpdir:
35+
output_path = Path(tmpdir) / "generated"
36+
write_data(result, output_path, Formatter.NONE)
37+
38+
# Verify static files were created
39+
assert (output_path / "errors.py").exists()
40+
assert (output_path / "response.py").exists()
41+
42+
# Verify content
43+
errors_content = (output_path / "errors.py").read_text()
44+
assert "class APIError" in errors_content
45+
46+
response_content = (output_path / "response.py").read_text()
47+
assert "class DetailedResponse" in response_content
48+
49+
50+
def test_empty_static_files():
51+
"""Test that empty static files list doesn't cause issues."""
52+
result = ConversionResult(
53+
models=[],
54+
services=[],
55+
api_config=APIConfig(
56+
file_name="api_config",
57+
base_url="https://api.example.com",
58+
content='class APIConfig:\n pass\n',
59+
),
60+
static_files=[], # Empty list
61+
)
62+
63+
# Write to temp directory
64+
with tempfile.TemporaryDirectory() as tmpdir:
65+
output_path = Path(tmpdir) / "generated"
66+
write_data(result, output_path, Formatter.NONE)
67+
68+
# Verify basic structure still created
69+
assert (output_path / "api_config.py").exists()
70+
assert (output_path / "__init__.py").exists()
71+
assert (output_path / "models").is_dir()
72+
assert (output_path / "services").is_dir()

0 commit comments

Comments
 (0)