fix(python): generate valid code for webhooks with parameters

KH
3d ago
+351-65

Python generators render webhooks through the same api.mustache templates as normal operations, but DefaultGenerator calls postProcessWebhooksWithModels for webhooks, while the Python codegens only computed parameter typing (x-py-typing) and their imports in postProcessOperationsWithModels. As a result, any webhook with parameters produced invalid Python. Reproduced with the released openapi-generator-cli 7.26.0:

openapi: 3.1.0
info: {title: wh, version: '1'}
paths: {}
webhooks:
  itemEvent:
    post:
      operationId: itemEventPost
      tags: [hooks]
      parameters:
        - {name: filter, in: query, required: true, schema: {type: string}}
      responses: {'200': {description: ok}}

-g python emits filter: , in hooks_api.py (SyntaxError: invalid syntax); python-fastapi and python-pydantic-v1 fail the same way.

Changes

  • AbstractPythonCodegen, AbstractPythonPydanticV1Codegen: the per-operation post-processing is extracted into postProcessOperationsAndBuildImports(OperationMap) and is also called from a new postProcessWebhooksWithModels.
  • PythonClientCodegen: the JSON header flag (x-python-has-json-header, which emits import json) and the useIndependentImplicitClients member renaming now apply to webhooks too (a webhook named close no longer overrides the lifecycle close()).
  • PythonFastAPIServerCodegen: security imports, UploadFile typing and request-body examples now apply to webhooks. Request-body examples are read from the operation's vendor extensions, so a webhook and a path with the same name each keep their own example.
  • AbstractPythonConnexionServerCodegen, PythonFlaskConnexionServerCodegen (python-flask/aiohttp/blueplanet): webhooks run the Connexion processing instead of inheriting the Pydantic import replacement. These servers do not depend on pydantic, so their webhook controllers must not import it.

Generated output for normal (non-webhook) operations is unchanged: bin/generate-samples.sh bin/configs/python*.yaml produces no diff, and a normal API file generated by this branch is byte-identical to the 7.26.0 output.

Tests

  • src/test/resources/3_1/python/webhooks.yaml (new spec): webhooks with a required query parameter, a JSON-content header, security, multipart binary, an operation named close, multiple response content types, and a webhook/path name collision with distinct request-body examples.
  • New tests in PythonClientCodegenTest, PythonFastAPIServerCodegenTest, PythonFlaskConnexionServerCodegenTest (Connexion 2 default and Connexion 3) and PythonPydanticV1ClientCodegenTest. Each was checked to fail without its fix.
  • With this spec and a wider one, every generated .py from python, python-fastapi and python-pydantic-v1 passes python3 -m py_compile (7.26.0: 1–2 files fail per generator).

Known limitations (not changed here)

  • python-aiohttp / python-blueplanet emit x_json_arg = .from_dict(...) for a header parameter defined with content + $ref. This also happens for normal path operations in 7.26.0, so it is not webhook-specific.
  • When a path operation and a webhook share a tag, both are written to the same API file and the webhook overwrites the path file (FILEPATH_COLLISION). This is generator-independent.

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
    
    Ran ./mvnw -pl modules/openapi-generator test (5513 tests, 0 failures), ./bin/generate-samples.sh bin/configs/python*.yaml (the only generators touched) and ./bin/utils/export_docs_generators.sh; neither produced changed files.
  • 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) and reviewed and verified by me.

šŸ¤– Generated with Claude Code


Summary by cubic

Fixes Python generators emitting invalid code (e.g. filter: ,) for webhooks with parameters. The per-operation typing and import post-processing that only ran for normal operations now also runs for webhooks in python, python-fastapi, python-pydantic-v1, python-flask, python-aiohttp, and python-blueplanet; normal path operations are byte-identical to previous output.

  • Webhooks now get parameter typing, model imports, JSON-header imports, and independent-client method renaming (a webhook named close no longer overrides the lifecycle close()).
  • FastAPI webhooks receive security imports, UploadFile typing, and their own request-body examples; example lookup no longer collides with identically named path operations.
  • Connexion server generators no longer import Pydantic into webhook controllers.
  • Adds a regression spec and tests covering typed parameters, security, multipart binary, JSON-header deserialization, name collisions, and Connexion 3 skip markers.