Skip to content

Commit 1aa5731

Browse files
committedFeb 15, 2023
Unmarshallers format validators refactor
1 parent d22aaf9 commit 1aa5731

32 files changed

+3485
-1372
lines changed
 

‎openapi_core/unmarshalling/schemas/__init__.py

+98-13
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,116 @@
1-
from openapi_schema_validator import OAS30Validator
2-
from openapi_schema_validator import OAS31Validator
1+
from collections import OrderedDict
2+
from functools import partial
3+
4+
from isodate.isodatetime import parse_datetime
35

46
from openapi_core.unmarshalling.schemas.enums import ValidationContext
57
from openapi_core.unmarshalling.schemas.factories import (
68
SchemaUnmarshallersFactory,
79
)
10+
from openapi_core.unmarshalling.schemas.unmarshallers import AnyUnmarshaller
11+
from openapi_core.unmarshalling.schemas.unmarshallers import ArrayUnmarshaller
12+
from openapi_core.unmarshalling.schemas.unmarshallers import (
13+
MultiTypeUnmarshaller,
14+
)
15+
from openapi_core.unmarshalling.schemas.unmarshallers import (
16+
ObjectReadUnmarshaller,
17+
)
18+
from openapi_core.unmarshalling.schemas.unmarshallers import ObjectUnmarshaller
19+
from openapi_core.unmarshalling.schemas.unmarshallers import (
20+
ObjectWriteUnmarshaller,
21+
)
22+
from openapi_core.unmarshalling.schemas.unmarshallers import (
23+
PrimitiveUnmarshaller,
24+
)
25+
from openapi_core.unmarshalling.schemas.unmarshallers import TypesUnmarshaller
26+
from openapi_core.unmarshalling.schemas.util import format_byte
27+
from openapi_core.unmarshalling.schemas.util import format_date
28+
from openapi_core.unmarshalling.schemas.util import format_uuid
29+
from openapi_core.validation.schemas import (
30+
oas30_read_schema_validators_factory,
31+
)
32+
from openapi_core.validation.schemas import (
33+
oas30_write_schema_validators_factory,
34+
)
35+
from openapi_core.validation.schemas import oas31_schema_validators_factory
836

937
__all__ = [
10-
"oas30_request_schema_unmarshallers_factory",
11-
"oas30_response_schema_unmarshallers_factory",
12-
"oas31_request_schema_unmarshallers_factory",
13-
"oas31_response_schema_unmarshallers_factory",
38+
"oas30_format_unmarshallers",
39+
"oas31_format_unmarshallers",
40+
"oas30_write_schema_unmarshallers_factory",
41+
"oas30_read_schema_unmarshallers_factory",
1442
"oas31_schema_unmarshallers_factory",
1543
]
1644

