Skip to content

Commit 428958a

Browse files
authored
Merge pull request #393 from p1c2u/refactor/get-rid-of-create-spec-shortcut
Get rid of create_spec shortcut
2 parents 5e9af67 + cd92f42 commit 428958a

33 files changed

+495
-446
lines changed

Diff for: README.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,12 @@ Firstly create your specification object:
6262
.. code-block:: python
6363
6464
from json import load
65-
from openapi_core import create_spec
65+
from openapi_core import OpenAPISpec as Spec
6666
6767
with open('openapi.json', 'r') as spec_file:
6868
spec_dict = load(spec_file)
6969
70-
spec = create_spec(spec_dict)
70+
spec = Spec.create(spec_dict)
7171
7272
Request
7373
*******

Diff for: docs/customizations.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ By default, spec dict is validated on spec creation time. Disabling the validati
88

99
.. code-block:: python
1010
11-
from openapi_core import create_spec
11+
from openapi_core import OpenAPISpec as Spec
1212
13-
spec = create_spec(spec_dict, validate_spec=False)
13+
spec = Spec.create(spec_dict, validate=False)
1414
1515
Deserializers
1616
-------------

Diff for: docs/integrations.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ Django can be integrated by middleware. Add `DjangoOpenAPIMiddleware` to your `M
2121
.. code-block:: python
2222
2323
# settings.py
24-
from openapi_core import create_spec
24+
from openapi_core import OpenAPISpec as Spec
2525
2626
MIDDLEWARE = [
2727
# ...
2828
'openapi_core.contrib.django.middlewares.DjangoOpenAPIMiddleware',
2929
]
3030
31-
OPENAPI_SPEC = create_spec(spec_dict)
31+
OPENAPI_SPEC = Spec.create(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

Diff for: docs/usage.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ Firstly create your specification: object
66
.. code-block:: python
77
88
from json import load
9-
from openapi_core import create_spec
9+
from openapi_core import OpenAPISpec as Spec
1010
1111
with open('openapi.json', 'r') as spec_file:
1212
spec_dict = load(spec_file)
1313
14-
spec = create_spec(spec_dict)
14+
spec = Spec.create(spec_dict)
1515
1616
1717
Request

Diff for: openapi_core/__init__.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
"""OpenAPI core module"""
2-
from openapi_core.shortcuts import create_spec
32
from openapi_core.shortcuts import spec_validate_body
43
from openapi_core.shortcuts import spec_validate_data
54
from openapi_core.shortcuts import spec_validate_headers
65
from openapi_core.shortcuts import spec_validate_parameters
76
from openapi_core.shortcuts import spec_validate_security
87
from openapi_core.shortcuts import validate_request
98
from openapi_core.shortcuts import validate_response
9+
from openapi_core.spec import OpenAPIv30Spec
1010
from openapi_core.validation.request.validators import RequestBodyValidator
1111
from openapi_core.validation.request.validators import (
1212
RequestParametersValidator,
@@ -26,7 +26,9 @@
2626
__license__ = "BSD 3-Clause License"
2727

2828
__all__ = [
29-
"create_spec",
29+
"OpenAPIv30Spec",
30+
"OpenAPIv3Spec",
31+
"OpenAPISpec",
3032
"validate_request",
3133
"validate_response",
3234
"spec_validate_body",
@@ -42,3 +44,9 @@
4244
"ResponseDataValidator",
4345
"ResponseHeadersValidator",
4446
]
47+
48+
# aliases to the latest v3 version
49+
OpenAPIv3Spec = OpenAPIv30Spec
50+
51+
# aliases to the latest version
52+
OpenAPISpec = OpenAPIv3Spec

Diff for: openapi_core/shortcuts.py

-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
"""OpenAPI core shortcuts module"""
22
# backward compatibility
3-
from openapi_core.spec.shortcuts import create_spec
43
from openapi_core.validation.request.shortcuts import spec_validate_body
54
from openapi_core.validation.request.shortcuts import spec_validate_parameters
65
from openapi_core.validation.request.shortcuts import spec_validate_security
@@ -10,7 +9,6 @@
109
from openapi_core.validation.response.shortcuts import validate_response
1110

1211
__all__ = [
13-
"create_spec",
1412
"validate_request",
1513
"validate_response",
1614
"spec_validate_body",

Diff for: openapi_core/spec/__init__.py

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from openapi_core.spec.paths import OpenAPIv30Spec
2+
3+
__all__ = [
4+
"OpenAPIv30Spec",
5+
]

Diff for: openapi_core/spec/paths.py

+42-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,51 @@
1+
from jsonschema.validators import RefResolver
2+
from openapi_spec_validator import default_handlers
3+
from openapi_spec_validator import openapi_v3_spec_validator
4+
from openapi_spec_validator.validators import Dereferencer
15
from pathable.paths import AccessorPath
26

37
from openapi_core.spec.accessors import SpecAccessor
48

59
SPEC_SEPARATOR = "#"
610

711

8-
class SpecPath(AccessorPath):
12+
class Spec(AccessorPath):
913
@classmethod
10-
def from_spec(cls, spec_dict, dereferencer=None, *args, **kwargs):
11-
separator = kwargs.pop("separator", SPEC_SEPARATOR)
12-
accessor = SpecAccessor(spec_dict, dereferencer)
14+
def from_dict(
15+
cls,
16+
data,
17+
*args,
18+
url="",
19+
ref_resolver_handlers=default_handlers,
20+
separator=SPEC_SEPARATOR,
21+
):
22+
ref_resolver = RefResolver(url, data, handlers=ref_resolver_handlers)
23+
dereferencer = Dereferencer(ref_resolver)
24+
accessor = SpecAccessor(data, dereferencer)
1325
return cls(accessor, *args, separator=separator)
26+
27+
28+
class OpenAPIv30Spec(Spec):
29+
30+
validator = openapi_v3_spec_validator
31+
32+
@classmethod
33+
def create(
34+
cls,
35+
data,
36+
*args,
37+
url="",
38+
ref_resolver_handlers=default_handlers,
39+
separator=SPEC_SEPARATOR,
40+
validate=True,
41+
):
42+
if validate:
43+
cls.validator.validate(data, spec_url=url)
44+
45+
return cls.from_dict(
46+
data,
47+
*args,
48+
url=url,
49+
ref_resolver_handlers=ref_resolver_handlers,
50+
separator=separator,
51+
)

Diff for: openapi_core/templating/paths/util.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from typing import Tuple
22

3-
from openapi_core.spec.paths import SpecPath
3+
from openapi_core.spec.paths import OpenAPIv30Spec as Spec
44
from openapi_core.templating.datatypes import TemplateResult
55

66

7-
def template_path_len(template_path: Tuple[SpecPath, TemplateResult]) -> int:
7+
def template_path_len(template_path: Tuple[Spec, TemplateResult]) -> int:
88
return len(template_path[1].variables)

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
import yaml
1717

18-
from openapi_core import create_spec
18+
from openapi_core import OpenAPISpec as Spec
1919

2020
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
2121
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@@ -123,4 +123,4 @@
123123

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

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

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
import yaml
44

5-
from openapi_core import create_spec
5+
from openapi_core import OpenAPISpec as Spec
66
from openapi_core.contrib.falcon.middlewares import FalconOpenAPIMiddleware
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 = create_spec(spec_dict)
10+
spec = Spec.create(spec_dict)
1111
openapi_middleware = FalconOpenAPIMiddleware.from_spec(spec)

Diff for: tests/integration/contrib/flask/test_flask_decorator.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from flask import make_response
55

66
from openapi_core.contrib.flask.decorators import FlaskOpenAPIViewDecorator
7-
from openapi_core.shortcuts import create_spec
7+
from openapi_core.spec import OpenAPIv30Spec as Spec
88
from openapi_core.validation.request.datatypes import Parameters
99

1010

@@ -15,7 +15,7 @@ class TestFlaskOpenAPIDecorator:
1515
@pytest.fixture
1616
def spec(self, factory):
1717
specfile = "contrib/flask/data/v3.0/flask_factory.yaml"
18-
return create_spec(factory.spec_from_file(specfile))
18+
return Spec.create(factory.spec_from_file(specfile))
1919

2020
@pytest.fixture
2121
def decorator(self, spec):

Diff for: tests/integration/contrib/flask/test_flask_validation.py

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

33
from openapi_core.contrib.flask import FlaskOpenAPIRequest
44
from openapi_core.contrib.flask import FlaskOpenAPIResponse
5-
from openapi_core.shortcuts import create_spec
5+
from openapi_core.spec import OpenAPIv30Spec as Spec
66
from openapi_core.validation.request.validators import RequestValidator
77
from openapi_core.validation.response.validators import ResponseValidator
88

@@ -11,7 +11,7 @@ class TestFlaskOpenAPIValidation:
1111
@pytest.fixture
1212
def flask_spec(self, factory):
1313
specfile = "contrib/flask/data/v3.0/flask_factory.yaml"
14-
return create_spec(factory.spec_from_file(specfile))
14+
return Spec.create(factory.spec_from_file(specfile))
1515

1616
def test_response_validator_path_pattern(
1717
self, flask_spec, request_factory, response_factory

Diff for: tests/integration/contrib/flask/test_flask_views.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from flask import make_response
55

66
from openapi_core.contrib.flask.views import FlaskOpenAPIView
7-
from openapi_core.shortcuts import create_spec
7+
from openapi_core.spec import OpenAPIv30Spec as Spec
88

99

1010
class TestFlaskOpenAPIView:
@@ -14,7 +14,7 @@ class TestFlaskOpenAPIView:
1414
@pytest.fixture
1515
def spec(self, factory):
1616
specfile = "contrib/flask/data/v3.0/flask_factory.yaml"
17-
return create_spec(factory.spec_from_file(specfile))
17+
return Spec.create(factory.spec_from_file(specfile))
1818

1919
@pytest.fixture
2020
def app(self):

Diff for: tests/integration/contrib/requests/test_requests_validation.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from openapi_core.contrib.requests import RequestsOpenAPIRequest
66
from openapi_core.contrib.requests import RequestsOpenAPIResponse
7-
from openapi_core.shortcuts import create_spec
7+
from openapi_core.spec import OpenAPIv30Spec as Spec
88
from openapi_core.validation.request.validators import RequestValidator
99
from openapi_core.validation.response.validators import ResponseValidator
1010

@@ -13,7 +13,7 @@ class TestRequestsOpenAPIValidation:
1313
@pytest.fixture
1414
def spec(self, factory):
1515
specfile = "contrib/requests/data/v3.0/requests_factory.yaml"
16-
return create_spec(factory.spec_from_file(specfile))
16+
return Spec.create(factory.spec_from_file(specfile))
1717

1818
@responses.activate
1919
def test_response_validator_path_pattern(self, spec):

Diff for: tests/integration/schema/test_empty.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import pytest
22
from jsonschema.exceptions import ValidationError
33

4-
from openapi_core.shortcuts import create_spec
4+
from openapi_core.spec import OpenAPIv30Spec as Spec
55

66

77
class TestEmpty:
@@ -11,8 +11,8 @@ def spec_dict(self, factory):
1111

1212
@pytest.fixture
1313
def spec(self, spec_dict):
14-
return create_spec(spec_dict)
14+
return Spec.create(spec_dict)
1515

1616
def test_raises_on_invalid(self, spec_dict):
1717
with pytest.raises(ValidationError):
18-
create_spec(spec_dict)
18+
Spec.create(spec_dict)

Diff for: tests/integration/schema/test_link_spec.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
from openapi_core.shortcuts import create_spec
1+
from openapi_core.spec import OpenAPIv30Spec as Spec
22

33

44
class TestLinkSpec:
55
def test_no_param(self, factory):
66
spec_dict = factory.spec_from_file("data/v3.0/links.yaml")
7-
spec = create_spec(spec_dict)
7+
spec = Spec.create(spec_dict)
88
resp = spec / "paths#/status#get#responses#default"
99

1010
links = resp / "links"
@@ -18,7 +18,7 @@ def test_no_param(self, factory):
1818

1919
def test_param(self, factory):
2020
spec_dict = factory.spec_from_file("data/v3.0/links.yaml")
21-
spec = create_spec(spec_dict)
21+
spec = Spec.create(spec_dict)
2222
resp = spec / "paths#/status/{resourceId}#get#responses#default"
2323

2424
links = resp / "links"

Diff for: tests/integration/schema/test_path_params.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import pytest
22

3-
from openapi_core.shortcuts import create_spec
3+
from openapi_core.spec import OpenAPIv30Spec as Spec
44

55

66
class TestMinimal:
@@ -10,7 +10,7 @@ class TestMinimal:
1010
@pytest.mark.parametrize("spec_path", spec_paths)
1111
def test_param_present(self, factory, spec_path):
1212
spec_dict = factory.spec_from_file(spec_path)
13-
spec = create_spec(spec_dict)
13+
spec = Spec.create(spec_dict)
1414

1515
path = spec / "paths#/resource/{resId}"
1616

Diff for: tests/integration/schema/test_spec.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from openapi_core.schema.servers import get_server_url
66
from openapi_core.schema.specs import get_spec_url
7-
from openapi_core.shortcuts import create_spec
7+
from openapi_core.spec import OpenAPIv30Spec as Spec
88
from openapi_core.validation.request.validators import RequestValidator
99
from openapi_core.validation.response.validators import ResponseValidator
1010

@@ -29,7 +29,7 @@ def spec_dict(self, factory):
2929

3030
@pytest.fixture
3131
def spec(self, spec_dict, spec_uri):
32-
return create_spec(spec_dict, spec_uri)
32+
return Spec.create(spec_dict, url=spec_uri)
3333

3434
@pytest.fixture
3535
def request_validator(self, spec):

Diff for: tests/integration/validation/test_minimal.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import pytest
22

3-
from openapi_core.shortcuts import create_spec
3+
from openapi_core.spec import OpenAPIv30Spec as Spec
44
from openapi_core.templating.paths.exceptions import OperationNotFound
55
from openapi_core.templating.paths.exceptions import PathNotFound
66
from openapi_core.testing import MockRequest
@@ -27,7 +27,7 @@ class TestMinimal:
2727
@pytest.mark.parametrize("spec_path", spec_paths)
2828
def test_hosts(self, factory, server, spec_path):
2929
spec_dict = factory.spec_from_file(spec_path)
30-
spec = create_spec(spec_dict)
30+
spec = Spec.create(spec_dict)
3131
validator = RequestValidator(spec)
3232
request = MockRequest(server, "get", "/status")
3333

@@ -39,7 +39,7 @@ def test_hosts(self, factory, server, spec_path):
3939
@pytest.mark.parametrize("spec_path", spec_paths)
4040
def test_invalid_operation(self, factory, server, spec_path):
4141
spec_dict = factory.spec_from_file(spec_path)
42-
spec = create_spec(spec_dict)
42+
spec = Spec.create(spec_dict)
4343
validator = RequestValidator(spec)
4444
request = MockRequest(server, "post", "/status")
4545

@@ -54,7 +54,7 @@ def test_invalid_operation(self, factory, server, spec_path):
5454
@pytest.mark.parametrize("spec_path", spec_paths)
5555
def test_invalid_path(self, factory, server, spec_path):
5656
spec_dict = factory.spec_from_file(spec_path)
57-
spec = create_spec(spec_dict)
57+
spec = Spec.create(spec_dict)
5858
validator = RequestValidator(spec)
5959
request = MockRequest(server, "get", "/nonexistent")
6060

0 commit comments

Comments
 (0)