diff --git a/openapi_core/casting/schemas/exceptions.py b/openapi_core/casting/schemas/exceptions.py index cc10672a..aa50b3f9 100644 --- a/openapi_core/casting/schemas/exceptions.py +++ b/openapi_core/casting/schemas/exceptions.py @@ -1,13 +1,13 @@ -import attr +from dataclasses import dataclass from openapi_core.exceptions import OpenAPIError -@attr.s(hash=True) +@dataclass class CastError(OpenAPIError): """Schema cast operation error""" - value = attr.ib() - type = attr.ib() + value: str + type: str def __str__(self): return "Failed to cast value {value} to type {type}".format( diff --git a/openapi_core/contrib/django/requests.py b/openapi_core/contrib/django/requests.py index b8624bd6..d067ce55 100644 --- a/openapi_core/contrib/django/requests.py +++ b/openapi_core/contrib/django/requests.py @@ -1,8 +1,9 @@ """OpenAPI core contrib django requests module""" import re - from urllib.parse import urljoin +from werkzeug.datastructures import ImmutableMultiDict, Headers + from openapi_core.contrib.django.compat import ( get_request_headers, get_current_scheme_host, ) @@ -43,13 +44,16 @@ def create(cls, request): route = route[:-1] path_pattern = '/' + route + request_headers = get_request_headers(request) path = request.resolver_match and request.resolver_match.kwargs or {} - headers = get_request_headers(request) + query = ImmutableMultiDict(request.GET) + header = Headers(request_headers.items()) + cookie = ImmutableMultiDict(dict(request.COOKIES)) parameters = RequestParameters( path=path, - query=request.GET, - header=list(headers.items()), - cookie=request.COOKIES, + query=query, + header=header, + cookie=cookie, ) current_scheme_host = get_current_scheme_host(request) full_url_pattern = urljoin(current_scheme_host, path_pattern) diff --git a/openapi_core/contrib/django/responses.py b/openapi_core/contrib/django/responses.py index d0e75f79..d32c7566 100644 --- a/openapi_core/contrib/django/responses.py +++ b/openapi_core/contrib/django/responses.py @@ -1,4 +1,6 @@ """OpenAPI core contrib django responses module""" +from werkzeug.datastructures import Headers + from openapi_core.contrib.django.compat import get_response_headers from openapi_core.validation.response.datatypes import OpenAPIResponse @@ -9,9 +11,10 @@ class DjangoOpenAPIResponseFactory: def create(cls, response): mimetype = response["Content-Type"] headers = get_response_headers(response) + header = Headers(headers.items()) return OpenAPIResponse( data=response.content, status_code=response.status_code, - headers=list(headers.items()), + headers=header, mimetype=mimetype, ) diff --git a/openapi_core/contrib/falcon/requests.py b/openapi_core/contrib/falcon/requests.py index 27a5faba..9f6b5292 100644 --- a/openapi_core/contrib/falcon/requests.py +++ b/openapi_core/contrib/falcon/requests.py @@ -1,7 +1,7 @@ """OpenAPI core contrib falcon responses module""" from json import dumps -from werkzeug.datastructures import ImmutableMultiDict +from werkzeug.datastructures import ImmutableMultiDict, Headers from openapi_core.contrib.falcon.compat import get_request_media from openapi_core.validation.request.datatypes import ( @@ -29,11 +29,12 @@ def create(cls, request, default_when_empty={}): mimetype = request.content_type.partition(";")[0] query = ImmutableMultiDict(list(request.params.items())) + header = Headers(request.headers) # Path gets deduced by path finder against spec parameters = RequestParameters( query=query, - header=request.headers, + header=header, cookie=request.cookies, ) url_pattern = request.prefix + request.path diff --git a/openapi_core/contrib/falcon/responses.py b/openapi_core/contrib/falcon/responses.py index b0477956..f99da684 100644 --- a/openapi_core/contrib/falcon/responses.py +++ b/openapi_core/contrib/falcon/responses.py @@ -1,4 +1,6 @@ """OpenAPI core contrib falcon responses module""" +from werkzeug.datastructures import Headers + from openapi_core.contrib.falcon.compat import get_response_text from openapi_core.validation.response.datatypes import OpenAPIResponse @@ -15,10 +17,11 @@ def create(cls, response): mimetype = response.options.default_media_type data = get_response_text(response) + headers = Headers(response.headers) return OpenAPIResponse( data=data, status_code=status_code, - headers=response.headers, + headers=headers, mimetype=mimetype, ) diff --git a/openapi_core/contrib/flask/requests.py b/openapi_core/contrib/flask/requests.py index 7b4ec3bf..6fb9f367 100644 --- a/openapi_core/contrib/flask/requests.py +++ b/openapi_core/contrib/flask/requests.py @@ -1,8 +1,9 @@ """OpenAPI core contrib flask requests module""" import re - from urllib.parse import urljoin +from werkzeug.datastructures import Headers + from openapi_core.validation.request.datatypes import ( RequestParameters, OpenAPIRequest, ) @@ -24,10 +25,11 @@ def create(cls, request): else: path_pattern = cls.path_regex.sub(r'{\1}', request.url_rule.rule) + header = Headers(request.headers) parameters = RequestParameters( path=request.view_args, query=request.args, - header=request.headers, + header=header, cookie=request.cookies, ) full_url_pattern = urljoin(request.host_url, path_pattern) diff --git a/openapi_core/contrib/flask/responses.py b/openapi_core/contrib/flask/responses.py index cb52f5c1..a36a36ac 100644 --- a/openapi_core/contrib/flask/responses.py +++ b/openapi_core/contrib/flask/responses.py @@ -1,4 +1,6 @@ """OpenAPI core contrib flask responses module""" +from werkzeug.datastructures import Headers + from openapi_core.validation.response.datatypes import OpenAPIResponse @@ -6,9 +8,10 @@ class FlaskOpenAPIResponseFactory: @classmethod def create(cls, response): + header = Headers(response.headers) return OpenAPIResponse( data=response.data, status_code=response._status_code, - headers=response.headers, + headers=header, mimetype=response.mimetype, ) diff --git a/openapi_core/contrib/requests/requests.py b/openapi_core/contrib/requests/requests.py index 49c74f5d..7f20f2b9 100644 --- a/openapi_core/contrib/requests/requests.py +++ b/openapi_core/contrib/requests/requests.py @@ -2,7 +2,7 @@ from urllib.parse import urlparse, parse_qs -from werkzeug.datastructures import ImmutableMultiDict +from werkzeug.datastructures import ImmutableMultiDict, Headers from requests import Request from openapi_core.validation.request.datatypes import ( @@ -43,9 +43,9 @@ def create(cls, request): mimetype = request.headers.get('Content-Type') or \ request.headers.get('Accept') - # Headers - request.headers is not an instance of dict + # Headers - request.headers is not an instance of Headers # which is expected - header = dict(request.headers) + header = Headers(dict(request.headers)) # Body # TODO: figure out if request._body_position is relevant diff --git a/openapi_core/contrib/requests/responses.py b/openapi_core/contrib/requests/responses.py index c7d3359e..47725a5e 100644 --- a/openapi_core/contrib/requests/responses.py +++ b/openapi_core/contrib/requests/responses.py @@ -1,4 +1,6 @@ """OpenAPI core contrib requests responses module""" +from werkzeug.datastructures import Headers + from openapi_core.validation.response.datatypes import OpenAPIResponse @@ -7,7 +9,7 @@ class RequestsOpenAPIResponseFactory: @classmethod def create(cls, response): mimetype = response.headers.get('Content-Type') - headers = dict(response.headers) + headers = Headers(dict(response.headers)) return OpenAPIResponse( data=response.content, status_code=response.status_code, diff --git a/openapi_core/deserializing/exceptions.py b/openapi_core/deserializing/exceptions.py index 2ff5774e..b8ae2ed3 100644 --- a/openapi_core/deserializing/exceptions.py +++ b/openapi_core/deserializing/exceptions.py @@ -1,13 +1,13 @@ -import attr +from dataclasses import dataclass from openapi_core.exceptions import OpenAPIError -@attr.s(hash=True) +@dataclass class DeserializeError(OpenAPIError): """Deserialize operation error""" - value = attr.ib() - style = attr.ib() + value: str + style: str def __str__(self): return "Failed to deserialize value {value} with style {style}".format( diff --git a/openapi_core/deserializing/parameters/exceptions.py b/openapi_core/deserializing/parameters/exceptions.py index 6187f2c0..0966d93e 100644 --- a/openapi_core/deserializing/parameters/exceptions.py +++ b/openapi_core/deserializing/parameters/exceptions.py @@ -1,11 +1,11 @@ -import attr +from dataclasses import dataclass from openapi_core.deserializing.exceptions import DeserializeError -@attr.s(hash=True) +@dataclass class EmptyParameterValue(DeserializeError): - name = attr.ib() + name: str def __str__(self): return "Value of parameter cannot be empty: {0}".format(self.name) diff --git a/openapi_core/exceptions.py b/openapi_core/exceptions.py index bdc5eba0..4fcf4d02 100644 --- a/openapi_core/exceptions.py +++ b/openapi_core/exceptions.py @@ -1,5 +1,8 @@ """OpenAPI core exceptions module""" -import attr +from dataclasses import dataclass + +from openapi_core.validation.request.datatypes import OpenAPIRequest +from openapi_core.validation.response.datatypes import OpenAPIResponse class OpenAPIError(Exception): @@ -15,18 +18,18 @@ class MissingHeaderError(OpenAPIHeaderError): pass -@attr.s(hash=True) +@dataclass class MissingHeader(MissingHeaderError): - name = attr.ib() + name: str def __str__(self): return "Missing header (without default value): {0}".format( self.name) -@attr.s(hash=True) +@dataclass class MissingRequiredHeader(MissingHeaderError): - name = attr.ib() + name: str def __str__(self): return "Missing required header: {0}".format(self.name) @@ -41,18 +44,18 @@ class MissingParameterError(OpenAPIParameterError): pass -@attr.s(hash=True) +@dataclass class MissingParameter(MissingParameterError): - name = attr.ib() + name: str def __str__(self): return "Missing parameter (without default value): {0}".format( self.name) -@attr.s(hash=True) +@dataclass class MissingRequiredParameter(MissingParameterError): - name = attr.ib() + name: str def __str__(self): return "Missing required parameter: {0}".format(self.name) @@ -67,17 +70,17 @@ class MissingRequestBodyError(OpenAPIRequestBodyError): pass -@attr.s(hash=True) +@dataclass class MissingRequestBody(MissingRequestBodyError): - request = attr.ib() + request: OpenAPIRequest def __str__(self): return "Missing request body" -@attr.s(hash=True) +@dataclass class MissingRequiredRequestBody(MissingRequestBodyError): - request = attr.ib() + request: OpenAPIRequest def __str__(self): return "Missing required request body" @@ -87,9 +90,9 @@ class OpenAPIResponseError(OpenAPIError): pass -@attr.s(hash=True) +@dataclass class MissingResponseContent(OpenAPIResponseError): - response = attr.ib() + response: OpenAPIResponse def __str__(self): return "Missing response content" diff --git a/openapi_core/templating/datatypes.py b/openapi_core/templating/datatypes.py index 0a03d15d..5aa62d49 100644 --- a/openapi_core/templating/datatypes.py +++ b/openapi_core/templating/datatypes.py @@ -1,10 +1,12 @@ -import attr +from typing import Dict, Optional +from dataclasses import dataclass -@attr.s + +@dataclass class TemplateResult: - pattern = attr.ib(default=None) - variables = attr.ib(default=None) + pattern: Optional[str] = None + variables: Optional[Dict] = None @property def resolved(self): diff --git a/openapi_core/templating/media_types/exceptions.py b/openapi_core/templating/media_types/exceptions.py index aa1240ca..03c429e1 100644 --- a/openapi_core/templating/media_types/exceptions.py +++ b/openapi_core/templating/media_types/exceptions.py @@ -1,4 +1,6 @@ -import attr +from typing import List + +from dataclasses import dataclass from openapi_core.exceptions import OpenAPIError @@ -7,10 +9,10 @@ class MediaTypeFinderError(OpenAPIError): """Media type finder error""" -@attr.s(hash=True) +@dataclass class MediaTypeNotFound(MediaTypeFinderError): - mimetype = attr.ib() - availableMimetypes = attr.ib() + mimetype: str + availableMimetypes: List[str] def __str__(self): return ( diff --git a/openapi_core/templating/paths/exceptions.py b/openapi_core/templating/paths/exceptions.py index 0ed2e7e4..615b9f5e 100644 --- a/openapi_core/templating/paths/exceptions.py +++ b/openapi_core/templating/paths/exceptions.py @@ -1,4 +1,4 @@ -import attr +from dataclasses import dataclass from openapi_core.exceptions import OpenAPIError @@ -7,30 +7,30 @@ class PathError(OpenAPIError): """Path error""" -@attr.s(hash=True) +@dataclass class PathNotFound(PathError): """Find path error""" - url = attr.ib() + url: str def __str__(self): return "Path not found for {0}".format(self.url) -@attr.s(hash=True) +@dataclass class OperationNotFound(PathError): """Find path operation error""" - url = attr.ib() - method = attr.ib() + url: str + method: str def __str__(self): return "Operation {0} not found for {1}".format( self.method, self.url) -@attr.s(hash=True) +@dataclass class ServerNotFound(PathError): """Find server error""" - url = attr.ib() + url: str def __str__(self): return "Server not found for {0}".format(self.url) diff --git a/openapi_core/templating/responses/exceptions.py b/openapi_core/templating/responses/exceptions.py index 3602ae63..1427efc9 100644 --- a/openapi_core/templating/responses/exceptions.py +++ b/openapi_core/templating/responses/exceptions.py @@ -1,4 +1,6 @@ -import attr +from typing import List + +from dataclasses import dataclass from openapi_core.exceptions import OpenAPIError @@ -7,11 +9,11 @@ class ResponseFinderError(OpenAPIError): """Response finder error""" -@attr.s(hash=True) +@dataclass class ResponseNotFound(ResponseFinderError): """Find response error""" - http_status = attr.ib() - responses = attr.ib() + http_status: int + availableresponses: List[str] def __str__(self): return "Unknown response http status: {0}".format( diff --git a/openapi_core/templating/responses/finders.py b/openapi_core/templating/responses/finders.py index 6e5532e9..9518fd90 100644 --- a/openapi_core/templating/responses/finders.py +++ b/openapi_core/templating/responses/finders.py @@ -16,6 +16,6 @@ def find(self, http_status='default'): return self.responses / http_status_range if 'default' not in self.responses: - raise ResponseNotFound(http_status, self.responses) + raise ResponseNotFound(http_status, list(self.responses.keys())) return self.responses / 'default' diff --git a/openapi_core/testing/requests.py b/openapi_core/testing/requests.py index fdde9d61..d7af9495 100644 --- a/openapi_core/testing/requests.py +++ b/openapi_core/testing/requests.py @@ -1,7 +1,7 @@ """OpenAPI core testing requests module""" from urllib.parse import urljoin -from werkzeug.datastructures import ImmutableMultiDict +from werkzeug.datastructures import Headers, ImmutableMultiDict from openapi_core.validation.request.datatypes import ( RequestParameters, OpenAPIRequest, @@ -15,13 +15,18 @@ def create( cls, host_url, method, path, path_pattern=None, args=None, view_args=None, headers=None, cookies=None, data=None, mimetype='application/json'): + path_pattern = path_pattern or path + + path = view_args or {} + query = ImmutableMultiDict(args or {}) + header = Headers(headers or {}) + cookie = ImmutableMultiDict(cookies or {}) parameters = RequestParameters( - path=view_args or {}, - query=ImmutableMultiDict(args or []), - header=headers or {}, - cookie=cookies or {}, + path=path, + query=query, + header=header, + cookie=cookie, ) - path_pattern = path_pattern or path method = method.lower() body = data or '' full_url_pattern = urljoin(host_url, path_pattern) diff --git a/openapi_core/testing/responses.py b/openapi_core/testing/responses.py index 2e19bec6..9eae17eb 100644 --- a/openapi_core/testing/responses.py +++ b/openapi_core/testing/responses.py @@ -1,4 +1,6 @@ """OpenAPI core testing responses module""" +from werkzeug.datastructures import Headers + from openapi_core.validation.response.datatypes import OpenAPIResponse @@ -8,9 +10,10 @@ class MockResponseFactory: def create( cls, data, status_code=200, headers=None, mimetype='application/json'): + headers = Headers(headers or {}) return OpenAPIResponse( data=data, status_code=status_code, - headers=headers or {}, + headers=headers, mimetype=mimetype, ) diff --git a/openapi_core/unmarshalling/schemas/exceptions.py b/openapi_core/unmarshalling/schemas/exceptions.py index 67eede67..20bb63fa 100644 --- a/openapi_core/unmarshalling/schemas/exceptions.py +++ b/openapi_core/unmarshalling/schemas/exceptions.py @@ -1,4 +1,6 @@ -import attr +from typing import List + +from dataclasses import dataclass, field from openapi_core.exceptions import OpenAPIError @@ -18,11 +20,11 @@ class UnmarshallerError(UnmarshalError): pass -@attr.s(hash=True) +@dataclass class InvalidSchemaValue(ValidateError): - value = attr.ib() - type = attr.ib() - schema_errors = attr.ib(factory=tuple) + value: str + type: str + schema_errors: List[Exception] = field(default_factory=list) def __str__(self): return ( @@ -30,12 +32,12 @@ def __str__(self): ).format(value=self.value, type=self.type, errors=self.schema_errors) -@attr.s(hash=True) +@dataclass class InvalidSchemaFormatValue(UnmarshallerError): """Value failed to format with formatter""" - value = attr.ib() - type = attr.ib() - original_exception = attr.ib() + value: str + type: str + original_exception: Exception def __str__(self): return ( @@ -46,10 +48,10 @@ def __str__(self): ) -@attr.s(hash=True) +@dataclass class FormatterNotFoundError(UnmarshallerError): """Formatter not found to unmarshal""" - type_format = attr.ib() + type_format: str def __str__(self): return "Formatter not found for {format} format".format( diff --git a/openapi_core/validation/datatypes.py b/openapi_core/validation/datatypes.py index a5434c25..1eb58b9d 100644 --- a/openapi_core/validation/datatypes.py +++ b/openapi_core/validation/datatypes.py @@ -1,10 +1,12 @@ """OpenAPI core validation datatypes module""" -import attr +from typing import List +from dataclasses import dataclass -@attr.s + +@dataclass class BaseValidationResult: - errors = attr.ib(factory=list) + errors: List[Exception] def raise_for_errors(self): for error in self.errors: diff --git a/openapi_core/validation/exceptions.py b/openapi_core/validation/exceptions.py index 1791fa0e..004068f1 100644 --- a/openapi_core/validation/exceptions.py +++ b/openapi_core/validation/exceptions.py @@ -1,5 +1,5 @@ """OpenAPI core validation exceptions module""" -import attr +from dataclasses import dataclass from openapi_core.exceptions import OpenAPIError @@ -8,7 +8,7 @@ class ValidationError(OpenAPIError): pass -@attr.s(hash=True) +@dataclass class InvalidSecurity(ValidationError): def __str__(self): diff --git a/openapi_core/validation/request/datatypes.py b/openapi_core/validation/request/datatypes.py index 9c0a07b8..f93feb0f 100644 --- a/openapi_core/validation/request/datatypes.py +++ b/openapi_core/validation/request/datatypes.py @@ -1,11 +1,13 @@ """OpenAPI core validation request datatypes module""" -import attr +from typing import Dict, Optional + +from dataclasses import dataclass, field from werkzeug.datastructures import ImmutableMultiDict, Headers from openapi_core.validation.datatypes import BaseValidationResult -@attr.s +@dataclass class RequestParameters: """OpenAPI request parameters dataclass. @@ -15,20 +17,20 @@ class RequestParameters: header Request headers as Headers. cookie - Request cookies as dict. + Request cookies as MultiDict. path Path parameters as dict. Gets resolved against spec if empty. """ - query = attr.ib(factory=ImmutableMultiDict) - header = attr.ib(factory=Headers, converter=Headers) - cookie = attr.ib(factory=dict) - path = attr.ib(factory=dict) + query: ImmutableMultiDict = field(default_factory=ImmutableMultiDict) + header: Headers = field(default_factory=Headers) + cookie: ImmutableMultiDict = field(default_factory=ImmutableMultiDict) + path: Dict = field(default_factory=dict) def __getitem__(self, location): return getattr(self, location) -@attr.s +@dataclass class OpenAPIRequest: """OpenAPI request dataclass. @@ -51,18 +53,15 @@ class OpenAPIRequest: the mimetype would be "text/html". """ - full_url_pattern = attr.ib() - method = attr.ib() - body = attr.ib() - mimetype = attr.ib() - parameters = attr.ib(factory=RequestParameters) + full_url_pattern: str + method: str + body: str + mimetype: str + parameters: RequestParameters = field(default_factory=RequestParameters) -@attr.s +@dataclass class RequestValidationResult(BaseValidationResult): - body = attr.ib(default=None) - parameters = attr.ib(factory=RequestParameters) - security = attr.ib(default=None) - server = attr.ib(default=None) - path = attr.ib(default=None) - operation = attr.ib(default=None) + body: Optional[str] = None + parameters: RequestParameters = field(default_factory=RequestParameters) + security: Optional[Dict[str, str]] = None diff --git a/openapi_core/validation/response/datatypes.py b/openapi_core/validation/response/datatypes.py index ea58a0c7..3fa06fa2 100644 --- a/openapi_core/validation/response/datatypes.py +++ b/openapi_core/validation/response/datatypes.py @@ -1,11 +1,12 @@ """OpenAPI core validation response datatypes module""" -import attr +from typing import Dict, Optional +from dataclasses import dataclass, field from werkzeug.datastructures import Headers from openapi_core.validation.datatypes import BaseValidationResult -@attr.s +@dataclass class OpenAPIResponse: """OpenAPI request dataclass. @@ -19,13 +20,13 @@ class OpenAPIResponse: mimetype Lowercase content type without charset. """ - data = attr.ib() - status_code = attr.ib() - mimetype = attr.ib() - headers = attr.ib(factory=Headers, converter=Headers) + data: str + status_code: int + mimetype: str + headers: Headers = field(default_factory=Headers) -@attr.s +@dataclass class ResponseValidationResult(BaseValidationResult): - data = attr.ib(default=None) - headers = attr.ib(factory=dict) + data: Optional[str] = None + headers: Dict = field(default_factory=dict) diff --git a/requirements.txt b/requirements.txt index 75a2cf77..3542d48a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,6 +2,6 @@ isodate==0.6.0 dictpath==0.1.3 openapi-spec-validator openapi-schema-validator -attrs parse==1.14.0 more-itertools>=5.0.0 +dataclasses==0.8; python_version=="3.6" diff --git a/setup.cfg b/setup.cfg index 67f4cc8b..7de244ae 100644 --- a/setup.cfg +++ b/setup.cfg @@ -29,10 +29,10 @@ install_requires = dictpath openapi-spec-validator openapi-schema-validator - attrs werkzeug parse more-itertools + dataclasses; python_version=="3.6" tests_require = pytest>=5.0.0 pytest-flake8 diff --git a/tests/integration/contrib/flask/test_flask_requests.py b/tests/integration/contrib/flask/test_flask_requests.py index 5de5070f..64d3f8cc 100644 --- a/tests/integration/contrib/flask/test_flask_requests.py +++ b/tests/integration/contrib/flask/test_flask_requests.py @@ -1,6 +1,6 @@ from urllib.parse import urljoin -from werkzeug.datastructures import EnvironHeaders, ImmutableMultiDict +from werkzeug.datastructures import Headers, ImmutableMultiDict from openapi_core.contrib.flask import FlaskOpenAPIRequest from openapi_core.validation.request.datatypes import RequestParameters @@ -15,7 +15,7 @@ def test_simple(self, request_factory, request): path = {} query = ImmutableMultiDict([]) - headers = EnvironHeaders(request.environ) + headers = Headers(request.headers) cookies = {} assert openapi_request.parameters == RequestParameters( path=path, @@ -39,7 +39,7 @@ def test_multiple_values(self, request_factory, request): query = ImmutableMultiDict([ ('a', 'b'), ('a', 'c'), ]) - headers = EnvironHeaders(request.environ) + headers = Headers(request.headers) cookies = {} assert openapi_request.parameters == RequestParameters( path=path, @@ -60,7 +60,7 @@ def test_url_rule(self, request_factory, request): path = {'id': 12} query = ImmutableMultiDict([]) - headers = EnvironHeaders(request.environ) + headers = Headers(request.headers) cookies = {} assert openapi_request.parameters == RequestParameters( path=path, diff --git a/tests/integration/contrib/requests/test_requests_requests.py b/tests/integration/contrib/requests/test_requests_requests.py index 2ea214e3..d6f92d43 100644 --- a/tests/integration/contrib/requests/test_requests_requests.py +++ b/tests/integration/contrib/requests/test_requests_requests.py @@ -4,6 +4,9 @@ from openapi_core.validation.request.datatypes import RequestParameters +from werkzeug.datastructures import Headers + + class TestRequestsOpenAPIRequest: def test_simple(self, request_factory, request): @@ -13,7 +16,7 @@ def test_simple(self, request_factory, request): path = {} query = ImmutableMultiDict([]) - headers = request.headers + headers = Headers(dict(request.headers)) cookies = {} prepared = request.prepare() assert openapi_request.parameters == RequestParameters( @@ -37,7 +40,7 @@ def test_multiple_values(self, request_factory, request): query = ImmutableMultiDict([ ('a', 'b'), ('a', 'c'), ]) - headers = request.headers + headers = Headers(dict(request.headers)) cookies = {} assert openapi_request.parameters == RequestParameters( path=path, @@ -59,9 +62,9 @@ def test_url_rule(self, request_factory, request): # empty when not bound to spec path = {} query = ImmutableMultiDict([]) - headers = ( - ('Content-Type', 'application/json'), - ) + headers = Headers({ + 'Content-Type': 'application/json', + }) cookies = {} assert openapi_request.parameters == RequestParameters( path=path, diff --git a/tests/integration/contrib/test_django.py b/tests/integration/contrib/test_django.py index 76bf5f84..55e5d443 100644 --- a/tests/integration/contrib/test_django.py +++ b/tests/integration/contrib/test_django.py @@ -1,6 +1,7 @@ import sys import pytest +from werkzeug.datastructures import Headers from openapi_core.contrib.django import ( DjangoOpenAPIRequest, DjangoOpenAPIResponse, @@ -71,9 +72,9 @@ def test_no_resolver(self, request_factory): path = {} query = {} - headers = { + headers = Headers({ 'Cookie': '', - } + }) cookies = {} assert openapi_request.parameters == RequestParameters( path=path, @@ -96,9 +97,9 @@ def test_simple(self, request_factory): path = {} query = {} - headers = { + headers = Headers({ 'Cookie': '', - } + }) cookies = {} assert openapi_request.parameters == RequestParameters( path=path, @@ -123,9 +124,9 @@ def test_url_rule(self, request_factory): 'object_id': '1', } query = {} - headers = { + headers = Headers({ 'Cookie': '', - } + }) cookies = {} assert openapi_request.parameters == RequestParameters( path=path, @@ -148,9 +149,9 @@ def test_url_regexp_pattern(self, request_factory): path = {} query = {} - headers = { + headers = Headers({ 'Cookie': '', - } + }) cookies = {} assert openapi_request.parameters == RequestParameters( path=path,