From 9dbf25bb625d608e957af9159dcebc6bd9f6a374 Mon Sep 17 00:00:00 2001 From: Dylan Tack Date: Mon, 1 Dec 2025 14:00:27 -0800 Subject: [PATCH] accomodate type changes in werkzeug 3.1.4 --- openapi_core/datatypes.py | 6 +++++- openapi_core/protocols.py | 8 +++++++- openapi_core/validation/response/validators.py | 7 ++++--- poetry.lock | 14 +++++++------- pyproject.toml | 4 +--- 5 files changed, 24 insertions(+), 15 deletions(-) diff --git a/openapi_core/datatypes.py b/openapi_core/datatypes.py index 38746aff..12ffcbba 100644 --- a/openapi_core/datatypes.py +++ b/openapi_core/datatypes.py @@ -6,10 +6,14 @@ from dataclasses import field from typing import Any from typing import Mapping +from typing import Union from werkzeug.datastructures import Headers from werkzeug.datastructures import ImmutableMultiDict +# Type alias for headers that accepts both Mapping and werkzeug Headers +HeadersType = Union[Mapping[str, Any], Headers] + @dataclass class RequestParameters: @@ -27,7 +31,7 @@ class RequestParameters: """ query: Mapping[str, Any] = field(default_factory=ImmutableMultiDict) - header: Mapping[str, Any] = field(default_factory=Headers) + header: HeadersType = field(default_factory=Headers) cookie: Mapping[str, Any] = field(default_factory=ImmutableMultiDict) path: Mapping[str, Any] = field(default_factory=dict) diff --git a/openapi_core/protocols.py b/openapi_core/protocols.py index 160354f3..0397956d 100644 --- a/openapi_core/protocols.py +++ b/openapi_core/protocols.py @@ -4,10 +4,16 @@ from typing import Mapping from typing import Optional from typing import Protocol +from typing import Union from typing import runtime_checkable +from werkzeug.datastructures import Headers + from openapi_core.datatypes import RequestParameters +# Type alias for headers that accepts both Mapping and werkzeug Headers +HeadersType = Union[Mapping[str, Any], Headers] + @runtime_checkable class BaseRequest(Protocol): @@ -109,7 +115,7 @@ def content_type(self) -> str: """The content type with parameters and always lowercase.""" @property - def headers(self) -> Mapping[str, Any]: + def headers(self) -> HeadersType: """Response headers as Headers.""" @property diff --git a/openapi_core/validation/response/validators.py b/openapi_core/validation/response/validators.py index cd4d4350..b600d996 100644 --- a/openapi_core/validation/response/validators.py +++ b/openapi_core/validation/response/validators.py @@ -15,6 +15,7 @@ from openapi_core.casting.schemas import oas30_read_schema_casters_factory from openapi_core.casting.schemas import oas31_schema_casters_factory from openapi_core.exceptions import OpenAPIError +from openapi_core.protocols import HeadersType from openapi_core.protocols import Request from openapi_core.protocols import Response from openapi_core.protocols import WebhookRequest @@ -44,7 +45,7 @@ def _iter_errors( self, status_code: int, data: Optional[bytes], - headers: Mapping[str, Any], + headers: HeadersType, mimetype: str, operation: SchemaPath, ) -> Iterator[Exception]: @@ -91,7 +92,7 @@ def _iter_data_errors( def _iter_headers_errors( self, status_code: int, - headers: Mapping[str, Any], + headers: HeadersType, operation: SchemaPath, ) -> Iterator[Exception]: try: @@ -141,7 +142,7 @@ def _get_data_value(self, data: Optional[bytes]) -> bytes: return data def _get_headers( - self, headers: Mapping[str, Any], operation_response: SchemaPath + self, headers: HeadersType, operation_response: SchemaPath ) -> Dict[str, Any]: if "headers" not in operation_response: return {} diff --git a/poetry.lock b/poetry.lock index 3c42f013..821d0408 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand. [[package]] name = "aiohappyeyeballs" @@ -2730,18 +2730,18 @@ testing = ["coverage", "pytest (>=3.1.0)", "pytest-cov", "pytest-xdist"] [[package]] name = "werkzeug" -version = "3.0.6" +version = "3.1.4" description = "The comprehensive WSGI web application library." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["main", "dev"] files = [ - {file = "werkzeug-3.0.6-py3-none-any.whl", hash = "sha256:1bc0c2310d2fbb07b1dd1105eba2f7af72f322e1e455f2f93c993bee8c8a5f17"}, - {file = "werkzeug-3.0.6.tar.gz", hash = "sha256:a8dd59d4de28ca70471a34cba79bed5f7ef2e036a76b3ab0835474246eb41f8d"}, + {file = "werkzeug-3.1.4-py3-none-any.whl", hash = "sha256:2ad50fb9ed09cc3af22c54698351027ace879a0b60a3b5edf5730b2f7d876905"}, + {file = "werkzeug-3.1.4.tar.gz", hash = "sha256:cd3cd98b1b92dc3b7b3995038826c68097dcb16f9baa63abe35f20eafeb9fe5e"}, ] [package.dependencies] -MarkupSafe = ">=2.1.1" +markupsafe = ">=2.1.1" [package.extras] watchdog = ["watchdog (>=2.3)"] @@ -2872,4 +2872,4 @@ starlette = ["aioitertools", "starlette"] [metadata] lock-version = "2.1" python-versions = "^3.9.0" -content-hash = "e65afc8fd5e0b210f7ad24da23b3321d7c9cd76cc8a81d7672d336668fbead0c" +content-hash = "85d4f608bc5c8d49dba112249b81e33f17527ca02389d331cee92bbe8d00188d" diff --git a/pyproject.toml b/pyproject.toml index 4621aaa7..9e5ecb3a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,9 +71,7 @@ parse = "*" openapi-schema-validator = "^0.6.0" openapi-spec-validator = "^0.7.1" requests = {version = "*", optional = true} -# werkzeug 3.1.2 changed the definition of Headers -# See https://github.com/python-openapi/openapi-core/issues/938 -werkzeug = "<3.1.2" +werkzeug = ">=2.1.0" jsonschema-path = "^0.3.4" jsonschema = "^4.23.0" multidict = {version = "^6.0.4", optional = true}