Skip to content

Commit ec1781e

Browse files
committed
spec create deprecated
1 parent 3cc812f commit ec1781e

File tree

24 files changed

+218
-187
lines changed

24 files changed

+218
-187
lines changed

README.rst

+1-5
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,9 @@ Firstly create your specification object. By default, OpenAPI spec version is de
6262

6363
.. code-block:: python
6464
65-
from json import load
6665
from openapi_core import Spec
6766
68-
with open('openapi.json', 'r') as spec_file:
69-
spec_dict = load(spec_file)
70-
71-
spec = Spec.create(spec_dict)
67+
spec = Spec.from_file_path('openapi.json')
7268
7369
Request
7470
*******

docs/customizations.rst

+4-2
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ Customizations
44
Spec validation
55
---------------
66

7-
By default, spec dict is validated on spec creation time. Disabling the validator can improve the performance.
7+
By default, the provided specification is validated on ``Spec`` object creation time.
8+
9+
If you know you have a valid specification already, disabling the validator can improve the performance.
810

911
.. code-block:: python
1012
1113
from openapi_core import Spec
1214
13-
spec = Spec.create(spec_dict, validator=None)
15+
spec = Spec.from_dict(spec_dict, validator=None)
1416
1517
Deserializers
1618
-------------

docs/integrations.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Django can be integrated by middleware. Add ``DjangoOpenAPIMiddleware`` to your
2828
'openapi_core.contrib.django.middlewares.DjangoOpenAPIMiddleware',
2929
]
3030
31-
OPENAPI_SPEC = Spec.create(spec_dict)
31+
OPENAPI_SPEC = Spec.from_dict(spec_dict)
3232
3333
After that you have access to validation result object with all validated request data from Django view through request object.
3434

docs/usage.rst

+1-5
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,9 @@ Firstly create your specification object. By default, OpenAPI spec version is de
55

66
.. code-block:: python
77
8-
from json import load
98
from openapi_core import Spec
109
11-
with open('openapi.json', 'r') as spec_file:
12-
spec_dict = load(spec_file)
13-
14-
spec = Spec.create(spec_dict)
10+
spec = Spec.from_file_path('openapi.json')
1511
1612
1713
Request

openapi_core/spec/paths.py

+27-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import warnings
12
from typing import Any
23
from typing import Dict
34
from typing import Hashable
@@ -27,13 +28,37 @@ def create(
2728
separator: str = SPEC_SEPARATOR,
2829
validator: Optional[SupportsValidation] = openapi_spec_validator_proxy,
2930
) -> TSpec:
30-
if validator is not None:
31-
validator.validate(data, spec_url=url)
31+
warnings.warn(
32+
"Spec.create method is deprecated. Use Spec.from_dict instead.",
33+
DeprecationWarning,
34+
)
3235

3336
return cls.from_dict(
3437
data,
3538
*args,
3639
spec_url=url,
3740
ref_resolver_handlers=ref_resolver_handlers,
3841
separator=separator,
42+
validator=validator,
43+
)
44+
45+
@classmethod
46+
def from_dict(
47+
cls: Type[TSpec],
48+
data: Mapping[Hashable, Any],
49+
*args: Any,
50+
spec_url: str = "",
51+
ref_resolver_handlers: Dict[str, Any] = default_handlers,
52+
separator: str = SPEC_SEPARATOR,
53+
validator: Optional[SupportsValidation] = openapi_spec_validator_proxy,
54+
) -> TSpec:
55+
if validator is not None:
56+
validator.validate(data, spec_url=spec_url)
57+
58+
return super().from_dict(
59+
data,
60+
*args,
61+
spec_url=spec_url,
62+
ref_resolver_handlers=ref_resolver_handlers,
63+
separator=separator,
3964
)

