Skip to content

Commit 54b8011

Browse files
committed
Mimetype wildcards support
1 parent 469c558 commit 54b8011

File tree

7 files changed

+75
-6
lines changed

7 files changed

+75
-6
lines changed

openapi_core/schema/content/__init__.py

Whitespace-only changes.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from openapi_core.schema.exceptions import OpenAPIMappingError
2+
3+
4+
class OpenAPIContentError(OpenAPIMappingError):
5+
pass
6+
7+
8+
class MimeTypeNotFound(OpenAPIContentError):
9+
pass

openapi_core/schema/content/models.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
"""OpenAPI core content models module"""
2+
import fnmatch
3+
4+
from six import iteritems
5+
6+
from openapi_core.schema.content.exceptions import MimeTypeNotFound
7+
8+
9+
class Content(dict):
10+
11+
def __getitem__(self, mimetype):
12+
try:
13+
return super(Content, self).__getitem__(mimetype)
14+
except KeyError:
15+
pass
16+
17+
for key, value in iteritems(self):
18+
if fnmatch.fnmatch(mimetype, key):
19+
return value
20+
21+
raise MimeTypeNotFound("{0} mimetype not found")

openapi_core/schema/request_bodies/models.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""OpenAPI core request bodies models module"""
2-
2+
from openapi_core.schema.content.exceptions import MimeTypeNotFound
3+
from openapi_core.schema.content.models import Content
34
from openapi_core.schema.media_types.exceptions import InvalidContentType
45
from openapi_core.schema.request_bodies.exceptions import MissingRequestBody
56

@@ -8,13 +9,13 @@ class RequestBody(object):
89
"""Represents an OpenAPI RequestBody."""
910

1011
def __init__(self, content, required=False):
11-
self.content = dict(content)
12+
self.content = Content(content)
1213
self.required = required
1314

1415
def __getitem__(self, mimetype):
1516
try:
1617
return self.content[mimetype]
17-
except KeyError:
18+
except MimeTypeNotFound:
1819
raise InvalidContentType(
1920
"Invalid mime type `{0}`".format(mimetype))
2021

openapi_core/schema/responses/models.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
"""OpenAPI core responses models module"""
2+
from openapi_core.schema.content.exceptions import MimeTypeNotFound
3+
from openapi_core.schema.content.models import Content
24
from openapi_core.schema.media_types.exceptions import InvalidContentType
35
from openapi_core.schema.responses.exceptions import MissingResponseContent
46

@@ -11,13 +13,13 @@ def __init__(
1113
self.http_status = http_status
1214
self.description = description
1315
self.headers = headers and dict(headers) or {}
14-
self.content = content and dict(content) or {}
16+
self.content = content and Content(content) or Content()
1517
self.links = links and dict(links) or {}
1618

1719
def __getitem__(self, mimetype):
1820
try:
1921
return self.content[mimetype]
20-
except KeyError:
22+
except MimeTypeNotFound:
2123
raise InvalidContentType(
2224
"Invalid mime type `{0}`".format(mimetype))
2325

tests/integration/data/v3.0/petstore.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ paths:
106106
application/json:
107107
schema:
108108
$ref: "#/components/schemas/PetData"
109+
image/*:
110+
schema:
111+
type: string
112+
format: binary
109113
default:
110114
$ref: "#/components/responses/ErrorResponse"
111115
/tags:

tests/integration/test_petstore.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ def test_spec(self, spec, spec_dict):
112112
continue
113113

114114
assert type(media_type.schema) == Schema
115-
assert media_type.schema.type == schema_spec['type']
115+
assert media_type.schema.type.value ==\
116+
schema_spec['type']
116117
assert media_type.schema.required == schema_spec.get(
117118
'required', [])
118119

@@ -675,6 +676,37 @@ def test_get_pet_not_found(self, spec, response_validator):
675676
assert response_result.errors == []
676677
assert response_result.data == data_json
677678

679+
def test_get_pet_wildcard(self, spec, response_validator):
680+
host_url = 'http://petstore.swagger.io/v1'
681+
path_pattern = '/v1/pets/{petId}'
682+
view_args = {
683+
'petId': '1',
684+
}
685+
request = MockRequest(
686+
host_url, 'GET', '/pets/1',
687+
path_pattern=path_pattern, view_args=view_args,
688+
)
689+
690+
parameters = request.get_parameters(spec)
691+
692+
assert parameters == {
693+
'path': {
694+
'petId': 1,
695+
}
696+
}
697+
698+
body = request.get_body(spec)
699+
700+
assert body is None
701+
702+
data = b'imagedata'
703+
response = MockResponse(data, mimetype='image/png')
704+
705+
response_result = response_validator.validate(request, response)
706+
707+
assert response_result.errors == []
708+
assert response_result.data == data
709+
678710
def test_get_tags(self, spec, response_validator):
679711
host_url = 'http://petstore.swagger.io/v1'
680712
path_pattern = '/v1/tags'

0 commit comments

Comments
 (0)