Skip to content

Commit 0bbf787

Browse files
committed
Flask factories; Get rid of wrappers
1 parent cffc47c commit 0bbf787

File tree

10 files changed

+125
-186
lines changed

10 files changed

+125
-186
lines changed

README.rst

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ or use shortcuts for simple validation
8181
validated_params = validate_parameters(spec, request)
8282
validated_body = validate_body(spec, request)
8383
84-
Request object should implement BaseOpenAPIRequest interface. You can use FlaskOpenAPIRequest a Flask/Werkzeug request wrapper implementation:
84+
Request object should be instance of OpenAPIRequest class. You can use FlaskOpenAPIRequest a Flask/Werkzeug request factory:
8585

8686
.. code-block:: python
8787
@@ -92,16 +92,16 @@ Request object should implement BaseOpenAPIRequest interface. You can use FlaskO
9292
validator = RequestValidator(spec)
9393
result = validator.validate(openapi_request)
9494
95-
or specify request wrapper class for shortcuts
95+
or simply specify request factory for shortcuts
9696

9797
.. code-block:: python
9898
9999
from openapi_core import validate_parameters, validate_body
100100
101101
validated_params = validate_parameters(
102-
spec, request, wrapper_class=FlaskOpenAPIRequest)
102+
spec, request, request_factory=FlaskOpenAPIRequest)
103103
validated_body = validate_body(
104-
spec, request, wrapper_class=FlaskOpenAPIRequest)
104+
spec, request, request_factory=FlaskOpenAPIRequest)
105105
106106
You can also validate responses
107107

@@ -136,7 +136,7 @@ or use shortcuts for simple validation
136136
137137
validated_data = validate_data(spec, request, response)
138138
139-
Response object should implement BaseOpenAPIResponse interface. You can use FlaskOpenAPIResponse a Flask/Werkzeug response wrapper implementation:
139+
Response object should be instance of OpenAPIResponse class. You can use FlaskOpenAPIResponse a Flask/Werkzeug response factory:
140140

141141
.. code-block:: python
142142
@@ -147,14 +147,14 @@ Response object should implement BaseOpenAPIResponse interface. You can use Flas
147147
validator = ResponseValidator(spec)
148148
result = validator.validate(openapi_request, openapi_response)
149149
150-
or specify response wrapper class for shortcuts
150+
or simply specify response factory for shortcuts
151151

152152
.. code-block:: python
153153
154154
from openapi_core import validate_parameters, validate_body
155155
156156
validated_data = validate_data(
157-
spec, request, response, response_wrapper_class=FlaskOpenAPIResponse)
157+
spec, request, response, response_factory=FlaskOpenAPIResponse)
158158
159159
Related projects
160160
================
Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
from openapi_core.contrib.flask.requests import FlaskOpenAPIRequest
2-
from openapi_core.contrib.flask.responses import FlaskOpenAPIResponse
1+
from openapi_core.contrib.flask.requests import FlaskOpenAPIRequestFactory
2+
from openapi_core.contrib.flask.responses import FlaskOpenAPIResponseFactory
33

4-
__all__ = ['FlaskOpenAPIRequest', 'FlaskOpenAPIResponse']
4+
# backward compatibility
5+
FlaskOpenAPIRequest = FlaskOpenAPIRequestFactory.create
6+
FlaskOpenAPIResponse = FlaskOpenAPIResponseFactory.create
7+
8+
__all__ = [
9+
'FlaskOpenAPIRequestFactory', 'FlaskOpenAPIResponseFactory',
10+
'FlaskOpenAPIRequest', 'FlaskOpenAPIResponse',
11+
]
Lines changed: 28 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,39 @@
11
"""OpenAPI core contrib flask requests module"""
22
import re
33

4-
from openapi_core.wrappers.base import BaseOpenAPIRequest
4+
from openapi_core.validation.request.datatypes import (
5+
RequestParameters, OpenAPIRequest,
6+
)
57

68
# http://flask.pocoo.org/docs/1.0/quickstart/#variable-rules
79
PATH_PARAMETER_PATTERN = r'<(?:(?:string|int|float|path|uuid):)?(\w+)>'
810

911

10-
class FlaskOpenAPIRequest(BaseOpenAPIRequest):
12+
class FlaskOpenAPIRequestFactory(object):
1113

