Skip to content

Commit

Permalink
Merge pull request #699 from python-openapi/feature/move-mimetype-to-…
Browse files Browse the repository at this point in the history
…content-type

Replace mimetype with content_type
  • Loading branch information
p1c2u authored Oct 21, 2023
2 parents cc95ed0 + 2a3bd96 commit efaa5ac
Show file tree
Hide file tree
Showing 29 changed files with 94 additions and 83 deletions.
2 changes: 1 addition & 1 deletion openapi_core/contrib/aiohttp/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,5 @@ def body(self) -> str | None:
return self._body

@property
def mimetype(self) -> str:
def content_type(self) -> str:
return self.request.content_type
2 changes: 1 addition & 1 deletion openapi_core/contrib/aiohttp/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def status_code(self) -> int:
return self.response.status

@property
def mimetype(self) -> str:
def content_type(self) -> str:
return self.response.content_type or ""

@property
Expand Down
6 changes: 4 additions & 2 deletions openapi_core/contrib/django/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,5 +81,7 @@ def body(self) -> str:
return self.request.body.decode("utf-8")

@property
def mimetype(self) -> str:
return self.request.content_type or ""
def content_type(self) -> str:
content_type = self.request.META.get("CONTENT_TYPE", "")
assert isinstance(content_type, str)
return content_type
2 changes: 1 addition & 1 deletion openapi_core/contrib/django/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def headers(self) -> Headers:
return Headers(self.response.headers.items())

@property
def mimetype(self) -> str:
def content_type(self) -> str:
content_type = self.response.get("Content-Type", "")
assert isinstance(content_type, str)
return content_type
4 changes: 2 additions & 2 deletions openapi_core/contrib/falcon/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ def body(self) -> Optional[str]:
return dumps(getattr(self.request, "json", media))

@property
def mimetype(self) -> str:
def content_type(self) -> str:
if self.request.content_type:
assert isinstance(self.request.content_type, str)
return self.request.content_type.partition(";")[0]
return self.request.content_type

assert isinstance(self.request.options, RequestOptions)
assert isinstance(self.request.options.default_media_type, str)
Expand Down
10 changes: 5 additions & 5 deletions openapi_core/contrib/falcon/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ def status_code(self) -> int:
return int(self.response.status[:3])

@property
def mimetype(self) -> str:
mimetype = ""
def content_type(self) -> str:
content_type = ""
if self.response.content_type:
mimetype = self.response.content_type.partition(";")[0]
content_type = self.response.content_type
else:
mimetype = self.response.options.default_media_type
return mimetype
content_type = self.response.options.default_media_type
return content_type

@property
def headers(self) -> Headers:
Expand Down
4 changes: 2 additions & 2 deletions openapi_core/contrib/requests/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,13 @@ def body(self) -> Optional[str]:
return self.request.body

@property
def mimetype(self) -> str:
def content_type(self) -> str:
# Order matters because all python requests issued from a session
# include Accept */* which does not necessarily match the content type
return str(
self.request.headers.get("Content-Type")
or self.request.headers.get("Accept")
).split(";")[0]
)


class RequestsOpenAPIWebhookRequest(RequestsOpenAPIRequest):
Expand Down
2 changes: 1 addition & 1 deletion openapi_core/contrib/requests/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def status_code(self) -> int:
return int(self.response.status_code)

@property
def mimetype(self) -> str:
def content_type(self) -> str:
return str(self.response.headers.get("Content-Type", ""))

@property
Expand Down
12 changes: 6 additions & 6 deletions openapi_core/contrib/starlette/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ def body(self) -> Optional[str]:
return body

@property
def mimetype(self) -> str:
content_type = self.request.headers.get("Content-Type")
if content_type:
return content_type.partition(";")[0]

return ""
def content_type(self) -> str:
# default value according to RFC 2616
return (
self.request.headers.get("Content-Type")
or "application/octet-stream"
)
4 changes: 2 additions & 2 deletions openapi_core/contrib/starlette/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ def status_code(self) -> int:
return self.response.status_code

@property
def mimetype(self) -> str:
return self.response.media_type or ""
def content_type(self) -> str:
return self.response.headers.get("Content-Type") or ""

