-
Notifications
You must be signed in to change notification settings - Fork 38
feat: OpenAPI 3.1 support (parsers, generators, comprehensive tests) #99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: OpenAPI 3.1 support (parsers, generators, comprehensive tests) #99
Conversation
…nums, composites) and add edge tests; fix allOf import aggregation
…ponse handling) with edge tests
…PI types, model_dump) and update templates
…ive generate_data tests and status doc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces comprehensive OpenAPI 3.1 support with version detection, dedicated parsers for both 3.0 and 3.1, unified code generation, and extensive test coverage for new features and backward compatibility validation.
Key changes include:
- Implemented version detection utility with separate parser modules for OpenAPI 3.0/3.1
- Enhanced model and service generators with improved schema handling (refs, composites, DataType enums)
- Added comprehensive test suites covering feature completeness, edge cases, and regression testing with Swagger Petstore specs
- Updated core functionality to use unified model unions enabling cross-version typing
Reviewed Changes
Copilot reviewed 44 out of 47 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
tests/test_version_detector_edges.py |
Tests version detection edge cases and error handling |
tests/test_swagger_petstore_31.py |
Swagger Petstore 3.1 regression tests and code generation validation |
tests/test_swagger_petstore_30.py |
Swagger Petstore 3.0 regression tests for backward compatibility |
tests/test_service_generator_edges.py |
Edge case tests for service generator functionality |
tests/test_openapi_31_*.py |
Comprehensive OpenAPI 3.1 feature coverage and completeness testing |
tests/test_openapi_30.py |
OpenAPI 3.0 specific functionality tests |
tests/test_model_generator_edges.py |
Edge case tests for model generator type conversion |
| Various test data files | Test fixtures for OpenAPI 3.1 specifications and Swagger Petstore examples |
src/openapi_python_generator/version_detector.py |
Version detection utility for routing to appropriate parsers |
src/openapi_python_generator/parsers/openapi_31.py |
OpenAPI 3.1 specific parser implementation |
tests/test_openapi_31_coverage.py
Outdated
| }, | ||
| } | ||
|
|
||
| with pytest.raises(Exception): # Should fail to parse |
Copilot
AI
Aug 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using a bare Exception catch is too broad. Consider catching more specific exceptions like ValidationError or pydantic.ValidationError to make the test more precise and meaningful.
| with pytest.raises(Exception): # Should fail to parse | |
| with pytest.raises(ValidationError): # Should fail to parse |
tests/test_openapi_31_coverage.py
Outdated
| }, | ||
| } | ||
|
|
||
| with pytest.raises(Exception): # Should fail to parse |
Copilot
AI
Aug 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using a bare Exception catch is too broad. Consider catching more specific exceptions like ValidationError or pydantic.ValidationError to make the test more precise and meaningful.
| with pytest.raises(Exception): # Should fail to parse | |
| with pytest.raises(ValidationError): # Should fail to parse |
tests/test_model_generator_edges.py
Outdated
| def test_type_converter_unknown_list_first_type_fallback(): | ||
| # Invalid enum value in list should raise ValidationError (spec invalid) | ||
| import pydantic | ||
| with pytest.raises(pydantic.ValidationError): # type: ignore[attr-defined] |
Copilot
AI
Aug 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type: ignore comment suggests an import issue. Consider importing ValidationError directly from pydantic at the top of the file instead of using pydantic.ValidationError to avoid the type checker warning.
| with pytest.raises(pydantic.ValidationError): # type: ignore[attr-defined] | |
| with pytest.raises(ValidationError): |
- Merge path-level parameters into operations - Add default tag fallback (fixes None_service filename) - Add path placeholder fallback param injection - Harden requestBody & response schema handling across 3.0/3.1
…ttp; add cross-library 204 tests
|
This is great! Thank you! I'll review this asap and give you feedback |
MarcoMuellner
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I generally like the changes - they are also much smaller then i would have assumed. So great work :) I do have some comments - maybe lets resolve those first, before i can approve it?
| version = detect_openapi_version(data) | ||
|
|
||
| if version == "3.0": | ||
| openapi_obj = parse_openapi_30(data) # type: ignore[assignment] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure why we would ignore the type here?
|
|
||
| # Use version-specific generator | ||
| if version == "3.0": | ||
| result = generate_code_30( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For both function i would prefer to replace . with an underscore, i.e. generate_code_3_0
| if isinstance(reference_obj, Reference30): | ||
| return MediaType30(schema=reference_obj) | ||
| elif isinstance(reference_obj, Reference31): | ||
| return MediaType31(schema=reference_obj) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar for these types.
I am also not a 100% sure that this type of abstraction is ... good? It feels a bit icky to do it this way. Rather, i'd have a new type MediaType that within itself does the abstraction for it if you understand what i mean.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This goes for all other objects as well.
| {%- endif %} | ||
| {% else %} | ||
| return response.json() | ||
| return body |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does feel a bit dangerous, as it breaks the current way the template works - and may cause isses for users. Is this strictly necessary for this change?
| responses = "^0.25.7" | ||
| types-PyYAML = "^6.0.12.20240808" | ||
| types-requests = "^2.32.0.20241016" | ||
| types-urllib3 = "^1.26.25.14" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please fix this - this doesn't work. Also not sure why this is needed for this change?
|
I took the liberty of improving on your work here - thank you doug! Keep them coming :) |
Closes #79
Summary
Adds end-to-end OpenAPI 3.1 support: version detection, dedicated 3.0 & 3.1 parsers, unified model & service code generation, and extensive test coverage.
Key Changes
generator&api_configfor 3.0+ (model_dump usage, shared unions)Test Status
poetry run pytest -q→ 232 passed, 11 xfailed (intentional skips for unsupported 3.1 features not yet implemented)Follow-ups (separate PRs)
Backward Compatibility
No breaking changes for OpenAPI 3.0 users; 3.1 is auto-detected and handled transparently.
Feedback welcome.