fix(response): ASGIStreamingResponse headers accept iterable of tuples#4810
Open
trippusultan wants to merge 5 commits into
Open
fix(response): ASGIStreamingResponse headers accept iterable of tuples#4810trippusultan wants to merge 5 commits into
trippusultan wants to merge 5 commits into
Conversation
Add support for JSON Schema 2020-12's `$dynamicRef` and `$dynamicAnchor` keywords to the `Schema` dataclass, completing Litestar's OAS 3.1 schema vocabulary coverage. These keywords enable dynamic schema composition, allowing schemas to reference anchors defined in other schemas at runtime. Co-Authored-By: Claude Opus 4.5 <<EMAIL>>
…uples Update ASGIStreamingResponse.__init__ and Stream.to_asgi_response to accept Iterable[tuple[str, str]] in addition to dict[str, Any] for the headers parameter, matching the type signature of the base ASGIResponse class. This allows users to set repeated HTTP headers (e.g. multiple Set-Cookie headers) on streaming responses. Co-Authored-By: Claude Opus 4.5 <<EMAIL>>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4810 +/- ##
==========================================
- Coverage 67.28% 67.25% -0.03%
==========================================
Files 292 292
Lines 15164 15170 +6
Branches 1710 1711 +1
==========================================
Hits 10203 10203
- Misses 4819 4824 +5
- Partials 142 143 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
| discouraged, and later versions of this specification may remove it. | ||
| """ | ||
|
|
||
| dynamic_ref: str | None = field(default=None, metadata={"alias": "$dynamicRef"}) |
Member
There was a problem hiding this comment.
This has nothing to do with headers
provinzkraut
requested changes
Jun 9, 2026
Comment on lines
+779
to
+831
| def test_schema_dynamic_ref_and_anchor() -> None: | ||
| """Test that Schema supports $dynamicRef and $dynamicAnchor fields.""" | ||
| schema = Schema( | ||
| type=OpenAPIType.OBJECT, | ||
| dynamic_ref="#/components/schemas/Pet", | ||
| dynamic_anchor="petAnchor", | ||
| ) | ||
|
|
||
| assert schema.dynamic_ref == "#/components/schemas/Pet" | ||
| assert schema.dynamic_anchor == "petAnchor" | ||
|
|
||
| # Test serialization to dict | ||
| schema_dict = schema.to_schema() | ||
| assert schema_dict["$dynamicRef"] == "#/components/schemas/Pet" | ||
| assert schema_dict["$dynamicAnchor"] == "petAnchor" | ||
|
|
||
|
|
||
| def test_schema_dynamic_ref_and_anchor_optional() -> None: | ||
| """Test that dynamic_ref and dynamic_anchor are optional.""" | ||
| schema = Schema(type=OpenAPIType.STRING) | ||
|
|
||
| assert schema.dynamic_ref is None | ||
| assert schema.dynamic_anchor is None | ||
|
|
||
| schema_dict = schema.to_schema() | ||
| assert "$dynamicRef" not in schema_dict | ||
| assert "$dynamicAnchor" not in schema_dict | ||
|
|
||
|
|
||
| def test_schema_dynamic_ref_and_anchor_with_other_fields() -> None: | ||
| """Test that dynamic_ref and dynamic_anchor work with other schema fields.""" | ||
| schema = Schema( | ||
| type=OpenAPIType.OBJECT, | ||
| title="TestSchema", | ||
| description="A test schema", | ||
| dynamic_ref="#/components/schemas/Base", | ||
| dynamic_anchor="testAnchor", | ||
| properties={"name": Schema(type=OpenAPIType.STRING)}, | ||
| required=["name"], | ||
| ) | ||
|
|
||
| assert schema.dynamic_ref == "#/components/schemas/Base" | ||
| assert schema.dynamic_anchor == "testAnchor" | ||
| assert schema.title == "TestSchema" | ||
| assert schema.description == "A test schema" | ||
|
|
||
| schema_dict = schema.to_schema() | ||
| assert schema_dict["$dynamicRef"] == "#/components/schemas/Base" | ||
| assert schema_dict["$dynamicAnchor"] == "testAnchor" | ||
| assert schema_dict["title"] == "TestSchema" | ||
| assert schema_dict["description"] == "A test schema" | ||
| assert "name" in schema_dict.get("properties", {}) | ||
| assert schema_dict.get("required") == ["name"] |
Member
There was a problem hiding this comment.
This has nothing to do with the PR
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
Updates
ASGIStreamingResponseto acceptIterable[tuple[str, str]]in addition todict[str, Any]for theheadersparameter, matching the type signature of the baseASGIResponseclass.Previously,
ASGIStreamingResponse.__init__only accepteddict[str, Any], while its parent classASGIResponseaccepteddict[str, Any] | Iterable[tuple[str, str]]. This inconsistency prevented users from setting repeated HTTP headers (e.g. multipleSet-Cookieheaders) on streaming responses.Changes
ASGIStreamingResponse.__init__type signature to match base classStream.to_asgi_responseto handle both dict and iterable headersTests
All 308 response and OpenAPI tests pass:
Fixes #4780