17-
oas30_request_schema_unmarshallers_factory = SchemaUnmarshallersFactory(
18-
OAS30Validator,
19-
context=ValidationContext.REQUEST,
45+
oas30_unmarshallers_dict = OrderedDict(
46+
[
47+
("string", PrimitiveUnmarshaller),
48+
("integer", PrimitiveUnmarshaller),
49+
("number", PrimitiveUnmarshaller),
50+
("boolean", PrimitiveUnmarshaller),
51+
("array", ArrayUnmarshaller),
52+
("object", ObjectUnmarshaller),
53+
]
54+
)
55+
oas30_write_unmarshallers_dict = oas30_unmarshallers_dict.copy()
56+
oas30_write_unmarshallers_dict.update(
57+
{
58+
"object": ObjectWriteUnmarshaller,
59+
}
60+
)
61+
oas30_read_unmarshallers_dict = oas30_unmarshallers_dict.copy()
62+
oas30_read_unmarshallers_dict.update(
63+
{
64+
"object": ObjectReadUnmarshaller,
65+
}
66+
)
67+
oas31_unmarshallers_dict = oas30_unmarshallers_dict.copy()
68+
oas31_unmarshallers_dict.update(
69+
{
70+
"null": PrimitiveUnmarshaller,
71+
}
72+
)
73+
74+
oas30_write_types_unmarshaller = TypesUnmarshaller(
75+
oas30_unmarshallers_dict,
76+
AnyUnmarshaller,
77+
)
78+
oas30_read_types_unmarshaller = TypesUnmarshaller(
79+
oas30_unmarshallers_dict,
80+
AnyUnmarshaller,
81+
)
82+
oas31_types_unmarshaller = TypesUnmarshaller(
83+
oas31_unmarshallers_dict,
84+
AnyUnmarshaller,
85+
multi=MultiTypeUnmarshaller,
86+
)
87+
88+
oas30_format_unmarshallers = {
89+
# string compatible
90+
"date": format_date,
91+
"date-time": parse_datetime,
92+
"binary": bytes,
93+
"uuid": format_uuid,
94+
"byte": format_byte,
95+
}
96+
oas31_format_unmarshallers = oas30_format_unmarshallers
97+
98+
oas30_write_schema_unmarshallers_factory = SchemaUnmarshallersFactory(
99+
oas30_write_schema_validators_factory,
100+
oas30_write_types_unmarshaller,
101+
format_unmarshallers=oas30_format_unmarshallers,
20102
)
21103

22-
oas30_response_schema_unmarshallers_factory = SchemaUnmarshallersFactory(
23-
OAS30Validator,
24-
context=ValidationContext.RESPONSE,
104+
oas30_read_schema_unmarshallers_factory = SchemaUnmarshallersFactory(
105+
oas30_read_schema_validators_factory,
106+
oas30_read_types_unmarshaller,
107+
format_unmarshallers=oas30_format_unmarshallers,
25108
)
26109

27110
oas31_schema_unmarshallers_factory = SchemaUnmarshallersFactory(
28-
OAS31Validator,
111+
oas31_schema_validators_factory,
112+
oas31_types_unmarshaller,
113+
format_unmarshallers=oas31_format_unmarshallers,
29114
)
30115

31116
# alias to v31 version (request/response are the same bcs no context needed)
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
from typing import Any
2+
from typing import Callable
13
from typing import Dict
24
from typing import Optional
35

46
from openapi_core.unmarshalling.schemas.formatters import Formatter
57

8+
FormatUnmarshaller = Callable[[Any], Any]
9+
610
CustomFormattersDict = Dict[str, Formatter]
711
FormattersDict = Dict[Optional[str], Formatter]
12+
UnmarshallersDict = Dict[str, Callable[[Any], Any]]
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
from dataclasses import dataclass
2-
from dataclasses import field
3-
from typing import Iterable
42

53
from openapi_core.exceptions import OpenAPIError
64

@@ -9,49 +7,32 @@ class UnmarshalError(OpenAPIError):
97
"""Schema unmarshal operation error"""
108

119

12-
class ValidateError(UnmarshalError):
13-
"""Schema validate operation error"""
14-
15-
1610
class UnmarshallerError(UnmarshalError):
1711
"""Unmarshaller error"""
1812

1913

2014
@dataclass
21-
class InvalidSchemaValue(ValidateError):
22-
value: str
23-
type: str
24-
schema_errors: Iterable[Exception] = field(default_factory=list)
15+
class FormatterNotFoundError(UnmarshallerError):
16+
"""Formatter not found to unmarshal"""
17+
18+
type_format: str
2519

2620
def __str__(self) -> str:
27-
return (
28-
"Value {value} not valid for schema of type {type}: {errors}"
29-
).format(value=self.value, type=self.type, errors=self.schema_errors)
21+
return f"Formatter not found for {self.type_format} format"
3022

3123

32-
@dataclass
33-
class InvalidSchemaFormatValue(UnmarshallerError):
34-
"""Value failed to format with formatter"""
24+
class FormatUnmarshalError(UnmarshallerError):
25+
"""Unable to unmarshal value for format"""
3526

3627
value: str
3728
type: str
3829
original_exception: Exception
3930

4031
def __str__(self) -> str:
4132
return (
42-
"Failed to format value {value} to format {type}: {exception}"
33+
"Unable to unmarshal value {value} for format {type}: {exception}"
4334
).format(
4435
value=self.value,
4536
type=self.type,
4637
exception=self.original_exception,
4738
)
48-
49-
50-
@dataclass
51-
class FormatterNotFoundError(UnmarshallerError):
52-
"""Formatter not found to unmarshal"""
53-
54-
type_format: str
55-
56-
def __str__(self) -> str:
57-
return f"Formatter not found for {self.type_format} format"

0 commit comments

Comments
 (0)