Skip to content

Commit

Permalink
Merge pull request #393 from p1c2u/refactor/get-rid-of-create-spec-sh…
Browse files Browse the repository at this point in the history
…ortcut

Get rid of create_spec shortcut
  • Loading branch information
p1c2u authored Feb 13, 2022
2 parents 5e9af67 + cd92f42 commit 428958a
Show file tree
Hide file tree
Showing 33 changed files with 495 additions and 446 deletions.
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,12 @@ Firstly create your specification object:
.. code-block:: python
from json import load
from openapi_core import create_spec
from openapi_core import OpenAPISpec as Spec
with open('openapi.json', 'r') as spec_file:
spec_dict = load(spec_file)
spec = create_spec(spec_dict)
spec = Spec.create(spec_dict)
Request
*******
Expand Down
4 changes: 2 additions & 2 deletions docs/customizations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ By default, spec dict is validated on spec creation time. Disabling the validati

.. code-block:: python
from openapi_core import create_spec
from openapi_core import OpenAPISpec as Spec
spec = create_spec(spec_dict, validate_spec=False)
spec = Spec.create(spec_dict, validate=False)
Deserializers
-------------
Expand Down
4 changes: 2 additions & 2 deletions docs/integrations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ Django can be integrated by middleware. Add `DjangoOpenAPIMiddleware` to your `M
.. code-block:: python
# settings.py
from openapi_core import create_spec
from openapi_core import OpenAPISpec as Spec
MIDDLEWARE = [
# ...
'openapi_core.contrib.django.middlewares.DjangoOpenAPIMiddleware',
]
OPENAPI_SPEC = create_spec(spec_dict)
OPENAPI_SPEC = Spec.create(spec_dict)
After that you have access to validation result object with all validated request data from Django view through request object.

Expand Down
4 changes: 2 additions & 2 deletions docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ Firstly create your specification: object
.. code-block:: python
from json import load
from openapi_core import create_spec
from openapi_core import OpenAPISpec as Spec
with open('openapi.json', 'r') as spec_file:
spec_dict = load(spec_file)
spec = create_spec(spec_dict)
spec = Spec.create(spec_dict)
Request
Expand Down
12 changes: 10 additions & 2 deletions openapi_core/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"""OpenAPI core module"""
from openapi_core.shortcuts import create_spec
from openapi_core.shortcuts import spec_validate_body
from openapi_core.shortcuts import spec_validate_data
from openapi_core.shortcuts import spec_validate_headers
from openapi_core.shortcuts import spec_validate_parameters
from openapi_core.shortcuts import spec_validate_security
from openapi_core.shortcuts import validate_request
from openapi_core.shortcuts import validate_response
from openapi_core.spec import OpenAPIv30Spec
from openapi_core.validation.request.validators import RequestBodyValidator
from openapi_core.validation.request.validators import (
RequestParametersValidator,
Expand All @@ -26,7 +26,9 @@
__license__ = "BSD 3-Clause License"

__all__ = [
"create_spec",
"OpenAPIv30Spec",
"OpenAPIv3Spec",
"OpenAPISpec",
"validate_request",
"validate_response",
"spec_validate_body",
Expand All @@ -42,3 +44,9 @@
"ResponseDataValidator",
"ResponseHeadersValidator",
]

# aliases to the latest v3 version
OpenAPIv3Spec = OpenAPIv30Spec

# aliases to the latest version
OpenAPISpec = OpenAPIv3Spec
2 changes: 0 additions & 2 deletions openapi_core/shortcuts.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""OpenAPI core shortcuts module"""
# backward compatibility
from openapi_core.spec.shortcuts import create_spec
from openapi_core.validation.request.shortcuts import spec_validate_body
from openapi_core.validation.request.shortcuts import spec_validate_parameters
from openapi_core.validation.request.shortcuts import spec_validate_security
Expand All @@ -10,7 +9,6 @@
from openapi_core.validation.response.shortcuts import validate_response

__all__ = [
"create_spec",
"validate_request",
"validate_response",
"spec_validate_body",
Expand Down
5 changes: 5 additions & 0 deletions openapi_core/spec/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from openapi_core.spec.paths import OpenAPIv30Spec

__all__ = [
"OpenAPIv30Spec",
]
46 changes: 42 additions & 4 deletions openapi_core/spec/paths.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,51 @@
from jsonschema.validators import RefResolver
from openapi_spec_validator import default_handlers
from openapi_spec_validator import openapi_v3_spec_validator
from openapi_spec_validator.validators import Dereferencer
from pathable.paths import AccessorPath

from openapi_core.spec.accessors import SpecAccessor

SPEC_SEPARATOR = "#"


class SpecPath(AccessorPath):
class Spec(AccessorPath):
@classmethod
def from_spec(cls, spec_dict, dereferencer=None, *args, **kwargs):
separator = kwargs.pop("separator", SPEC_SEPARATOR)
accessor = SpecAccessor(spec_dict, dereferencer)
def from_dict(
cls,
data,
*args,
url="",
ref_resolver_handlers=default_handlers,
separator=SPEC_SEPARATOR,
):
ref_resolver = RefResolver(url, data, handlers=ref_resolver_handlers)
dereferencer = Dereferencer(ref_resolver)
accessor = SpecAccessor(data, dereferencer)
return cls(accessor, *args, separator=separator)


class OpenAPIv30Spec(Spec):

validator = openapi_v3_spec_validator

@classmethod
def create(
cls,
data,
*args,
url="",
ref_resolver_handlers=default_handlers,
separator=SPEC_SEPARATOR,
validate=True,
):
if validate:
cls.validator.validate(data, spec_url=url)

return cls.from_dict(
data,
*args,
url=url,
ref_resolver_handlers=ref_resolver_handlers,
separator=separator,
)
4 changes: 2 additions & 2 deletions openapi_core/templating/paths/util.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from typing import Tuple

from openapi_core.spec.paths import SpecPath
from openapi_core.spec.paths import OpenAPIv30Spec as Spec
from openapi_core.templating.datatypes import TemplateResult


def template_path_len(template_path: Tuple[SpecPath, TemplateResult]) -> int:
def template_path_len(template_path: Tuple[Spec, TemplateResult]) -> int:
return len(template_path[1].variables)
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

import yaml

from openapi_core import create_spec
from openapi_core import OpenAPISpec as Spec

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

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

OPENAPI_SPEC = create_spec(OPENAPI_SPEC_DICT)
OPENAPI_SPEC = Spec.create(OPENAPI_SPEC_DICT)
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

import yaml

from openapi_core import create_spec
from openapi_core import OpenAPISpec as Spec
from openapi_core.contrib.falcon.middlewares import FalconOpenAPIMiddleware

openapi_spec_path = Path("tests/integration/data/v3.0/petstore.yaml")
spec_dict = yaml.load(openapi_spec_path.read_text(), yaml.Loader)
spec = create_spec(spec_dict)
spec = Spec.create(spec_dict)
openapi_middleware = FalconOpenAPIMiddleware.from_spec(spec)
4 changes: 2 additions & 2 deletions tests/integration/contrib/flask/test_flask_decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from flask import make_response

from openapi_core.contrib.flask.decorators import FlaskOpenAPIViewDecorator
from openapi_core.shortcuts import create_spec
from openapi_core.spec import OpenAPIv30Spec as Spec
from openapi_core.validation.request.datatypes import Parameters


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

@pytest.fixture
def decorator(self, spec):
Expand Down
4 changes: 2 additions & 2 deletions tests/integration/contrib/flask/test_flask_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from openapi_core.contrib.flask import FlaskOpenAPIRequest
from openapi_core.contrib.flask import FlaskOpenAPIResponse
from openapi_core.shortcuts import create_spec
from openapi_core.spec import OpenAPIv30Spec as Spec
from openapi_core.validation.request.validators import RequestValidator
from openapi_core.validation.response.validators import ResponseValidator

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

def test_response_validator_path_pattern(
self, flask_spec, request_factory, response_factory
Expand Down
4 changes: 2 additions & 2 deletions tests/integration/contrib/flask/test_flask_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from flask import make_response

from openapi_core.contrib.flask.views import FlaskOpenAPIView
from openapi_core.shortcuts import create_spec
from openapi_core.spec import OpenAPIv30Spec as Spec


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

@pytest.fixture
def app(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from openapi_core.contrib.requests import RequestsOpenAPIRequest
from openapi_core.contrib.requests import RequestsOpenAPIResponse
from openapi_core.shortcuts import create_spec
from openapi_core.spec import OpenAPIv30Spec as Spec
from openapi_core.validation.request.validators import RequestValidator
from openapi_core.validation.response.validators import ResponseValidator

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

@responses.activate
def test_response_validator_path_pattern(self, spec):
Expand Down
6 changes: 3 additions & 3 deletions tests/integration/schema/test_empty.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pytest
from jsonschema.exceptions import ValidationError

from openapi_core.shortcuts import create_spec
from openapi_core.spec import OpenAPIv30Spec as Spec


class TestEmpty:
Expand All @@ -11,8 +11,8 @@ def spec_dict(self, factory):

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

def test_raises_on_invalid(self, spec_dict):
with pytest.raises(ValidationError):
create_spec(spec_dict)
Spec.create(spec_dict)
6 changes: 3 additions & 3 deletions tests/integration/schema/test_link_spec.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from openapi_core.shortcuts import create_spec
from openapi_core.spec import OpenAPIv30Spec as Spec


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

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

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

links = resp / "links"
Expand Down
4 changes: 2 additions & 2 deletions tests/integration/schema/test_path_params.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import pytest

from openapi_core.shortcuts import create_spec
from openapi_core.spec import OpenAPIv30Spec as Spec


class TestMinimal:
Expand All @@ -10,7 +10,7 @@ class TestMinimal:
@pytest.mark.parametrize("spec_path", spec_paths)
def test_param_present(self, factory, spec_path):
spec_dict = factory.spec_from_file(spec_path)
spec = create_spec(spec_dict)
spec = Spec.create(spec_dict)

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

Expand Down
4 changes: 2 additions & 2 deletions tests/integration/schema/test_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from openapi_core.schema.servers import get_server_url
from openapi_core.schema.specs import get_spec_url
from openapi_core.shortcuts import create_spec
from openapi_core.spec import OpenAPIv30Spec as Spec
from openapi_core.validation.request.validators import RequestValidator
from openapi_core.validation.response.validators import ResponseValidator

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

@pytest.fixture
def spec(self, spec_dict, spec_uri):
return create_spec(spec_dict, spec_uri)
return Spec.create(spec_dict, url=spec_uri)

@pytest.fixture
def request_validator(self, spec):
Expand Down
8 changes: 4 additions & 4 deletions tests/integration/validation/test_minimal.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import pytest

from openapi_core.shortcuts import create_spec
from openapi_core.spec import OpenAPIv30Spec as Spec
from openapi_core.templating.paths.exceptions import OperationNotFound
from openapi_core.templating.paths.exceptions import PathNotFound
from openapi_core.testing import MockRequest
Expand All @@ -27,7 +27,7 @@ class TestMinimal:
@pytest.mark.parametrize("spec_path", spec_paths)
def test_hosts(self, factory, server, spec_path):
spec_dict = factory.spec_from_file(spec_path)
spec = create_spec(spec_dict)
spec = Spec.create(spec_dict)
validator = RequestValidator(spec)
request = MockRequest(server, "get", "/status")

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

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

Expand Down
Loading

0 comments on commit 428958a

Please sign in to comment.