1214
path_regex = re.compile(PATH_PARAMETER_PATTERN)
1315

14-
def __init__(self, request):
15-
self.request = request
16-
17-
@property
18-
def host_url(self):
19-
return self.request.host_url
20-
21-
@property
22-
def path(self):
23-
return self.request.path
24-
25-
@property
26-
def method(self):
27-
return self.request.method.lower()
28-
29-
@property
30-
def path_pattern(self):
31-
if self.request.url_rule is None:
32-
return self.path
33-
34-
return self.path_regex.sub(r'{\1}', self.request.url_rule.rule)
35-
36-
@property
37-
def parameters(self):
38-
return {
39-
'path': self.request.view_args,
40-
'query': self.request.args,
41-
'header': self.request.headers,
42-
'cookie': self.request.cookies,
43-
}
44-
45-
@property
46-
def body(self):
47-
return self.request.data
48-
49-
@property
50-
def mimetype(self):
51-
return self.request.mimetype
16+
@classmethod
17+
def create(cls, request):
18+
method = request.method.lower()
19+
20+
if request.url_rule is None:
21+
path_pattern = request.path
22+
else:
23+
path_pattern = cls.path_regex.sub(r'{\1}', request.url_rule.rule)
24+
25+
parameters = RequestParameters(
26+
path=request.view_args,
27+
query=request.args,
28+
header=request.headers,
29+
cookie=request.cookies,
30+
)
31+
return OpenAPIRequest(
32+
host_url=request.host_url,
33+
path=request.path,
34+
path_pattern=path_pattern,
35+
method=method,
36+
parameters=parameters,
37+
body=request.data,
38+
mimetype=request.mimetype,
39+
)
Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,15 @@
11
"""OpenAPI core contrib flask responses module"""
22
import re
33

4-
from openapi_core.wrappers.base import BaseOpenAPIResponse
4+
from openapi_core.validation.response.datatypes import OpenAPIResponse
55

66

7-
class FlaskOpenAPIResponse(BaseOpenAPIResponse):
7+
class FlaskOpenAPIResponseFactory(object):
88

9-
def __init__(self, response):
10-
self.response = response
11-
12-
@property
13-
def data(self):
14-
return self.response.data
15-
16-
@property
17-
def status_code(self):
18-
return self.response._status_code
19-
20-
@property
21-
def mimetype(self):
22-
return self.response.mimetype
9+
@classmethod
10+
def create(cls, response):
11+
return OpenAPIResponse(
12+
data=response.data,
13+
status_code=response._status_code,
14+
mimetype=response.mimetype,
15+
)

openapi_core/shortcuts.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ def create_spec(spec_dict, spec_url=''):
2020
return spec_factory.create(spec_dict, spec_url=spec_url)
2121

2222

23-
def validate_parameters(spec, request, wrapper_class=None):
24-
if wrapper_class is not None:
25-
request = wrapper_class(request)
23+
def validate_parameters(spec, request, request_factory=None):
24+
if request_factory is not None:
25+
request = request_factory(request)
2626

2727
validator = RequestValidator(spec)
2828
result = validator.validate(request)
@@ -38,9 +38,9 @@ def validate_parameters(spec, request, wrapper_class=None):
3838
return result.parameters
3939

4040

41-
def validate_body(spec, request, wrapper_class=None):
42-
if wrapper_class is not None:
43-
request = wrapper_class(request)
41+
def validate_body(spec, request, request_factory=None):
42+
if request_factory is not None:
43+
request = request_factory(request)
4444

4545
validator = RequestValidator(spec)
4646
result = validator.validate(request)
@@ -55,13 +55,13 @@ def validate_body(spec, request, wrapper_class=None):
5555

5656
def validate_data(
5757
spec, request, response,
58-
request_wrapper_class=None,
59-
response_wrapper_class=None):
60-
if request_wrapper_class is not None:
61-
request = request_wrapper_class(request)
58+
request_factory=None,
59+
response_factory=None):
60+
if request_factory is not None:
61+
request = request_factory(request)
6262

63-
if response_wrapper_class is not None:
64-
response = response_wrapper_class(response)
63+
if response_factory is not None:
64+
response = response_factory(response)
6565

