Skip to content

Commit d793a37

Browse files
committed
Unmarshallers format validators refactor
1 parent d22aaf9 commit d793a37

31 files changed

+1267
-1280
lines changed

Diff for: openapi_core/unmarshalling/schemas/__init__.py

+72-7
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,96 @@
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 FormatUnmarshaller
13+
from openapi_core.unmarshalling.schemas.unmarshallers import (
14+
MultiTypeUnmarshaller,
15+
)
16+
from openapi_core.unmarshalling.schemas.unmarshallers import ObjectUnmarshaller
17+
from openapi_core.unmarshalling.schemas.unmarshallers import TypesUnmarshaller
18+
from openapi_core.unmarshalling.schemas.util import format_byte
19+
from openapi_core.unmarshalling.schemas.util import format_date
20+
from openapi_core.unmarshalling.schemas.util import format_uuid
21+
from openapi_core.validation.schemas import (
22+
oas30_read_schema_validators_factory,
23+
)
24+
from openapi_core.validation.schemas import (
25+
oas30_write_schema_validators_factory,
26+
)
27+
from openapi_core.validation.schemas import oas31_schema_validators_factory
828

929
__all__ = [
30+
"oas30_format_unmarshallers",
31+
"oas31_format_unmarshallers",
1032
"oas30_request_schema_unmarshallers_factory",
1133
"oas30_response_schema_unmarshallers_factory",
1234
"oas31_request_schema_unmarshallers_factory",
1335
"oas31_response_schema_unmarshallers_factory",
1436
"oas31_schema_unmarshallers_factory",
1537
]
1638

17-
oas30_request_schema_unmarshallers_factory = SchemaUnmarshallersFactory(
18-
OAS30Validator,
39+
oas30_unmarshallers_dict = OrderedDict(
40+
[
41+
("string", FormatUnmarshaller),
42+
("integer", FormatUnmarshaller),
43+
("number", FormatUnmarshaller),
44+
("boolean", FormatUnmarshaller),
45+
("array", ArrayUnmarshaller),
46+
("object", ObjectUnmarshaller),
47+
]
48+
)
49+
oas31_unmarshallers_dict = oas30_unmarshallers_dict.copy()
50+
oas31_unmarshallers_dict.update(
51+
{
52+
"null": FormatUnmarshaller,
53+
}
54+
)
55+
56+
oas30_types_unmarshaller = TypesUnmarshaller(
57+
oas30_unmarshallers_dict,
58+
AnyUnmarshaller,
59+
)
60+
oas31_types_unmarshaller = TypesUnmarshaller(
61+
oas31_unmarshallers_dict,
62+
AnyUnmarshaller,
63+
multi=MultiTypeUnmarshaller,
64+
)
65+
66+
oas30_format_unmarshallers = {
67+
# string compatible
68+
"date": format_date,
69+
"date-time": parse_datetime,
70+
"binary": bytes,
71+
"uuid": format_uuid,
72+
"byte": format_byte,
73+
}
74+
oas31_format_unmarshallers = oas30_format_unmarshallers
75+
76+
oas30_write_schema_unmarshallers_factory = SchemaUnmarshallersFactory(
77+
oas30_write_schema_validators_factory,
78+
oas30_types_unmarshaller,
79+
format_unmarshallers=oas30_format_unmarshallers,
1980
context=ValidationContext.REQUEST,
2081
)
2182

22-
oas30_response_schema_unmarshallers_factory = SchemaUnmarshallersFactory(
23-
OAS30Validator,
83+
oas30_read_schema_unmarshallers_factory = SchemaUnmarshallersFactory(
84+
oas30_read_schema_validators_factory,
85+
oas30_types_unmarshaller,
86+
format_unmarshallers=oas30_format_unmarshallers,
2487
context=ValidationContext.RESPONSE,
2588
)
2689

2790
oas31_schema_unmarshallers_factory = SchemaUnmarshallersFactory(
28-
OAS31Validator,
91+
oas31_schema_validators_factory,
92+
oas31_types_unmarshaller,
93+
format_unmarshallers=oas31_format_unmarshallers,
2994
)
3095

3196
# alias to v31 version (request/response are the same bcs no context needed)

Diff for: openapi_core/unmarshalling/schemas/datatypes.py

+5
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]]

Diff for: openapi_core/unmarshalling/schemas/exceptions.py

+8-27
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)