Skip to content

Commit 4a7f88b

Browse files
authored
Merge pull request #345 from p1c2u/refactor/dataclasses-refactor
Dataclasses refactor
2 parents e9e43eb + 30d0f06 commit 4a7f88b

File tree

29 files changed

+177
-134
lines changed

29 files changed

+177
-134
lines changed

openapi_core/casting/schemas/exceptions.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import attr
1+
from dataclasses import dataclass
22

33
from openapi_core.exceptions import OpenAPIError
44

55

6-
@attr.s(hash=True)
6+
@dataclass
77
class CastError(OpenAPIError):
88
"""Schema cast operation error"""
9-
value = attr.ib()
10-
type = attr.ib()
9+
value: str
10+
type: str
1111

1212
def __str__(self):
1313
return "Failed to cast value {value} to type {type}".format(

openapi_core/contrib/django/requests.py

+9-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
"""OpenAPI core contrib django requests module"""
22
import re
3-
43
from urllib.parse import urljoin
54

5+
from werkzeug.datastructures import ImmutableMultiDict, Headers
6+
67
from openapi_core.contrib.django.compat import (
78
get_request_headers, get_current_scheme_host,
89
)
@@ -43,13 +44,16 @@ def create(cls, request):
4344
route = route[:-1]
4445
path_pattern = '/' + route
4546

47+
request_headers = get_request_headers(request)
4648
path = request.resolver_match and request.resolver_match.kwargs or {}
47-
headers = get_request_headers(request)
49+
query = ImmutableMultiDict(request.GET)
50+
header = Headers(request_headers.items())
51+
cookie = ImmutableMultiDict(dict(request.COOKIES))
4852
parameters = RequestParameters(
4953
path=path,
50-
query=request.GET,
51-
header=list(headers.items()),
52-
cookie=request.COOKIES,
54+
query=query,
55+
header=header,
56+
cookie=cookie,
5357
)
5458
current_scheme_host = get_current_scheme_host(request)
5559
full_url_pattern = urljoin(current_scheme_host, path_pattern)

openapi_core/contrib/django/responses.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
"""OpenAPI core contrib django responses module"""
2+
from werkzeug.datastructures import Headers
3+
24
from openapi_core.contrib.django.compat import get_response_headers
35
from openapi_core.validation.response.datatypes import OpenAPIResponse
46

@@ -9,9 +11,10 @@ class DjangoOpenAPIResponseFactory:
911
def create(cls, response):
1012
mimetype = response["Content-Type"]
1113
headers = get_response_headers(response)
14+
header = Headers(headers.items())
1215
return OpenAPIResponse(
1316
data=response.content,
1417
status_code=response.status_code,
15-
headers=list(headers.items()),
18+
headers=header,
1619
mimetype=mimetype,
1720
)

openapi_core/contrib/falcon/requests.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""OpenAPI core contrib falcon responses module"""
22
from json import dumps
33

4-
from werkzeug.datastructures import ImmutableMultiDict
4+
from werkzeug.datastructures import ImmutableMultiDict, Headers
55

66
from openapi_core.contrib.falcon.compat import get_request_media
77
from openapi_core.validation.request.datatypes import (
@@ -29,11 +29,12 @@ def create(cls, request, default_when_empty={}):
2929
mimetype = request.content_type.partition(";")[0]
3030

3131
query = ImmutableMultiDict(list(request.params.items()))
32+
header = Headers(request.headers)
3233

3334
# Path gets deduced by path finder against spec
3435
parameters = RequestParameters(
3536
query=query,
36-
header=request.headers,
37+
header=header,
3738
cookie=request.cookies,
3839
)
3940
url_pattern = request.prefix + request.path

openapi_core/contrib/falcon/responses.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
"""OpenAPI core contrib falcon responses module"""
2+
from werkzeug.datastructures import Headers
3+
24
from openapi_core.contrib.falcon.compat import get_response_text
35
from openapi_core.validation.response.datatypes import OpenAPIResponse
46

@@ -15,10 +17,11 @@ def create(cls, response):
1517
mimetype = response.options.default_media_type
1618

1719
data = get_response_text(response)
20+
headers = Headers(response.headers)
1821

1922
return OpenAPIResponse(
2023
data=data,
2124
status_code=status_code,
22-
headers=response.headers,
25+
headers=headers,
2326
mimetype=mimetype,
2427
)

openapi_core/contrib/flask/requests.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
"""OpenAPI core contrib flask requests module"""
22
import re
3-
43
from urllib.parse import urljoin
54

5+
from werkzeug.datastructures import Headers
6+
67
from openapi_core.validation.request.datatypes import (
78
RequestParameters, OpenAPIRequest,
89
)
@@ -24,10 +25,11 @@ def create(cls, request):
2425
else:
2526
path_pattern = cls.path_regex.sub(r'{\1}', request.url_rule.rule)
2627

28+
header = Headers(request.headers)
2729
parameters = RequestParameters(
2830
path=request.view_args,
2931
query=request.args,
30-
header=request.headers,
32+
header=header,
3133
cookie=request.cookies,
3234
)
3335
full_url_pattern = urljoin(request.host_url, path_pattern)
+4-1
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
"""OpenAPI core contrib flask responses module"""
2+
from werkzeug.datastructures import Headers
3+
24
from openapi_core.validation.response.datatypes import OpenAPIResponse
35

46

57
class FlaskOpenAPIResponseFactory:
68

79
@classmethod
810
def create(cls, response):
11+
header = Headers(response.headers)
912
return OpenAPIResponse(
1013
data=response.data,
1114
status_code=response._status_code,
12-
headers=response.headers,
15+
headers=header,
1316
mimetype=response.mimetype,
1417
)

openapi_core/contrib/requests/requests.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from urllib.parse import urlparse, parse_qs
44

5-
from werkzeug.datastructures import ImmutableMultiDict
5+
from werkzeug.datastructures import ImmutableMultiDict, Headers
66
from requests import Request
77

88
from openapi_core.validation.request.datatypes import (
@@ -43,9 +43,9 @@ def create(cls, request):
4343
mimetype = request.headers.get('Content-Type') or \
4444
request.headers.get('Accept')
4545

46-
# Headers - request.headers is not an instance of dict
46+
# Headers - request.headers is not an instance of Headers
4747
# which is expected
48-
header = dict(request.headers)
48+
header = Headers(dict(request.headers))
4949

5050
# Body
5151
# TODO: figure out if request._body_position is relevant

openapi_core/contrib/requests/responses.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
"""OpenAPI core contrib requests responses module"""
2+
from werkzeug.datastructures import Headers
3+
24
from openapi_core.validation.response.datatypes import OpenAPIResponse
35

46

@@ -7,7 +9,7 @@ class RequestsOpenAPIResponseFactory:
79
@classmethod
810
def create(cls, response):
911
mimetype = response.headers.get('Content-Type')
10-
headers = dict(response.headers)
12+
headers = Headers(dict(response.headers))
1113
return OpenAPIResponse(
1214
data=response.content,
1315
status_code=response.status_code,

openapi_core/deserializing/exceptions.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import attr
1+
from dataclasses import dataclass
22

33
from openapi_core.exceptions import OpenAPIError
44

55

6-
@attr.s(hash=True)
6+
@dataclass
77
class DeserializeError(OpenAPIError):
88
"""Deserialize operation error"""
9-
value = attr.ib()
10-
style = attr.ib()
9+
value: str
10+
style: str
1111

1212
def __str__(self):
1313
return "Failed to deserialize value {value} with style {style}".format(
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import attr
1+
from dataclasses import dataclass
22

33
from openapi_core.deserializing.exceptions import DeserializeError
44

55

6-
@attr.s(hash=True)
6+
@dataclass
77
class EmptyParameterValue(DeserializeError):
8-
name = attr.ib()
8+
name: str
99

1010
def __str__(self):
1111
return "Value of parameter cannot be empty: {0}".format(self.name)

openapi_core/exceptions.py

+18-15
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
"""OpenAPI core exceptions module"""
2-
import attr
2+
from dataclasses import dataclass
3+
4+
from openapi_core.validation.request.datatypes import OpenAPIRequest
5+
from openapi_core.validation.response.datatypes import OpenAPIResponse
36

47

58
class OpenAPIError(Exception):
@@ -15,18 +18,18 @@ class MissingHeaderError(OpenAPIHeaderError):
1518
pass
1619

1720

18-
@attr.s(hash=True)
21+
@dataclass
1922
class MissingHeader(MissingHeaderError):
20-
name = attr.ib()
23+
name: str
2124

2225
def __str__(self):
2326
return "Missing header (without default value): {0}".format(
2427
self.name)
2528

2629

27-
@attr.s(hash=True)
30+
@dataclass
2831
class MissingRequiredHeader(MissingHeaderError):
29-
name = attr.ib()
32+
name: str
3033

3134
def __str__(self):
3235
return "Missing required header: {0}".format(self.name)
@@ -41,18 +44,18 @@ class MissingParameterError(OpenAPIParameterError):
4144
pass
4245

4346

44-
@attr.s(hash=True)
47+
@dataclass
4548
class MissingParameter(MissingParameterError):
46-
name = attr.ib()
49+
name: str
4750

4851
def __str__(self):
4952
return "Missing parameter (without default value): {0}".format(
5053
self.name)
5154

5255

53-
@attr.s(hash=True)
56+
@dataclass
5457
class MissingRequiredParameter(MissingParameterError):
55-
name = attr.ib()
58+
name: str
5659

5760
def __str__(self):
5861
return "Missing required parameter: {0}".format(self.name)
@@ -67,17 +70,17 @@ class MissingRequestBodyError(OpenAPIRequestBodyError):
6770
pass
6871

6972

70-
@attr.s(hash=True)
73+
@dataclass
7174
class MissingRequestBody(MissingRequestBodyError):
72-
request = attr.ib()
75+
request: OpenAPIRequest
7376

7477
def __str__(self):
7578
return "Missing request body"
7679

7780

78-
@attr.s(hash=True)
81+
@dataclass
7982
class MissingRequiredRequestBody(MissingRequestBodyError):
80-
request = attr.ib()
83+
request: OpenAPIRequest
8184

8285
def __str__(self):
8386
return "Missing required request body"
@@ -87,9 +90,9 @@ class OpenAPIResponseError(OpenAPIError):
8790
pass
8891

8992

90-
@attr.s(hash=True)
93+
@dataclass
9194
class MissingResponseContent(OpenAPIResponseError):
92-
response = attr.ib()
95+
response: OpenAPIResponse
9396

9497
def __str__(self):
9598
return "Missing response content"

openapi_core/templating/datatypes.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
import attr
1+
from typing import Dict, Optional
22

3+
from dataclasses import dataclass
34

4-
@attr.s
5+
6+
@dataclass
57
class TemplateResult:
6-
pattern = attr.ib(default=None)
7-
variables = attr.ib(default=None)
8+
pattern: Optional[str] = None
9+
variables: Optional[Dict] = None
810

911
@property
1012
def resolved(self):

openapi_core/templating/media_types/exceptions.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import attr
1+
from typing import List
2+
3+
from dataclasses import dataclass
24

35
from openapi_core.exceptions import OpenAPIError
46

@@ -7,10 +9,10 @@ class MediaTypeFinderError(OpenAPIError):
79
"""Media type finder error"""
810

911

10-
@attr.s(hash=True)
12+
@dataclass
1113
class MediaTypeNotFound(MediaTypeFinderError):
12-
mimetype = attr.ib()
13-
availableMimetypes = attr.ib()
14+
mimetype: str
15+
availableMimetypes: List[str]
1416

1517
def __str__(self):
1618
return (
+8-8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import attr
1+
from dataclasses import dataclass
22

33
from openapi_core.exceptions import OpenAPIError
44

@@ -7,30 +7,30 @@ class PathError(OpenAPIError):
77
"""Path error"""
88

99

10-
@attr.s(hash=True)
10+
@dataclass
1111
class PathNotFound(PathError):
1212
"""Find path error"""
13-
url = attr.ib()
13+
url: str
1414

1515
def __str__(self):
1616
return "Path not found for {0}".format(self.url)
1717

1818

19-
@attr.s(hash=True)
19+
@dataclass
2020
class OperationNotFound(PathError):
2121
"""Find path operation error"""
22-
url = attr.ib()
23-
method = attr.ib()
22+
url: str
23+
method: str
2424

2525
def __str__(self):
2626
return "Operation {0} not found for {1}".format(
2727
self.method, self.url)
2828

2929

30-
@attr.s(hash=True)
30+
@dataclass
3131
class ServerNotFound(PathError):
3232
"""Find server error"""
33-
url = attr.ib()
33+
url: str
3434

3535
def __str__(self):
3636
return "Server not found for {0}".format(self.url)

0 commit comments

Comments
 (0)