@property
def headers(self) -> Headers:
Expand Down
5 changes: 3 additions & 2 deletions openapi_core/contrib/werkzeug/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ def body(self) -> Optional[str]:
return self.request.get_data(as_text=True)

@property
def mimetype(self) -> str:
return self.request.mimetype
def content_type(self) -> str:
# default value according to RFC 2616
return self.request.content_type or "application/octet-stream"

def get_path(self, path: str) -> str:
return "".join([self.request.root_path, path])
2 changes: 1 addition & 1 deletion openapi_core/contrib/werkzeug/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def status_code(self) -> int:
return self.response._status_code

@property
def mimetype(self) -> str:
def content_type(self) -> str:
return str(self.response.mimetype)

@property
Expand Down
24 changes: 10 additions & 14 deletions openapi_core/protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def body(self) -> Optional[str]:
...

@property
def mimetype(self) -> str:
def content_type(self) -> str:
...


Expand All @@ -48,11 +48,9 @@ class Request(BaseRequest, Protocol):
to write resolved path parameters.
body
The request body, as string.
mimetype
Like content type, but without parameters (eg, without charset,
type etc.) and always lowercase.
For example if the content type is "text/HTML; charset=utf-8"
the mimetype would be "text/html".
content_type
The content type with parameters (eg, charset, boundary etc.)
and always lowercase.
"""

@property
Expand All @@ -78,11 +76,9 @@ class WebhookRequest(BaseRequest, Protocol):
to write resolved path parameters.
body
The request body, as string.
mimetype
Like content type, but without parameters (eg, without charset,
type etc.) and always lowercase.
For example if the content type is "text/HTML; charset=utf-8"
the mimetype would be "text/html".
content_type
The content type with parameters (eg, charset, boundary etc.)
and always lowercase.
"""

