From eaca25214fa8d5a49556a5d98c405a84e4f5e7c6 Mon Sep 17 00:00:00 2001 From: Bernardo Gomes Date: Sun, 18 Oct 2026 20:24:01 -0300 Subject: [PATCH 1/8] add suport to lazy import and defer --- .../samples-python-client-echo-api.yaml | 1 + ...thon-client-legacy-model-dictionaries.yaml | 1 + .../samples-python-lazy-imports.yaml | 51 +++++++ .../workflows/samples-python-petstore.yaml | 1 + docs/generators/python.md | 2 + .../languages/PythonClientCodegen.java | 48 ++++++- .../src/main/resources/python/README.mustache | 1 + .../python/README_onlypackage.mustache | 3 +- .../src/main/resources/python/api.mustache | 22 +-- .../resources/python/exports_api.mustache | 2 +- .../resources/python/exports_model.mustache | 2 +- .../resources/python/exports_package.mustache | 4 +- .../resources/python/github-workflow.mustache | 2 +- .../main/resources/python/gitlab-ci.mustache | 5 + .../python/lazy_configuration.mustache | 31 +++++ .../resources/python/model_anyof.mustache | 4 +- .../resources/python/model_generic.mustache | 4 +- .../resources/python/model_oneof.mustache | 4 +- .../main/resources/python/pyproject.mustache | 8 +- .../resources/python/requirements.mustache | 2 +- .../src/main/resources/python/setup.mustache | 7 +- .../src/main/resources/python/travis.mustache | 3 + .../python/PythonClientCodegenTest.java | 125 ++++++++++++++++++ .../resources/3_1/python/lazy-imports.yaml | 74 +++++++++++ .../3_1/python/lazy_imports_runtime.py | 119 +++++++++++++++++ .../.github/workflows/python.yml | 2 +- .../.gitlab-ci.yml | 3 + .../.travis.yml | 1 + .../python/.github/workflows/python.yml | 2 +- samples/client/echo_api/python/.gitlab-ci.yml | 3 + samples/client/echo_api/python/.travis.yml | 1 + .../.github/workflows/python.yml | 2 +- .../.gitlab-ci.yml | 3 + .../.travis.yml | 1 + .../.github/workflows/python.yml | 2 +- .../petstore/python-aiohttp/.gitlab-ci.yml | 3 + .../petstore/python-aiohttp/.travis.yml | 1 + .../.github/workflows/python.yml | 2 +- .../petstore/python-httpx-sync/.gitlab-ci.yml | 3 + .../petstore/python-httpx-sync/.travis.yml | 1 + .../python-httpx/.github/workflows/python.yml | 2 +- .../petstore/python-httpx/.gitlab-ci.yml | 3 + .../client/petstore/python-httpx/.travis.yml | 1 + .../.github/workflows/python.yml | 2 +- .../python-httpx2-sync/.gitlab-ci.yml | 3 + .../petstore/python-httpx2-sync/.travis.yml | 1 + .../.github/workflows/python.yml | 2 +- .../petstore/python-httpx2/.gitlab-ci.yml | 3 + .../client/petstore/python-httpx2/.travis.yml | 1 + .../.github/workflows/python.yml | 2 +- .../python-lazyImports/.gitlab-ci.yml | 3 + .../petstore/python-lazyImports/.travis.yml | 1 + .../python/.github/workflows/python.yml | 2 +- .../client/petstore/python/.gitlab-ci.yml | 3 + .../client/petstore/python/.travis.yml | 1 + 55 files changed, 544 insertions(+), 42 deletions(-) create mode 100644 .github/workflows/samples-python-lazy-imports.yaml create mode 100644 modules/openapi-generator/src/main/resources/python/lazy_configuration.mustache create mode 100644 modules/openapi-generator/src/test/resources/3_1/python/lazy-imports.yaml create mode 100644 modules/openapi-generator/src/test/resources/3_1/python/lazy_imports_runtime.py diff --git a/.github/workflows/samples-python-client-echo-api.yaml b/.github/workflows/samples-python-client-echo-api.yaml index 8b1622881ffa..f13ccdd0c91a 100644 --- a/.github/workflows/samples-python-client-echo-api.yaml +++ b/.github/workflows/samples-python-client-echo-api.yaml @@ -23,6 +23,7 @@ jobs: - "3.12" - "3.13" - "3.14" + - "3.15" steps: - uses: actions/checkout@v7 - uses: actions/setup-python@v7 diff --git a/.github/workflows/samples-python-client-legacy-model-dictionaries.yaml b/.github/workflows/samples-python-client-legacy-model-dictionaries.yaml index e9c6acc8888a..064026f90d58 100644 --- a/.github/workflows/samples-python-client-legacy-model-dictionaries.yaml +++ b/.github/workflows/samples-python-client-legacy-model-dictionaries.yaml @@ -19,6 +19,7 @@ jobs: - "3.12" - "3.13" - "3.14" + - "3.15" steps: - uses: actions/checkout@v7 - uses: actions/setup-python@v7 diff --git a/.github/workflows/samples-python-lazy-imports.yaml b/.github/workflows/samples-python-lazy-imports.yaml new file mode 100644 index 000000000000..f1cf7d2b3812 --- /dev/null +++ b/.github/workflows/samples-python-lazy-imports.yaml @@ -0,0 +1,51 @@ +name: "Python Client: Lazy imports and deferred validators" + +on: + pull_request: + paths: + - .github/workflows/samples-python-lazy-imports.yaml + - .mvn/** + - pom.xml + - modules/openapi-generator-core/** + - modules/openapi-generator/pom.xml + - modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java + - modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java + - modules/openapi-generator/src/main/resources/python/** + - modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientCodegenTest.java + - modules/openapi-generator/src/test/resources/3_1/python/lazy* + +jobs: + runtime: + name: Runtime contracts (Python 3.15) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - name: Set up JDK 11 + uses: actions/setup-java@v6 + with: + java-version: 11 + distribution: temurin + cache: maven + - name: Set up Python 3.15 + uses: actions/setup-python@v7 + id: py + with: + python-version: "3.15" + - name: Install runtime dependencies + run: >- + python -m pip install + "pydantic>=2.14" + "python-dateutil>=2.8.2" + "typing-extensions>=4.7.1" + "urllib3>=2.7.0,<3" + "aiohttp>=3.14.1" + "aiohttp-retry>=2.8.3" + "httpx>=0.28.1" + "httpx2>=2.13.0,<3" + - name: Test all import strategies with and without deferred validators + run: >- + ./mvnw --batch-mode --no-snapshot-updates + -pl modules/openapi-generator -am test + -Dtest=PythonClientCodegenTest + -Dsurefire.failIfNoSpecifiedTests=false + -Dpython315="${{ steps.py.outputs.python-path }}" diff --git a/.github/workflows/samples-python-petstore.yaml b/.github/workflows/samples-python-petstore.yaml index 6f2678efd6e9..73dc30d75366 100644 --- a/.github/workflows/samples-python-petstore.yaml +++ b/.github/workflows/samples-python-petstore.yaml @@ -37,6 +37,7 @@ jobs: - "3.12" - "3.13" - "3.14" + - "3.15" sample: - samples/openapi3/client/petstore/python-aiohttp - samples/openapi3/client/petstore/python-httpx2 diff --git a/docs/generators/python.md b/docs/generators/python.md index 828b94f83cfc..3289d41cbbca 100644 --- a/docs/generators/python.md +++ b/docs/generators/python.md @@ -23,10 +23,12 @@ These options may be applied as additional-properties (cli) or configOptions (pl |compatibleWithPythonLegacy|Enable compatibility with python-legacy. Currently, generated model field aliases preserve normalized Python constructor names while accepting wire names, and to_dict() emits every declared field, using None for missing attributes, under public names by default and wire names with serialize=True. Generic models expose openapi_types and attribute_map, reject unknown constructor keys, and use legacy display and equality helpers. Container conversion is limited to immediate list elements and dictionary values, matching python-legacy. Synchronous urllib3 operations keep async_req, _preload_content, tuple with_http_info() behavior, and integer _request_timeout inputs. JSON and request serialization remain unchanged.| |false| |dateFormat|date format for query parameters| |%Y-%m-%d| |datetimeFormat|datetime format for query parameters| |%Y-%m-%dT%H:%M:%S%z| +|deferBuild|Set defer_build=True only on the generated @validate_call decorators, building each operation's argument validator on its first call instead of at import time. This can reduce startup work and memory for operations that are never called. Argument validation remains enabled, but construction costs and schema construction errors move to the first call. Model configuration is unchanged: in the evaluated POC, also deferring models increased retained memory, with evidence of reduced reuse of nested validators and serializers and additional pending-model placeholders. That result depends on the Pydantic version and workload, not a universal limitation. Can be used independently or with either lazy import option.| |false| |disallowAdditionalPropertiesIfNotPresent|If false, the 'additionalProperties' implementation (set to true by default) is compliant with the OAS and JSON schema specifications. If true (default), keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.|
**false**
The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.
**true**
Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.
|true| |generateSourceCodeOnly|Specifies that only a library source code is to be generated.| |false| |hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |true| |lazyImports|Enable lazy imports.| |false| +|lazyNativeImport|Use native lazy imports for generated APIs and models. Requires Python 3.15 or newer and Pydantic 2.14 or newer. Lazy imports load a module on first use rather than when the import statement is executed. Large clients can contain many Pydantic models that an application never uses; avoiding their eager loading can reduce startup work and initial memory use. The cost moves to first use, import errors and module initialization side effects may occur later, and gains depend on which APIs and models are used. Cannot be combined with lazyImports=true. Enabling deferBuild=true can also reduce initial memory use by deferring operation argument validators. Native imports are not guaranteed to use less memory than lazyImports.| |false| |library|library template (sub-template) to use: asyncio, urllib3, httpx, httpx2| |urllib3| |mapNumberTo|Map number to Union[StrictFloat, StrictInt], StrictFloat, float or Decimal.| |Union[StrictFloat, StrictInt]| |packageName|python package name (convention: snake_case).| |openapi_client| diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java index af9aab3b7388..39f01bbed644 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java @@ -62,6 +62,8 @@ public class PythonClientCodegen extends AbstractPythonCodegen implements Codege public static final String SET_ENSURE_ASCII_TO_FALSE = "setEnsureAsciiToFalse"; public static final String POETRY1_FALLBACK = "poetry1"; public static final String LAZY_IMPORTS = "lazyImports"; + public static final String LAZY_NATIVE_IMPORT = "lazyNativeImport"; + public static final String DEFER_BUILD = "deferBuild"; public static final String BUILD_SYSTEM = "buildSystem"; public static final String SUPPORT_HTTPX_SYNC = "supportHttpxSync"; public static final String USE_INDEPENDENT_IMPLICIT_CLIENTS = "useIndependentImplicitClients"; @@ -119,6 +121,8 @@ public class PythonClientCodegen extends AbstractPythonCodegen implements Codege @Setter protected boolean setEnsureAsciiToFalse = false; @Setter protected boolean useIndependentImplicitClients = false; @Setter protected boolean compatibleWithPythonLegacy = false; + @Setter protected boolean lazyNativeImport = false; + @Setter protected boolean deferBuild = false; private String sourceFolder; private String testFolder; @@ -228,6 +232,24 @@ public PythonClientCodegen() { cliOptions.add(new CliOption(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP, CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP_DESC).defaultValue("false")); cliOptions.add(new CliOption(POETRY1_FALLBACK, "Fallback to formatting pyproject.toml to Poetry 1.x format.")); cliOptions.add(new CliOption(LAZY_IMPORTS, "Enable lazy imports.").defaultValue(Boolean.FALSE.toString())); + cliOptions.add(CliOption.newBoolean(LAZY_NATIVE_IMPORT, + "Use native lazy imports for generated APIs and models. Requires Python 3.15 or newer and Pydantic 2.14 or newer. " + + "Lazy imports load a module on first use rather than when the import statement is executed. " + + "Large clients can contain many Pydantic models that an application never uses; avoiding their eager loading " + + "can reduce startup work and initial memory use. The cost moves to first use, import errors and module " + + "initialization side effects may occur later, and gains depend on which APIs and models are used. " + + "Cannot be combined with lazyImports=true. Enabling deferBuild=true can also reduce initial memory use " + + "by deferring operation argument validators. Native imports are not guaranteed to use less memory than lazyImports.") + .defaultValue(Boolean.FALSE.toString())); + cliOptions.add(CliOption.newBoolean(DEFER_BUILD, + "Set defer_build=True only on the generated @validate_call decorators, building each operation's argument validator " + + "on its first call instead of at import time. This can reduce startup work and memory for operations that are never called. " + + "Argument validation remains enabled, but construction costs and schema construction errors move to the first call. " + + "Model configuration is unchanged: in the evaluated POC, also deferring models increased retained memory, " + + "with evidence of reduced reuse of nested validators and serializers and additional pending-model placeholders. " + + "That result depends on the Pydantic version and workload, not a universal limitation. " + + "Can be used independently or with either lazy import option.") + .defaultValue(Boolean.FALSE.toString())); cliOptions.add(new CliOption(BUILD_SYSTEM, "Build system to use in pyproject.toml (setuptools, hatchling).").defaultValue("setuptools")); cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, "directory for generated python source code; 'src' for _src layout_, unset (or '.') for _flat layout_.")); cliOptions.add(CliOption.newBoolean(SUPPORT_HTTPX_SYNC, "Generate synchronous '_sync' variants of each API method (httpx and httpx2 libraries only). " + @@ -369,6 +391,19 @@ public void processOpts() { if (additionalProperties.containsKey(LAZY_IMPORTS)) { additionalProperties.put(LAZY_IMPORTS, Boolean.valueOf(additionalProperties.get(LAZY_IMPORTS).toString())); } + if (additionalProperties.containsKey(LAZY_NATIVE_IMPORT)) { + setLazyNativeImport(convertPropertyToBooleanAndWriteBack(LAZY_NATIVE_IMPORT)); + } else { + additionalProperties.put(LAZY_NATIVE_IMPORT, lazyNativeImport); + } + if (lazyNativeImport && Boolean.TRUE.equals(additionalProperties.get(LAZY_IMPORTS))) { + throw new IllegalArgumentException("lazyNativeImport=true cannot be combined with lazyImports=true. Choose one lazy import strategy."); + } + if (additionalProperties.containsKey(DEFER_BUILD)) { + setDeferBuild(convertPropertyToBooleanAndWriteBack(DEFER_BUILD)); + } else { + additionalProperties.put(DEFER_BUILD, deferBuild); + } if (additionalProperties.containsKey(COMPATIBLE_WITH_PYTHON_LEGACY)) { setCompatibleWithPythonLegacy(convertPropertyToBooleanAndWriteBack(COMPATIBLE_WITH_PYTHON_LEGACY)); @@ -604,7 +639,7 @@ public String generatePackageName(String packageName) { @Override public String generatorLanguageVersion() { - return "3.10+"; + return lazyNativeImport ? "3.15+" : "3.10+"; } @Override @@ -634,7 +669,16 @@ public OperationsMap postProcessOperationsWithModels( objs.put("x-python-has-json-header", true); } - return super.postProcessOperationsWithModels(objs, allModels); + OperationsMap result = super.postProcessOperationsWithModels(objs, allModels); + if (lazyNativeImport) { + for (Map modelImport : result.getImports()) { + // Other imports in this list include stdlib and Pydantic types. + if (modelImport.get("import").startsWith("from " + packageName + ".models.")) { + modelImport.put("x-python-lazy-import", "true"); + } + } + } + return result; } private void renameIndependentClientOperationMembers( diff --git a/modules/openapi-generator/src/main/resources/python/README.mustache b/modules/openapi-generator/src/main/resources/python/README.mustache index 172c0c4738c6..c8ebece7f124 100644 --- a/modules/openapi-generator/src/main/resources/python/README.mustache +++ b/modules/openapi-generator/src/main/resources/python/README.mustache @@ -20,6 +20,7 @@ For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}}) Python {{{generatorLanguageVersion}}} +{{>lazy_configuration}} {{#poetry1}} Packaging retains the deprecated `[tool.poetry.dev-dependencies]` table for compatibility with legacy Poetry 1 releases. Generate with `poetry1=false` to use diff --git a/modules/openapi-generator/src/main/resources/python/README_onlypackage.mustache b/modules/openapi-generator/src/main/resources/python/README_onlypackage.mustache index d205966d0bc5..91add2fd13c0 100644 --- a/modules/openapi-generator/src/main/resources/python/README_onlypackage.mustache +++ b/modules/openapi-generator/src/main/resources/python/README_onlypackage.mustache @@ -20,6 +20,7 @@ For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}}) Python {{{generatorLanguageVersion}}} +{{>lazy_configuration}} ## Installation & Usage This python library package is generated without supporting files like setup.py or requirements files @@ -36,7 +37,7 @@ To be able to use it, you will need these dependencies in your own package that * pem >= 19.3.0 * pycryptodome >= 3.9.0 {{/hasHttpSignatureMethods}} -* pydantic >= 2.11 +* pydantic >= {{#lazyNativeImport}}2.14{{/lazyNativeImport}}{{^lazyNativeImport}}2.11{{/lazyNativeImport}} * typing-extensions >= 4.7.1 ## Getting Started diff --git a/modules/openapi-generator/src/main/resources/python/api.mustache b/modules/openapi-generator/src/main/resources/python/api.mustache index c771516a8a49..5f25c0133f77 100644 --- a/modules/openapi-generator/src/main/resources/python/api.mustache +++ b/modules/openapi-generator/src/main/resources/python/api.mustache @@ -9,7 +9,7 @@ from typing import Any, Dict, List, Optional, Tuple, Union from typing_extensions import Annotated {{#imports}} -{{import}} +{{#x-python-lazy-import}}lazy {{/x-python-lazy-import}}{{import}} {{/imports}} from {{packageName}}.api_client import ApiClient, RequestSerialized @@ -96,16 +96,16 @@ Synchronous urllib3 legacy flags can return a future or raw response. Keep the o annotation precise because Kubernetes Watch inspects it: https://github.com/kubernetes-client/python/blob/6cc5456d79dd8c0ccc9e275a0811aeb025714bea/kubernetes/watch/watch.py#L36-L48 }} - @validate_call + @validate_call{{#deferBuild}}(config={"defer_build": True}){{/deferBuild}} def {{operationId}}{{>partial_api_args_legacy}} -> {{{returnType}}}{{^returnType}}None{{/returnType}}: {{/async}} {{#async}} - @validate_call + @validate_call{{#deferBuild}}(config={"defer_build": True}){{/deferBuild}} async def {{operationId}}{{>partial_api_args}} -> {{{returnType}}}{{^returnType}}None{{/returnType}}: {{/async}} {{/compatibleWithPythonLegacyApi}} {{^compatibleWithPythonLegacyApi}} - @validate_call + @validate_call{{#deferBuild}}(config={"defer_build": True}){{/deferBuild}} {{#async}}async {{/async}}def {{operationId}}{{>partial_api_args}} -> {{{returnType}}}{{^returnType}}None{{/returnType}}: {{/compatibleWithPythonLegacyApi}} {{>partial_api}} @@ -151,16 +151,16 @@ https://github.com/OpenAPITools/openapi-generator/blob/c84b949df1a9ec04ba75989cb {{#compatibleWithPythonLegacyApi}} {{^async}} - @validate_call + @validate_call{{#deferBuild}}(config={"defer_build": True}){{/deferBuild}} def {{operationId}}_with_http_info{{>partial_api_args_legacy}} -> Tuple[{{{returnType}}}{{^returnType}}None{{/returnType}}, int, Any]: {{/async}} {{#async}} - @validate_call + @validate_call{{#deferBuild}}(config={"defer_build": True}){{/deferBuild}} async def {{operationId}}_with_http_info{{>partial_api_args}} -> ApiResponse[{{{returnType}}}{{^returnType}}None{{/returnType}}]: {{/async}} {{/compatibleWithPythonLegacyApi}} {{^compatibleWithPythonLegacyApi}} - @validate_call + @validate_call{{#deferBuild}}(config={"defer_build": True}){{/deferBuild}} {{#async}}async {{/async}}def {{operationId}}_with_http_info{{>partial_api_args}} -> ApiResponse[{{{returnType}}}{{^returnType}}None{{/returnType}}]: {{/compatibleWithPythonLegacyApi}} {{>partial_api}} @@ -201,7 +201,7 @@ https://github.com/OpenAPITools/openapi-generator/blob/c84b949df1a9ec04ba75989cb {{^compatibleWithPythonLegacyApi}} - @validate_call + @validate_call{{#deferBuild}}(config={"defer_build": True}){{/deferBuild}} {{#async}}async {{/async}}def {{operationId}}_without_preload_content{{>partial_api_args}} -> RESTResponseType: {{>partial_api}} response_data = {{#async}}await {{/async}}self.api_client.call_api( @@ -213,7 +213,7 @@ https://github.com/OpenAPITools/openapi-generator/blob/c84b949df1a9ec04ba75989cb {{/compatibleWithPythonLegacyApi}} {{#supportHttpxSync}} - @validate_call + @validate_call{{#deferBuild}}(config={"defer_build": True}){{/deferBuild}} def {{operationId}}_sync{{>partial_api_args}} -> {{{returnType}}}{{^returnType}}None{{/returnType}}: """{{#isDeprecated}}(Deprecated) {{/isDeprecated}}{{{summary}}}{{^summary}}{{operationId}}{{/summary}} (synchronous) @@ -234,7 +234,7 @@ https://github.com/OpenAPITools/openapi-generator/blob/c84b949df1a9ec04ba75989cb ) - @validate_call + @validate_call{{#deferBuild}}(config={"defer_build": True}){{/deferBuild}} def {{operationId}}_sync_with_http_info{{>partial_api_args}} -> ApiResponse[{{{returnType}}}{{^returnType}}None{{/returnType}}]: """{{#isDeprecated}}(Deprecated) {{/isDeprecated}}{{{summary}}}{{^summary}}{{operationId}}{{/summary}} (synchronous) @@ -255,7 +255,7 @@ https://github.com/OpenAPITools/openapi-generator/blob/c84b949df1a9ec04ba75989cb ) - @validate_call + @validate_call{{#deferBuild}}(config={"defer_build": True}){{/deferBuild}} def {{operationId}}_sync_without_preload_content{{>partial_api_args}} -> RESTResponseType: """{{#isDeprecated}}(Deprecated) {{/isDeprecated}}{{{summary}}}{{^summary}}{{operationId}}{{/summary}} (synchronous) diff --git a/modules/openapi-generator/src/main/resources/python/exports_api.mustache b/modules/openapi-generator/src/main/resources/python/exports_api.mustache index 8eead04ab0fd..e0ce0c6f6e1d 100644 --- a/modules/openapi-generator/src/main/resources/python/exports_api.mustache +++ b/modules/openapi-generator/src/main/resources/python/exports_api.mustache @@ -1,3 +1,3 @@ # import apis into api package -{{#apiInfo}}{{#apis}}from {{apiPackage}}.{{classFilename}} import {{classname}} +{{#apiInfo}}{{#apis}}{{#lazyNativeImport}}lazy {{/lazyNativeImport}}from {{apiPackage}}.{{classFilename}} import {{classname}} {{/apis}}{{/apiInfo}} diff --git a/modules/openapi-generator/src/main/resources/python/exports_model.mustache b/modules/openapi-generator/src/main/resources/python/exports_model.mustache index 60dc9c65775c..8b2d500627e4 100644 --- a/modules/openapi-generator/src/main/resources/python/exports_model.mustache +++ b/modules/openapi-generator/src/main/resources/python/exports_model.mustache @@ -1,3 +1,3 @@ # import models into model package -{{#models}}{{#model}}from {{modelPackage}}.{{classFilename}} import {{classname}} +{{#models}}{{#model}}{{#lazyNativeImport}}lazy {{/lazyNativeImport}}from {{modelPackage}}.{{classFilename}} import {{classname}} {{/model}}{{/models}} diff --git a/modules/openapi-generator/src/main/resources/python/exports_package.mustache b/modules/openapi-generator/src/main/resources/python/exports_package.mustache index 96bd44ecb1f8..d551aaac851a 100644 --- a/modules/openapi-generator/src/main/resources/python/exports_package.mustache +++ b/modules/openapi-generator/src/main/resources/python/exports_package.mustache @@ -1,5 +1,5 @@ # import apis into sdk package -{{#apiInfo}}{{#apis}}from {{apiPackage}}.{{classFilename}} import {{classname}} as {{classname}} +{{#apiInfo}}{{#apis}}{{#lazyNativeImport}}lazy {{/lazyNativeImport}}from {{apiPackage}}.{{classFilename}} import {{classname}} as {{classname}} {{/apis}}{{/apiInfo}} # import ApiClient from {{packageName}}.api_response import ApiResponse as ApiResponse @@ -16,5 +16,5 @@ from {{packageName}}.signing import HttpSigningConfiguration as HttpSigningConfi {{/hasHttpSignatureMethods}} # import models into sdk package -{{#models}}{{#model}}from {{modelPackage}}.{{classFilename}} import {{classname}} as {{classname}} +{{#models}}{{#model}}{{#lazyNativeImport}}lazy {{/lazyNativeImport}}from {{modelPackage}}.{{classFilename}} import {{classname}} as {{classname}} {{/model}}{{/models}} diff --git a/modules/openapi-generator/src/main/resources/python/github-workflow.mustache b/modules/openapi-generator/src/main/resources/python/github-workflow.mustache index f6f72ae69958..979e3a493e75 100644 --- a/modules/openapi-generator/src/main/resources/python/github-workflow.mustache +++ b/modules/openapi-generator/src/main/resources/python/github-workflow.mustache @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: [<%^lazyNativeImport%>"3.10", "3.11", "3.12", "3.13", "3.14", <%/lazyNativeImport%>"3.15"] steps: - uses: actions/checkout@v4 diff --git a/modules/openapi-generator/src/main/resources/python/gitlab-ci.mustache b/modules/openapi-generator/src/main/resources/python/gitlab-ci.mustache index 701ffbfd7e8a..8ea09b037280 100644 --- a/modules/openapi-generator/src/main/resources/python/gitlab-ci.mustache +++ b/modules/openapi-generator/src/main/resources/python/gitlab-ci.mustache @@ -14,6 +14,7 @@ stages: - pip install -r test-requirements.txt - pytest --cov={{{packageName}}} +{{^lazyNativeImport}} pytest-3.10: extends: .pytest image: python:3.10-alpine @@ -29,3 +30,7 @@ pytest-3.13: pytest-3.14: extends: .pytest image: python:3.14-alpine +{{/lazyNativeImport}} +pytest-3.15: + extends: .pytest + image: python:3.15-alpine diff --git a/modules/openapi-generator/src/main/resources/python/lazy_configuration.mustache b/modules/openapi-generator/src/main/resources/python/lazy_configuration.mustache new file mode 100644 index 000000000000..b1bf61c33763 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/python/lazy_configuration.mustache @@ -0,0 +1,31 @@ +{{#lazyNativeImport}} +### Native lazy imports + +This client was generated with `lazyNativeImport=true` and requires Python 3.15+ +and Pydantic 2.14+. Its generated API and model imports use `lazy from`: modules +load on first use, so applications that use only a subset of a large client's +Pydantic models can avoid loading unused modules and reduce startup work and +initial memory use. + +Import costs move to first use; import failures and module initialization side +effects can happen later. Evaluating type annotations, constructing schemas, or +using models can resolve lazy imports. Gains depend on the workload, and native +imports are not guaranteed to use less memory than `lazyImports=true`. +The two import options cannot be enabled together. Combining native imports with +`deferBuild=true` can also reduce initial memory use. +{{/lazyNativeImport}} +{{#deferBuild}} +### Deferred operation validators + +This client was generated with `deferBuild=true`. Its `@validate_call` decorators +set `defer_build=True`, building each operation's argument validator on its first +call. This can reduce startup work and memory for operations that are never +called. Argument validation remains enabled; construction costs and schema +construction errors move to first call. + +This setting does not change `model_config`. In the evaluated POC, also deferring +models increased retained memory. The diagnostic evidence pointed to reduced +reuse of nested validators and serializers, plus pending-model placeholders. +This is workload- and Pydantic-version-dependent, not a universal limitation. +`deferBuild` can be used on its own or with either lazy import strategy. +{{/deferBuild}} diff --git a/modules/openapi-generator/src/main/resources/python/model_anyof.mustache b/modules/openapi-generator/src/main/resources/python/model_anyof.mustache index 7a7f52f755a0..9cd2db2362a6 100644 --- a/modules/openapi-generator/src/main/resources/python/model_anyof.mustache +++ b/modules/openapi-generator/src/main/resources/python/model_anyof.mustache @@ -7,7 +7,7 @@ import re # noqa: F401 {{{.}}} {{/vendorExtensions.x-py-other-imports}} {{#vendorExtensions.x-py-model-imports}} -{{{.}}} +{{#lazyNativeImport}}lazy {{/lazyNativeImport}}{{{.}}} {{/vendorExtensions.x-py-model-imports}} from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict from typing_extensions import Literal, Self @@ -210,7 +210,7 @@ class {{classname}}({{#parent}}{{{.}}}{{/parent}}{{^parent}}BaseModel{{/parent}} {{#vendorExtensions.x-py-postponed-model-imports.size}} {{#vendorExtensions.x-py-postponed-model-imports}} -{{{.}}} +{{#lazyNativeImport}}lazy {{/lazyNativeImport}}{{{.}}} {{/vendorExtensions.x-py-postponed-model-imports}} # TODO: Rewrite to not use raise_errors {{classname}}.model_rebuild(raise_errors=False) diff --git a/modules/openapi-generator/src/main/resources/python/model_generic.mustache b/modules/openapi-generator/src/main/resources/python/model_generic.mustache index 67ee274208cf..3d4320290d95 100644 --- a/modules/openapi-generator/src/main/resources/python/model_generic.mustache +++ b/modules/openapi-generator/src/main/resources/python/model_generic.mustache @@ -7,7 +7,7 @@ import json {{{.}}} {{/vendorExtensions.x-py-other-imports}} {{#vendorExtensions.x-py-model-imports}} -{{{.}}} +{{#lazyNativeImport}}lazy {{/lazyNativeImport}}{{{.}}} {{/vendorExtensions.x-py-model-imports}} from typing import Optional, Set from typing_extensions import Self @@ -650,7 +650,7 @@ https://github.com/OpenAPITools/openapi-generator/blob/c84b949df1a9ec04ba75989cb {{#vendorExtensions.x-py-postponed-model-imports.size}} {{#vendorExtensions.x-py-postponed-model-imports}} -{{{.}}} +{{#lazyNativeImport}}lazy {{/lazyNativeImport}}{{{.}}} {{/vendorExtensions.x-py-postponed-model-imports}} # TODO: Rewrite to not use raise_errors {{classname}}.model_rebuild(raise_errors=False) diff --git a/modules/openapi-generator/src/main/resources/python/model_oneof.mustache b/modules/openapi-generator/src/main/resources/python/model_oneof.mustache index 8365ae0bb61f..17291b5a16a2 100644 --- a/modules/openapi-generator/src/main/resources/python/model_oneof.mustache +++ b/modules/openapi-generator/src/main/resources/python/model_oneof.mustache @@ -5,7 +5,7 @@ import pprint {{{.}}} {{/vendorExtensions.x-py-other-imports}} {{#vendorExtensions.x-py-model-imports}} -{{{.}}} +{{#lazyNativeImport}}lazy {{/lazyNativeImport}}{{{.}}} {{/vendorExtensions.x-py-model-imports}} from pydantic import StrictStr, Field from typing import Union, List, Set, Optional, Dict @@ -238,7 +238,7 @@ class {{classname}}({{#parent}}{{{.}}}{{/parent}}{{^parent}}BaseModel{{/parent}} {{#vendorExtensions.x-py-postponed-model-imports.size}} {{#vendorExtensions.x-py-postponed-model-imports}} -{{{.}}} +{{#lazyNativeImport}}lazy {{/lazyNativeImport}}{{{.}}} {{/vendorExtensions.x-py-postponed-model-imports}} # TODO: Rewrite to not use raise_errors {{classname}}.model_rebuild(raise_errors=False) diff --git a/modules/openapi-generator/src/main/resources/python/pyproject.mustache b/modules/openapi-generator/src/main/resources/python/pyproject.mustache index 96b7113fa667..af044b07a9ef 100644 --- a/modules/openapi-generator/src/main/resources/python/pyproject.mustache +++ b/modules/openapi-generator/src/main/resources/python/pyproject.mustache @@ -37,7 +37,7 @@ packages = [ include = ["{{#sourceFolder}}{{{sourceFolder}}}/{{/sourceFolder}}{{packageName}}/py.typed"] [tool.poetry.dependencies] -python = "^3.10" +python = "^{{#lazyNativeImport}}3.15{{/lazyNativeImport}}{{^lazyNativeImport}}3.10{{/lazyNativeImport}}" {{^async}} urllib3 = ">= 2.7.0, < 3.0.0" {{/async}} @@ -56,11 +56,11 @@ httpx2 = ">= 2.13.0, < 3" pem = ">= 19.3.0" pycryptodome = ">= 3.9.0" {{/hasHttpSignatureMethods}} -pydantic = ">= 2.11" +pydantic = ">= {{#lazyNativeImport}}2.14{{/lazyNativeImport}}{{^lazyNativeImport}}2.11{{/lazyNativeImport}}" typing-extensions = ">= 4.7.1" {{/poetry1}} {{^poetry1}} -requires-python = ">=3.10" +requires-python = ">={{#lazyNativeImport}}3.15{{/lazyNativeImport}}{{^lazyNativeImport}}3.10{{/lazyNativeImport}}" dependencies = [ {{^async}} @@ -81,7 +81,7 @@ dependencies = [ "pem (>=19.3.0)", "pycryptodome (>=3.9.0)", {{/hasHttpSignatureMethods}} - "pydantic (>=2.11)", + "pydantic (>={{#lazyNativeImport}}2.14{{/lazyNativeImport}}{{^lazyNativeImport}}2.11{{/lazyNativeImport}})", "typing-extensions (>=4.7.1)", ] diff --git a/modules/openapi-generator/src/main/resources/python/requirements.mustache b/modules/openapi-generator/src/main/resources/python/requirements.mustache index 36f07decbdbf..1265d6cfad8f 100644 --- a/modules/openapi-generator/src/main/resources/python/requirements.mustache +++ b/modules/openapi-generator/src/main/resources/python/requirements.mustache @@ -16,5 +16,5 @@ httpx2 >= 2.13.0, < 3 pem >= 19.3.0 pycryptodome >= 3.9.0 {{/hasHttpSignatureMethods}} -pydantic >= 2.11 +pydantic >= {{#lazyNativeImport}}2.14{{/lazyNativeImport}}{{^lazyNativeImport}}2.11{{/lazyNativeImport}} typing-extensions >= 4.7.1 diff --git a/modules/openapi-generator/src/main/resources/python/setup.mustache b/modules/openapi-generator/src/main/resources/python/setup.mustache index 53763437f7ac..61e2446ea094 100644 --- a/modules/openapi-generator/src/main/resources/python/setup.mustache +++ b/modules/openapi-generator/src/main/resources/python/setup.mustache @@ -10,7 +10,7 @@ from setuptools import setup, find_packages # noqa: H301 # http://pypi.python.org/pypi/setuptools NAME = "{{{projectName}}}" VERSION = "{{packageVersion}}" -PYTHON_REQUIRES = ">= 3.10" +PYTHON_REQUIRES = ">= {{#lazyNativeImport}}3.15{{/lazyNativeImport}}{{^lazyNativeImport}}3.10{{/lazyNativeImport}}" REQUIRES = [ {{^async}} "urllib3 >= 2.7.0, < 3.0.0", @@ -30,7 +30,7 @@ REQUIRES = [ "pem >= 19.3.0", "pycryptodome >= 3.9.0", {{/hasHttpSignatureMethods}} - "pydantic >= 2.11", + "pydantic >= {{#lazyNativeImport}}2.14{{/lazyNativeImport}}{{^lazyNativeImport}}2.11{{/lazyNativeImport}}", "typing-extensions >= 4.7.1", ] @@ -43,6 +43,9 @@ setup( url="{{packageUrl}}", keywords=["OpenAPI", "OpenAPI-Generator", "{{{appName}}}"], install_requires=REQUIRES, +{{#lazyNativeImport}} + python_requires=PYTHON_REQUIRES, +{{/lazyNativeImport}} {{#sourceFolder}} package_dir={"": "{{{sourceFolder}}}"}, {{/sourceFolder}} diff --git a/modules/openapi-generator/src/main/resources/python/travis.mustache b/modules/openapi-generator/src/main/resources/python/travis.mustache index 983251a4640b..e7e92c452bd3 100644 --- a/modules/openapi-generator/src/main/resources/python/travis.mustache +++ b/modules/openapi-generator/src/main/resources/python/travis.mustache @@ -1,11 +1,14 @@ # ref: https://docs.travis-ci.com/user/languages/python language: python python: +{{^lazyNativeImport}} - "3.10" - "3.11" - "3.12" - "3.13" - "3.14" +{{/lazyNativeImport}} + - "3.15" # uncomment the following if needed #- "3.14-dev" # 3.14 development branch #- "nightly" # nightly build diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientCodegenTest.java index 2a20d3796d6e..808f9f53bc03 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientCodegenTest.java @@ -39,6 +39,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Collectors; @@ -49,6 +50,127 @@ public class PythonClientCodegenTest { + @DataProvider(name = "pythonLazyOptions") + public Object[][] pythonLazyOptions() { + List options = new ArrayList<>(); + for (String library : List.of("urllib3", "asyncio", "httpx", "httpx2")) { + for (String imports : List.of("eager", "lazyImports", "lazyNativeImport")) { + for (boolean deferred : List.of(false, true)) { + options.add(new Object[] {library, imports, deferred}); + } + } + } + return options.toArray(new Object[0][]); + } + + @Test(dataProvider = "pythonLazyOptions") + public void testPythonLazyOptions(String library, String imports, boolean deferred) throws Exception { + PythonClientCodegen codegen = new PythonClientCodegen(); + codegen.setLibrary(library); + boolean nativeImports = "lazyNativeImport".equals(imports); + boolean oldImports = "lazyImports".equals(imports); + codegen.additionalProperties().put(PythonClientCodegen.LAZY_NATIVE_IMPORT, String.valueOf(nativeImports)); + codegen.additionalProperties().put(PythonClientCodegen.LAZY_IMPORTS, String.valueOf(oldImports)); + codegen.additionalProperties().put(PythonClientCodegen.DEFER_BUILD, String.valueOf(deferred)); + // Exercise both packaging formats, and the sync operation decorators too. + codegen.additionalProperties().put(PythonClientCodegen.POETRY1_FALLBACK, deferred); + if ("httpx".equals(library) || "httpx2".equals(library)) { + codegen.additionalProperties().put(PythonClientCodegen.SUPPORT_HTTPX_SYNC, true); + } + Path output = Paths.get(generateFiles(codegen, "src/test/resources/3_1/python/lazy-imports.yaml")); + Path api = output.resolve("openapi_client/api/parents_api.py"); + assertFileContains(api, "from pydantic import validate_call", "from openapi_client.api_client import ApiClient"); + if (deferred) { + assertFileContains(api, "@validate_call(config={\"defer_build\": True})"); + Assert.assertFalse(Files.readAllLines(api).stream().anyMatch(line -> line.trim().equals("@validate_call"))); + } else { + assertFileContains(api, "@validate_call\n"); + TestUtils.assertFileNotContains(api, "defer_build"); + } + for (String model : List.of("parent", "child", "choice", "any_choice", "left", "right")) { + TestUtils.assertFileNotContains(output.resolve("openapi_client/models/" + model + ".py"), "defer_build"); + } + Path exports = output.resolve("openapi_client/__init__.py"); + assertFileContains(output.resolve(".gitlab-ci.yml"), "pytest-3.15:", "image: python:3.15-alpine"); + assertFileContains(output.resolve(".travis.yml"), " - \"3.15\""); + assertFileContains(output.resolve(".github/workflows/python.yml"), nativeImports + ? "python-version: [\"3.15\"]" + : "python-version: [\"3.10\", \"3.11\", \"3.12\", \"3.13\", \"3.14\", \"3.15\"]"); + for (String version : List.of("3.10", "3.11", "3.12", "3.13", "3.14")) { + Assert.assertEquals(Files.readString(output.resolve(".gitlab-ci.yml")).contains("pytest-" + version + ":"), !nativeImports); + Assert.assertEquals(Files.readString(output.resolve(".travis.yml")).contains(" - \"" + version + "\""), !nativeImports); + } + if (nativeImports) { + assertFileContains(api, "lazy from openapi_client.models.parent import Parent"); + assertFileContains(exports, "lazy from openapi_client.api.parents_api import ParentsApi", + "lazy from openapi_client.models.parent import Parent", "from openapi_client.api_client import ApiClient"); + TestUtils.assertFileNotContains(exports, "def __getattr__"); + assertFileContains(output.resolve("openapi_client/api/__init__.py"), "lazy from openapi_client.api.parents_api"); + assertFileContains(output.resolve("openapi_client/models/__init__.py"), "lazy from openapi_client.models.parent"); + assertFileContains(output.resolve("openapi_client/models/parent.py"), "lazy from openapi_client.models.child"); + assertFileContains(output.resolve("openapi_client/models/choice.py"), "lazy from openapi_client.models.child"); + assertFileContains(output.resolve("openapi_client/models/any_choice.py"), "lazy from openapi_client.models.child"); + assertFileContains(output.resolve("openapi_client/models/left.py"), "lazy from openapi_client.models.right"); + assertFileContains(output.resolve("setup.py"), "PYTHON_REQUIRES = \">= 3.15\"", "python_requires=PYTHON_REQUIRES", "pydantic >= 2.14"); + assertFileContains(output.resolve("requirements.txt"), "pydantic >= 2.14"); + assertFileContains(output.resolve("pyproject.toml"), deferred ? "python = \"^3.15\"" : "requires-python = \">=3.15\""); + assertFileContains(output.resolve("pyproject.toml"), deferred ? "pydantic = \">= 2.14\"" : "pydantic (>=2.14)"); + assertFileContains(output.resolve("README.md"), "Python 3.15+", "Native lazy imports"); + } else { + TestUtils.assertFileNotContains(api, "lazy from "); + TestUtils.assertFileNotContains(exports, "lazy from "); + Assert.assertEquals(Files.readString(exports).contains("def __getattr__"), oldImports); + assertFileContains(output.resolve("pyproject.toml"), deferred ? "python = \"^3.10\"" : "requires-python = \">=3.10\""); + assertFileContains(output.resolve("requirements.txt"), "pydantic >= 2.11"); + assertFileContains(output.resolve("README.md"), "Python 3.10+"); + } + if (deferred) { + assertFileContains(output.resolve("README.md"), "Deferred operation validators", "pending-model placeholders"); + } + + // Optional runtime checks use a real Python 3.15 interpreter and installed client dependencies. + String python = System.getProperty("python315"); + if (python != null) { + Path log = Files.createTempFile("python-lazy-runtime-", ".log"); + Process process = new ProcessBuilder(python, "src/test/resources/3_1/python/lazy_imports_runtime.py", + output.toString(), library, imports, String.valueOf(deferred)) + .redirectErrorStream(true).redirectOutput(log.toFile()).start(); + if (!process.waitFor(30, TimeUnit.SECONDS)) { + process.destroyForcibly(); + Assert.fail("Python lazy imports runtime check timed out: " + log); + } + Assert.assertEquals(process.exitValue(), 0, Files.readString(log)); + } + } + + @Test + public void testLazyImportStrategiesAreMutuallyExclusive() { + for (Object enabled : List.of(true, "true")) { + PythonClientCodegen codegen = new PythonClientCodegen(); + codegen.additionalProperties().put(PythonClientCodegen.LAZY_IMPORTS, enabled); + codegen.additionalProperties().put(PythonClientCodegen.LAZY_NATIVE_IMPORT, enabled); + IllegalArgumentException exception = Assert.expectThrows(IllegalArgumentException.class, codegen::processOpts); + Assert.assertTrue(exception.getMessage().contains("cannot be combined")); + } + } + + @Test + public void testNativeLazySourceOnlyWithCustomPackage() throws IOException { + PythonClientCodegen codegen = new PythonClientCodegen(); + codegen.setLazyNativeImport(true); + codegen.setDeferBuild(true); + codegen.additionalProperties().put(CodegenConstants.PACKAGE_NAME, "nested.client"); + codegen.additionalProperties().put(CodegenConstants.SOURCE_FOLDER, "src"); + codegen.additionalProperties().put(CodegenConstants.SOURCECODEONLY_GENERATION, true); + Path output = Paths.get(generateFiles(codegen, "src/test/resources/3_1/python/lazy-imports.yaml")); + assertFileContains(output.resolve("src/nested/client/api/parents_api.py"), + "lazy from nested.client.models.parent import Parent", "@validate_call(config={\"defer_build\": True})"); + assertFileContains(output.resolve("src/nested/client/models/parent.py"), "lazy from nested.client.models.child"); + assertFileContains(output.resolve("nested/client_README.md"), "Python 3.15+", "pydantic >= 2.14", + "Native lazy imports", "Deferred operation validators"); + Assert.assertFalse(Files.exists(output.resolve("pyproject.toml"))); + } + @DataProvider(name = "pythonPackagingOptions") public Object[][] pythonPackagingOptions() { List options = new ArrayList<>(); @@ -196,6 +318,9 @@ public void testInitialConfigValues() throws Exception { Boolean.FALSE); Assert.assertEquals(codegen.isHideGenerationTimestamp(), true); Assert.assertNull(codegen.additionalProperties().get(CodegenConstants.SOURCE_FOLDER)); + Assert.assertEquals(codegen.additionalProperties().get(PythonClientCodegen.LAZY_NATIVE_IMPORT), Boolean.FALSE); + Assert.assertEquals(codegen.additionalProperties().get(PythonClientCodegen.DEFER_BUILD), Boolean.FALSE); + Assert.assertEquals(codegen.generatorLanguageVersion(), "3.10+"); } @Test diff --git a/modules/openapi-generator/src/test/resources/3_1/python/lazy-imports.yaml b/modules/openapi-generator/src/test/resources/3_1/python/lazy-imports.yaml new file mode 100644 index 000000000000..460ee3e871fe --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_1/python/lazy-imports.yaml @@ -0,0 +1,74 @@ +openapi: 3.0.3 +info: + title: Lazy imports regression + version: 1.0.0 +paths: + /parents/{id}: + get: + tags: [Parents] + operationId: getParent + parameters: + - name: id + in: path + required: true + schema: + type: integer + responses: + '200': + description: A parent with nested children + content: + application/json: + schema: + $ref: '#/components/schemas/Parent' + /unused: + get: + tags: [Unused] + operationId: getUnused + responses: + '200': + description: An unused model + content: + application/json: + schema: + $ref: '#/components/schemas/Unused' +components: + schemas: + Child: + type: object + required: [id, name] + properties: + id: + type: integer + name: + type: string + Parent: + type: object + required: [children] + properties: + children: + type: array + items: + $ref: '#/components/schemas/Child' + Unused: + type: object + properties: + value: + type: string + Choice: + oneOf: + - $ref: '#/components/schemas/Child' + - type: string + AnyChoice: + anyOf: + - $ref: '#/components/schemas/Child' + - type: integer + Left: + type: object + properties: + right: + $ref: '#/components/schemas/Right' + Right: + type: object + properties: + left: + $ref: '#/components/schemas/Left' diff --git a/modules/openapi-generator/src/test/resources/3_1/python/lazy_imports_runtime.py b/modules/openapi-generator/src/test/resources/3_1/python/lazy_imports_runtime.py new file mode 100644 index 000000000000..ba0105c168ad --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_1/python/lazy_imports_runtime.py @@ -0,0 +1,119 @@ +"""Runtime contracts for clients generated from lazy-imports.yaml. + +Run through PythonClientCodegenTest with -Dpython315=/path/to/python3.15. +The interpreter needs the dependencies for all four Python libraries. +""" + +import asyncio +import compileall +import importlib +import inspect +import json +from pathlib import Path +import sys + +from pydantic import ValidationError + + +output, library, imports, deferred = sys.argv[1:] +sys.path.insert(0, output) +assert compileall.compile_dir(Path(output) / "openapi_client", quiet=1) +package = importlib.import_module("openapi_client") +assert Path(package.__file__).resolve().is_relative_to(Path(output).resolve()) +if imports != "eager": + assert "openapi_client.api.unused_api" not in sys.modules + assert "openapi_client.models.unused" not in sys.modules + + +class Response: + status = 200 + reason = "OK" + headers = {"content-type": "application/json"} + data = json.dumps({"children": [{"id": 7, "name": "child"}]}).encode() + + def getheader(self, name, default=None): + return self.headers.get(name, default) + + def read(self): + return self.data + + +class AsyncResponse(Response): + async def read(self): + return self.data + + +async def exercise_api(): + client = package.ApiClient(package.Configuration(host="https://example.invalid")) + calls = [] + + def call(*args, **kwargs): + calls.append(args) + assert "/parents/7" in args[1] + return Response() + + async def async_call(*args, **kwargs): + call(*args, **kwargs) + return AsyncResponse() + + client.call_api = call if library == "urllib3" else async_call + api = package.ParentsApi(client) + + async def invoke(**kwargs): + value = api.get_parent(**kwargs) + return await value if inspect.isawaitable(value) else value + + try: + # Argument errors must still be raised before any HTTP request. + for arguments in ({}, {"id": "invalid"}): + try: + await invoke(**arguments) + except ValidationError: + pass + else: + raise AssertionError("Invalid operation arguments were accepted") + assert not calls + + for _ in range(2): + result = await invoke(id=7) + assert result.children[0].id == 7 + assert result.to_dict() == {"children": [{"id": 7, "name": "child"}]} + assert client.sanitize_for_serialization(result) == result.to_dict() + assert len(calls) == 2 + + from openapi_client import Parent + from openapi_client.models import Parent as ModelExport + from openapi_client.api import ParentsApi + + assert isinstance(result, Parent) + assert Parent is ModelExport + assert isinstance(api, ParentsApi) + assert Parent.model_config.get("defer_build", False) is False + assert "children" in Parent.model_json_schema()["properties"] + try: + Parent.from_dict({"children": [{"id": "invalid", "name": "child"}]}) + except ValidationError: + pass + else: + raise AssertionError("Invalid nested model was accepted") + assert Parent.from_json(result.to_json()) == result + + from openapi_client import AnyChoice, Choice, Left, Right + + for composed in (Choice, AnyChoice): + value = composed.from_dict({"id": 7, "name": "child"}) + assert value.actual_instance.id == 7 + assert composed.model_json_schema() + circular = Left.from_dict({"right": {"left": None}}) + assert isinstance(circular.right, Right) + assert circular.to_dict() == {"right": {}} + assert Left.model_json_schema() + finally: + if library == "urllib3": + client.rest_client.pool_manager.clear() + else: + await client.close() + + +asyncio.run(exercise_api()) +print(f"Runtime contracts passed: {library}, {imports}, deferBuild={deferred}") diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.github/workflows/python.yml b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.github/workflows/python.yml index b17065bfa1d4..a0cf208ec8b5 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.github/workflows/python.yml +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.gitlab-ci.yml b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.gitlab-ci.yml index 4c036842aee1..564d7416bbbb 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.gitlab-ci.yml +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.gitlab-ci.yml @@ -29,3 +29,6 @@ pytest-3.13: pytest-3.14: extends: .pytest image: python:3.14-alpine +pytest-3.15: + extends: .pytest + image: python:3.15-alpine diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.travis.yml b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.travis.yml index a58e1c9adaf6..ef719723eb0d 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.travis.yml +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.travis.yml @@ -6,6 +6,7 @@ python: - "3.12" - "3.13" - "3.14" + - "3.15" # uncomment the following if needed #- "3.14-dev" # 3.14 development branch #- "nightly" # nightly build diff --git a/samples/client/echo_api/python/.github/workflows/python.yml b/samples/client/echo_api/python/.github/workflows/python.yml index b17065bfa1d4..a0cf208ec8b5 100644 --- a/samples/client/echo_api/python/.github/workflows/python.yml +++ b/samples/client/echo_api/python/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/client/echo_api/python/.gitlab-ci.yml b/samples/client/echo_api/python/.gitlab-ci.yml index 4c036842aee1..564d7416bbbb 100644 --- a/samples/client/echo_api/python/.gitlab-ci.yml +++ b/samples/client/echo_api/python/.gitlab-ci.yml @@ -29,3 +29,6 @@ pytest-3.13: pytest-3.14: extends: .pytest image: python:3.14-alpine +pytest-3.15: + extends: .pytest + image: python:3.15-alpine diff --git a/samples/client/echo_api/python/.travis.yml b/samples/client/echo_api/python/.travis.yml index a58e1c9adaf6..ef719723eb0d 100644 --- a/samples/client/echo_api/python/.travis.yml +++ b/samples/client/echo_api/python/.travis.yml @@ -6,6 +6,7 @@ python: - "3.12" - "3.13" - "3.14" + - "3.15" # uncomment the following if needed #- "3.14-dev" # 3.14 development branch #- "nightly" # nightly build diff --git a/samples/client/others/python-legacy-model-dictionaries/.github/workflows/python.yml b/samples/client/others/python-legacy-model-dictionaries/.github/workflows/python.yml index b4a39b34607b..5bfcc9d802df 100644 --- a/samples/client/others/python-legacy-model-dictionaries/.github/workflows/python.yml +++ b/samples/client/others/python-legacy-model-dictionaries/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/client/others/python-legacy-model-dictionaries/.gitlab-ci.yml b/samples/client/others/python-legacy-model-dictionaries/.gitlab-ci.yml index 547b0fd99b87..84413b5e8b91 100644 --- a/samples/client/others/python-legacy-model-dictionaries/.gitlab-ci.yml +++ b/samples/client/others/python-legacy-model-dictionaries/.gitlab-ci.yml @@ -29,3 +29,6 @@ pytest-3.13: pytest-3.14: extends: .pytest image: python:3.14-alpine +pytest-3.15: + extends: .pytest + image: python:3.15-alpine diff --git a/samples/client/others/python-legacy-model-dictionaries/.travis.yml b/samples/client/others/python-legacy-model-dictionaries/.travis.yml index 1e3bffd3b917..12309a614799 100644 --- a/samples/client/others/python-legacy-model-dictionaries/.travis.yml +++ b/samples/client/others/python-legacy-model-dictionaries/.travis.yml @@ -6,6 +6,7 @@ python: - "3.12" - "3.13" - "3.14" + - "3.15" # uncomment the following if needed #- "3.14-dev" # 3.14 development branch #- "nightly" # nightly build diff --git a/samples/openapi3/client/petstore/python-aiohttp/.github/workflows/python.yml b/samples/openapi3/client/petstore/python-aiohttp/.github/workflows/python.yml index da1eaf6fe1d7..20c4eae353fb 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python-aiohttp/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/openapi3/client/petstore/python-aiohttp/.gitlab-ci.yml b/samples/openapi3/client/petstore/python-aiohttp/.gitlab-ci.yml index 89cc724c729c..ed57a8f29294 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/.gitlab-ci.yml +++ b/samples/openapi3/client/petstore/python-aiohttp/.gitlab-ci.yml @@ -29,3 +29,6 @@ pytest-3.13: pytest-3.14: extends: .pytest image: python:3.14-alpine +pytest-3.15: + extends: .pytest + image: python:3.15-alpine diff --git a/samples/openapi3/client/petstore/python-aiohttp/.travis.yml b/samples/openapi3/client/petstore/python-aiohttp/.travis.yml index 1197382a3ed8..58b0a87885b9 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/.travis.yml +++ b/samples/openapi3/client/petstore/python-aiohttp/.travis.yml @@ -6,6 +6,7 @@ python: - "3.12" - "3.13" - "3.14" + - "3.15" # uncomment the following if needed #- "3.14-dev" # 3.14 development branch #- "nightly" # nightly build diff --git a/samples/openapi3/client/petstore/python-httpx-sync/.github/workflows/python.yml b/samples/openapi3/client/petstore/python-httpx-sync/.github/workflows/python.yml index da1eaf6fe1d7..20c4eae353fb 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python-httpx-sync/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/openapi3/client/petstore/python-httpx-sync/.gitlab-ci.yml b/samples/openapi3/client/petstore/python-httpx-sync/.gitlab-ci.yml index 89cc724c729c..ed57a8f29294 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/.gitlab-ci.yml +++ b/samples/openapi3/client/petstore/python-httpx-sync/.gitlab-ci.yml @@ -29,3 +29,6 @@ pytest-3.13: pytest-3.14: extends: .pytest image: python:3.14-alpine +pytest-3.15: + extends: .pytest + image: python:3.15-alpine diff --git a/samples/openapi3/client/petstore/python-httpx-sync/.travis.yml b/samples/openapi3/client/petstore/python-httpx-sync/.travis.yml index 1197382a3ed8..58b0a87885b9 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/.travis.yml +++ b/samples/openapi3/client/petstore/python-httpx-sync/.travis.yml @@ -6,6 +6,7 @@ python: - "3.12" - "3.13" - "3.14" + - "3.15" # uncomment the following if needed #- "3.14-dev" # 3.14 development branch #- "nightly" # nightly build diff --git a/samples/openapi3/client/petstore/python-httpx/.github/workflows/python.yml b/samples/openapi3/client/petstore/python-httpx/.github/workflows/python.yml index da1eaf6fe1d7..20c4eae353fb 100644 --- a/samples/openapi3/client/petstore/python-httpx/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python-httpx/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/openapi3/client/petstore/python-httpx/.gitlab-ci.yml b/samples/openapi3/client/petstore/python-httpx/.gitlab-ci.yml index 89cc724c729c..ed57a8f29294 100644 --- a/samples/openapi3/client/petstore/python-httpx/.gitlab-ci.yml +++ b/samples/openapi3/client/petstore/python-httpx/.gitlab-ci.yml @@ -29,3 +29,6 @@ pytest-3.13: pytest-3.14: extends: .pytest image: python:3.14-alpine +pytest-3.15: + extends: .pytest + image: python:3.15-alpine diff --git a/samples/openapi3/client/petstore/python-httpx/.travis.yml b/samples/openapi3/client/petstore/python-httpx/.travis.yml index 1197382a3ed8..58b0a87885b9 100644 --- a/samples/openapi3/client/petstore/python-httpx/.travis.yml +++ b/samples/openapi3/client/petstore/python-httpx/.travis.yml @@ -6,6 +6,7 @@ python: - "3.12" - "3.13" - "3.14" + - "3.15" # uncomment the following if needed #- "3.14-dev" # 3.14 development branch #- "nightly" # nightly build diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/.github/workflows/python.yml b/samples/openapi3/client/petstore/python-httpx2-sync/.github/workflows/python.yml index da1eaf6fe1d7..20c4eae353fb 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python-httpx2-sync/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/.gitlab-ci.yml b/samples/openapi3/client/petstore/python-httpx2-sync/.gitlab-ci.yml index 89cc724c729c..ed57a8f29294 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/.gitlab-ci.yml +++ b/samples/openapi3/client/petstore/python-httpx2-sync/.gitlab-ci.yml @@ -29,3 +29,6 @@ pytest-3.13: pytest-3.14: extends: .pytest image: python:3.14-alpine +pytest-3.15: + extends: .pytest + image: python:3.15-alpine diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/.travis.yml b/samples/openapi3/client/petstore/python-httpx2-sync/.travis.yml index 1197382a3ed8..58b0a87885b9 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/.travis.yml +++ b/samples/openapi3/client/petstore/python-httpx2-sync/.travis.yml @@ -6,6 +6,7 @@ python: - "3.12" - "3.13" - "3.14" + - "3.15" # uncomment the following if needed #- "3.14-dev" # 3.14 development branch #- "nightly" # nightly build diff --git a/samples/openapi3/client/petstore/python-httpx2/.github/workflows/python.yml b/samples/openapi3/client/petstore/python-httpx2/.github/workflows/python.yml index da1eaf6fe1d7..20c4eae353fb 100644 --- a/samples/openapi3/client/petstore/python-httpx2/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python-httpx2/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/openapi3/client/petstore/python-httpx2/.gitlab-ci.yml b/samples/openapi3/client/petstore/python-httpx2/.gitlab-ci.yml index 89cc724c729c..ed57a8f29294 100644 --- a/samples/openapi3/client/petstore/python-httpx2/.gitlab-ci.yml +++ b/samples/openapi3/client/petstore/python-httpx2/.gitlab-ci.yml @@ -29,3 +29,6 @@ pytest-3.13: pytest-3.14: extends: .pytest image: python:3.14-alpine +pytest-3.15: + extends: .pytest + image: python:3.15-alpine diff --git a/samples/openapi3/client/petstore/python-httpx2/.travis.yml b/samples/openapi3/client/petstore/python-httpx2/.travis.yml index 1197382a3ed8..58b0a87885b9 100644 --- a/samples/openapi3/client/petstore/python-httpx2/.travis.yml +++ b/samples/openapi3/client/petstore/python-httpx2/.travis.yml @@ -6,6 +6,7 @@ python: - "3.12" - "3.13" - "3.14" + - "3.15" # uncomment the following if needed #- "3.14-dev" # 3.14 development branch #- "nightly" # nightly build diff --git a/samples/openapi3/client/petstore/python-lazyImports/.github/workflows/python.yml b/samples/openapi3/client/petstore/python-lazyImports/.github/workflows/python.yml index da1eaf6fe1d7..20c4eae353fb 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python-lazyImports/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/openapi3/client/petstore/python-lazyImports/.gitlab-ci.yml b/samples/openapi3/client/petstore/python-lazyImports/.gitlab-ci.yml index 89cc724c729c..ed57a8f29294 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/.gitlab-ci.yml +++ b/samples/openapi3/client/petstore/python-lazyImports/.gitlab-ci.yml @@ -29,3 +29,6 @@ pytest-3.13: pytest-3.14: extends: .pytest image: python:3.14-alpine +pytest-3.15: + extends: .pytest + image: python:3.15-alpine diff --git a/samples/openapi3/client/petstore/python-lazyImports/.travis.yml b/samples/openapi3/client/petstore/python-lazyImports/.travis.yml index 1197382a3ed8..58b0a87885b9 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/.travis.yml +++ b/samples/openapi3/client/petstore/python-lazyImports/.travis.yml @@ -6,6 +6,7 @@ python: - "3.12" - "3.13" - "3.14" + - "3.15" # uncomment the following if needed #- "3.14-dev" # 3.14 development branch #- "nightly" # nightly build diff --git a/samples/openapi3/client/petstore/python/.github/workflows/python.yml b/samples/openapi3/client/petstore/python/.github/workflows/python.yml index da1eaf6fe1d7..20c4eae353fb 100644 --- a/samples/openapi3/client/petstore/python/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/openapi3/client/petstore/python/.gitlab-ci.yml b/samples/openapi3/client/petstore/python/.gitlab-ci.yml index 89cc724c729c..ed57a8f29294 100755 --- a/samples/openapi3/client/petstore/python/.gitlab-ci.yml +++ b/samples/openapi3/client/petstore/python/.gitlab-ci.yml @@ -29,3 +29,6 @@ pytest-3.13: pytest-3.14: extends: .pytest image: python:3.14-alpine +pytest-3.15: + extends: .pytest + image: python:3.15-alpine diff --git a/samples/openapi3/client/petstore/python/.travis.yml b/samples/openapi3/client/petstore/python/.travis.yml index 1197382a3ed8..58b0a87885b9 100755 --- a/samples/openapi3/client/petstore/python/.travis.yml +++ b/samples/openapi3/client/petstore/python/.travis.yml @@ -6,6 +6,7 @@ python: - "3.12" - "3.13" - "3.14" + - "3.15" # uncomment the following if needed #- "3.14-dev" # 3.14 development branch #- "nightly" # nightly build From 11ed859848d04514d92b65b8351388560f0e69fe Mon Sep 17 00:00:00 2001 From: Bernardo Gomes Date: Sun, 18 Oct 2026 21:32:26 -0300 Subject: [PATCH 2/8] Add support to python 3.15 --- .github/workflows/samples-python-client-echo-api.yaml | 3 ++- .../samples-python-client-legacy-model-dictionaries.yaml | 1 + .github/workflows/samples-python-petstore.yaml | 1 + .../workflows/samples-python-pydantic-v1-client-echo-api.yaml | 3 ++- .github/workflows/samples-python-pydantic-v1-petstore.yaml | 1 + .../src/main/resources/python/github-workflow.mustache | 2 +- .../src/main/resources/python/gitlab-ci.mustache | 3 +++ .../src/main/resources/python/travis.mustache | 1 + .../.github/workflows/python.yml | 2 +- .../.gitlab-ci.yml | 3 +++ .../.travis.yml | 1 + samples/client/echo_api/python/.github/workflows/python.yml | 2 +- samples/client/echo_api/python/.gitlab-ci.yml | 3 +++ samples/client/echo_api/python/.travis.yml | 1 + .../.github/workflows/python.yml | 2 +- .../others/python-legacy-model-dictionaries/.gitlab-ci.yml | 3 +++ .../client/others/python-legacy-model-dictionaries/.travis.yml | 1 + .../petstore/python-aiohttp/.github/workflows/python.yml | 2 +- samples/openapi3/client/petstore/python-aiohttp/.gitlab-ci.yml | 3 +++ samples/openapi3/client/petstore/python-aiohttp/.travis.yml | 1 + .../petstore/python-httpx-sync/.github/workflows/python.yml | 2 +- .../openapi3/client/petstore/python-httpx-sync/.gitlab-ci.yml | 3 +++ samples/openapi3/client/petstore/python-httpx-sync/.travis.yml | 1 + .../client/petstore/python-httpx/.github/workflows/python.yml | 2 +- samples/openapi3/client/petstore/python-httpx/.gitlab-ci.yml | 3 +++ samples/openapi3/client/petstore/python-httpx/.travis.yml | 1 + .../petstore/python-httpx2-sync/.github/workflows/python.yml | 2 +- .../openapi3/client/petstore/python-httpx2-sync/.gitlab-ci.yml | 3 +++ .../openapi3/client/petstore/python-httpx2-sync/.travis.yml | 1 + .../client/petstore/python-httpx2/.github/workflows/python.yml | 2 +- samples/openapi3/client/petstore/python-httpx2/.gitlab-ci.yml | 3 +++ samples/openapi3/client/petstore/python-httpx2/.travis.yml | 1 + .../petstore/python-lazyImports/.github/workflows/python.yml | 2 +- .../openapi3/client/petstore/python-lazyImports/.gitlab-ci.yml | 3 +++ .../openapi3/client/petstore/python-lazyImports/.travis.yml | 1 + .../client/petstore/python/.github/workflows/python.yml | 2 +- samples/openapi3/client/petstore/python/.gitlab-ci.yml | 3 +++ samples/openapi3/client/petstore/python/.travis.yml | 1 + 38 files changed, 62 insertions(+), 13 deletions(-) diff --git a/.github/workflows/samples-python-client-echo-api.yaml b/.github/workflows/samples-python-client-echo-api.yaml index 8b1622881ffa..4c59ff6aa336 100644 --- a/.github/workflows/samples-python-client-echo-api.yaml +++ b/.github/workflows/samples-python-client-echo-api.yaml @@ -23,6 +23,7 @@ jobs: - "3.12" - "3.13" - "3.14" + - "3.15" steps: - uses: actions/checkout@v7 - uses: actions/setup-python@v7 @@ -34,7 +35,7 @@ jobs: run: | git clone https://github.com/wing328/http-echo-server -b openapi-generator-test-server (cd http-echo-server && npm install && npm start &) - - name: Install + - name: Install working-directory: ${{ matrix.sample }} run: | pip install -r requirements.txt diff --git a/.github/workflows/samples-python-client-legacy-model-dictionaries.yaml b/.github/workflows/samples-python-client-legacy-model-dictionaries.yaml index e9c6acc8888a..064026f90d58 100644 --- a/.github/workflows/samples-python-client-legacy-model-dictionaries.yaml +++ b/.github/workflows/samples-python-client-legacy-model-dictionaries.yaml @@ -19,6 +19,7 @@ jobs: - "3.12" - "3.13" - "3.14" + - "3.15" steps: - uses: actions/checkout@v7 - uses: actions/setup-python@v7 diff --git a/.github/workflows/samples-python-petstore.yaml b/.github/workflows/samples-python-petstore.yaml index 6f2678efd6e9..73dc30d75366 100644 --- a/.github/workflows/samples-python-petstore.yaml +++ b/.github/workflows/samples-python-petstore.yaml @@ -37,6 +37,7 @@ jobs: - "3.12" - "3.13" - "3.14" + - "3.15" sample: - samples/openapi3/client/petstore/python-aiohttp - samples/openapi3/client/petstore/python-httpx2 diff --git a/.github/workflows/samples-python-pydantic-v1-client-echo-api.yaml b/.github/workflows/samples-python-pydantic-v1-client-echo-api.yaml index fcdfab673f79..96cc763f99ad 100644 --- a/.github/workflows/samples-python-pydantic-v1-client-echo-api.yaml +++ b/.github/workflows/samples-python-pydantic-v1-client-echo-api.yaml @@ -22,6 +22,7 @@ jobs: - "3.12" - "3.13" #- "3.14" + #- "3.15" steps: - uses: actions/checkout@v7 - uses: actions/setup-python@v7 @@ -33,7 +34,7 @@ jobs: run: | git clone https://github.com/wing328/http-echo-server -b openapi-generator-test-server (cd http-echo-server && npm install && npm start &) - - name: Install + - name: Install working-directory: ${{ matrix.sample }} run: | pip install -r requirements.txt diff --git a/.github/workflows/samples-python-pydantic-v1-petstore.yaml b/.github/workflows/samples-python-pydantic-v1-petstore.yaml index 2980de678d92..1d74a46b1f93 100644 --- a/.github/workflows/samples-python-pydantic-v1-petstore.yaml +++ b/.github/workflows/samples-python-pydantic-v1-petstore.yaml @@ -20,6 +20,7 @@ jobs: - "3.12" - "3.13" - "3.14" + - "3.15" sample: - samples/openapi3/client/petstore/python-pydantic-v1-aiohttp - samples/openapi3/client/petstore/python-pydantic-v1 diff --git a/modules/openapi-generator/src/main/resources/python/github-workflow.mustache b/modules/openapi-generator/src/main/resources/python/github-workflow.mustache index f6f72ae69958..f99648fe6eec 100644 --- a/modules/openapi-generator/src/main/resources/python/github-workflow.mustache +++ b/modules/openapi-generator/src/main/resources/python/github-workflow.mustache @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/modules/openapi-generator/src/main/resources/python/gitlab-ci.mustache b/modules/openapi-generator/src/main/resources/python/gitlab-ci.mustache index 701ffbfd7e8a..45c976bd791e 100644 --- a/modules/openapi-generator/src/main/resources/python/gitlab-ci.mustache +++ b/modules/openapi-generator/src/main/resources/python/gitlab-ci.mustache @@ -29,3 +29,6 @@ pytest-3.13: pytest-3.14: extends: .pytest image: python:3.14-alpine +pytest-3.15: + extends: .pytest + image: python:3.15-alpine diff --git a/modules/openapi-generator/src/main/resources/python/travis.mustache b/modules/openapi-generator/src/main/resources/python/travis.mustache index 983251a4640b..c236d322bf22 100644 --- a/modules/openapi-generator/src/main/resources/python/travis.mustache +++ b/modules/openapi-generator/src/main/resources/python/travis.mustache @@ -6,6 +6,7 @@ python: - "3.12" - "3.13" - "3.14" + - "3.15" # uncomment the following if needed #- "3.14-dev" # 3.14 development branch #- "nightly" # nightly build diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.github/workflows/python.yml b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.github/workflows/python.yml index b17065bfa1d4..a0cf208ec8b5 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.github/workflows/python.yml +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.gitlab-ci.yml b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.gitlab-ci.yml index 4c036842aee1..564d7416bbbb 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.gitlab-ci.yml +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.gitlab-ci.yml @@ -29,3 +29,6 @@ pytest-3.13: pytest-3.14: extends: .pytest image: python:3.14-alpine +pytest-3.15: + extends: .pytest + image: python:3.15-alpine diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.travis.yml b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.travis.yml index a58e1c9adaf6..ef719723eb0d 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.travis.yml +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.travis.yml @@ -6,6 +6,7 @@ python: - "3.12" - "3.13" - "3.14" + - "3.15" # uncomment the following if needed #- "3.14-dev" # 3.14 development branch #- "nightly" # nightly build diff --git a/samples/client/echo_api/python/.github/workflows/python.yml b/samples/client/echo_api/python/.github/workflows/python.yml index b17065bfa1d4..a0cf208ec8b5 100644 --- a/samples/client/echo_api/python/.github/workflows/python.yml +++ b/samples/client/echo_api/python/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/client/echo_api/python/.gitlab-ci.yml b/samples/client/echo_api/python/.gitlab-ci.yml index 4c036842aee1..564d7416bbbb 100644 --- a/samples/client/echo_api/python/.gitlab-ci.yml +++ b/samples/client/echo_api/python/.gitlab-ci.yml @@ -29,3 +29,6 @@ pytest-3.13: pytest-3.14: extends: .pytest image: python:3.14-alpine +pytest-3.15: + extends: .pytest + image: python:3.15-alpine diff --git a/samples/client/echo_api/python/.travis.yml b/samples/client/echo_api/python/.travis.yml index a58e1c9adaf6..ef719723eb0d 100644 --- a/samples/client/echo_api/python/.travis.yml +++ b/samples/client/echo_api/python/.travis.yml @@ -6,6 +6,7 @@ python: - "3.12" - "3.13" - "3.14" + - "3.15" # uncomment the following if needed #- "3.14-dev" # 3.14 development branch #- "nightly" # nightly build diff --git a/samples/client/others/python-legacy-model-dictionaries/.github/workflows/python.yml b/samples/client/others/python-legacy-model-dictionaries/.github/workflows/python.yml index b4a39b34607b..5bfcc9d802df 100644 --- a/samples/client/others/python-legacy-model-dictionaries/.github/workflows/python.yml +++ b/samples/client/others/python-legacy-model-dictionaries/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/client/others/python-legacy-model-dictionaries/.gitlab-ci.yml b/samples/client/others/python-legacy-model-dictionaries/.gitlab-ci.yml index 547b0fd99b87..84413b5e8b91 100644 --- a/samples/client/others/python-legacy-model-dictionaries/.gitlab-ci.yml +++ b/samples/client/others/python-legacy-model-dictionaries/.gitlab-ci.yml @@ -29,3 +29,6 @@ pytest-3.13: pytest-3.14: extends: .pytest image: python:3.14-alpine +pytest-3.15: + extends: .pytest + image: python:3.15-alpine diff --git a/samples/client/others/python-legacy-model-dictionaries/.travis.yml b/samples/client/others/python-legacy-model-dictionaries/.travis.yml index 1e3bffd3b917..12309a614799 100644 --- a/samples/client/others/python-legacy-model-dictionaries/.travis.yml +++ b/samples/client/others/python-legacy-model-dictionaries/.travis.yml @@ -6,6 +6,7 @@ python: - "3.12" - "3.13" - "3.14" + - "3.15" # uncomment the following if needed #- "3.14-dev" # 3.14 development branch #- "nightly" # nightly build diff --git a/samples/openapi3/client/petstore/python-aiohttp/.github/workflows/python.yml b/samples/openapi3/client/petstore/python-aiohttp/.github/workflows/python.yml index da1eaf6fe1d7..20c4eae353fb 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python-aiohttp/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/openapi3/client/petstore/python-aiohttp/.gitlab-ci.yml b/samples/openapi3/client/petstore/python-aiohttp/.gitlab-ci.yml index 89cc724c729c..ed57a8f29294 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/.gitlab-ci.yml +++ b/samples/openapi3/client/petstore/python-aiohttp/.gitlab-ci.yml @@ -29,3 +29,6 @@ pytest-3.13: pytest-3.14: extends: .pytest image: python:3.14-alpine +pytest-3.15: + extends: .pytest + image: python:3.15-alpine diff --git a/samples/openapi3/client/petstore/python-aiohttp/.travis.yml b/samples/openapi3/client/petstore/python-aiohttp/.travis.yml index 1197382a3ed8..58b0a87885b9 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/.travis.yml +++ b/samples/openapi3/client/petstore/python-aiohttp/.travis.yml @@ -6,6 +6,7 @@ python: - "3.12" - "3.13" - "3.14" + - "3.15" # uncomment the following if needed #- "3.14-dev" # 3.14 development branch #- "nightly" # nightly build diff --git a/samples/openapi3/client/petstore/python-httpx-sync/.github/workflows/python.yml b/samples/openapi3/client/petstore/python-httpx-sync/.github/workflows/python.yml index da1eaf6fe1d7..20c4eae353fb 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python-httpx-sync/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/openapi3/client/petstore/python-httpx-sync/.gitlab-ci.yml b/samples/openapi3/client/petstore/python-httpx-sync/.gitlab-ci.yml index 89cc724c729c..ed57a8f29294 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/.gitlab-ci.yml +++ b/samples/openapi3/client/petstore/python-httpx-sync/.gitlab-ci.yml @@ -29,3 +29,6 @@ pytest-3.13: pytest-3.14: extends: .pytest image: python:3.14-alpine +pytest-3.15: + extends: .pytest + image: python:3.15-alpine diff --git a/samples/openapi3/client/petstore/python-httpx-sync/.travis.yml b/samples/openapi3/client/petstore/python-httpx-sync/.travis.yml index 1197382a3ed8..58b0a87885b9 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/.travis.yml +++ b/samples/openapi3/client/petstore/python-httpx-sync/.travis.yml @@ -6,6 +6,7 @@ python: - "3.12" - "3.13" - "3.14" + - "3.15" # uncomment the following if needed #- "3.14-dev" # 3.14 development branch #- "nightly" # nightly build diff --git a/samples/openapi3/client/petstore/python-httpx/.github/workflows/python.yml b/samples/openapi3/client/petstore/python-httpx/.github/workflows/python.yml index da1eaf6fe1d7..20c4eae353fb 100644 --- a/samples/openapi3/client/petstore/python-httpx/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python-httpx/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/openapi3/client/petstore/python-httpx/.gitlab-ci.yml b/samples/openapi3/client/petstore/python-httpx/.gitlab-ci.yml index 89cc724c729c..ed57a8f29294 100644 --- a/samples/openapi3/client/petstore/python-httpx/.gitlab-ci.yml +++ b/samples/openapi3/client/petstore/python-httpx/.gitlab-ci.yml @@ -29,3 +29,6 @@ pytest-3.13: pytest-3.14: extends: .pytest image: python:3.14-alpine +pytest-3.15: + extends: .pytest + image: python:3.15-alpine diff --git a/samples/openapi3/client/petstore/python-httpx/.travis.yml b/samples/openapi3/client/petstore/python-httpx/.travis.yml index 1197382a3ed8..58b0a87885b9 100644 --- a/samples/openapi3/client/petstore/python-httpx/.travis.yml +++ b/samples/openapi3/client/petstore/python-httpx/.travis.yml @@ -6,6 +6,7 @@ python: - "3.12" - "3.13" - "3.14" + - "3.15" # uncomment the following if needed #- "3.14-dev" # 3.14 development branch #- "nightly" # nightly build diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/.github/workflows/python.yml b/samples/openapi3/client/petstore/python-httpx2-sync/.github/workflows/python.yml index da1eaf6fe1d7..20c4eae353fb 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python-httpx2-sync/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/.gitlab-ci.yml b/samples/openapi3/client/petstore/python-httpx2-sync/.gitlab-ci.yml index 89cc724c729c..ed57a8f29294 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/.gitlab-ci.yml +++ b/samples/openapi3/client/petstore/python-httpx2-sync/.gitlab-ci.yml @@ -29,3 +29,6 @@ pytest-3.13: pytest-3.14: extends: .pytest image: python:3.14-alpine +pytest-3.15: + extends: .pytest + image: python:3.15-alpine diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/.travis.yml b/samples/openapi3/client/petstore/python-httpx2-sync/.travis.yml index 1197382a3ed8..58b0a87885b9 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/.travis.yml +++ b/samples/openapi3/client/petstore/python-httpx2-sync/.travis.yml @@ -6,6 +6,7 @@ python: - "3.12" - "3.13" - "3.14" + - "3.15" # uncomment the following if needed #- "3.14-dev" # 3.14 development branch #- "nightly" # nightly build diff --git a/samples/openapi3/client/petstore/python-httpx2/.github/workflows/python.yml b/samples/openapi3/client/petstore/python-httpx2/.github/workflows/python.yml index da1eaf6fe1d7..20c4eae353fb 100644 --- a/samples/openapi3/client/petstore/python-httpx2/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python-httpx2/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/openapi3/client/petstore/python-httpx2/.gitlab-ci.yml b/samples/openapi3/client/petstore/python-httpx2/.gitlab-ci.yml index 89cc724c729c..ed57a8f29294 100644 --- a/samples/openapi3/client/petstore/python-httpx2/.gitlab-ci.yml +++ b/samples/openapi3/client/petstore/python-httpx2/.gitlab-ci.yml @@ -29,3 +29,6 @@ pytest-3.13: pytest-3.14: extends: .pytest image: python:3.14-alpine +pytest-3.15: + extends: .pytest + image: python:3.15-alpine diff --git a/samples/openapi3/client/petstore/python-httpx2/.travis.yml b/samples/openapi3/client/petstore/python-httpx2/.travis.yml index 1197382a3ed8..58b0a87885b9 100644 --- a/samples/openapi3/client/petstore/python-httpx2/.travis.yml +++ b/samples/openapi3/client/petstore/python-httpx2/.travis.yml @@ -6,6 +6,7 @@ python: - "3.12" - "3.13" - "3.14" + - "3.15" # uncomment the following if needed #- "3.14-dev" # 3.14 development branch #- "nightly" # nightly build diff --git a/samples/openapi3/client/petstore/python-lazyImports/.github/workflows/python.yml b/samples/openapi3/client/petstore/python-lazyImports/.github/workflows/python.yml index da1eaf6fe1d7..20c4eae353fb 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python-lazyImports/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/openapi3/client/petstore/python-lazyImports/.gitlab-ci.yml b/samples/openapi3/client/petstore/python-lazyImports/.gitlab-ci.yml index 89cc724c729c..ed57a8f29294 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/.gitlab-ci.yml +++ b/samples/openapi3/client/petstore/python-lazyImports/.gitlab-ci.yml @@ -29,3 +29,6 @@ pytest-3.13: pytest-3.14: extends: .pytest image: python:3.14-alpine +pytest-3.15: + extends: .pytest + image: python:3.15-alpine diff --git a/samples/openapi3/client/petstore/python-lazyImports/.travis.yml b/samples/openapi3/client/petstore/python-lazyImports/.travis.yml index 1197382a3ed8..58b0a87885b9 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/.travis.yml +++ b/samples/openapi3/client/petstore/python-lazyImports/.travis.yml @@ -6,6 +6,7 @@ python: - "3.12" - "3.13" - "3.14" + - "3.15" # uncomment the following if needed #- "3.14-dev" # 3.14 development branch #- "nightly" # nightly build diff --git a/samples/openapi3/client/petstore/python/.github/workflows/python.yml b/samples/openapi3/client/petstore/python/.github/workflows/python.yml index da1eaf6fe1d7..20c4eae353fb 100644 --- a/samples/openapi3/client/petstore/python/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/openapi3/client/petstore/python/.gitlab-ci.yml b/samples/openapi3/client/petstore/python/.gitlab-ci.yml index 89cc724c729c..ed57a8f29294 100755 --- a/samples/openapi3/client/petstore/python/.gitlab-ci.yml +++ b/samples/openapi3/client/petstore/python/.gitlab-ci.yml @@ -29,3 +29,6 @@ pytest-3.13: pytest-3.14: extends: .pytest image: python:3.14-alpine +pytest-3.15: + extends: .pytest + image: python:3.15-alpine diff --git a/samples/openapi3/client/petstore/python/.travis.yml b/samples/openapi3/client/petstore/python/.travis.yml index 1197382a3ed8..58b0a87885b9 100755 --- a/samples/openapi3/client/petstore/python/.travis.yml +++ b/samples/openapi3/client/petstore/python/.travis.yml @@ -6,6 +6,7 @@ python: - "3.12" - "3.13" - "3.14" + - "3.15" # uncomment the following if needed #- "3.14-dev" # 3.14 development branch #- "nightly" # nightly build From 4a492662690dbe40cb2789894e313fdec3b952ee Mon Sep 17 00:00:00 2001 From: Bernardo Gomes Date: Sun, 18 Oct 2026 21:58:50 -0300 Subject: [PATCH 3/8] fix break change at pycryptodome --- .../python-pydantic-v1/tests/test_http_signature.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/samples/openapi3/client/petstore/python-pydantic-v1/tests/test_http_signature.py b/samples/openapi3/client/petstore/python-pydantic-v1/tests/test_http_signature.py index 569ae0ce4973..ec8d000df551 100644 --- a/samples/openapi3/client/petstore/python-pydantic-v1/tests/test_http_signature.py +++ b/samples/openapi3/client/petstore/python-pydantic-v1/tests/test_http_signature.py @@ -228,8 +228,9 @@ def setUpFiles(cls): if not os.path.exists(cls.rsa4096_key_path): key = RSA.generate(4096) private_key = key.export_key( + format='PEM', passphrase=cls.private_key_passphrase, - protection='PEM' + pkcs=1 ) with open(cls.rsa4096_key_path, "wb") as f: f.write(private_key) @@ -451,14 +452,16 @@ def test_invalid_configuration(self): 'Exception message: {0}'.format(str(cm.exception))) # Private key passphrase is missing but key is encrypted. - with self.assertRaises(Exception) as cm: + with self.assertRaisesRegex( + ValueError, + r'Not a valid clear PKCS#8 structure|' + r'The private key is encrypted: a passphrase is required' + ): signing_cfg = signing.HttpSigningConfiguration( key_id="my-key-id", signing_scheme=signing.SCHEME_HS2019, private_key_path=self.ec_p521_key_path, ) - self.assertTrue(re.match('Not a valid clear PKCS#8 structure', str(cm.exception)), - 'Exception message: {0}'.format(str(cm.exception))) # File containing private key must exist. with self.assertRaises(Exception) as cm: From e34d325251c85c445dc9feae70f70d9bbb2d9712 Mon Sep 17 00:00:00 2001 From: Bernardo Gomes Date: Sun, 18 Oct 2026 22:05:57 -0300 Subject: [PATCH 4/8] fix break change at pycryptodome --- .../python-lazyImports/tests/test_http_signature.py | 11 +++++++---- .../petstore/python/tests/test_http_signature.py | 11 +++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/samples/openapi3/client/petstore/python-lazyImports/tests/test_http_signature.py b/samples/openapi3/client/petstore/python-lazyImports/tests/test_http_signature.py index 1d5f05abb462..3fa65ada8d23 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/tests/test_http_signature.py +++ b/samples/openapi3/client/petstore/python-lazyImports/tests/test_http_signature.py @@ -254,8 +254,9 @@ def setUpFiles(cls): if not os.path.exists(cls.rsa4096_key_path): key = RSA.generate(4096) private_key = key.export_key( + format='PEM', passphrase=cls.private_key_passphrase, - protection='PEM' + pkcs=1 ) with open(cls.rsa4096_key_path, "wb") as f: f.write(private_key) @@ -481,14 +482,16 @@ def test_invalid_configuration(self): 'Exception message: {0}'.format(str(cm.exception))) # Private key passphrase is missing but key is encrypted. - with self.assertRaises(Exception) as cm: + with self.assertRaisesRegex( + ValueError, + r'Not a valid clear PKCS#8 structure|' + r'The private key is encrypted: a passphrase is required' + ): signing_cfg = signing.HttpSigningConfiguration( key_id="my-key-id", signing_scheme=signing.SCHEME_HS2019, private_key_path=self.ec_p521_key_path, ) - self.assertTrue(re.match('Not a valid clear PKCS#8 structure', str(cm.exception)), - 'Exception message: {0}'.format(str(cm.exception))) # File containing private key must exist. with self.assertRaises(Exception) as cm: diff --git a/samples/openapi3/client/petstore/python/tests/test_http_signature.py b/samples/openapi3/client/petstore/python/tests/test_http_signature.py index 1d5f05abb462..64e5278814fa 100644 --- a/samples/openapi3/client/petstore/python/tests/test_http_signature.py +++ b/samples/openapi3/client/petstore/python/tests/test_http_signature.py @@ -254,8 +254,9 @@ def setUpFiles(cls): if not os.path.exists(cls.rsa4096_key_path): key = RSA.generate(4096) private_key = key.export_key( + format='PEM' passphrase=cls.private_key_passphrase, - protection='PEM' + pkcs=1 ) with open(cls.rsa4096_key_path, "wb") as f: f.write(private_key) @@ -481,14 +482,16 @@ def test_invalid_configuration(self): 'Exception message: {0}'.format(str(cm.exception))) # Private key passphrase is missing but key is encrypted. - with self.assertRaises(Exception) as cm: + with self.assertRaisesRegex( + ValueError, + r'Not a valid clear PKCS#8 structure|' + r'The private key is encrypted: a passphrase is required' + ): signing_cfg = signing.HttpSigningConfiguration( key_id="my-key-id", signing_scheme=signing.SCHEME_HS2019, private_key_path=self.ec_p521_key_path, ) - self.assertTrue(re.match('Not a valid clear PKCS#8 structure', str(cm.exception)), - 'Exception message: {0}'.format(str(cm.exception))) # File containing private key must exist. with self.assertRaises(Exception) as cm: From 41991c6ac14ce69e7314d4cf27def16b8865eed2 Mon Sep 17 00:00:00 2001 From: Bernardo Gomes Date: Sun, 18 Oct 2026 22:12:04 -0300 Subject: [PATCH 5/8] add missed , --- .../client/petstore/python/tests/test_http_signature.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/openapi3/client/petstore/python/tests/test_http_signature.py b/samples/openapi3/client/petstore/python/tests/test_http_signature.py index 64e5278814fa..3fa65ada8d23 100644 --- a/samples/openapi3/client/petstore/python/tests/test_http_signature.py +++ b/samples/openapi3/client/petstore/python/tests/test_http_signature.py @@ -254,7 +254,7 @@ def setUpFiles(cls): if not os.path.exists(cls.rsa4096_key_path): key = RSA.generate(4096) private_key = key.export_key( - format='PEM' + format='PEM', passphrase=cls.private_key_passphrase, pkcs=1 ) From 3d5d5d2bae812e08379f63a01c4e27061916bc1d Mon Sep 17 00:00:00 2001 From: Bernardo Gomes Date: Sun, 18 Oct 2026 22:20:47 -0300 Subject: [PATCH 6/8] remove 3.10 python --- .../src/main/resources/python/github-workflow.mustache | 2 +- .../src/main/resources/python/gitlab-ci.mustache | 3 --- .../src/main/resources/python/travis.mustache | 1 - .../.github/workflows/python.yml | 2 +- .../.gitlab-ci.yml | 3 --- .../.travis.yml | 1 - samples/client/echo_api/python/.github/workflows/python.yml | 2 +- samples/client/echo_api/python/.gitlab-ci.yml | 3 --- samples/client/echo_api/python/.travis.yml | 1 - .../.github/workflows/python.yml | 2 +- .../others/python-legacy-model-dictionaries/.gitlab-ci.yml | 3 --- .../client/others/python-legacy-model-dictionaries/.travis.yml | 1 - .../petstore/python-aiohttp/.github/workflows/python.yml | 2 +- samples/openapi3/client/petstore/python-aiohttp/.gitlab-ci.yml | 3 --- samples/openapi3/client/petstore/python-aiohttp/.travis.yml | 1 - .../petstore/python-httpx-sync/.github/workflows/python.yml | 2 +- .../openapi3/client/petstore/python-httpx-sync/.gitlab-ci.yml | 3 --- samples/openapi3/client/petstore/python-httpx-sync/.travis.yml | 1 - .../client/petstore/python-httpx/.github/workflows/python.yml | 2 +- samples/openapi3/client/petstore/python-httpx/.gitlab-ci.yml | 3 --- samples/openapi3/client/petstore/python-httpx/.travis.yml | 1 - .../petstore/python-httpx2-sync/.github/workflows/python.yml | 2 +- .../openapi3/client/petstore/python-httpx2-sync/.gitlab-ci.yml | 3 --- .../openapi3/client/petstore/python-httpx2-sync/.travis.yml | 1 - .../client/petstore/python-httpx2/.github/workflows/python.yml | 2 +- samples/openapi3/client/petstore/python-httpx2/.gitlab-ci.yml | 3 --- samples/openapi3/client/petstore/python-httpx2/.travis.yml | 1 - .../petstore/python-lazyImports/.github/workflows/python.yml | 2 +- .../openapi3/client/petstore/python-lazyImports/.gitlab-ci.yml | 3 --- .../openapi3/client/petstore/python-lazyImports/.travis.yml | 1 - .../client/petstore/python/.github/workflows/python.yml | 2 +- samples/openapi3/client/petstore/python/.gitlab-ci.yml | 3 --- samples/openapi3/client/petstore/python/.travis.yml | 1 - 33 files changed, 11 insertions(+), 55 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/python/github-workflow.mustache b/modules/openapi-generator/src/main/resources/python/github-workflow.mustache index f99648fe6eec..2a39a0294ff1 100644 --- a/modules/openapi-generator/src/main/resources/python/github-workflow.mustache +++ b/modules/openapi-generator/src/main/resources/python/github-workflow.mustache @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] + python-version: ["3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/modules/openapi-generator/src/main/resources/python/gitlab-ci.mustache b/modules/openapi-generator/src/main/resources/python/gitlab-ci.mustache index 45c976bd791e..b9e2fde25088 100644 --- a/modules/openapi-generator/src/main/resources/python/gitlab-ci.mustache +++ b/modules/openapi-generator/src/main/resources/python/gitlab-ci.mustache @@ -14,9 +14,6 @@ stages: - pip install -r test-requirements.txt - pytest --cov={{{packageName}}} -pytest-3.10: - extends: .pytest - image: python:3.10-alpine pytest-3.11: extends: .pytest image: python:3.11-alpine diff --git a/modules/openapi-generator/src/main/resources/python/travis.mustache b/modules/openapi-generator/src/main/resources/python/travis.mustache index c236d322bf22..401fbf7dcc46 100644 --- a/modules/openapi-generator/src/main/resources/python/travis.mustache +++ b/modules/openapi-generator/src/main/resources/python/travis.mustache @@ -1,7 +1,6 @@ # ref: https://docs.travis-ci.com/user/languages/python language: python python: - - "3.10" - "3.11" - "3.12" - "3.13" diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.github/workflows/python.yml b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.github/workflows/python.yml index a0cf208ec8b5..155511037cb0 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.github/workflows/python.yml +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] + python-version: ["3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.gitlab-ci.yml b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.gitlab-ci.yml index 564d7416bbbb..dd6dabc8dc6b 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.gitlab-ci.yml +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.gitlab-ci.yml @@ -14,9 +14,6 @@ stages: - pip install -r test-requirements.txt - pytest --cov=openapi_client -pytest-3.10: - extends: .pytest - image: python:3.10-alpine pytest-3.11: extends: .pytest image: python:3.11-alpine diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.travis.yml b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.travis.yml index ef719723eb0d..4427cc321d15 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.travis.yml +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.travis.yml @@ -1,7 +1,6 @@ # ref: https://docs.travis-ci.com/user/languages/python language: python python: - - "3.10" - "3.11" - "3.12" - "3.13" diff --git a/samples/client/echo_api/python/.github/workflows/python.yml b/samples/client/echo_api/python/.github/workflows/python.yml index a0cf208ec8b5..155511037cb0 100644 --- a/samples/client/echo_api/python/.github/workflows/python.yml +++ b/samples/client/echo_api/python/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] + python-version: ["3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/client/echo_api/python/.gitlab-ci.yml b/samples/client/echo_api/python/.gitlab-ci.yml index 564d7416bbbb..dd6dabc8dc6b 100644 --- a/samples/client/echo_api/python/.gitlab-ci.yml +++ b/samples/client/echo_api/python/.gitlab-ci.yml @@ -14,9 +14,6 @@ stages: - pip install -r test-requirements.txt - pytest --cov=openapi_client -pytest-3.10: - extends: .pytest - image: python:3.10-alpine pytest-3.11: extends: .pytest image: python:3.11-alpine diff --git a/samples/client/echo_api/python/.travis.yml b/samples/client/echo_api/python/.travis.yml index ef719723eb0d..4427cc321d15 100644 --- a/samples/client/echo_api/python/.travis.yml +++ b/samples/client/echo_api/python/.travis.yml @@ -1,7 +1,6 @@ # ref: https://docs.travis-ci.com/user/languages/python language: python python: - - "3.10" - "3.11" - "3.12" - "3.13" diff --git a/samples/client/others/python-legacy-model-dictionaries/.github/workflows/python.yml b/samples/client/others/python-legacy-model-dictionaries/.github/workflows/python.yml index 5bfcc9d802df..340f4e5b2a15 100644 --- a/samples/client/others/python-legacy-model-dictionaries/.github/workflows/python.yml +++ b/samples/client/others/python-legacy-model-dictionaries/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] + python-version: ["3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/client/others/python-legacy-model-dictionaries/.gitlab-ci.yml b/samples/client/others/python-legacy-model-dictionaries/.gitlab-ci.yml index 84413b5e8b91..df08a258e997 100644 --- a/samples/client/others/python-legacy-model-dictionaries/.gitlab-ci.yml +++ b/samples/client/others/python-legacy-model-dictionaries/.gitlab-ci.yml @@ -14,9 +14,6 @@ stages: - pip install -r test-requirements.txt - pytest --cov=legacy_model_dict_client -pytest-3.10: - extends: .pytest - image: python:3.10-alpine pytest-3.11: extends: .pytest image: python:3.11-alpine diff --git a/samples/client/others/python-legacy-model-dictionaries/.travis.yml b/samples/client/others/python-legacy-model-dictionaries/.travis.yml index 12309a614799..fe19f9874f0f 100644 --- a/samples/client/others/python-legacy-model-dictionaries/.travis.yml +++ b/samples/client/others/python-legacy-model-dictionaries/.travis.yml @@ -1,7 +1,6 @@ # ref: https://docs.travis-ci.com/user/languages/python language: python python: - - "3.10" - "3.11" - "3.12" - "3.13" diff --git a/samples/openapi3/client/petstore/python-aiohttp/.github/workflows/python.yml b/samples/openapi3/client/petstore/python-aiohttp/.github/workflows/python.yml index 20c4eae353fb..8111d2dfb97a 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python-aiohttp/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] + python-version: ["3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/openapi3/client/petstore/python-aiohttp/.gitlab-ci.yml b/samples/openapi3/client/petstore/python-aiohttp/.gitlab-ci.yml index ed57a8f29294..a2b202376fa8 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/.gitlab-ci.yml +++ b/samples/openapi3/client/petstore/python-aiohttp/.gitlab-ci.yml @@ -14,9 +14,6 @@ stages: - pip install -r test-requirements.txt - pytest --cov=petstore_api -pytest-3.10: - extends: .pytest - image: python:3.10-alpine pytest-3.11: extends: .pytest image: python:3.11-alpine diff --git a/samples/openapi3/client/petstore/python-aiohttp/.travis.yml b/samples/openapi3/client/petstore/python-aiohttp/.travis.yml index 58b0a87885b9..e8d58f51989e 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/.travis.yml +++ b/samples/openapi3/client/petstore/python-aiohttp/.travis.yml @@ -1,7 +1,6 @@ # ref: https://docs.travis-ci.com/user/languages/python language: python python: - - "3.10" - "3.11" - "3.12" - "3.13" diff --git a/samples/openapi3/client/petstore/python-httpx-sync/.github/workflows/python.yml b/samples/openapi3/client/petstore/python-httpx-sync/.github/workflows/python.yml index 20c4eae353fb..8111d2dfb97a 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python-httpx-sync/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] + python-version: ["3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/openapi3/client/petstore/python-httpx-sync/.gitlab-ci.yml b/samples/openapi3/client/petstore/python-httpx-sync/.gitlab-ci.yml index ed57a8f29294..a2b202376fa8 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/.gitlab-ci.yml +++ b/samples/openapi3/client/petstore/python-httpx-sync/.gitlab-ci.yml @@ -14,9 +14,6 @@ stages: - pip install -r test-requirements.txt - pytest --cov=petstore_api -pytest-3.10: - extends: .pytest - image: python:3.10-alpine pytest-3.11: extends: .pytest image: python:3.11-alpine diff --git a/samples/openapi3/client/petstore/python-httpx-sync/.travis.yml b/samples/openapi3/client/petstore/python-httpx-sync/.travis.yml index 58b0a87885b9..e8d58f51989e 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/.travis.yml +++ b/samples/openapi3/client/petstore/python-httpx-sync/.travis.yml @@ -1,7 +1,6 @@ # ref: https://docs.travis-ci.com/user/languages/python language: python python: - - "3.10" - "3.11" - "3.12" - "3.13" diff --git a/samples/openapi3/client/petstore/python-httpx/.github/workflows/python.yml b/samples/openapi3/client/petstore/python-httpx/.github/workflows/python.yml index 20c4eae353fb..8111d2dfb97a 100644 --- a/samples/openapi3/client/petstore/python-httpx/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python-httpx/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] + python-version: ["3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/openapi3/client/petstore/python-httpx/.gitlab-ci.yml b/samples/openapi3/client/petstore/python-httpx/.gitlab-ci.yml index ed57a8f29294..a2b202376fa8 100644 --- a/samples/openapi3/client/petstore/python-httpx/.gitlab-ci.yml +++ b/samples/openapi3/client/petstore/python-httpx/.gitlab-ci.yml @@ -14,9 +14,6 @@ stages: - pip install -r test-requirements.txt - pytest --cov=petstore_api -pytest-3.10: - extends: .pytest - image: python:3.10-alpine pytest-3.11: extends: .pytest image: python:3.11-alpine diff --git a/samples/openapi3/client/petstore/python-httpx/.travis.yml b/samples/openapi3/client/petstore/python-httpx/.travis.yml index 58b0a87885b9..e8d58f51989e 100644 --- a/samples/openapi3/client/petstore/python-httpx/.travis.yml +++ b/samples/openapi3/client/petstore/python-httpx/.travis.yml @@ -1,7 +1,6 @@ # ref: https://docs.travis-ci.com/user/languages/python language: python python: - - "3.10" - "3.11" - "3.12" - "3.13" diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/.github/workflows/python.yml b/samples/openapi3/client/petstore/python-httpx2-sync/.github/workflows/python.yml index 20c4eae353fb..8111d2dfb97a 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python-httpx2-sync/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] + python-version: ["3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/.gitlab-ci.yml b/samples/openapi3/client/petstore/python-httpx2-sync/.gitlab-ci.yml index ed57a8f29294..a2b202376fa8 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/.gitlab-ci.yml +++ b/samples/openapi3/client/petstore/python-httpx2-sync/.gitlab-ci.yml @@ -14,9 +14,6 @@ stages: - pip install -r test-requirements.txt - pytest --cov=petstore_api -pytest-3.10: - extends: .pytest - image: python:3.10-alpine pytest-3.11: extends: .pytest image: python:3.11-alpine diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/.travis.yml b/samples/openapi3/client/petstore/python-httpx2-sync/.travis.yml index 58b0a87885b9..e8d58f51989e 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/.travis.yml +++ b/samples/openapi3/client/petstore/python-httpx2-sync/.travis.yml @@ -1,7 +1,6 @@ # ref: https://docs.travis-ci.com/user/languages/python language: python python: - - "3.10" - "3.11" - "3.12" - "3.13" diff --git a/samples/openapi3/client/petstore/python-httpx2/.github/workflows/python.yml b/samples/openapi3/client/petstore/python-httpx2/.github/workflows/python.yml index 20c4eae353fb..8111d2dfb97a 100644 --- a/samples/openapi3/client/petstore/python-httpx2/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python-httpx2/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] + python-version: ["3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/openapi3/client/petstore/python-httpx2/.gitlab-ci.yml b/samples/openapi3/client/petstore/python-httpx2/.gitlab-ci.yml index ed57a8f29294..a2b202376fa8 100644 --- a/samples/openapi3/client/petstore/python-httpx2/.gitlab-ci.yml +++ b/samples/openapi3/client/petstore/python-httpx2/.gitlab-ci.yml @@ -14,9 +14,6 @@ stages: - pip install -r test-requirements.txt - pytest --cov=petstore_api -pytest-3.10: - extends: .pytest - image: python:3.10-alpine pytest-3.11: extends: .pytest image: python:3.11-alpine diff --git a/samples/openapi3/client/petstore/python-httpx2/.travis.yml b/samples/openapi3/client/petstore/python-httpx2/.travis.yml index 58b0a87885b9..e8d58f51989e 100644 --- a/samples/openapi3/client/petstore/python-httpx2/.travis.yml +++ b/samples/openapi3/client/petstore/python-httpx2/.travis.yml @@ -1,7 +1,6 @@ # ref: https://docs.travis-ci.com/user/languages/python language: python python: - - "3.10" - "3.11" - "3.12" - "3.13" diff --git a/samples/openapi3/client/petstore/python-lazyImports/.github/workflows/python.yml b/samples/openapi3/client/petstore/python-lazyImports/.github/workflows/python.yml index 20c4eae353fb..8111d2dfb97a 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python-lazyImports/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] + python-version: ["3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/openapi3/client/petstore/python-lazyImports/.gitlab-ci.yml b/samples/openapi3/client/petstore/python-lazyImports/.gitlab-ci.yml index ed57a8f29294..a2b202376fa8 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/.gitlab-ci.yml +++ b/samples/openapi3/client/petstore/python-lazyImports/.gitlab-ci.yml @@ -14,9 +14,6 @@ stages: - pip install -r test-requirements.txt - pytest --cov=petstore_api -pytest-3.10: - extends: .pytest - image: python:3.10-alpine pytest-3.11: extends: .pytest image: python:3.11-alpine diff --git a/samples/openapi3/client/petstore/python-lazyImports/.travis.yml b/samples/openapi3/client/petstore/python-lazyImports/.travis.yml index 58b0a87885b9..e8d58f51989e 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/.travis.yml +++ b/samples/openapi3/client/petstore/python-lazyImports/.travis.yml @@ -1,7 +1,6 @@ # ref: https://docs.travis-ci.com/user/languages/python language: python python: - - "3.10" - "3.11" - "3.12" - "3.13" diff --git a/samples/openapi3/client/petstore/python/.github/workflows/python.yml b/samples/openapi3/client/petstore/python/.github/workflows/python.yml index 20c4eae353fb..8111d2dfb97a 100644 --- a/samples/openapi3/client/petstore/python/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python/.github/workflows/python.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] + python-version: ["3.11", "3.12", "3.13", "3.14", "3.15"] steps: - uses: actions/checkout@v4 diff --git a/samples/openapi3/client/petstore/python/.gitlab-ci.yml b/samples/openapi3/client/petstore/python/.gitlab-ci.yml index ed57a8f29294..a2b202376fa8 100755 --- a/samples/openapi3/client/petstore/python/.gitlab-ci.yml +++ b/samples/openapi3/client/petstore/python/.gitlab-ci.yml @@ -14,9 +14,6 @@ stages: - pip install -r test-requirements.txt - pytest --cov=petstore_api -pytest-3.10: - extends: .pytest - image: python:3.10-alpine pytest-3.11: extends: .pytest image: python:3.11-alpine diff --git a/samples/openapi3/client/petstore/python/.travis.yml b/samples/openapi3/client/petstore/python/.travis.yml index 58b0a87885b9..e8d58f51989e 100755 --- a/samples/openapi3/client/petstore/python/.travis.yml +++ b/samples/openapi3/client/petstore/python/.travis.yml @@ -1,7 +1,6 @@ # ref: https://docs.travis-ci.com/user/languages/python language: python python: - - "3.10" - "3.11" - "3.12" - "3.13" From 53ee63c2342fec1f2be71b4d02287e83a5689df0 Mon Sep 17 00:00:00 2001 From: Bernardo Gomes Date: Sun, 18 Oct 2026 22:52:11 -0300 Subject: [PATCH 7/8] remove 3.10 python --- .github/workflows/samples-python-client-echo-api.yaml | 1 - .../samples-python-client-legacy-model-dictionaries.yaml | 1 - .github/workflows/samples-python-fastapi-server.yaml | 2 +- .github/workflows/samples-python-petstore.yaml | 1 - .../samples-python-pydantic-v1-client-echo-api.yaml | 1 - .github/workflows/samples-python-pydantic-v1-petstore.yaml | 1 - docs/generators/python-fastapi.md | 2 +- docs/generators/python.md | 2 +- .../openapitools/codegen/languages/PythonClientCodegen.java | 2 +- .../codegen/languages/PythonFastAPIServerCodegen.java | 2 +- .../src/main/resources/python/pyproject.mustache | 4 ++-- .../src/main/resources/python/setup.mustache | 2 +- .../README.md | 2 +- .../pyproject.toml | 2 +- .../setup.py | 2 +- samples/client/echo_api/python/README.md | 2 +- samples/client/echo_api/python/pyproject.toml | 2 +- samples/client/echo_api/python/setup.py | 2 +- .../others/python-legacy-model-dictionaries/README.md | 2 +- .../others/python-legacy-model-dictionaries/pyproject.toml | 2 +- .../client/others/python-legacy-model-dictionaries/setup.py | 2 +- samples/openapi3/client/petstore/python-aiohttp/README.md | 2 +- .../openapi3/client/petstore/python-aiohttp/pyproject.toml | 2 +- samples/openapi3/client/petstore/python-aiohttp/setup.py | 2 +- .../openapi3/client/petstore/python-httpx-sync/README.md | 2 +- .../client/petstore/python-httpx-sync/pyproject.toml | 2 +- samples/openapi3/client/petstore/python-httpx-sync/setup.py | 2 +- samples/openapi3/client/petstore/python-httpx/README.md | 2 +- .../openapi3/client/petstore/python-httpx/pyproject.toml | 2 +- samples/openapi3/client/petstore/python-httpx/setup.py | 2 +- .../openapi3/client/petstore/python-httpx2-sync/README.md | 2 +- .../client/petstore/python-httpx2-sync/pyproject.toml | 2 +- .../openapi3/client/petstore/python-httpx2-sync/setup.py | 2 +- samples/openapi3/client/petstore/python-httpx2/README.md | 2 +- .../openapi3/client/petstore/python-httpx2/pyproject.toml | 2 +- samples/openapi3/client/petstore/python-httpx2/setup.py | 2 +- .../openapi3/client/petstore/python-lazyImports/README.md | 2 +- .../client/petstore/python-lazyImports/pyproject.toml | 2 +- .../openapi3/client/petstore/python-lazyImports/setup.py | 2 +- samples/openapi3/client/petstore/python/README.md | 2 +- samples/openapi3/client/petstore/python/pyproject.toml | 2 +- samples/openapi3/client/petstore/python/setup.py | 2 +- samples/server/petstore/python-fastapi/Dockerfile | 6 +++--- samples/server/petstore/python-fastapi/README.md | 2 +- samples/server/petstore/python-fastapi/setup.cfg | 4 ++-- 45 files changed, 44 insertions(+), 49 deletions(-) diff --git a/.github/workflows/samples-python-client-echo-api.yaml b/.github/workflows/samples-python-client-echo-api.yaml index 4c59ff6aa336..823993c72cff 100644 --- a/.github/workflows/samples-python-client-echo-api.yaml +++ b/.github/workflows/samples-python-client-echo-api.yaml @@ -18,7 +18,6 @@ jobs: - samples/client/echo_api/python - samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent python-version: - - "3.10" - "3.11" - "3.12" - "3.13" diff --git a/.github/workflows/samples-python-client-legacy-model-dictionaries.yaml b/.github/workflows/samples-python-client-legacy-model-dictionaries.yaml index 064026f90d58..8248a0006d4e 100644 --- a/.github/workflows/samples-python-client-legacy-model-dictionaries.yaml +++ b/.github/workflows/samples-python-client-legacy-model-dictionaries.yaml @@ -14,7 +14,6 @@ jobs: fail-fast: false matrix: python-version: - - "3.10" - "3.11" - "3.12" - "3.13" diff --git a/.github/workflows/samples-python-fastapi-server.yaml b/.github/workflows/samples-python-fastapi-server.yaml index f99d5fbeffc9..902a08aa6586 100644 --- a/.github/workflows/samples-python-fastapi-server.yaml +++ b/.github/workflows/samples-python-fastapi-server.yaml @@ -21,7 +21,7 @@ jobs: - uses: actions/checkout@v7 - uses: actions/setup-python@v7 with: - python-version: '3.10' + python-version: "3.11" - name: Install dependencies working-directory: ${{ matrix.sample }} run: | diff --git a/.github/workflows/samples-python-petstore.yaml b/.github/workflows/samples-python-petstore.yaml index 73dc30d75366..9f07ebd8a3de 100644 --- a/.github/workflows/samples-python-petstore.yaml +++ b/.github/workflows/samples-python-petstore.yaml @@ -32,7 +32,6 @@ jobs: fail-fast: false matrix: python-version: - - "3.10" - "3.11" - "3.12" - "3.13" diff --git a/.github/workflows/samples-python-pydantic-v1-client-echo-api.yaml b/.github/workflows/samples-python-pydantic-v1-client-echo-api.yaml index 96cc763f99ad..94b042250b5f 100644 --- a/.github/workflows/samples-python-pydantic-v1-client-echo-api.yaml +++ b/.github/workflows/samples-python-pydantic-v1-client-echo-api.yaml @@ -17,7 +17,6 @@ jobs: # clients - samples/client/echo_api/python-pydantic-v1/ python-version: - - "3.10" - "3.11" - "3.12" - "3.13" diff --git a/.github/workflows/samples-python-pydantic-v1-petstore.yaml b/.github/workflows/samples-python-pydantic-v1-petstore.yaml index 1d74a46b1f93..f9c5c9d5647c 100644 --- a/.github/workflows/samples-python-pydantic-v1-petstore.yaml +++ b/.github/workflows/samples-python-pydantic-v1-petstore.yaml @@ -15,7 +15,6 @@ jobs: fail-fast: false matrix: python-version: - - "3.10" - "3.11" - "3.12" - "3.13" diff --git a/docs/generators/python-fastapi.md b/docs/generators/python-fastapi.md index b1a2d987450a..304dc57d9839 100644 --- a/docs/generators/python-fastapi.md +++ b/docs/generators/python-fastapi.md @@ -10,7 +10,7 @@ title: Documentation for the python-fastapi Generator | generator stability | BETA | | | generator type | SERVER | | | generator language | Python | | -| generator language version | 3.10 | | +| generator language version | 3.11 | | | generator default templating engine | mustache | | | helpTxt | Generates a Python FastAPI server (beta). Models are defined with the pydantic library | | diff --git a/docs/generators/python.md b/docs/generators/python.md index 828b94f83cfc..deeba9c77a20 100644 --- a/docs/generators/python.md +++ b/docs/generators/python.md @@ -10,7 +10,7 @@ title: Documentation for the python Generator | generator stability | STABLE | | | generator type | CLIENT | | | generator language | Python | | -| generator language version | 3.10+ | | +| generator language version | 3.11+ | | | generator default templating engine | mustache | | | helpTxt | Generates a Python client library. | | diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java index af9aab3b7388..798bb17b7c2d 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonClientCodegen.java @@ -604,7 +604,7 @@ public String generatePackageName(String packageName) { @Override public String generatorLanguageVersion() { - return "3.10+"; + return "3.11+"; } @Override diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonFastAPIServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonFastAPIServerCodegen.java index ecaf15cdf630..632ce9eed835 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonFastAPIServerCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonFastAPIServerCodegen.java @@ -591,7 +591,7 @@ public void postProcess() { @Override public String generatorLanguageVersion() { - return "3.10"; + return "3.11"; } @Override diff --git a/modules/openapi-generator/src/main/resources/python/pyproject.mustache b/modules/openapi-generator/src/main/resources/python/pyproject.mustache index 96b7113fa667..109cff467caa 100644 --- a/modules/openapi-generator/src/main/resources/python/pyproject.mustache +++ b/modules/openapi-generator/src/main/resources/python/pyproject.mustache @@ -37,7 +37,7 @@ packages = [ include = ["{{#sourceFolder}}{{{sourceFolder}}}/{{/sourceFolder}}{{packageName}}/py.typed"] [tool.poetry.dependencies] -python = "^3.10" +python = "^3.11" {{^async}} urllib3 = ">= 2.7.0, < 3.0.0" {{/async}} @@ -60,7 +60,7 @@ pydantic = ">= 2.11" typing-extensions = ">= 4.7.1" {{/poetry1}} {{^poetry1}} -requires-python = ">=3.10" +requires-python = ">=3.11" dependencies = [ {{^async}} diff --git a/modules/openapi-generator/src/main/resources/python/setup.mustache b/modules/openapi-generator/src/main/resources/python/setup.mustache index 53763437f7ac..8f0da3eee18d 100644 --- a/modules/openapi-generator/src/main/resources/python/setup.mustache +++ b/modules/openapi-generator/src/main/resources/python/setup.mustache @@ -10,7 +10,7 @@ from setuptools import setup, find_packages # noqa: H301 # http://pypi.python.org/pypi/setuptools NAME = "{{{projectName}}}" VERSION = "{{packageVersion}}" -PYTHON_REQUIRES = ">= 3.10" +PYTHON_REQUIRES = ">= 3.11" REQUIRES = [ {{^async}} "urllib3 >= 2.7.0, < 3.0.0", diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/README.md b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/README.md index 91786c45dfc1..50cdefda03ae 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/README.md +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/README.md @@ -10,7 +10,7 @@ This Python package is automatically generated by the [OpenAPI Generator](https: ## Requirements. -Python 3.10+ +Python 3.11+ Packaging uses standard `[project]` metadata and `[dependency-groups]` (PEP 621/735). Install the package with `python -m pip install .`; install development dependencies diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/pyproject.toml b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/pyproject.toml index 5ca31fa22b75..c8ba8d656bd2 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/pyproject.toml +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/pyproject.toml @@ -8,7 +8,7 @@ authors = [ license = { text = "Apache 2.0" } readme = "README.md" keywords = ["OpenAPI", "OpenAPI-Generator", "Echo Server API"] -requires-python = ">=3.10" +requires-python = ">=3.11" dependencies = [ "urllib3 (>=2.7.0,<3.0.0)", diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/setup.py b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/setup.py index 2232e7608cb4..20494a74d591 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/setup.py +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/setup.py @@ -21,7 +21,7 @@ # http://pypi.python.org/pypi/setuptools NAME = "openapi-client" VERSION = "1.0.0" -PYTHON_REQUIRES = ">= 3.10" +PYTHON_REQUIRES = ">= 3.11" REQUIRES = [ "urllib3 >= 2.7.0, < 3.0.0", "python-dateutil >= 2.8.2", diff --git a/samples/client/echo_api/python/README.md b/samples/client/echo_api/python/README.md index 91786c45dfc1..50cdefda03ae 100644 --- a/samples/client/echo_api/python/README.md +++ b/samples/client/echo_api/python/README.md @@ -10,7 +10,7 @@ This Python package is automatically generated by the [OpenAPI Generator](https: ## Requirements. -Python 3.10+ +Python 3.11+ Packaging uses standard `[project]` metadata and `[dependency-groups]` (PEP 621/735). Install the package with `python -m pip install .`; install development dependencies diff --git a/samples/client/echo_api/python/pyproject.toml b/samples/client/echo_api/python/pyproject.toml index 5ca31fa22b75..c8ba8d656bd2 100644 --- a/samples/client/echo_api/python/pyproject.toml +++ b/samples/client/echo_api/python/pyproject.toml @@ -8,7 +8,7 @@ authors = [ license = { text = "Apache 2.0" } readme = "README.md" keywords = ["OpenAPI", "OpenAPI-Generator", "Echo Server API"] -requires-python = ">=3.10" +requires-python = ">=3.11" dependencies = [ "urllib3 (>=2.7.0,<3.0.0)", diff --git a/samples/client/echo_api/python/setup.py b/samples/client/echo_api/python/setup.py index 2232e7608cb4..20494a74d591 100644 --- a/samples/client/echo_api/python/setup.py +++ b/samples/client/echo_api/python/setup.py @@ -21,7 +21,7 @@ # http://pypi.python.org/pypi/setuptools NAME = "openapi-client" VERSION = "1.0.0" -PYTHON_REQUIRES = ">= 3.10" +PYTHON_REQUIRES = ">= 3.11" REQUIRES = [ "urllib3 >= 2.7.0, < 3.0.0", "python-dateutil >= 2.8.2", diff --git a/samples/client/others/python-legacy-model-dictionaries/README.md b/samples/client/others/python-legacy-model-dictionaries/README.md index 25df6323a088..0875297f5f68 100644 --- a/samples/client/others/python-legacy-model-dictionaries/README.md +++ b/samples/client/others/python-legacy-model-dictionaries/README.md @@ -10,7 +10,7 @@ This Python package is automatically generated by the [OpenAPI Generator](https: ## Requirements. -Python 3.10+ +Python 3.11+ Packaging uses standard `[project]` metadata and `[dependency-groups]` (PEP 621/735). Install the package with `python -m pip install .`; install development dependencies diff --git a/samples/client/others/python-legacy-model-dictionaries/pyproject.toml b/samples/client/others/python-legacy-model-dictionaries/pyproject.toml index 1e9c1a3105e5..5f5e6b8ae3d5 100644 --- a/samples/client/others/python-legacy-model-dictionaries/pyproject.toml +++ b/samples/client/others/python-legacy-model-dictionaries/pyproject.toml @@ -7,7 +7,7 @@ authors = [ ] readme = "README.md" keywords = ["OpenAPI", "OpenAPI-Generator", "Legacy model dictionaries"] -requires-python = ">=3.10" +requires-python = ">=3.11" dependencies = [ "urllib3 (>=2.7.0,<3.0.0)", diff --git a/samples/client/others/python-legacy-model-dictionaries/setup.py b/samples/client/others/python-legacy-model-dictionaries/setup.py index eb35f2c58fa2..d18c5efcc6cf 100644 --- a/samples/client/others/python-legacy-model-dictionaries/setup.py +++ b/samples/client/others/python-legacy-model-dictionaries/setup.py @@ -20,7 +20,7 @@ # http://pypi.python.org/pypi/setuptools NAME = "legacy-model-dict-client" VERSION = "1.0.0" -PYTHON_REQUIRES = ">= 3.10" +PYTHON_REQUIRES = ">= 3.11" REQUIRES = [ "urllib3 >= 2.7.0, < 3.0.0", "python-dateutil >= 2.8.2", diff --git a/samples/openapi3/client/petstore/python-aiohttp/README.md b/samples/openapi3/client/petstore/python-aiohttp/README.md index 7e15564de3cc..ca524c24be72 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/README.md +++ b/samples/openapi3/client/petstore/python-aiohttp/README.md @@ -10,7 +10,7 @@ This Python package is automatically generated by the [OpenAPI Generator](https: ## Requirements. -Python 3.10+ +Python 3.11+ Packaging retains the deprecated `[tool.poetry.dev-dependencies]` table for compatibility with legacy Poetry 1 releases. Generate with `poetry1=false` to use diff --git a/samples/openapi3/client/petstore/python-aiohttp/pyproject.toml b/samples/openapi3/client/petstore/python-aiohttp/pyproject.toml index 16d5fca0c199..bcf671a77754 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/pyproject.toml +++ b/samples/openapi3/client/petstore/python-aiohttp/pyproject.toml @@ -10,7 +10,7 @@ keywords = ["OpenAPI", "OpenAPI-Generator", "OpenAPI Petstore"] include = ["petstore_api/py.typed"] [tool.poetry.dependencies] -python = "^3.10" +python = "^3.11" python-dateutil = ">= 2.8.2" aiohttp = ">= 3.14.1" aiohttp-retry = ">= 2.8.3" diff --git a/samples/openapi3/client/petstore/python-aiohttp/setup.py b/samples/openapi3/client/petstore/python-aiohttp/setup.py index 75a720848ea9..662f156c19cf 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/setup.py +++ b/samples/openapi3/client/petstore/python-aiohttp/setup.py @@ -20,7 +20,7 @@ # http://pypi.python.org/pypi/setuptools NAME = "petstore-api" VERSION = "1.0.0" -PYTHON_REQUIRES = ">= 3.10" +PYTHON_REQUIRES = ">= 3.11" REQUIRES = [ "python-dateutil >= 2.8.2", "aiohttp >= 3.14.1", diff --git a/samples/openapi3/client/petstore/python-httpx-sync/README.md b/samples/openapi3/client/petstore/python-httpx-sync/README.md index d696bf8659b7..1903b0062bd5 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/README.md +++ b/samples/openapi3/client/petstore/python-httpx-sync/README.md @@ -10,7 +10,7 @@ This Python package is automatically generated by the [OpenAPI Generator](https: ## Requirements. -Python 3.10+ +Python 3.11+ Packaging uses standard `[project]` metadata and `[dependency-groups]` (PEP 621/735). Install the package with `python -m pip install .`; install development dependencies diff --git a/samples/openapi3/client/petstore/python-httpx-sync/pyproject.toml b/samples/openapi3/client/petstore/python-httpx-sync/pyproject.toml index 046bc636c51e..15b2a10b849b 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/pyproject.toml +++ b/samples/openapi3/client/petstore/python-httpx-sync/pyproject.toml @@ -8,7 +8,7 @@ authors = [ license = { text = "Apache-2.0" } readme = "README.md" keywords = ["OpenAPI", "OpenAPI-Generator", "OpenAPI Petstore"] -requires-python = ">=3.10" +requires-python = ">=3.11" dependencies = [ "python-dateutil (>=2.8.2)", diff --git a/samples/openapi3/client/petstore/python-httpx-sync/setup.py b/samples/openapi3/client/petstore/python-httpx-sync/setup.py index 89ef2676e4c8..e3fbfe697e5a 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/setup.py +++ b/samples/openapi3/client/petstore/python-httpx-sync/setup.py @@ -20,7 +20,7 @@ # http://pypi.python.org/pypi/setuptools NAME = "petstore-api" VERSION = "1.0.0" -PYTHON_REQUIRES = ">= 3.10" +PYTHON_REQUIRES = ">= 3.11" REQUIRES = [ "python-dateutil >= 2.8.2", "httpx >= 0.28.1", diff --git a/samples/openapi3/client/petstore/python-httpx/README.md b/samples/openapi3/client/petstore/python-httpx/README.md index d696bf8659b7..1903b0062bd5 100644 --- a/samples/openapi3/client/petstore/python-httpx/README.md +++ b/samples/openapi3/client/petstore/python-httpx/README.md @@ -10,7 +10,7 @@ This Python package is automatically generated by the [OpenAPI Generator](https: ## Requirements. -Python 3.10+ +Python 3.11+ Packaging uses standard `[project]` metadata and `[dependency-groups]` (PEP 621/735). Install the package with `python -m pip install .`; install development dependencies diff --git a/samples/openapi3/client/petstore/python-httpx/pyproject.toml b/samples/openapi3/client/petstore/python-httpx/pyproject.toml index 046bc636c51e..15b2a10b849b 100644 --- a/samples/openapi3/client/petstore/python-httpx/pyproject.toml +++ b/samples/openapi3/client/petstore/python-httpx/pyproject.toml @@ -8,7 +8,7 @@ authors = [ license = { text = "Apache-2.0" } readme = "README.md" keywords = ["OpenAPI", "OpenAPI-Generator", "OpenAPI Petstore"] -requires-python = ">=3.10" +requires-python = ">=3.11" dependencies = [ "python-dateutil (>=2.8.2)", diff --git a/samples/openapi3/client/petstore/python-httpx/setup.py b/samples/openapi3/client/petstore/python-httpx/setup.py index 89ef2676e4c8..e3fbfe697e5a 100644 --- a/samples/openapi3/client/petstore/python-httpx/setup.py +++ b/samples/openapi3/client/petstore/python-httpx/setup.py @@ -20,7 +20,7 @@ # http://pypi.python.org/pypi/setuptools NAME = "petstore-api" VERSION = "1.0.0" -PYTHON_REQUIRES = ">= 3.10" +PYTHON_REQUIRES = ">= 3.11" REQUIRES = [ "python-dateutil >= 2.8.2", "httpx >= 0.28.1", diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/README.md b/samples/openapi3/client/petstore/python-httpx2-sync/README.md index cf31ce123a3c..01536b739b3b 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/README.md +++ b/samples/openapi3/client/petstore/python-httpx2-sync/README.md @@ -10,7 +10,7 @@ This Python package is automatically generated by the [OpenAPI Generator](https: ## Requirements. -Python 3.10+ +Python 3.11+ Packaging uses standard `[project]` metadata and `[dependency-groups]` (PEP 621/735). Install the package with `python -m pip install .`; install development dependencies diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/pyproject.toml b/samples/openapi3/client/petstore/python-httpx2-sync/pyproject.toml index 759565d25be0..d0c97fcd113f 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/pyproject.toml +++ b/samples/openapi3/client/petstore/python-httpx2-sync/pyproject.toml @@ -8,7 +8,7 @@ authors = [ license = { text = "Apache-2.0" } readme = "README.md" keywords = ["OpenAPI", "OpenAPI-Generator", "OpenAPI Petstore"] -requires-python = ">=3.10" +requires-python = ">=3.11" dependencies = [ "python-dateutil (>=2.8.2)", diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/setup.py b/samples/openapi3/client/petstore/python-httpx2-sync/setup.py index c90f36d75a91..def9367fbbd0 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/setup.py +++ b/samples/openapi3/client/petstore/python-httpx2-sync/setup.py @@ -20,7 +20,7 @@ # http://pypi.python.org/pypi/setuptools NAME = "petstore-api" VERSION = "1.0.0" -PYTHON_REQUIRES = ">= 3.10" +PYTHON_REQUIRES = ">= 3.11" REQUIRES = [ "python-dateutil >= 2.8.2", "httpx2 >= 2.13.0, < 3", diff --git a/samples/openapi3/client/petstore/python-httpx2/README.md b/samples/openapi3/client/petstore/python-httpx2/README.md index 762afbfcdb00..63c9ecaaa336 100644 --- a/samples/openapi3/client/petstore/python-httpx2/README.md +++ b/samples/openapi3/client/petstore/python-httpx2/README.md @@ -10,7 +10,7 @@ This Python package is automatically generated by the [OpenAPI Generator](https: ## Requirements. -Python 3.10+ +Python 3.11+ Packaging uses standard `[project]` metadata and `[dependency-groups]` (PEP 621/735). Install the package with `python -m pip install .`; install development dependencies diff --git a/samples/openapi3/client/petstore/python-httpx2/pyproject.toml b/samples/openapi3/client/petstore/python-httpx2/pyproject.toml index 759565d25be0..d0c97fcd113f 100644 --- a/samples/openapi3/client/petstore/python-httpx2/pyproject.toml +++ b/samples/openapi3/client/petstore/python-httpx2/pyproject.toml @@ -8,7 +8,7 @@ authors = [ license = { text = "Apache-2.0" } readme = "README.md" keywords = ["OpenAPI", "OpenAPI-Generator", "OpenAPI Petstore"] -requires-python = ">=3.10" +requires-python = ">=3.11" dependencies = [ "python-dateutil (>=2.8.2)", diff --git a/samples/openapi3/client/petstore/python-httpx2/setup.py b/samples/openapi3/client/petstore/python-httpx2/setup.py index c90f36d75a91..def9367fbbd0 100644 --- a/samples/openapi3/client/petstore/python-httpx2/setup.py +++ b/samples/openapi3/client/petstore/python-httpx2/setup.py @@ -20,7 +20,7 @@ # http://pypi.python.org/pypi/setuptools NAME = "petstore-api" VERSION = "1.0.0" -PYTHON_REQUIRES = ">= 3.10" +PYTHON_REQUIRES = ">= 3.11" REQUIRES = [ "python-dateutil >= 2.8.2", "httpx2 >= 2.13.0, < 3", diff --git a/samples/openapi3/client/petstore/python-lazyImports/README.md b/samples/openapi3/client/petstore/python-lazyImports/README.md index d907bad2411f..83d11d217232 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/README.md +++ b/samples/openapi3/client/petstore/python-lazyImports/README.md @@ -10,7 +10,7 @@ This Python package is automatically generated by the [OpenAPI Generator](https: ## Requirements. -Python 3.10+ +Python 3.11+ Packaging uses standard `[project]` metadata and `[dependency-groups]` (PEP 621/735). Install the package with `python -m pip install .`; install development dependencies diff --git a/samples/openapi3/client/petstore/python-lazyImports/pyproject.toml b/samples/openapi3/client/petstore/python-lazyImports/pyproject.toml index abc3fa06045a..763ab84520b5 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/pyproject.toml +++ b/samples/openapi3/client/petstore/python-lazyImports/pyproject.toml @@ -8,7 +8,7 @@ authors = [ license = { text = "Apache-2.0" } readme = "README.md" keywords = ["OpenAPI", "OpenAPI-Generator", "OpenAPI Petstore"] -requires-python = ">=3.10" +requires-python = ">=3.11" dependencies = [ "urllib3 (>=2.7.0,<3.0.0)", diff --git a/samples/openapi3/client/petstore/python-lazyImports/setup.py b/samples/openapi3/client/petstore/python-lazyImports/setup.py index f07225fced95..0e0385045013 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/setup.py +++ b/samples/openapi3/client/petstore/python-lazyImports/setup.py @@ -20,7 +20,7 @@ # http://pypi.python.org/pypi/setuptools NAME = "petstore-api" VERSION = "1.0.0" -PYTHON_REQUIRES = ">= 3.10" +PYTHON_REQUIRES = ">= 3.11" REQUIRES = [ "urllib3 >= 2.7.0, < 3.0.0", "python-dateutil >= 2.8.2", diff --git a/samples/openapi3/client/petstore/python/README.md b/samples/openapi3/client/petstore/python/README.md index f50f803b5806..55e5221848a5 100755 --- a/samples/openapi3/client/petstore/python/README.md +++ b/samples/openapi3/client/petstore/python/README.md @@ -10,7 +10,7 @@ This Python package is automatically generated by the [OpenAPI Generator](https: ## Requirements. -Python 3.10+ +Python 3.11+ Packaging uses standard `[project]` metadata and `[dependency-groups]` (PEP 621/735). Install the package with `python -m pip install .`; install development dependencies diff --git a/samples/openapi3/client/petstore/python/pyproject.toml b/samples/openapi3/client/petstore/python/pyproject.toml index abc3fa06045a..763ab84520b5 100644 --- a/samples/openapi3/client/petstore/python/pyproject.toml +++ b/samples/openapi3/client/petstore/python/pyproject.toml @@ -8,7 +8,7 @@ authors = [ license = { text = "Apache-2.0" } readme = "README.md" keywords = ["OpenAPI", "OpenAPI-Generator", "OpenAPI Petstore"] -requires-python = ">=3.10" +requires-python = ">=3.11" dependencies = [ "urllib3 (>=2.7.0,<3.0.0)", diff --git a/samples/openapi3/client/petstore/python/setup.py b/samples/openapi3/client/petstore/python/setup.py index f07225fced95..0e0385045013 100755 --- a/samples/openapi3/client/petstore/python/setup.py +++ b/samples/openapi3/client/petstore/python/setup.py @@ -20,7 +20,7 @@ # http://pypi.python.org/pypi/setuptools NAME = "petstore-api" VERSION = "1.0.0" -PYTHON_REQUIRES = ">= 3.10" +PYTHON_REQUIRES = ">= 3.11" REQUIRES = [ "urllib3 >= 2.7.0, < 3.0.0", "python-dateutil >= 2.8.2", diff --git a/samples/server/petstore/python-fastapi/Dockerfile b/samples/server/petstore/python-fastapi/Dockerfile index 15e66460952f..851657206ba7 100644 --- a/samples/server/petstore/python-fastapi/Dockerfile +++ b/samples/server/petstore/python-fastapi/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.10 AS builder +FROM python:3.11 AS builder WORKDIR /usr/src/app @@ -11,7 +11,7 @@ COPY . . RUN pip install --no-cache-dir . -FROM python:3.10 AS test_runner +FROM python:3.11 AS test_runner WORKDIR /tmp COPY --from=builder /venv /venv COPY --from=builder /usr/src/app/tests tests @@ -24,7 +24,7 @@ RUN pip install pytest RUN pytest tests -FROM python:3.10 AS service +FROM python:3.11 AS service WORKDIR /root/app/site-packages COPY --from=test_runner /venv /venv ENV PATH=/venv/bin:$PATH diff --git a/samples/server/petstore/python-fastapi/README.md b/samples/server/petstore/python-fastapi/README.md index b62fa4c4d749..65a20feaf77d 100644 --- a/samples/server/petstore/python-fastapi/README.md +++ b/samples/server/petstore/python-fastapi/README.md @@ -8,7 +8,7 @@ This Python package is automatically generated by the [OpenAPI Generator](https: ## Requirements. -Python >= 3.10 +Python >= 3.11 ## Installation & Usage diff --git a/samples/server/petstore/python-fastapi/setup.cfg b/samples/server/petstore/python-fastapi/setup.cfg index ee047207bdea..980977a052ef 100644 --- a/samples/server/petstore/python-fastapi/setup.cfg +++ b/samples/server/petstore/python-fastapi/setup.cfg @@ -4,11 +4,11 @@ version = 3.4.5 description = This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. long_description = file: README.md keywords = OpenAPI OpenAPI Petstore -python_requires = >= 3.10.* +python_requires = >= 3.11.* classifiers = Operating System :: OS Independent Programming Language :: Python :: 3 - Programming Language :: Python :: 3.10 + Programming Language :: Python :: 3.11 [options] install_requires = fastapi[all] From 5ea99b7cd1945184e598085357dec242cb117ba6 Mon Sep 17 00:00:00 2001 From: Bernardo Gomes Date: Mon, 19 Oct 2026 06:41:10 -0300 Subject: [PATCH 8/8] update python.yml --- .../.github/workflows/python.yml | 1 + samples/client/echo_api/python/.github/workflows/python.yml | 1 + .../.github/workflows/python.yml | 1 + .../client/petstore/python-aiohttp/.github/workflows/python.yml | 1 + .../petstore/python-httpx-sync/.github/workflows/python.yml | 1 + .../client/petstore/python-httpx/.github/workflows/python.yml | 1 + .../petstore/python-httpx2-sync/.github/workflows/python.yml | 1 + .../client/petstore/python-httpx2/.github/workflows/python.yml | 1 + .../petstore/python-lazyImports/.github/workflows/python.yml | 1 + .../openapi3/client/petstore/python/.github/workflows/python.yml | 1 + 10 files changed, 10 insertions(+) diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.github/workflows/python.yml b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.github/workflows/python.yml index e394798c323b..155511037cb0 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.github/workflows/python.yml +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/.github/workflows/python.yml @@ -12,6 +12,7 @@ permissions: jobs: build: + runs-on: ubuntu-latest strategy: matrix: diff --git a/samples/client/echo_api/python/.github/workflows/python.yml b/samples/client/echo_api/python/.github/workflows/python.yml index e394798c323b..155511037cb0 100644 --- a/samples/client/echo_api/python/.github/workflows/python.yml +++ b/samples/client/echo_api/python/.github/workflows/python.yml @@ -12,6 +12,7 @@ permissions: jobs: build: + runs-on: ubuntu-latest strategy: matrix: diff --git a/samples/client/others/python-legacy-model-dictionaries/.github/workflows/python.yml b/samples/client/others/python-legacy-model-dictionaries/.github/workflows/python.yml index cc913fc57a22..340f4e5b2a15 100644 --- a/samples/client/others/python-legacy-model-dictionaries/.github/workflows/python.yml +++ b/samples/client/others/python-legacy-model-dictionaries/.github/workflows/python.yml @@ -12,6 +12,7 @@ permissions: jobs: build: + runs-on: ubuntu-latest strategy: matrix: diff --git a/samples/openapi3/client/petstore/python-aiohttp/.github/workflows/python.yml b/samples/openapi3/client/petstore/python-aiohttp/.github/workflows/python.yml index 57f8c91abb46..8111d2dfb97a 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python-aiohttp/.github/workflows/python.yml @@ -12,6 +12,7 @@ permissions: jobs: build: + runs-on: ubuntu-latest strategy: matrix: diff --git a/samples/openapi3/client/petstore/python-httpx-sync/.github/workflows/python.yml b/samples/openapi3/client/petstore/python-httpx-sync/.github/workflows/python.yml index 57f8c91abb46..8111d2dfb97a 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python-httpx-sync/.github/workflows/python.yml @@ -12,6 +12,7 @@ permissions: jobs: build: + runs-on: ubuntu-latest strategy: matrix: diff --git a/samples/openapi3/client/petstore/python-httpx/.github/workflows/python.yml b/samples/openapi3/client/petstore/python-httpx/.github/workflows/python.yml index 57f8c91abb46..8111d2dfb97a 100644 --- a/samples/openapi3/client/petstore/python-httpx/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python-httpx/.github/workflows/python.yml @@ -12,6 +12,7 @@ permissions: jobs: build: + runs-on: ubuntu-latest strategy: matrix: diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/.github/workflows/python.yml b/samples/openapi3/client/petstore/python-httpx2-sync/.github/workflows/python.yml index 57f8c91abb46..8111d2dfb97a 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python-httpx2-sync/.github/workflows/python.yml @@ -12,6 +12,7 @@ permissions: jobs: build: + runs-on: ubuntu-latest strategy: matrix: diff --git a/samples/openapi3/client/petstore/python-httpx2/.github/workflows/python.yml b/samples/openapi3/client/petstore/python-httpx2/.github/workflows/python.yml index 57f8c91abb46..8111d2dfb97a 100644 --- a/samples/openapi3/client/petstore/python-httpx2/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python-httpx2/.github/workflows/python.yml @@ -12,6 +12,7 @@ permissions: jobs: build: + runs-on: ubuntu-latest strategy: matrix: diff --git a/samples/openapi3/client/petstore/python-lazyImports/.github/workflows/python.yml b/samples/openapi3/client/petstore/python-lazyImports/.github/workflows/python.yml index 57f8c91abb46..8111d2dfb97a 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python-lazyImports/.github/workflows/python.yml @@ -12,6 +12,7 @@ permissions: jobs: build: + runs-on: ubuntu-latest strategy: matrix: diff --git a/samples/openapi3/client/petstore/python/.github/workflows/python.yml b/samples/openapi3/client/petstore/python/.github/workflows/python.yml index 57f8c91abb46..8111d2dfb97a 100644 --- a/samples/openapi3/client/petstore/python/.github/workflows/python.yml +++ b/samples/openapi3/client/petstore/python/.github/workflows/python.yml @@ -12,6 +12,7 @@ permissions: jobs: build: + runs-on: ubuntu-latest strategy: matrix: