Skip to content

fix(python-flask, python-aiohttp): generate valid security function names for scheme names with '-' or '.' - #25458

Open
khayashi4337 wants to merge 4 commits into
OpenAPITools:masterfrom
khayashi4337:fix/python-connexion-security-function-names
Open

khayashi4337 wants to merge 4 commits into
OpenAPITools:masterfrom
khayashi4337:fix/python-connexion-security-function-names

Conversation

@khayashi4337

@khayashi4337 khayashi4337 commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Security scheme names may contain - and .: OpenAPI component keys match ^[a-zA-Z0-9\.\-_]+$. The generated python-flask / python-aiohttp security_controller.py uses the name verbatim in function names, and the x-*InfoFunc extensions in the generated openapi.yaml point at the same names. For example, with a scheme named api-key:

def info_from_api-key(api_key, required_scopes):   # SyntaxError

The module doesn't compile, so the generated app can't start. I didn't find an existing issue for this.

Changes

  • Each scheme name gets one Python identifier suffix, computed once in preprocessOpenAPI, in spec order. Characters other than [A-Za-z0-9_] become _. Names that would collide (e.g. api-key and api.key) are numbered _2, _3, and so on.
  • addSecurityExtensions (x-apikeyInfoFunc, x-basicInfoFunc, x-bearerInfoFunc, x-tokenInfoFunc, x-scopeValidateFunc) and the security_controller.mustache templates both use that suffix. The templates get it through a fromSecurity override that sets x-python-connexion-security-function-suffix.
  • Names that are already valid identifiers produce exactly the same output as before. User-provided x-*InfoFunc extensions are kept.

Verification

  • Python*Test / AbstractPython*Test pass. The new test covers python-flask, python-flask with useConnexion3, and python-aiohttp. It uses schemes api-key, petstore.auth (OAuth2), basic-auth, bearer-token, 1st-key, a literal api_key_2 next to the colliding api.key, and a scheme with a user-provided x-apikeyInfoFunc. It fails without the change.
  • I generated python-flask from that spec. All .py files pass compileall. On Connexion 2.14.2, every protected operation (apiKey, basic, bearer, OAuth2, the colliding and the user-provided ones) returns 401 without credentials and 200 with them. With the generator from master, the same project doesn't compile. A second review also exercised Connexion 3.3.0 and aiohttp.
  • bin/generate-samples.sh bin/configs/python*.yaml produces no diff.

Note: #25457 also overrides fromSecurity in the same class. Whichever lands second needs the two bodies merged into one override.

PR checklist

  • Read the contribution guidelines.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    Regenerated all bin/configs/python*.yaml samples: no diff. Generator options and docs are unchanged.
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

cc @cbornet @tomplus @krjakbrjak @fa0311 (Python technical committee)

Parts of this change were drafted with AI coding assistants (Devin, Claude Code, with reviews by Codex and Fable) and reviewed and verified by me.

🤖 Generated with Claude Code


Summary by cubic

Fixes generated python-flask and python-aiohttp apps failing to compile when a security scheme name contains - or . (e.g. api-key). Scheme names were used verbatim in security_controller.py function names and in the x-*InfoFunc/x-scopeValidateFunc references in the spec, producing invalid Python like def info_from_api-key(...).

Each scheme name now maps to a valid Python identifier suffix computed once per spec: non-[A-Za-z0-9_] characters become _, names that are already valid identifiers keep their unnumbered suffix, and sanitized names that would collide (e.g. api-key and api.key) get _2, _3, etc. Both the security_controller.mustache templates and the x-*Func extensions use the same suffix via a fromSecurity override, and user-provided x-*InfoFunc extensions are preserved.

The new test parses the generated openapi.yaml and asserts each x-*Func reference points at the matching generated function, covering python-flask, python-flask with useConnexion3, and python-aiohttp; generated samples are unchanged. Note: #25457 also overrides fromSecurity in the same class — whichever lands second must merge the two method bodies.

Written for commit 956dcb6. Summary will update on new commits.

View guided diff

…ames for scheme names with '-' or '.'

Security scheme names may contain '-' and '.' (component keys match
^[a-zA-Z0-9.\-_]+$), but the generated security_controller.py used them
verbatim in function names, e.g. 'def info_from_api-key(', and the
x-apikeyInfoFunc / x-basicInfoFunc / x-bearerInfoFunc / x-tokenInfoFunc /
x-scopeValidateFunc extensions pointed at the same invalid names. The
module didn't compile, so the app couldn't start.

Each scheme name now gets one Python identifier suffix, computed once in
preprocessOpenAPI in spec order: characters other than [A-Za-z0-9_]
become '_', and names that would collide (e.g. 'api-key' and 'api.key')
are numbered (_2, _3, ...). Both addSecurityExtensions and the
security_controller templates use it, the latter through a fromSecurity
override that sets x-python-connexion-security-function-suffix. Names
that are already valid identifiers produce exactly the same output as
before, and user-provided x-*InfoFunc extensions are kept.

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 5 files

Reply with feedback, questions, or to request a fix.

View guided diff | Re-trigger cubic

khayashi4337 and others added 2 commits October 29, 2026 16:40
…ion-security-function-names

# Conflicts:
#	modules/openapi-generator/src/test/java/org/openapitools/codegen/python/AbstractPythonConnexionServerCodegenTest.java
… already-valid security scheme names

Reserve the security function name suffix of scheme names that are already
valid Python identifiers before numbering the names that need character
replacement. Previously suffixes were assigned purely in spec order, so a
sanitized name like "api-key" -> "api_key" claimed the suffix first and
"api_key" listed after it was bumped to "api_key_2" (and a literal
"api_key_2" to "api_key_2_2"), changing the generated output for names that
were already valid.

Also make testSecuritySchemeNamesProduceValidPythonFunctions parse the
generated openapi.yaml and assert, per scheme, that each x-*Func extension
points at the expected function defined in security_controller.py, instead
of only checking that the reference strings occur somewhere in the file.
Add an "api_key" scheme listed after "api-key" to the fixture to cover the
ordering regression.

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 3 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

View guided diff | Re-trigger cubic

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant