docs: lead README Quick Start with Pydantic models and drop redundant route/method - #290
Merged
Merged
Conversation
…ate discrete params Resolve three related registry/decorator issues: - #279: Introduce canonical_function_id() (module.qualname via inspect.unwrap) so decorator and bridge agree on function identity. Bridge lookup now prefers find_by_function_id(), falls back to endpoint key, and only uses short-name matching when unambiguous (warns otherwise). - #284: OpenAPIRegistry.set/setdefault/get now acquire the internal RLock themselves, making mutators self-locking and safe within outer transactions. - #285: @openapi emits DeprecationWarning when discrete request_model/ request_body/response_model/response params are used, steering callers to the unified requests=/responses= API. Adds tests/test_registry_identity.py and tests/test_deprecation.py. Coverage 96.17% (>= 95% gate). Closes #279 Closes #284 Closes #285
Addresses review on #286: - Emit the discrete-parameter DeprecationWarning only after the mixed-style ValueError checks, so callers who pass both unified and discrete params get the error without a spurious deprecation warning. - Format the deprecated parameter names as a comma-separated string instead of a Python list repr for readability. - Document the registry key shape (short-name + fully-qualified id on name collisions) in docs/troubleshooting.md so get_openapi_registry() consumers are not surprised on upgrade.
… route/method Rewrite the Quick Start and Before/After examples to showcase the recommended request_model=/response_model= path instead of hand-written raw JSON Schema dicts. The @openapi decorator already infers route and method from the adjacent @app.route binding, so those arguments (and the optional @app.function_name noise) are removed from the headline example. The raw JSON Schema path is preserved in a collapsible Advanced section, with a note that Pydantic v2 is optional. Closes #289
…anslations Address review feedback: - Note in the Quick Start handler that @openapi documents the contract but does not perform runtime validation (points to azure-functions-validation), resolving the confusion of models being defined but not used to parse input. - Add an 'outdated translation' banner to README.ko/ja/zh-CN pointing readers to the canonical English README until translations are synced.
Keep the Quick Start headline focused on the @openapi decorator (the 'aha' moment) by moving the openapi.json / openapi.yaml / docs route registration into a collapsible <details> block. The wiring stays fully visible on click. Also fix a lost indentation on the handler's req.get_json() line.
There was a problem hiding this comment.
Pull request overview
This PR updates the documentation examples to lead with Pydantic models, but it also introduces runtime behavior changes in the OpenAPI registry/bridge/decorator layers (plus new tests) around validation-metadata versioning, registry identity, locking, and parameter deprecations.
Changes:
- Refresh README Quick Start and “✅ With” snippets to showcase
request_model=/response_model=Pydantic usage, and reorganize advanced raw-JSON-Schema examples into<details>sections. - Add a read-side validation metadata contract module and update bridge logic to read nested
validation.versionand merge discovered metadata into the correct registry entry (canonical identity / endpoint / guarded short-name fallback). - Harden registry behavior with internal locking for mutators/accessors, canonical callable identity (
module.qualname), and add tests covering deprecation warnings, identity collisions, and nested version gating.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
README.md |
Reworks headline examples to lead with Pydantic models; moves raw-schema path into an “Advanced” <details> block; keeps wiring endpoints visible. |
README.ja.md |
Adds “translation may be out of date” warning pointing to README.md. |
README.ko.md |
Adds “translation may be out of date” warning pointing to README.md. |
README.zh-CN.md |
Adds “translation may be out of date” warning pointing to README.md. |
docs/troubleshooting.md |
Documents registry key behavior in name-collision scenarios. |
src/azure_functions_openapi/_validation_contract.py |
Introduces a TypedDict-based mirror of the validation metadata namespace contract. |
src/azure_functions_openapi/bridge.py |
Switches to nested validation.version gating and canonical identity-based merge logic for discovered validation metadata. |
src/azure_functions_openapi/decorator.py |
Adds deprecation warnings for discrete request/response params and records canonical _function_id for entries. |
src/azure_functions_openapi/registry.py |
Adds locking to accessors/mutators, identity-based lookup helpers, and a canonical callable identity helper. |
tests/test_bridge.py |
Updates/extends version-gating tests to match nested validation.version payloads and adds regression coverage. |
tests/test_deprecation.py |
Adds tests asserting deprecation warnings for discrete parameters and equivalence with unified parameters. |
tests/test_registry_identity.py |
Adds tests for canonical identity collisions and registry locking/merge behavior. |
tests/test_validation_contract.py |
Adds tests for validation contract constants and basic TypedDict shape. |
Comment on lines
+10
to
18
| from azure_functions_openapi._validation_contract import ( | ||
| HANDLER_METADATA_ATTR, | ||
| SUPPORTED_VALIDATION_VERSIONS, | ||
| VALIDATION_NAMESPACE, | ||
| ) | ||
| from azure_functions_openapi.decorator import register_openapi_metadata | ||
| from azure_functions_openapi.exceptions import OpenAPISpecConfigError | ||
| from azure_functions_openapi.registry import registry | ||
| from azure_functions_openapi.registry import canonical_function_id, registry | ||
| from azure_functions_openapi.routes import DEFAULT_ROUTE_PREFIX, normalize_route_prefix |
Comment on lines
+142
to
+145
| target = inspect.unwrap(handler) if callable(handler) else handler | ||
| module = getattr(target, "__module__", "") or "" | ||
| qualname = getattr(target, "__qualname__", None) or getattr(target, "__name__", "") or "" | ||
| return f"{module}.{qualname}" |
Comment on lines
+29
to
+40
| class _ValidationMetadataRequired(TypedDict): | ||
| """Keys present on every validation payload.""" | ||
|
|
||
| version: int | ||
|
|
||
|
|
||
| class ValidationMetadata(_ValidationMetadataRequired, total=False): | ||
| """The ``validation`` namespace payload read from ``HANDLER_METADATA_ATTR``. | ||
|
|
||
| ``body``/``query``/``path``/``headers``/``response_model`` carry user-defined | ||
| Pydantic model classes (or ``None``), hence ``Any``. | ||
| """ |
6 tasks
Answer the reader's immediate 'do I need Pydantic?' question right after the headline example, before the collapsed spec/Swagger UI wiring.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
request_model=/response_model=Pydantic path instead of hand-written raw JSON Schema dicts.route=/method=from@openapi(...)(the decorator already infers them from the adjacent@app.routebinding via_extract_binding_hints()) and remove the optional@app.function_name(...)noise from the headline handler.openapi_json/openapi_yaml/swagger_uiregistration functions visible so the real wiring stays clear.<details>section and add a note that Pydantic v2 is optional.README-only; no code changes.
Closes #289