openapi_core/spec/shortcuts.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""OpenAPI core spec shortcuts module"""
2+
import warnings
23
from typing import Any
34
from typing import Dict
45
from typing import Hashable
@@ -18,13 +19,18 @@ def create_spec(
1819
handlers: Dict[str, Any] = default_handlers,
1920
validate_spec: bool = True,
2021
) -> Spec:
22+
warnings.warn(
23+
"create_spec function is deprecated. Use Spec.from_dict instead.",
24+
DeprecationWarning,
25+
)
26+
2127
validator: Optional[SupportsValidation] = None
2228
if validate_spec:
2329
validator = openapi_spec_validator_proxy
2430

25-
return Spec.create(
31+
return Spec.from_dict(
2632
spec_dict,
27-
url=spec_url,
33+
spec_url=spec_url,
2834
ref_resolver_handlers=handlers,
2935
validator=validator,
3036
)

openapi_core/unmarshalling/schemas/unmarshallers.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,9 @@ class ArrayUnmarshaller(ComplexUnmarshaller):
294294
@property
295295
def items_unmarshaller(self) -> "BaseSchemaUnmarshaller":
296296
# sometimes we don't have any schema i.e. free-form objects
297-
items_schema = self.schema.get("items", Spec.from_dict({}))
297+
items_schema = self.schema.get(
298+
"items", Spec.from_dict({}, validator=None)
299+
)
298300
return self.unmarshallers_factory.create(items_schema)
299301

300302
def unmarshal(self, value: Any) -> Optional[List[Any]]:
@@ -383,7 +385,9 @@ def _unmarshal_properties(
383385
if additional_properties is not False:
384386
# free-form object
385387
if additional_properties is True:
386-
additional_prop_schema = Spec.from_dict({"nullable": True})
388+
additional_prop_schema = Spec.from_dict(
389+
{"nullable": True}, validator=None
390+
)
387391
# defined schema
388392
else:
389393
additional_prop_schema = self.schema / "additionalProperties"

tests/integration/conftest.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ def content_from_file(spec_file):
1616

1717
def spec_from_file(spec_file):
1818
spec_dict, spec_url = content_from_file(spec_file)
19-
return Spec.create(spec_dict, url=spec_url)
19+
return Spec.from_dict(spec_dict, spec_url=spec_url)
2020

2121

2222
def spec_from_url(spec_url):
2323
content = request.urlopen(spec_url)
2424
spec_dict = safe_load(content)
25-
return Spec.create(spec_dict, url=spec_url)
25+
return Spec.from_dict(spec_dict, spec_url=spec_url)
2626

2727

2828
class Factory(dict):

tests/integration/contrib/django/data/v3.0/djangoproject/settings.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,4 @@
123123

124124
OPENAPI_SPEC_DICT = yaml.load(OPENAPI_SPEC_PATH.read_text(), yaml.Loader)
125125

126-
OPENAPI_SPEC = Spec.create(OPENAPI_SPEC_DICT)
126+
OPENAPI_SPEC = Spec.from_dict(OPENAPI_SPEC_DICT)

tests/integration/contrib/falcon/data/v3.0/falconproject/openapi.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@
77

88
openapi_spec_path = Path("tests/integration/data/v3.0/petstore.yaml")
99
spec_dict = yaml.load(openapi_spec_path.read_text(), yaml.Loader)
10-
spec = Spec.create(spec_dict)
10+
spec = Spec.from_dict(spec_dict)
1111
openapi_middleware = FalconOpenAPIMiddleware.from_spec(spec)

tests/integration/schema/test_empty.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@
77
class TestEmpty:
88
def test_raises_on_invalid(self):
99
with pytest.raises(ValidatorDetectError):
10-
Spec.create("")
10+
Spec.from_dict("")

tests/integration/schema/test_spec.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ def spec_dict(self, factory):
3232

3333
@pytest.fixture
3434
def spec(self, spec_dict, spec_uri):
35-
return Spec.create(
36-
spec_dict, url=spec_uri, validator=openapi_v30_spec_validator
35+
return Spec.from_dict(
36+
spec_dict, spec_uri=spec_uri, validator=openapi_v30_spec_validator
3737
)
3838

3939
@pytest.fixture
@@ -325,9 +325,9 @@ def spec_dict(self, factory):
325325

326326
@pytest.fixture
327327
def spec(self, spec_dict, spec_uri):
328-
return Spec.create(
328+
return Spec.from_dict(
329329
spec_dict,
330-
url=spec_uri,
330+
spec_url=spec_uri,
331331
validator=openapi_v31_spec_validator,
332332
)
333333

tests/integration/validation/test_petstore.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def spec_dict(self, factory):
6161

6262
@pytest.fixture(scope="module")
6363
def spec(self, spec_dict, spec_uri):
64-
return Spec.create(spec_dict, url=spec_uri)
64+
return Spec.from_dict(spec_dict, spec_url=spec_uri)
6565

6666
def test_get_pets(self, spec):
6767
host_url = "http://petstore.swagger.io/v1"

tests/integration/validation/test_validators.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def spec_dict(self, factory):
4545

4646
@pytest.fixture(scope="session")
4747
def spec(self, spec_dict):
48-
return Spec.create(spec_dict)
48+
return Spec.from_dict(spec_dict)
4949

5050
def test_request_server_error(self, spec):
5151
request = MockRequest("http://petstore.invalid.net/v1", "get", "/")
@@ -443,7 +443,7 @@ def spec_dict(self):
443443

444444
@pytest.fixture(scope="session")
445445
def spec(self, spec_dict):
446-
return Spec.create(spec_dict)
446+
return Spec.from_dict(spec_dict)
447447

448448
def test_request_missing_param(self, spec):
449449
request = MockRequest("http://example.com", "get", "/resource")
@@ -576,7 +576,7 @@ def spec_dict(self, factory):
576576

577577
@pytest.fixture
578578
def spec(self, spec_dict):
579-
return Spec.create(spec_dict)
579+
return Spec.from_dict(spec_dict)
580580

581581
def test_invalid_server(self, spec):
582582
request = MockRequest("http://petstore.invalid.net/v1", "get", "/")

tests/unit/casting/test_schema_casters.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def test_array_invalid_type(self, caster_factory):
2020
"type": "number",
2121
},
2222
}
23-
schema = Spec.from_dict(spec)
23+
schema = Spec.from_dict(spec, validator=None)
2424
value = ["test", "test2"]
2525

2626
with pytest.raises(CastError):
@@ -34,7 +34,7 @@ def test_array_invalid_value(self, value, caster_factory):
3434
"oneOf": [{"type": "number"}, {"type": "string"}],
3535
},
3636
}
37-
schema = Spec.from_dict(spec)
37+
schema = Spec.from_dict(spec, validator=None)
3838

3939
with pytest.raises(
4040
CastError, match=f"Failed to cast value to array type: {value}"

tests/unit/deserializing/test_parameters_deserializers.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def create_deserializer(param):
1919

2020
def test_unsupported(self, deserializer_factory):
2121
spec = {"name": "param", "in": "header", "style": "unsupported"}
22-
param = Spec.from_dict(spec)
22+
param = Spec.from_dict(spec, validator=None)
2323
value = ""
2424

2525
with pytest.warns(UserWarning):
@@ -32,7 +32,7 @@ def test_query_empty(self, deserializer_factory):
3232
"name": "param",
3333
"in": "query",
3434
}
35-
param = Spec.from_dict(spec)
35+
param = Spec.from_dict(spec, validator=None)
3636
value = ""
3737

3838
with pytest.raises(EmptyQueryParameterValue):
@@ -43,7 +43,7 @@ def test_query_valid(self, deserializer_factory):
4343
"name": "param",
4444
"in": "query",
4545
}
46-
param = Spec.from_dict(spec)
46+
param = Spec.from_dict(spec, validator=None)
4747
value = "test"
4848

4949
result = deserializer_factory(param)(value)

tests/unit/extensions/test_factories.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class BarModel:
2727
def test_dynamic_model(self):
2828
factory = ModelPathFactory()
2929

30-
schema = Spec.from_dict({"x-model": "TestModel"})
30+
schema = Spec.from_dict({"x-model": "TestModel"}, validator=None)
3131
test_model_class = factory.create(schema, ["name"])
3232

3333
assert is_dataclass(test_model_class)
@@ -38,7 +38,9 @@ def test_dynamic_model(self):
3838
def test_model_path(self, loaded_model_class):
3939
factory = ModelPathFactory()
4040

41-
schema = Spec.from_dict({"x-model-path": "foo.BarModel"})
41+
schema = Spec.from_dict(
42+
{"x-model-path": "foo.BarModel"}, validator=None
43+
)
4244
test_model_class = factory.create(schema, ["a", "b"])
4345

4446
assert test_model_class == loaded_model_class

tests/unit/schema/test_schema_parameters.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def test_defaults(self, location, expected):
2020
"name": "default",
2121
"in": location,
2222
}
23-
param = Spec.from_dict(spec)
23+
param = Spec.from_dict(spec, validator=None)
2424
result = get_style(param)
2525

2626
assert result == expected
@@ -45,7 +45,7 @@ def test_defined(self, style, location):
4545
"in": location,
4646
"style": style,
4747
}
48-
param = Spec.from_dict(spec)
48+
param = Spec.from_dict(spec, validator=None)
4949
result = get_style(param)
5050

5151
assert result == style
@@ -69,7 +69,7 @@ def test_defaults_false(self, style, location):
6969
"in": location,
7070
"style": style,
7171
}
72-
param = Spec.from_dict(spec)
72+
param = Spec.from_dict(spec, validator=None)
7373
result = get_explode(param)
7474

7575
assert result is False
@@ -81,7 +81,7 @@ def test_defaults_true(self, location):
8181
"in": location,
8282
"style": "form",
8383
}
84-
param = Spec.from_dict(spec)
84+
param = Spec.from_dict(spec, validator=None)
8585
result = get_explode(param)
8686

8787
assert result is True
@@ -117,7 +117,7 @@ def test_defined(self, location, style, schema_type, explode):
117117
"type": schema_type,
118118
},
119119
}
120-
param = Spec.from_dict(spec)
120+
param = Spec.from_dict(spec, validator=None)
121121
result = get_explode(param)
122122

123123
assert result == explode

tests/unit/security/test_providers.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def test_header(self, header, scheme):
3232
"/pets",
3333
headers=headers,
3434
)
35-
scheme = Spec.from_dict(spec)
35+
scheme = Spec.from_dict(spec, validator=None)
3636
provider = HttpProvider(scheme)
3737

3838
result = provider(request)

tests/unit/templating/test_media_types_finders.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def spec(self):
1616

1717
@pytest.fixture(scope="class")
1818
def content(self, spec):
19-
return Spec.from_dict(spec)
19+
return Spec.from_dict(spec, validator=None)
2020

2121
@pytest.fixture(scope="class")
2222
def finder(self, content):

tests/unit/templating/test_paths_finders.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ def spec(self, info, paths, servers):
128128
"servers": servers,
129129
"paths": paths,
130130
}
131-
return Spec.from_dict(spec)
131+
return Spec.from_dict(spec, validator=None)
132132

133133
@pytest.fixture
134134
def finder(self, spec):
@@ -151,7 +151,7 @@ def spec(self, info, paths):
151151
"info": info,
152152
"paths": paths,
153153
}
154-
return Spec.from_dict(spec)
154+
return Spec.from_dict(spec, validator=None)
155155

156156

157157
class BaseTestOperationServer(BaseTestSpecServer):
@@ -171,7 +171,7 @@ def spec(self, info, paths):
171171
"info": info,
172172
"paths": paths,
173173
}
174-
return Spec.from_dict(spec)
174+
return Spec.from_dict(spec, validator=None)
175175

176176

177177
class BaseTestServerNotFound:

0 commit comments

Comments
 (0)