Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spec.create deprecated #463

Merged
merged 1 commit into from
Jan 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,9 @@ Firstly create your specification object. By default, OpenAPI spec version is de

.. code-block:: python

from json import load
from openapi_core import Spec

with open('openapi.json', 'r') as spec_file:
spec_dict = load(spec_file)

spec = Spec.create(spec_dict)
spec = Spec.from_file_path('openapi.json')

Request
*******
Expand Down
6 changes: 4 additions & 2 deletions docs/customizations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ Customizations
Spec validation
---------------

By default, spec dict is validated on spec creation time. Disabling the validator can improve the performance.
By default, the provided specification is validated on ``Spec`` object creation time.

If you know you have a valid specification already, disabling the validator can improve the performance.

.. code-block:: python

from openapi_core import Spec

spec = Spec.create(spec_dict, validator=None)
spec = Spec.from_dict(spec_dict, validator=None)

Deserializers
-------------
Expand Down
2 changes: 1 addition & 1 deletion docs/integrations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Django can be integrated by middleware. Add ``DjangoOpenAPIMiddleware`` to your
'openapi_core.contrib.django.middlewares.DjangoOpenAPIMiddleware',
]

OPENAPI_SPEC = Spec.create(spec_dict)
OPENAPI_SPEC = Spec.from_dict(spec_dict)

After that you have access to validation result object with all validated request data from Django view through request object.

Expand Down
6 changes: 1 addition & 5 deletions docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,9 @@ Firstly create your specification object. By default, OpenAPI spec version is de

.. code-block:: python

from json import load
from openapi_core import Spec

with open('openapi.json', 'r') as spec_file:
spec_dict = load(spec_file)

spec = Spec.create(spec_dict)
spec = Spec.from_file_path('openapi.json')


Request
Expand Down
29 changes: 27 additions & 2 deletions openapi_core/spec/paths.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import warnings
from typing import Any
from typing import Dict
from typing import Hashable
Expand Down Expand Up @@ -27,13 +28,37 @@ def create(
separator: str = SPEC_SEPARATOR,
validator: Optional[SupportsValidation] = openapi_spec_validator_proxy,
) -> TSpec:
if validator is not None:
validator.validate(data, spec_url=url)
warnings.warn(
"Spec.create method is deprecated. Use Spec.from_dict instead.",
DeprecationWarning,
)

return cls.from_dict(
data,
*args,
spec_url=url,
ref_resolver_handlers=ref_resolver_handlers,
separator=separator,
validator=validator,
)

@classmethod
def from_dict(
cls: Type[TSpec],
data: Mapping[Hashable, Any],
*args: Any,
spec_url: str = "",
ref_resolver_handlers: Mapping[str, Any] = default_handlers,
separator: str = SPEC_SEPARATOR,
validator: Optional[SupportsValidation] = openapi_spec_validator_proxy,
) -> TSpec:
if validator is not None:
validator.validate(data, spec_url=spec_url)

