fix(python-aiohttp): don't clash the Connexion context argument with a parameter named 'request'
Generated python-aiohttp apps register the API with pass_context_arg_name='request', and every handler takes the aiohttp request as its first argument request. A parameter whose handler argument name is also request breaks this:
async def list_things(request: web.Request, request=None) -> web.Response: # SyntaxError: duplicate argument
The app doesn't start. Even if it compiled, Connexion sets kwargs[pass_context_arg_name] after the parameters, so the parameter value would be overwritten by the request context. I didn't find an existing issue for this.
Changes
- The context argument name is computed once for the whole spec in
preprocessOpenAPI.add_apiis called once, and__init__.py,tests/conftest.pyand every controller must use the same name. - It stays
requestunless a handler argument would use that name. Then it becomesrequest_context, orrequest_context2,request_context3, ... if those are taken too. A warning is logged when this happens. - Handler argument names are collected the way the generator builds them:
- parameters, including path-level and
$ref'd ones; - the body argument name;
- form fields of the first content type, walking
allOf/$reflikefromRequestBodyToFormParameters; - across both
pathsandwebhooks; - including the numbers
DefaultCodegenappends to duplicate parameter names.
- parameters, including path-level and
- The templates (
__init__main.mustache,conftest.mustache,controller.mustache, including the.headers/.cookiesreads) take the name from theconnexionContextArgNameadditional property. - Specs without such a parameter generate exactly the same output as before.
Why rename the context argument instead of the parameter: Connexion derives the keyword it passes from the wire name, and the generated openapi.yaml keeps the original names. So the generator cannot choose a different handler argument name for the parameter. The context argument name, on the other hand, is ours to pick.
Verification
-
Python*Test/AbstractPython*Testpass (177). The new tests cover:- a query
request; requesttogether withrequest_context(givesrequest_context2);- duplicate names that
DefaultCodegenrenumbers (givesrequest_context3); - a multipart form field
requestinsideallOf; - an OAS 3.1 webhook with
request; - a spec without
request(staysrequest).
They fail without the change.
- a query
-
I generated python-aiohttp from those specs and from petstore. All
.pyfiles passcompileall. On Connexion 2.14.2,GET /v1/things?request=abcwithX-Trace: treturns 200 and the handler receivesrequest='abc'and the header value. The generatedtests/pass. With the generator from master, the same project doesn't compile. -
bin/generate-samples.sh bin/configs/python*.yamlproduces no diff.
Known limitations (unchanged by this PR):
- Names that Connexion and the generator convert differently, e.g.
re.quest, are not detected. Connexion'spythonic()givesrequest; the generator givesre_quest. That mismatch exists independently of this change. - Other arguments Connexion injects, such as
user/token_info, are out of scope here.
PR checklist
- Read the contribution guidelines.
- Run the following to build the project and update samples:
Regenerated all./mvnw clean package || exit ./bin/generate-samples.sh ./bin/configs/*.yaml || exit ./bin/utils/export_docs_generators.sh || exitbin/configs/python*.yamlsamples: 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 python-aiohttp generated apps becoming uncompilable when a spec has a parameter whose handler argument name is request. The Connexion context argument is now renamed to request_context (or request_context2, etc. if that is taken too), so generated handlers compile and the parameter value is no longer overwritten by the request context.
Details
- The context argument name is resolved once for the whole spec and shared by the templates via the
connexionContextArgNameadditional property. - Collision detection covers parameters (including path-level and
$ref'd ones), body argument names, form fields in composed schemas, webhooks, and duplicate-name renumbering. - Specs without a conflicting parameter generate identical output to before.