@property
Expand Down Expand Up @@ -119,8 +115,8 @@ class Response(Protocol):
The status code as integer.
headers
Response headers as Headers.
mimetype
Lowercase content type without charset.
content_type
The content type with parameters and always lowercase.
"""

@property
Expand All @@ -132,7 +128,7 @@ def status_code(self) -> int:
...

@property
def mimetype(self) -> str:
def content_type(self) -> str:
...

@property
Expand Down
4 changes: 2 additions & 2 deletions openapi_core/testing/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def __init__(
headers: Optional[Dict[str, Any]] = None,
cookies: Optional[Dict[str, Any]] = None,
data: Optional[str] = None,
mimetype: str = "application/json",
content_type: str = "application/json",
):
self.host_url = host_url
self.method = method.lower()
Expand All @@ -32,7 +32,7 @@ def __init__(
self.headers = headers
self.cookies = cookies
self.body = data or ""
self.mimetype = mimetype
self.content_type = content_type

self.parameters = RequestParameters(
path=self.view_args or {},
Expand Down
4 changes: 2 additions & 2 deletions openapi_core/testing/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ def __init__(
data: str,
status_code: int = 200,
headers: Optional[Dict[str, Any]] = None,
mimetype: str = "application/json",
content_type: str = "application/json",
):
self.data = data
self.status_code = status_code
self.headers = Headers(headers or {})
self.mimetype = mimetype
self.content_type = content_type
8 changes: 6 additions & 2 deletions openapi_core/unmarshalling/request/unmarshallers.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,9 @@ def _unmarshal(
params_errors = []

try:
body = self._get_body(request.body, request.mimetype, operation)
body = self._get_body(
request.body, request.content_type, operation
)
except MissingRequestBody:
body = None
body_errors = []
Expand All @@ -172,7 +174,9 @@ def _unmarshal_body(
self, request: BaseRequest, operation: SchemaPath, path: SchemaPath
) -> RequestUnmarshalResult:
try:
body = self._get_body(request.body, request.mimetype, operation)
body = self._get_body(
request.body, request.content_type, operation
)
except MissingRequestBody:
body = None
errors = []
Expand Down
4 changes: 2 additions & 2 deletions openapi_core/unmarshalling/response/unmarshallers.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def _unmarshal(

try:
validated_data = self._get_data(
response.data, response.mimetype, operation_response
response.data, response.content_type, operation_response
)
except DataValidationError as exc:
validated_data = None
Expand Down Expand Up @@ -106,7 +106,7 @@ def _unmarshal_data(

try:
validated = self._get_data(
response.data, response.mimetype, operation_response
response.data, response.content_type, operation_response
)
except DataValidationError as exc:
validated = None
Expand Down
4 changes: 2 additions & 2 deletions openapi_core/validation/request/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,15 @@ def _iter_errors(
yield from exc.errors

try:
self._get_body(request.body, request.mimetype, operation)
self._get_body(request.body, request.content_type, operation)
except RequestBodyValidationError as exc:
yield exc

def _iter_body_errors(
self, request: BaseRequest, operation: SchemaPath
) -> Iterator[Exception]:
try:
self._get_body(request.body, request.mimetype, operation)
self._get_body(request.body, request.content_type, operation)
except RequestBodyValidationError as exc:
yield exc

Expand Down
14 changes: 10 additions & 4 deletions openapi_core/validation/response/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,10 @@ def iter_errors(
return

yield from self._iter_data_errors(
response.status_code, response.data, response.mimetype, operation
response.status_code,
response.data,
response.content_type,
operation,
)


Expand Down Expand Up @@ -273,7 +276,7 @@ def iter_errors(
response.status_code,
response.data,
response.headers,
response.mimetype,
response.content_type,
operation,
)

Expand All @@ -292,7 +295,10 @@ def iter_errors(
return

yield from self._iter_data_errors(
response.status_code, response.data, response.mimetype, operation
response.status_code,
response.data,
response.content_type,
operation,
)


Expand Down Expand Up @@ -331,7 +337,7 @@ def iter_errors(
response.status_code,
response.data,
response.headers,
response.mimetype,
response.content_type,
operation,
)

Expand Down
14 changes: 7 additions & 7 deletions tests/integration/test_petstore.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ def test_get_pets_response(self, spec):
assert response_result.data.data[0].id == 1
assert response_result.data.data[0].name == "Cat"

def test_get_pets_response_no_schema(self, spec):
def test_get_pets_response_media_type(self, spec):
host_url = "http://petstore.swagger.io/v1"
path_pattern = "/v1/pets"
query_params = {
Expand Down Expand Up @@ -230,15 +230,15 @@ def test_get_pets_response_no_schema(self, spec):

assert result.body is None

data = b"<html></html>"
data = b"<html>\xb1\xbc</html>"
response = MockResponse(
data, status_code=404, mimetype="text/html; charset=utf-8"
data, status_code=404, content_type="text/html; charset=iso-8859-2"
)

response_result = unmarshal_response(request, response, spec=spec)

assert response_result.errors == []
assert response_result.data == data.decode("utf-8")
assert response_result.data == data.decode("iso-8859-2")

def test_get_pets_invalid_response(self, spec, response_unmarshaller):
host_url = "http://petstore.swagger.io/v1"
Expand Down Expand Up @@ -1015,7 +1015,7 @@ def test_post_pets_raises_invalid_mimetype(self, spec):
"/pets",
path_pattern=path_pattern,
data=data,
mimetype="text/html",
content_type="text/html",
headers=headers,
cookies=cookies,
)
Expand Down Expand Up @@ -1150,7 +1150,7 @@ def test_post_pets_raises_invalid_server_error(self, spec):
"/pets",
path_pattern=path_pattern,
data=data,
mimetype="text/html",
content_type="text/html",
headers=headers,
cookies=cookies,
)
Expand Down Expand Up @@ -1372,7 +1372,7 @@ def test_get_pet_wildcard(self, spec):
assert result.body is None

data = b"imagedata"
response = MockResponse(data, mimetype="image/png")
response = MockResponse(data, content_type="image/png")

response_result = unmarshal_response(request, response, spec=spec)

Expand Down
Loading

2 comments on commit efaa5ac

@Cap-JaTu
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated and tested with this commit.

Working perfectly!
Thank you very much. Now the library is highly usable in real-world.

@p1c2u
Copy link
Collaborator Author

@p1c2u p1c2u commented on efaa5ac Oct 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Cap-JaTu I'm glad it works for you

Please sign in to comment.