return super().from_dict(
data,
*args,
spec_url=spec_url,
ref_resolver_handlers=ref_resolver_handlers,
separator=separator,
)
10 changes: 8 additions & 2 deletions openapi_core/spec/shortcuts.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""OpenAPI core spec shortcuts module"""
import warnings
from typing import Any
from typing import Dict
from typing import Hashable
Expand All @@ -18,13 +19,18 @@ def create_spec(
handlers: Dict[str, Any] = default_handlers,
validate_spec: bool = True,
) -> Spec:
warnings.warn(
"create_spec function is deprecated. Use Spec.from_dict instead.",
DeprecationWarning,
)

validator: Optional[SupportsValidation] = None
if validate_spec:
validator = openapi_spec_validator_proxy

return Spec.create(
return Spec.from_dict(
spec_dict,
url=spec_url,
spec_url=spec_url,
ref_resolver_handlers=handlers,
validator=validator,
)
8 changes: 6 additions & 2 deletions openapi_core/unmarshalling/schemas/unmarshallers.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,9 @@ class ArrayUnmarshaller(ComplexUnmarshaller):
@property
def items_unmarshaller(self) -> "BaseSchemaUnmarshaller":
# sometimes we don't have any schema i.e. free-form objects
items_schema = self.schema.get("items", Spec.from_dict({}))
items_schema = self.schema.get(
"items", Spec.from_dict({}, validator=None)
)
return self.unmarshallers_factory.create(items_schema)

def unmarshal(self, value: Any) -> Optional[List[Any]]:
Expand Down Expand Up @@ -383,7 +385,9 @@ def _unmarshal_properties(
if additional_properties is not False:
# free-form object
if additional_properties is True:
additional_prop_schema = Spec.from_dict({"nullable": True})
additional_prop_schema = Spec.from_dict(
{"nullable": True}, validator=None
)
# defined schema
else:
additional_prop_schema = self.schema / "additionalProperties"
Expand Down
4 changes: 2 additions & 2 deletions tests/integration/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ def content_from_file(spec_file):

def spec_from_file(spec_file):
spec_dict, spec_url = content_from_file(spec_file)
return Spec.create(spec_dict, url=spec_url)
return Spec.from_dict(spec_dict, spec_url=spec_url)


def spec_from_url(spec_url):
content = request.urlopen(spec_url)
spec_dict = safe_load(content)
return Spec.create(spec_dict, url=spec_url)
return Spec.from_dict(spec_dict, spec_url=spec_url)


class Factory(dict):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,4 @@

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

OPENAPI_SPEC = Spec.create(OPENAPI_SPEC_DICT)
OPENAPI_SPEC = Spec.from_dict(OPENAPI_SPEC_DICT)
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@

openapi_spec_path = Path("tests/integration/data/v3.0/petstore.yaml")
spec_dict = yaml.load(openapi_spec_path.read_text(), yaml.Loader)
spec = Spec.create(spec_dict)
spec = Spec.from_dict(spec_dict)
openapi_middleware = FalconOpenAPIMiddleware.from_spec(spec)
2 changes: 1 addition & 1 deletion tests/integration/schema/test_empty.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
class TestEmpty:
def test_raises_on_invalid(self):
with pytest.raises(ValidatorDetectError):
Spec.create("")
Spec.from_dict("")
8 changes: 4 additions & 4 deletions tests/integration/schema/test_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ def spec_dict(self, factory):

@pytest.fixture
def spec(self, spec_dict, spec_uri):
return Spec.create(
spec_dict, url=spec_uri, validator=openapi_v30_spec_validator
return Spec.from_dict(
spec_dict, spec_url=spec_uri, validator=openapi_v30_spec_validator
)

@pytest.fixture
Expand Down Expand Up @@ -325,9 +325,9 @@ def spec_dict(self, factory):

@pytest.fixture
def spec(self, spec_dict, spec_uri):
return Spec.create(
return Spec.from_dict(
spec_dict,
url=spec_uri,
spec_url=spec_uri,
validator=openapi_v31_spec_validator,
)

Expand Down
2 changes: 1 addition & 1 deletion tests/integration/validation/test_petstore.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def spec_dict(self, factory):

@pytest.fixture(scope="module")
def spec(self, spec_dict, spec_uri):
return Spec.create(spec_dict, url=spec_uri)
return Spec.from_dict(spec_dict, spec_url=spec_uri)

def test_get_pets(self, spec):
host_url = "http://petstore.swagger.io/v1"
Expand Down
6 changes: 3 additions & 3 deletions tests/integration/validation/test_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def spec_dict(self, factory):

@pytest.fixture(scope="session")
def spec(self, spec_dict):
return Spec.create(spec_dict)
return Spec.from_dict(spec_dict)

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

@pytest.fixture(scope="session")
def spec(self, spec_dict):
return Spec.create(spec_dict)
return Spec.from_dict(spec_dict)

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

@pytest.fixture
def spec(self, spec_dict):
return Spec.create(spec_dict)
return Spec.from_dict(spec_dict)

def test_invalid_server(self, spec):
request = MockRequest("http://petstore.invalid.net/v1", "get", "/")
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/casting/test_schema_casters.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def test_array_invalid_type(self, caster_factory):
"type": "number",
},
}
schema = Spec.from_dict(spec)
schema = Spec.from_dict(spec, validator=None)
value = ["test", "test2"]

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

with pytest.raises(
CastError, match=f"Failed to cast value to array type: {value}"
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/deserializing/test_parameters_deserializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def create_deserializer(param):

def test_unsupported(self, deserializer_factory):
spec = {"name": "param", "in": "header", "style": "unsupported"}
param = Spec.from_dict(spec)
param = Spec.from_dict(spec, validator=None)
value = ""

with pytest.warns(UserWarning):
Expand All @@ -32,7 +32,7 @@ def test_query_empty(self, deserializer_factory):
"name": "param",
"in": "query",
}
param = Spec.from_dict(spec)
param = Spec.from_dict(spec, validator=None)
value = ""

with pytest.raises(EmptyQueryParameterValue):
Expand All @@ -43,7 +43,7 @@ def test_query_valid(self, deserializer_factory):
"name": "param",
"in": "query",
}
param = Spec.from_dict(spec)
param = Spec.from_dict(spec, validator=None)
value = "test"

result = deserializer_factory(param)(value)
Expand Down
6 changes: 4 additions & 2 deletions tests/unit/extensions/test_factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class BarModel:
def test_dynamic_model(self):
factory = ModelPathFactory()

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

assert is_dataclass(test_model_class)
Expand All @@ -38,7 +38,9 @@ def test_dynamic_model(self):
def test_model_path(self, loaded_model_class):
factory = ModelPathFactory()

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

assert test_model_class == loaded_model_class
10 changes: 5 additions & 5 deletions tests/unit/schema/test_schema_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def test_defaults(self, location, expected):
"name": "default",
"in": location,
}
param = Spec.from_dict(spec)
param = Spec.from_dict(spec, validator=None)
result = get_style(param)

assert result == expected
Expand All @@ -45,7 +45,7 @@ def test_defined(self, style, location):
"in": location,
"style": style,
}
param = Spec.from_dict(spec)
param = Spec.from_dict(spec, validator=None)
result = get_style(param)

assert result == style
Expand All @@ -69,7 +69,7 @@ def test_defaults_false(self, style, location):
"in": location,
"style": style,
}
param = Spec.from_dict(spec)
param = Spec.from_dict(spec, validator=None)
result = get_explode(param)

assert result is False
Expand All @@ -81,7 +81,7 @@ def test_defaults_true(self, location):
"in": location,
"style": "form",
}
param = Spec.from_dict(spec)
param = Spec.from_dict(spec, validator=None)
result = get_explode(param)

assert result is True
Expand Down Expand Up @@ -117,7 +117,7 @@ def test_defined(self, location, style, schema_type, explode):
"type": schema_type,
},
}
param = Spec.from_dict(spec)
param = Spec.from_dict(spec, validator=None)
result = get_explode(param)

assert result == explode
2 changes: 1 addition & 1 deletion tests/unit/security/test_providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def test_header(self, header, scheme):
"/pets",
headers=headers,
)
scheme = Spec.from_dict(spec)
scheme = Spec.from_dict(spec, validator=None)
provider = HttpProvider(scheme)

result = provider(request)
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/templating/test_media_types_finders.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def spec(self):

@pytest.fixture(scope="class")
def content(self, spec):
return Spec.from_dict(spec)
return Spec.from_dict(spec, validator=None)

@pytest.fixture(scope="class")
def finder(self, content):
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/templating/test_paths_finders.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def spec(self, info, paths, servers):
"servers": servers,
"paths": paths,
}
return Spec.from_dict(spec)
return Spec.from_dict(spec, validator=None)

@pytest.fixture
def finder(self, spec):
Expand All @@ -151,7 +151,7 @@ def spec(self, info, paths):
"info": info,
"paths": paths,
}
return Spec.from_dict(spec)
return Spec.from_dict(spec, validator=None)


class BaseTestOperationServer(BaseTestSpecServer):
Expand All @@ -171,7 +171,7 @@ def spec(self, info, paths):
"info": info,
"paths": paths,
}
return Spec.from_dict(spec)
return Spec.from_dict(spec, validator=None)


class BaseTestServerNotFound:
Expand Down
Loading