pyopenapi-gen 0.16.1__tar.gz → 0.18.0__tar.gz
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.
Potentially problematic release.
This version of pyopenapi-gen might be problematic. Click here for more details.
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.github/workflows/claude.yml +22 -6
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/CHANGELOG.md +113 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/PKG-INFO +249 -1
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/README.md +248 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/coverage.xml +197 -21
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/input/business_swagger.json +49 -16
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/poetry.lock +4 -4
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/pyproject.toml +4 -2
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/__init__.py +1 -1
- pyopenapi_gen-0.18.0/src/pyopenapi_gen/visit/endpoint/generators/endpoint_method_generator.py +215 -0
- pyopenapi_gen-0.18.0/src/pyopenapi_gen/visit/endpoint/generators/overload_generator.py +243 -0
- pyopenapi_gen-0.18.0/tests/visit/endpoint/generators/test_overload_generator.py +514 -0
- pyopenapi_gen-0.16.1/src/pyopenapi_gen/visit/endpoint/generators/endpoint_method_generator.py +0 -93
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.bandit +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.cursor/mcp.json +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.cursor/rules/architecture.mdc +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.cursor/rules/coding-conventions.mdc +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.cursor/rules/project-goal.mdc +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.cursor/rules/testing.mdc +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.github/BRANCH_PROTECTION.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.github/CLAUDE_CONFIGURATION.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.github/CODEOWNERS +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.github/dependabot.yml +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.github/workflows/ci.yml +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.github/workflows/claude-auto-approve.yml +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.github/workflows/claude-review-trigger.yml +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.github/workflows/pr-checks.yml +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.github/workflows/production-release.yml.backup +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.github/workflows/promote-to-staging.yml +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.github/workflows/semantic-release.yml +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.github/workflows/staging-publish.yml +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.github/workflows/testpypi-publish.yml +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.gitignore +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.python-version +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/.vscode/settings.json +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/CLAUDE.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/CONTRIBUTING.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/LICENSE +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/Makefile +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/docs/README.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/docs/architecture.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/docs/endpoint_visitor.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/docs/helpers.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/docs/ir_models.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/docs/line_writer.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/docs/loader.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/docs/model_visitor.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/docs/release-automation.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/docs/render_context.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/docs/unified_type_resolution.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/input/minimal_swagger.json +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/input/minimal_syntax_test.json +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/input/test_name_collision_spec.json +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/mkdocs.yml +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/scripts/sync_version_to_init.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/scripts/validate_version_sync.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/__main__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/cli.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/context/CLAUDE.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/context/file_manager.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/context/import_collector.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/context/render_context.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/CLAUDE.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/auth/base.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/auth/plugins.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/exceptions.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/http_status_codes.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/http_transport.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/loader/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/loader/loader.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/loader/operations/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/loader/operations/parser.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/loader/operations/post_processor.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/loader/operations/request_body.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/loader/parameters/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/loader/parameters/parser.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/loader/responses/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/loader/responses/parser.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/loader/schemas/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/loader/schemas/extractor.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/pagination.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/common/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/common/ref_resolution/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/common/ref_resolution/helpers/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/common/ref_resolution/helpers/cyclic_properties.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/common/ref_resolution/helpers/direct_cycle.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/common/ref_resolution/helpers/existing_schema.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/common/ref_resolution/helpers/list_response.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/common/ref_resolution/helpers/missing_ref.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/common/ref_resolution/helpers/new_schema.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/common/ref_resolution/helpers/stripped_suffix.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/common/ref_resolution/resolve_schema_ref.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/common/type_parser.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/context.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/cycle_helpers.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/keywords/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/keywords/all_of_parser.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/keywords/any_of_parser.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/keywords/array_items_parser.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/keywords/one_of_parser.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/keywords/properties_parser.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/schema_finalizer.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/schema_parser.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/transformers/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/transformers/inline_enum_extractor.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/transformers/inline_object_promoter.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/parsing/unified_cycle_detection.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/postprocess_manager.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/schemas.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/streaming_helpers.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/telemetry.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/utils.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/warning_collector.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/writers/code_writer.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/writers/documentation_writer.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/writers/line_writer.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core/writers/python_construct_renderer.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/core_package_template/README.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/emit/models_emitter.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/emitters/CLAUDE.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/emitters/client_emitter.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/emitters/core_emitter.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/emitters/docs_emitter.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/emitters/endpoints_emitter.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/emitters/exceptions_emitter.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/emitters/models_emitter.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/generator/CLAUDE.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/generator/client_generator.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/helpers/CLAUDE.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/helpers/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/helpers/endpoint_utils.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/helpers/type_cleaner.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/helpers/type_helper.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/helpers/type_resolution/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/helpers/type_resolution/array_resolver.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/helpers/type_resolution/composition_resolver.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/helpers/type_resolution/finalizer.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/helpers/type_resolution/named_resolver.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/helpers/type_resolution/object_resolver.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/helpers/type_resolution/primitive_resolver.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/helpers/type_resolution/resolver.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/helpers/url_utils.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/http_types.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/ir.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/py.typed +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/types/CLAUDE.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/types/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/types/contracts/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/types/contracts/protocols.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/types/contracts/types.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/types/resolvers/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/types/resolvers/reference_resolver.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/types/resolvers/response_resolver.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/types/resolvers/schema_resolver.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/types/services/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/types/services/type_service.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/types/strategies/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/types/strategies/response_strategy.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/visit/CLAUDE.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/visit/client_visitor.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/visit/docs_visitor.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/visit/endpoint/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/visit/endpoint/endpoint_visitor.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/visit/endpoint/generators/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/visit/endpoint/generators/docstring_generator.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/visit/endpoint/generators/request_generator.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/visit/endpoint/generators/response_handler_generator.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/visit/endpoint/generators/signature_generator.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/visit/endpoint/generators/url_args_generator.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/visit/endpoint/processors/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/visit/endpoint/processors/import_analyzer.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/visit/endpoint/processors/parameter_processor.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/visit/exception_visitor.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/visit/model/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/visit/model/alias_generator.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/visit/model/dataclass_generator.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/visit/model/enum_generator.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/visit/model/model_visitor.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/src/pyopenapi_gen/visit/visitor.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/api/test_programmatic_api.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/auth/auth_analysis.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/auth/test_auth_base.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/auth/test_auth_plugins.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/cli/cli_analysis.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/cli/test_cli_backup_diff.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/cli/test_cli_edge_cases.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/cli/test_cli_edge_cases_comprehensive.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/cli/test_cli_internal_utils.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/cli/test_http_pagination_cli.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/context/context_analysis.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/context/test_core_import_path.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/context/test_file_manager.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/context/test_import_collector.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/context/test_render_context.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/context/test_render_context_imports.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/context/test_render_context_relative_paths.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/core_analysis.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/loader/parameters/test_inline_enum_array_params.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/loader/test_extractor.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/loader/test_top_level_enum_extraction.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/common/ref_resolution/helpers/helpers_analysis.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/common/ref_resolution/helpers/test_cyclic_properties.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/common/ref_resolution/helpers/test_direct_cycle.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/common/ref_resolution/helpers/test_existing_schema.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/common/ref_resolution/helpers/test_list_response.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/common/ref_resolution/helpers/test_missing_ref.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/common/ref_resolution/helpers/test_new_schema.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/common/ref_resolution/helpers/test_stripped_suffix.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/keywords/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/keywords/keywords_analysis.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/keywords/test_all_of_parser.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/keywords/test_any_of_parser.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/keywords/test_array_items_parser.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/keywords/test_one_of_parser.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/keywords/test_properties_parser.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/parsing_analysis.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/test_context.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/test_cycle_detection.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/test_cycle_helpers.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/test_improved_schema_naming.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/test_inline_enum_extractor.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/test_inline_object_promoter.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/test_logging.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/test_ref_resolver.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/test_schema_finalizer.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/test_schema_parser.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/test_schema_parser_list_response.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/parsing/test_type_parser.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_dataclass_serialization.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_detect_circular_imports.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_edge_cases_integration.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_edge_cases_systematic.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_exceptions_module.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_forward_references.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_http_transport.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_import_resolution.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_ir.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_ir_schema.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_loader.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_loader_extensive.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_loader_invalid_refs.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_loader_malformed.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_loader_media_types.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_pagination.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_parsing_context.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_protocol_defaults.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_schema_parser_specific_case.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_schemas.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_simple_self_ref_check.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_streaming_helpers.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_telemetry.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_telemetry_client.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_utils.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/test_warning_collector.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/writers/test_code_writer.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/writers/test_documentation_writer.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/writers/test_line_writer.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/writers/test_python_construct_renderer_json_wizard.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/core/writers/writers_analysis.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/emitters/emitters_analysis.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/emitters/test_client_emitter.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/emitters/test_docs_emitter.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/emitters/test_duplicate_operations.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/emitters/test_endpoints_emitter.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/emitters/test_exceptions_emitter.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/emitters/test_list_response_generation.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/emitters/test_models_emitter.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/end_to_end/test_dataclass_serialization_e2e.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/examples/test_developer_experience_demo.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/generation/generation_analysis.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/generation/test_external_core_package.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/generation_issues/specs/minimal_addmessage_like.json +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/generation_issues/test_addmessage_like_issues.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/generation_issues/test_agent_include_parameter_typing.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/generation_issues/test_message_batch_response_issue.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/helpers/helpers_analysis.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/helpers/test_array_resolver.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/helpers/test_endpoint_utils.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/helpers/test_endpoint_utils_extended.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/helpers/test_get_endpoint_return_types.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/helpers/test_named_resolver.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/helpers/test_named_type_resolver.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/helpers/test_object_resolver.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/helpers/test_put_endpoint_return_types.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/helpers/test_type_cleaner.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/helpers/test_type_helper.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/helpers/test_url_utils.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/helpers/test_utils_helpers.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/integration/test_generated_code_structure.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/integrations/integrations_analysis.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/integrations/test_business_swagger_message_type.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/integrations/test_end_to_end_business_swagger.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/integrations/test_end_to_end_petstore.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/integrations/test_name_collisions.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/specs/response_unwrapping_spec.yaml +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/test_analysis_overview.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/test_init.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/types/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/types/test_business_swagger_integration.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/types/test_contracts_types.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/types/test_missing_imports_bug.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/types/test_reference_resolver.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/types/test_response_resolver.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/types/test_response_strategy.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/types/test_response_strategy_simplified.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/types/test_schema_resolver.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/types/test_schema_resolver_enums.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/types/test_type_service.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/endpoint/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/endpoint/generators/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/endpoint/generators/generators_analysis.md +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/endpoint/generators/test_dataclass_integration.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/endpoint/generators/test_docstring_generator.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/endpoint/generators/test_endpoint_method_generator.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/endpoint/generators/test_match_case_response.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/endpoint/generators/test_request_generator.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/endpoint/generators/test_response_handler_generator.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/endpoint/generators/test_response_handler_generator_strategy.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/endpoint/generators/test_signature_generator.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/endpoint/generators/test_url_args_generator.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/endpoint/processors/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/endpoint/processors/test_import_analyzer.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/endpoint/processors/test_import_analyzer.py.bak +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/endpoint/processors/test_parameter_processor.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/endpoint/test_endpoint_visitor.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/model/__init__.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/model/test_alias_generator.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/model/test_dataclass_generator.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/model/test_dataclass_generator_json_wizard.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/model/test_enum_generator.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/model/test_json_value_integration.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/model/test_json_value_wrapper.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/test_client_visitor.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/test_model_visitor.py +0 -0
- {pyopenapi_gen-0.16.1 → pyopenapi_gen-0.18.0}/tests/visit/test_visitor.py +0 -0
|
@@ -44,17 +44,33 @@ jobs:
|
|
|
44
44
|
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
45
45
|
direct_prompt: |
|
|
46
46
|
Review this PR for code quality, security, and compatibility:
|
|
47
|
-
|
|
47
|
+
|
|
48
|
+
**IMPORTANT: DO NOT run quality gates (formatting, linting, tests, type checking)**
|
|
49
|
+
The CI pipeline already handles: Black, Ruff, mypy, Bandit, and pytest.
|
|
50
|
+
Focus on code logic, architecture, and security only.
|
|
51
|
+
|
|
48
52
|
**For hotfixes and minor fixes:**
|
|
49
|
-
1. If code
|
|
53
|
+
1. If code logic is sound and architecture is good, fix any issues directly
|
|
50
54
|
2. Provide detailed analysis in comments
|
|
51
55
|
3. Note if manual approval is recommended
|
|
52
|
-
|
|
56
|
+
|
|
53
57
|
**For larger changes:**
|
|
54
|
-
1. Provide comprehensive review feedback
|
|
58
|
+
1. Provide comprehensive review feedback on logic and architecture
|
|
55
59
|
2. Create issues for complex problems
|
|
56
60
|
3. Suggest improvements and alternatives
|
|
57
|
-
|
|
58
|
-
Focus on
|
|
61
|
+
|
|
62
|
+
**Focus on:**
|
|
63
|
+
- Code logic and correctness
|
|
64
|
+
- Security vulnerabilities and best practices
|
|
65
|
+
- Architecture decisions and design patterns
|
|
66
|
+
- API compatibility and breaking changes
|
|
67
|
+
- Algorithm efficiency and performance implications
|
|
68
|
+
|
|
69
|
+
**Skip (CI handles these):**
|
|
70
|
+
- Formatting checks (Black)
|
|
71
|
+
- Linting (Ruff)
|
|
72
|
+
- Type checking (mypy)
|
|
73
|
+
- Security scanning (Bandit)
|
|
74
|
+
- Test execution (pytest)
|
|
59
75
|
timeout_minutes: 60
|
|
60
76
|
|
|
@@ -1,6 +1,119 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## v0.18.0 (2025-10-14)
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
- **ci**: Add github_token to Claude Code action
|
|
9
|
+
([`e3a18d5`](https://github.com/mindhiveoy/pyopenapi_gen/commit/e3a18d5377c206c9735981c588999decdf361fdf))
|
|
10
|
+
|
|
11
|
+
Fixes workflow validation error when Claude workflow differs between branches. The action requires
|
|
12
|
+
either: 1. Identical workflow file on main branch, OR 2. Explicit github_token parameter
|
|
13
|
+
|
|
14
|
+
Adding github_token allows the action to work on PR branches with workflow modifications before
|
|
15
|
+
they're merged to main.
|
|
16
|
+
|
|
17
|
+
- **ci**: Allow dependabot in semantic-release and optimize Claude Code reviews
|
|
18
|
+
([`717e90c`](https://github.com/mindhiveoy/pyopenapi_gen/commit/717e90c3a8bff13757434fb1375b0b7a30968fd9))
|
|
19
|
+
|
|
20
|
+
1. Added dependabot and renovate to semantic-release allowed_bots list - Fixes: Workflow initiated
|
|
21
|
+
by non-human actor error - Allows automated dependency updates to trigger releases
|
|
22
|
+
|
|
23
|
+
2. Updated Claude Code workflow prompt to skip quality gates - CI pipeline already runs: Black,
|
|
24
|
+
Ruff, mypy, Bandit, pytest - Claude now focuses on: code logic, security, architecture - Avoids
|
|
25
|
+
duplicate work and speeds up reviews
|
|
26
|
+
|
|
27
|
+
These changes reduce CI time and eliminate redundant quality checks.
|
|
28
|
+
|
|
29
|
+
### Chores
|
|
30
|
+
|
|
31
|
+
- **deps**: Update idna to version 3.11 and adjust python version requirement
|
|
32
|
+
([`a4adacb`](https://github.com/mindhiveoy/pyopenapi_gen/commit/a4adacbda45ec8e9b67b8734b7867188b38c2fc1))
|
|
33
|
+
|
|
34
|
+
- **release**: Sync __init__.py version [skip ci]
|
|
35
|
+
([`1f0e3af`](https://github.com/mindhiveoy/pyopenapi_gen/commit/1f0e3af6937d63394c6c0250e19890278f1a7bd1))
|
|
36
|
+
|
|
37
|
+
### Documentation
|
|
38
|
+
|
|
39
|
+
- **readme**: Add comprehensive programmatic API documentation
|
|
40
|
+
([`d2fca57`](https://github.com/mindhiveoy/pyopenapi_gen/commit/d2fca57f62b0a1c5f718401df3c1b8ac7a7bb02b))
|
|
41
|
+
|
|
42
|
+
Added detailed documentation for using pyopenapi_gen as a Python library:
|
|
43
|
+
|
|
44
|
+
- Why programmatic usage section - Architecture diagram with mermaid - Basic usage examples -
|
|
45
|
+
Advanced usage with all options - Multi-client generation script - Build system integration
|
|
46
|
+
example - Complete API reference - Comparison: CLI vs programmatic usage
|
|
47
|
+
|
|
48
|
+
This documentation covers the generate_client() function, ClientGenerator class, and GenerationError
|
|
49
|
+
exception, making it easy for users to integrate the generator into their build systems, CI/CD
|
|
50
|
+
pipelines, and custom tooling.
|
|
51
|
+
|
|
52
|
+
### Features
|
|
53
|
+
|
|
54
|
+
- **codegen**: Add @overload support for multi-content-type operations
|
|
55
|
+
([`bf608a7`](https://github.com/mindhiveoy/pyopenapi_gen/commit/bf608a7c47dc4c528f407456478002e3d6779886))
|
|
56
|
+
|
|
57
|
+
Implement PEP 484 @overload signatures for operations accepting multiple content types
|
|
58
|
+
(application/json, multipart/form-data, etc.). Enables IDE autocomplete and type checking for
|
|
59
|
+
endpoints with varying request formats.
|
|
60
|
+
|
|
61
|
+
Technical approach: - OverloadMethodGenerator creates @overload decorators per content type -
|
|
62
|
+
Literal types constrain content_type parameter per overload - Type-safe parameter mapping:
|
|
63
|
+
JSON→body, multipart→files, form→data - Assert statements for mypy type narrowing (validated,
|
|
64
|
+
marked nosec B101)
|
|
65
|
+
|
|
66
|
+
This addresses developer experience issues when working with upload endpoints that accept both JSON
|
|
67
|
+
metadata and multipart file uploads.
|
|
68
|
+
|
|
69
|
+
- **codegen**: Integrate @overload generation into endpoint method generator
|
|
70
|
+
([`d29cd13`](https://github.com/mindhiveoy/pyopenapi_gen/commit/d29cd131ed498c389366712eb873430ec0eb7e37))
|
|
71
|
+
|
|
72
|
+
Refactor EndpointMethodGenerator to detect multi-content-type operations and delegate to
|
|
73
|
+
OverloadMethodGenerator for type-safe signature generation. Maintains full backward compatibility
|
|
74
|
+
for single-content-type operations.
|
|
75
|
+
|
|
76
|
+
Implementation: - generate() branches on has_multiple_content_types() check -
|
|
77
|
+
_generate_standard_method() preserves existing single-content-type logic -
|
|
78
|
+
_generate_overloaded_method() orchestrates overload generation + runtime dispatch - Runtime
|
|
79
|
+
dispatch validates exactly one content-type parameter provided
|
|
80
|
+
|
|
81
|
+
Developers now receive accurate IDE autocomplete for multi-format endpoints, eliminating guesswork
|
|
82
|
+
about which parameters are valid for each content type.
|
|
83
|
+
|
|
84
|
+
- **spec**: Update business_swagger.json with multi-content-type example
|
|
85
|
+
([`5007e77`](https://github.com/mindhiveoy/pyopenapi_gen/commit/5007e7752440856f7111a7422af09ca6da8a5a5a))
|
|
86
|
+
|
|
87
|
+
- Update listDocuments endpoint with cursor and page-based pagination - Provides real-world example
|
|
88
|
+
for content-type overloading implementation
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
## v0.17.0 (2025-10-13)
|
|
92
|
+
|
|
93
|
+
### Chores
|
|
94
|
+
|
|
95
|
+
- **release**: Sync __init__.py version [skip ci]
|
|
96
|
+
([`287f52a`](https://github.com/mindhiveoy/pyopenapi_gen/commit/287f52aeea6de427fb0c3bd8014e5317a9052369))
|
|
97
|
+
|
|
98
|
+
### Features
|
|
99
|
+
|
|
100
|
+
- **ci**: Optimize Claude Code workflow and enable bot releases
|
|
101
|
+
([`c2efbfa`](https://github.com/mindhiveoy/pyopenapi_gen/commit/c2efbfa17f29ab040412935cf758c6c92cb1569a))
|
|
102
|
+
|
|
103
|
+
1. Claude Code Workflow Optimization: - Instruct Claude to skip quality gates (formatting, linting,
|
|
104
|
+
tests, type checking) - CI pipeline already handles: Black, Ruff, mypy, Bandit, pytest - Focus
|
|
105
|
+
Claude on: code logic, security, architecture, API compatibility - Reduces duplicate work and
|
|
106
|
+
speeds up PR reviews
|
|
107
|
+
|
|
108
|
+
2. Semantic-Release Bot Support: - Added allowed_bots = ["dependabot", "renovate"] to pyproject.toml
|
|
109
|
+
- Fixes: "Workflow initiated by non-human actor" error - Enables automated dependency updates to
|
|
110
|
+
trigger releases
|
|
111
|
+
|
|
112
|
+
Benefits: - Faster CI reviews (Claude skips redundant checks) - Better focus (Claude concentrates on
|
|
113
|
+
logic and security) - Automated releases from bot PRs (dependabot, renovate) - Less noise in PR
|
|
114
|
+
reviews
|
|
115
|
+
|
|
116
|
+
|
|
4
117
|
## v0.16.1 (2025-10-13)
|
|
5
118
|
|
|
6
119
|
### Bug Fixes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyopenapi-gen
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.18.0
|
|
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
|
|
@@ -123,6 +123,254 @@ async def main():
|
|
|
123
123
|
asyncio.run(main())
|
|
124
124
|
```
|
|
125
125
|
|
|
126
|
+
## 🐍 Using as a Library (Programmatic API)
|
|
127
|
+
|
|
128
|
+
### Why Programmatic Usage?
|
|
129
|
+
The generator was designed to work both as a CLI tool and as a Python library. Programmatic usage enables integration with build systems, CI/CD pipelines, code generators, and custom tooling. You get the same powerful code generation capabilities with full Python API access.
|
|
130
|
+
|
|
131
|
+
### What Is the Programmatic API?
|
|
132
|
+
A simple, function-based API that wraps the internal `ClientGenerator` class, providing a clean entry point for library usage without requiring knowledge of internal structure.
|
|
133
|
+
|
|
134
|
+
```mermaid
|
|
135
|
+
graph TD
|
|
136
|
+
A[Your Build Script] --> B[generate_client Function]
|
|
137
|
+
B --> C[ClientGenerator]
|
|
138
|
+
C --> D[Load OpenAPI Spec]
|
|
139
|
+
D --> E[Generate Code]
|
|
140
|
+
E --> F[Write Files]
|
|
141
|
+
F --> G[Post-Process]
|
|
142
|
+
G --> H[Return File List]
|
|
143
|
+
|
|
144
|
+
subgraph "Public API"
|
|
145
|
+
B
|
|
146
|
+
I[ClientGenerator Class]
|
|
147
|
+
J[GenerationError Exception]
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
subgraph "Advanced API"
|
|
151
|
+
K[load_ir_from_spec]
|
|
152
|
+
L[IR Models]
|
|
153
|
+
M[WarningCollector]
|
|
154
|
+
end
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### How to Use Programmatically
|
|
158
|
+
|
|
159
|
+
#### Basic Usage
|
|
160
|
+
```python
|
|
161
|
+
from pyopenapi_gen import generate_client
|
|
162
|
+
|
|
163
|
+
# Simple client generation
|
|
164
|
+
files = generate_client(
|
|
165
|
+
spec_path="input/openapi.yaml",
|
|
166
|
+
project_root=".",
|
|
167
|
+
output_package="pyapis.my_client"
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
print(f"Generated {len(files)} files")
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
#### Advanced Usage with All Options
|
|
174
|
+
```python
|
|
175
|
+
from pyopenapi_gen import generate_client, GenerationError
|
|
176
|
+
|
|
177
|
+
try:
|
|
178
|
+
files = generate_client(
|
|
179
|
+
spec_path="input/openapi.yaml",
|
|
180
|
+
project_root=".",
|
|
181
|
+
output_package="pyapis.my_client",
|
|
182
|
+
core_package="pyapis.core", # Optional shared core
|
|
183
|
+
force=True, # Overwrite without diff check
|
|
184
|
+
no_postprocess=False, # Run Black + mypy
|
|
185
|
+
verbose=True # Show progress
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
# Process generated files
|
|
189
|
+
for file_path in files:
|
|
190
|
+
print(f"Generated: {file_path}")
|
|
191
|
+
|
|
192
|
+
except GenerationError as e:
|
|
193
|
+
print(f"Generation failed: {e}")
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
#### Multi-Client Generation Script
|
|
197
|
+
```python
|
|
198
|
+
from pyopenapi_gen import generate_client
|
|
199
|
+
from pathlib import Path
|
|
200
|
+
|
|
201
|
+
# Configuration for multiple clients
|
|
202
|
+
clients = [
|
|
203
|
+
{"spec": "api_v1.yaml", "package": "pyapis.client_v1"},
|
|
204
|
+
{"spec": "api_v2.yaml", "package": "pyapis.client_v2"},
|
|
205
|
+
]
|
|
206
|
+
|
|
207
|
+
# Shared core package
|
|
208
|
+
core_package = "pyapis.core"
|
|
209
|
+
|
|
210
|
+
# Generate all clients
|
|
211
|
+
for client_config in clients:
|
|
212
|
+
print(f"Generating {client_config['package']}...")
|
|
213
|
+
|
|
214
|
+
generate_client(
|
|
215
|
+
spec_path=client_config["spec"],
|
|
216
|
+
project_root=".",
|
|
217
|
+
output_package=client_config["package"],
|
|
218
|
+
core_package=core_package,
|
|
219
|
+
force=True,
|
|
220
|
+
verbose=True
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
print("All clients generated successfully!")
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
#### Integration with Build Systems
|
|
227
|
+
```python
|
|
228
|
+
# Example: Custom build script
|
|
229
|
+
import sys
|
|
230
|
+
from pathlib import Path
|
|
231
|
+
from pyopenapi_gen import generate_client, GenerationError
|
|
232
|
+
|
|
233
|
+
def build_api_clients():
|
|
234
|
+
"""Generate all API clients as part of build process"""
|
|
235
|
+
|
|
236
|
+
specs_dir = Path("specs")
|
|
237
|
+
|
|
238
|
+
# Find all OpenAPI specs
|
|
239
|
+
spec_files = list(specs_dir.glob("*.yaml")) + list(specs_dir.glob("*.json"))
|
|
240
|
+
|
|
241
|
+
if not spec_files:
|
|
242
|
+
print("No OpenAPI specs found in specs/")
|
|
243
|
+
return False
|
|
244
|
+
|
|
245
|
+
# Generate clients
|
|
246
|
+
for spec_file in spec_files:
|
|
247
|
+
client_name = spec_file.stem
|
|
248
|
+
package_name = f"pyapis.{client_name}"
|
|
249
|
+
|
|
250
|
+
print(f"Generating client for {spec_file.name}...")
|
|
251
|
+
|
|
252
|
+
try:
|
|
253
|
+
generate_client(
|
|
254
|
+
spec_path=str(spec_file),
|
|
255
|
+
project_root="src",
|
|
256
|
+
output_package=package_name,
|
|
257
|
+
core_package="pyapis.core",
|
|
258
|
+
force=True
|
|
259
|
+
)
|
|
260
|
+
except GenerationError as e:
|
|
261
|
+
print(f"Failed to generate {client_name}: {e}", file=sys.stderr)
|
|
262
|
+
return False
|
|
263
|
+
|
|
264
|
+
return True
|
|
265
|
+
|
|
266
|
+
if __name__ == "__main__":
|
|
267
|
+
success = build_api_clients()
|
|
268
|
+
sys.exit(0 if success else 1)
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### API Reference
|
|
272
|
+
|
|
273
|
+
#### `generate_client()` Function
|
|
274
|
+
|
|
275
|
+
```python
|
|
276
|
+
def generate_client(
|
|
277
|
+
spec_path: str,
|
|
278
|
+
project_root: str,
|
|
279
|
+
output_package: str,
|
|
280
|
+
core_package: str | None = None,
|
|
281
|
+
force: bool = False,
|
|
282
|
+
no_postprocess: bool = False,
|
|
283
|
+
verbose: bool = False,
|
|
284
|
+
) -> List[Path]
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
**Parameters**:
|
|
288
|
+
- `spec_path`: Path to OpenAPI spec file (YAML or JSON)
|
|
289
|
+
- `project_root`: Root directory of your Python project
|
|
290
|
+
- `output_package`: Python package name (e.g., `'pyapis.my_client'`)
|
|
291
|
+
- `core_package`: Optional shared core package name (defaults to `{output_package}.core`)
|
|
292
|
+
- `force`: Skip diff check and overwrite existing output
|
|
293
|
+
- `no_postprocess`: Skip Black formatting and mypy type checking
|
|
294
|
+
- `verbose`: Print detailed progress information
|
|
295
|
+
|
|
296
|
+
**Returns**: List of `Path` objects for all generated files
|
|
297
|
+
|
|
298
|
+
**Raises**: `GenerationError` if generation fails
|
|
299
|
+
|
|
300
|
+
#### `ClientGenerator` Class (Advanced)
|
|
301
|
+
|
|
302
|
+
For advanced use cases requiring more control:
|
|
303
|
+
|
|
304
|
+
```python
|
|
305
|
+
from pyopenapi_gen import ClientGenerator, GenerationError
|
|
306
|
+
from pathlib import Path
|
|
307
|
+
|
|
308
|
+
# Create generator with custom settings
|
|
309
|
+
generator = ClientGenerator(verbose=True)
|
|
310
|
+
|
|
311
|
+
# Generate with full control
|
|
312
|
+
try:
|
|
313
|
+
files = generator.generate(
|
|
314
|
+
spec_path="openapi.yaml",
|
|
315
|
+
project_root=Path("."),
|
|
316
|
+
output_package="pyapis.my_client",
|
|
317
|
+
core_package="pyapis.core",
|
|
318
|
+
force=False,
|
|
319
|
+
no_postprocess=False
|
|
320
|
+
)
|
|
321
|
+
except GenerationError as e:
|
|
322
|
+
print(f"Generation failed: {e}")
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
#### `GenerationError` Exception
|
|
326
|
+
|
|
327
|
+
Raised when generation fails. Contains contextual information about the failure:
|
|
328
|
+
|
|
329
|
+
```python
|
|
330
|
+
from pyopenapi_gen import generate_client, GenerationError
|
|
331
|
+
|
|
332
|
+
try:
|
|
333
|
+
generate_client(
|
|
334
|
+
spec_path="invalid.yaml",
|
|
335
|
+
project_root=".",
|
|
336
|
+
output_package="test"
|
|
337
|
+
)
|
|
338
|
+
except GenerationError as e:
|
|
339
|
+
# Exception message includes context
|
|
340
|
+
print(f"Error: {e}")
|
|
341
|
+
# Typical causes:
|
|
342
|
+
# - Invalid OpenAPI specification
|
|
343
|
+
# - File I/O errors
|
|
344
|
+
# - Type checking failures
|
|
345
|
+
# - Invalid project structure
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Comparison: CLI vs Programmatic API
|
|
349
|
+
|
|
350
|
+
**CLI Usage**:
|
|
351
|
+
```bash
|
|
352
|
+
pyopenapi-gen input/openapi.yaml \
|
|
353
|
+
--project-root . \
|
|
354
|
+
--output-package pyapis.my_client \
|
|
355
|
+
--force \
|
|
356
|
+
--verbose
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
**Equivalent Programmatic Usage**:
|
|
360
|
+
```python
|
|
361
|
+
from pyopenapi_gen import generate_client
|
|
362
|
+
|
|
363
|
+
generate_client(
|
|
364
|
+
spec_path="input/openapi.yaml",
|
|
365
|
+
project_root=".",
|
|
366
|
+
output_package="pyapis.my_client",
|
|
367
|
+
force=True,
|
|
368
|
+
verbose=True
|
|
369
|
+
)
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
Both approaches use the same underlying implementation and produce identical results.
|
|
373
|
+
|
|
126
374
|
## 🔧 Configuration Options
|
|
127
375
|
|
|
128
376
|
### Standalone Client (Default)
|
|
@@ -65,6 +65,254 @@ async def main():
|
|
|
65
65
|
asyncio.run(main())
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
+
## 🐍 Using as a Library (Programmatic API)
|
|
69
|
+
|
|
70
|
+
### Why Programmatic Usage?
|
|
71
|
+
The generator was designed to work both as a CLI tool and as a Python library. Programmatic usage enables integration with build systems, CI/CD pipelines, code generators, and custom tooling. You get the same powerful code generation capabilities with full Python API access.
|
|
72
|
+
|
|
73
|
+
### What Is the Programmatic API?
|
|
74
|
+
A simple, function-based API that wraps the internal `ClientGenerator` class, providing a clean entry point for library usage without requiring knowledge of internal structure.
|
|
75
|
+
|
|
76
|
+
```mermaid
|
|
77
|
+
graph TD
|
|
78
|
+
A[Your Build Script] --> B[generate_client Function]
|
|
79
|
+
B --> C[ClientGenerator]
|
|
80
|
+
C --> D[Load OpenAPI Spec]
|
|
81
|
+
D --> E[Generate Code]
|
|
82
|
+
E --> F[Write Files]
|
|
83
|
+
F --> G[Post-Process]
|
|
84
|
+
G --> H[Return File List]
|
|
85
|
+
|
|
86
|
+
subgraph "Public API"
|
|
87
|
+
B
|
|
88
|
+
I[ClientGenerator Class]
|
|
89
|
+
J[GenerationError Exception]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
subgraph "Advanced API"
|
|
93
|
+
K[load_ir_from_spec]
|
|
94
|
+
L[IR Models]
|
|
95
|
+
M[WarningCollector]
|
|
96
|
+
end
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### How to Use Programmatically
|
|
100
|
+
|
|
101
|
+
#### Basic Usage
|
|
102
|
+
```python
|
|
103
|
+
from pyopenapi_gen import generate_client
|
|
104
|
+
|
|
105
|
+
# Simple client generation
|
|
106
|
+
files = generate_client(
|
|
107
|
+
spec_path="input/openapi.yaml",
|
|
108
|
+
project_root=".",
|
|
109
|
+
output_package="pyapis.my_client"
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
print(f"Generated {len(files)} files")
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
#### Advanced Usage with All Options
|
|
116
|
+
```python
|
|
117
|
+
from pyopenapi_gen import generate_client, GenerationError
|
|
118
|
+
|
|
119
|
+
try:
|
|
120
|
+
files = generate_client(
|
|
121
|
+
spec_path="input/openapi.yaml",
|
|
122
|
+
project_root=".",
|
|
123
|
+
output_package="pyapis.my_client",
|
|
124
|
+
core_package="pyapis.core", # Optional shared core
|
|
125
|
+
force=True, # Overwrite without diff check
|
|
126
|
+
no_postprocess=False, # Run Black + mypy
|
|
127
|
+
verbose=True # Show progress
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
# Process generated files
|
|
131
|
+
for file_path in files:
|
|
132
|
+
print(f"Generated: {file_path}")
|
|
133
|
+
|
|
134
|
+
except GenerationError as e:
|
|
135
|
+
print(f"Generation failed: {e}")
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
#### Multi-Client Generation Script
|
|
139
|
+
```python
|
|
140
|
+
from pyopenapi_gen import generate_client
|
|
141
|
+
from pathlib import Path
|
|
142
|
+
|
|
143
|
+
# Configuration for multiple clients
|
|
144
|
+
clients = [
|
|
145
|
+
{"spec": "api_v1.yaml", "package": "pyapis.client_v1"},
|
|
146
|
+
{"spec": "api_v2.yaml", "package": "pyapis.client_v2"},
|
|
147
|
+
]
|
|
148
|
+
|
|
149
|
+
# Shared core package
|
|
150
|
+
core_package = "pyapis.core"
|
|
151
|
+
|
|
152
|
+
# Generate all clients
|
|
153
|
+
for client_config in clients:
|
|
154
|
+
print(f"Generating {client_config['package']}...")
|
|
155
|
+
|
|
156
|
+
generate_client(
|
|
157
|
+
spec_path=client_config["spec"],
|
|
158
|
+
project_root=".",
|
|
159
|
+
output_package=client_config["package"],
|
|
160
|
+
core_package=core_package,
|
|
161
|
+
force=True,
|
|
162
|
+
verbose=True
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
print("All clients generated successfully!")
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
#### Integration with Build Systems
|
|
169
|
+
```python
|
|
170
|
+
# Example: Custom build script
|
|
171
|
+
import sys
|
|
172
|
+
from pathlib import Path
|
|
173
|
+
from pyopenapi_gen import generate_client, GenerationError
|
|
174
|
+
|
|
175
|
+
def build_api_clients():
|
|
176
|
+
"""Generate all API clients as part of build process"""
|
|
177
|
+
|
|
178
|
+
specs_dir = Path("specs")
|
|
179
|
+
|
|
180
|
+
# Find all OpenAPI specs
|
|
181
|
+
spec_files = list(specs_dir.glob("*.yaml")) + list(specs_dir.glob("*.json"))
|
|
182
|
+
|
|
183
|
+
if not spec_files:
|
|
184
|
+
print("No OpenAPI specs found in specs/")
|
|
185
|
+
return False
|
|
186
|
+
|
|
187
|
+
# Generate clients
|
|
188
|
+
for spec_file in spec_files:
|
|
189
|
+
client_name = spec_file.stem
|
|
190
|
+
package_name = f"pyapis.{client_name}"
|
|
191
|
+
|
|
192
|
+
print(f"Generating client for {spec_file.name}...")
|
|
193
|
+
|
|
194
|
+
try:
|
|
195
|
+
generate_client(
|
|
196
|
+
spec_path=str(spec_file),
|
|
197
|
+
project_root="src",
|
|
198
|
+
output_package=package_name,
|
|
199
|
+
core_package="pyapis.core",
|
|
200
|
+
force=True
|
|
201
|
+
)
|
|
202
|
+
except GenerationError as e:
|
|
203
|
+
print(f"Failed to generate {client_name}: {e}", file=sys.stderr)
|
|
204
|
+
return False
|
|
205
|
+
|
|
206
|
+
return True
|
|
207
|
+
|
|
208
|
+
if __name__ == "__main__":
|
|
209
|
+
success = build_api_clients()
|
|
210
|
+
sys.exit(0 if success else 1)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### API Reference
|
|
214
|
+
|
|
215
|
+
#### `generate_client()` Function
|
|
216
|
+
|
|
217
|
+
```python
|
|
218
|
+
def generate_client(
|
|
219
|
+
spec_path: str,
|
|
220
|
+
project_root: str,
|
|
221
|
+
output_package: str,
|
|
222
|
+
core_package: str | None = None,
|
|
223
|
+
force: bool = False,
|
|
224
|
+
no_postprocess: bool = False,
|
|
225
|
+
verbose: bool = False,
|
|
226
|
+
) -> List[Path]
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**Parameters**:
|
|
230
|
+
- `spec_path`: Path to OpenAPI spec file (YAML or JSON)
|
|
231
|
+
- `project_root`: Root directory of your Python project
|
|
232
|
+
- `output_package`: Python package name (e.g., `'pyapis.my_client'`)
|
|
233
|
+
- `core_package`: Optional shared core package name (defaults to `{output_package}.core`)
|
|
234
|
+
- `force`: Skip diff check and overwrite existing output
|
|
235
|
+
- `no_postprocess`: Skip Black formatting and mypy type checking
|
|
236
|
+
- `verbose`: Print detailed progress information
|
|
237
|
+
|
|
238
|
+
**Returns**: List of `Path` objects for all generated files
|
|
239
|
+
|
|
240
|
+
**Raises**: `GenerationError` if generation fails
|
|
241
|
+
|
|
242
|
+
#### `ClientGenerator` Class (Advanced)
|
|
243
|
+
|
|
244
|
+
For advanced use cases requiring more control:
|
|
245
|
+
|
|
246
|
+
```python
|
|
247
|
+
from pyopenapi_gen import ClientGenerator, GenerationError
|
|
248
|
+
from pathlib import Path
|
|
249
|
+
|
|
250
|
+
# Create generator with custom settings
|
|
251
|
+
generator = ClientGenerator(verbose=True)
|
|
252
|
+
|
|
253
|
+
# Generate with full control
|
|
254
|
+
try:
|
|
255
|
+
files = generator.generate(
|
|
256
|
+
spec_path="openapi.yaml",
|
|
257
|
+
project_root=Path("."),
|
|
258
|
+
output_package="pyapis.my_client",
|
|
259
|
+
core_package="pyapis.core",
|
|
260
|
+
force=False,
|
|
261
|
+
no_postprocess=False
|
|
262
|
+
)
|
|
263
|
+
except GenerationError as e:
|
|
264
|
+
print(f"Generation failed: {e}")
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
#### `GenerationError` Exception
|
|
268
|
+
|
|
269
|
+
Raised when generation fails. Contains contextual information about the failure:
|
|
270
|
+
|
|
271
|
+
```python
|
|
272
|
+
from pyopenapi_gen import generate_client, GenerationError
|
|
273
|
+
|
|
274
|
+
try:
|
|
275
|
+
generate_client(
|
|
276
|
+
spec_path="invalid.yaml",
|
|
277
|
+
project_root=".",
|
|
278
|
+
output_package="test"
|
|
279
|
+
)
|
|
280
|
+
except GenerationError as e:
|
|
281
|
+
# Exception message includes context
|
|
282
|
+
print(f"Error: {e}")
|
|
283
|
+
# Typical causes:
|
|
284
|
+
# - Invalid OpenAPI specification
|
|
285
|
+
# - File I/O errors
|
|
286
|
+
# - Type checking failures
|
|
287
|
+
# - Invalid project structure
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### Comparison: CLI vs Programmatic API
|
|
291
|
+
|
|
292
|
+
**CLI Usage**:
|
|
293
|
+
```bash
|
|
294
|
+
pyopenapi-gen input/openapi.yaml \
|
|
295
|
+
--project-root . \
|
|
296
|
+
--output-package pyapis.my_client \
|
|
297
|
+
--force \
|
|
298
|
+
--verbose
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
**Equivalent Programmatic Usage**:
|
|
302
|
+
```python
|
|
303
|
+
from pyopenapi_gen import generate_client
|
|
304
|
+
|
|
305
|
+
generate_client(
|
|
306
|
+
spec_path="input/openapi.yaml",
|
|
307
|
+
project_root=".",
|
|
308
|
+
output_package="pyapis.my_client",
|
|
309
|
+
force=True,
|
|
310
|
+
verbose=True
|
|
311
|
+
)
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
Both approaches use the same underlying implementation and produce identical results.
|
|
315
|
+
|
|
68
316
|
## 🔧 Configuration Options
|
|
69
317
|
|
|
70
318
|
### Standalone Client (Default)
|