6666
validator = ResponseValidator(spec)
6767
result = validator.validate(request, response)

openapi_core/wrappers/__init__.py

Whitespace-only changes.

openapi_core/wrappers/base.py

Lines changed: 0 additions & 49 deletions
This file was deleted.

tests/integration/contrib/test_flask.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44
from werkzeug.routing import Map, Rule, Subdomain
55
from werkzeug.test import create_environ
66

7-
from openapi_core.shortcuts import create_spec
8-
from openapi_core.validation.response.validators import ResponseValidator
9-
from openapi_core.validation.request.validators import RequestValidator
107
from openapi_core.contrib.flask import (
118
FlaskOpenAPIRequest, FlaskOpenAPIResponse,
129
)
10+
from openapi_core.shortcuts import create_spec
11+
from openapi_core.validation.request.datatypes import RequestParameters
12+
from openapi_core.validation.request.validators import RequestValidator
13+
from openapi_core.validation.response.validators import ResponseValidator
1314

1415

1516
@pytest.fixture
@@ -67,12 +68,12 @@ def test_simple(self, request_factory, request):
6768
query = ImmutableMultiDict([])
6869
headers = EnvironHeaders(request.environ)
6970
cookies = {}
70-
assert openapi_request.parameters == {
71-
'path': path,
72-
'query': query,
73-
'header': headers,
74-
'cookie': cookies,
75-
}
71+
assert openapi_request.parameters == RequestParameters(
72+
path=path,
73+
query=query,
74+
header=headers,
75+
cookie=cookies,
76+
)
7677
assert openapi_request.host_url == request.host_url
7778
assert openapi_request.path == request.path
7879
assert openapi_request.method == request.method.lower()
@@ -92,12 +93,12 @@ def test_multiple_values(self, request_factory, request):
9293
])
9394
headers = EnvironHeaders(request.environ)
9495
cookies = {}
95-
assert openapi_request.parameters == {
96-
'path': path,
97-
'query': query,
98-
'header': headers,
99-
'cookie': cookies,
100-
}
96+
assert openapi_request.parameters == RequestParameters(
97+
path=path,
98+
query=query,
99+
header=headers,
100+
cookie=cookies,
101+
)
101102
assert openapi_request.host_url == request.host_url
102103
assert openapi_request.path == request.path
103104
assert openapi_request.method == request.method.lower()
@@ -114,12 +115,12 @@ def test_url_rule(self, request_factory, request):
114115
query = ImmutableMultiDict([])
115116
headers = EnvironHeaders(request.environ)
116117
cookies = {}
117-
assert openapi_request.parameters == {
118-
'path': path,
119-
'query': query,
120-
'header': headers,
121-
'cookie': cookies,
122-
}
118+
assert openapi_request.parameters == RequestParameters(
119+
path=path,
120+
query=query,
121+
header=headers,
122+
cookie=cookies,
123+
)
123124
assert openapi_request.host_url == request.host_url
124125
assert openapi_request.path == request.path
125126
assert openapi_request.method == request.method.lower()
@@ -135,7 +136,6 @@ def test_invalid_server(self, response_factory):
135136

136137
openapi_response = FlaskOpenAPIResponse(response)
137138

138-
assert openapi_response.response == response
139139
assert openapi_response.data == response.data
140140
assert openapi_response.status_code == response._status_code
141141
assert openapi_response.mimetype == response.mimetype
@@ -145,7 +145,7 @@ class TestFlaskOpenAPIValidation(object):
145145

146146
@pytest.fixture
147147
def flask_spec(self, factory):
148-
specfile = 'data/v3.0/flask_wrapper.yaml'
148+
specfile = 'data/v3.0/flask_factory.yaml'
149149
return create_spec(factory.spec_from_file(specfile))
150150

151151
def test_response_validator_path_pattern(self,

tests/integration/data/v3.0/flask_wrapper.yaml renamed to tests/integration/data/v3.0/flask_factory.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
openapi: "3.0.0"
22
info:
3-
title: Basic OpenAPI specification used with test_wrappers.TestFlaskOpenAPIIValidation
3+
title: Basic OpenAPI specification used with test_flask.TestFlaskOpenAPIIValidation
44
version: "0.1"
55
servers:
66
- url: 'http://localhost'

0 commit comments

Comments
 (0)