Skip to content

Switch to jsonschema-spec #416

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

Merged
merged 1 commit into from
Sep 12, 2022
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
32 changes: 0 additions & 32 deletions openapi_core/spec/accessors.py

This file was deleted.

36 changes: 11 additions & 25 deletions openapi_core/spec/paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,37 @@
from typing import Dict
from typing import Hashable
from typing import Mapping
from typing import Type
from typing import TypeVar

from jsonschema.protocols import Validator
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 jsonschema_spec import Spec as JsonschemaSpec
from jsonschema_spec import default_handlers
from openapi_spec_validator import openapi_v30_spec_validator

from openapi_core.spec.accessors import SpecAccessor
TSpec = TypeVar("TSpec", bound="Spec")

SPEC_SEPARATOR = "#"


class Spec(AccessorPath):
@classmethod
def from_dict(
cls,
data: Mapping[Hashable, Any],
*args: Any,
url: str = "",
ref_resolver_handlers: Dict[str, Any] = default_handlers,
separator: str = SPEC_SEPARATOR,
) -> "Spec":
ref_resolver = RefResolver(url, data, handlers=ref_resolver_handlers)
dereferencer = Dereferencer(ref_resolver)
accessor = SpecAccessor(data, dereferencer)
return cls(accessor, *args, separator=separator)

class Spec(JsonschemaSpec):
@classmethod
def create(
cls,
cls: Type[TSpec],
data: Mapping[Hashable, Any],
*args: Any,
url: str = "",
ref_resolver_handlers: Dict[str, Any] = default_handlers,
separator: str = SPEC_SEPARATOR,
validator: Validator = openapi_v3_spec_validator,
) -> "Spec":
validator: Validator = openapi_v30_spec_validator,
) -> TSpec:
if validator is not None:
validator.validate(data, spec_url=url)

return cls.from_dict(
data,
*args,
url=url,
spec_url=url,
ref_resolver_handlers=ref_resolver_handlers,
separator=separator,
)
8 changes: 3 additions & 5 deletions openapi_core/spec/shortcuts.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@
from typing import Hashable
from typing import Mapping

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 jsonschema_spec import default_handlers
from openapi_spec_validator import openapi_v30_spec_validator

from openapi_core.spec.paths import Spec

Expand All @@ -20,7 +18,7 @@ def create_spec(
) -> Spec:
validator = None
if validate_spec:
validator = openapi_v3_spec_validator
validator = openapi_v30_spec_validator

return Spec.create(
spec_dict,
Expand Down
2 changes: 1 addition & 1 deletion openapi_core/unmarshalling/schemas/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def get_formatter(
return default_formatters.get(type_format)

def get_validator(self, schema: Spec) -> Validator:
resolver = schema.accessor.dereferencer.resolver_manager.resolver # type: ignore
resolver = schema.accessor.resolver # type: ignore
custom_format_checks = {
name: formatter.validate
for name, formatter in self.custom_formatters.items()
Expand Down
10 changes: 5 additions & 5 deletions openapi_core/unmarshalling/schemas/unmarshallers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
from typing import Optional

from isodate.isodatetime import parse_datetime
from jsonschema._types import is_array
from jsonschema._types import is_bool
from jsonschema._types import is_integer
from jsonschema._types import is_number
from jsonschema._types import is_object
from jsonschema.protocols import Validator
from openapi_schema_validator._format import oas30_format_checker
from openapi_schema_validator._types import is_array
from openapi_schema_validator._types import is_bool
from openapi_schema_validator._types import is_integer
from openapi_schema_validator._types import is_number
from openapi_schema_validator._types import is_object
from openapi_schema_validator._types import is_string

from openapi_core.extensions.models.factories import ModelFactory
Expand Down
63 changes: 35 additions & 28 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 3 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ module = [
"isodate.*",
"jsonschema.*",
"more_itertools.*",
"openapi_spec_validator.*",
"openapi_schema_validator.*",
"parse.*",
"requests.*",
"werkzeug.*",
Expand Down Expand Up @@ -60,11 +58,12 @@ flask = {version = "*", optional = true}
isodate = "*"
more-itertools = "*"
parse = "*"
openapi-schema-validator = "^0.2.0"
openapi-spec-validator = "^0.4.0"
openapi-schema-validator = "^0.3.0"
openapi-spec-validator = "^0.5.0"
requests = {version = "*", optional = true}
werkzeug = "*"
typing-extensions = "^4.3.0"
jsonschema-spec = "^0.1.1"

[tool.poetry.extras]
django = ["django"]
Expand Down
17 changes: 13 additions & 4 deletions tests/integration/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,27 @@
from urllib import request

import pytest
from openapi_spec_validator.schemas import read_yaml_file
from openapi_spec_validator.readers import read_from_filename
from yaml import safe_load

from openapi_core.spec import Spec

def spec_from_file(spec_file):

def content_from_file(spec_file):
directory = path.abspath(path.dirname(__file__))
path_full = path.join(directory, spec_file)
return read_yaml_file(path_full)
return read_from_filename(path_full)


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


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


class Factory(dict):
Expand All @@ -25,6 +33,7 @@ class Factory(dict):
@pytest.fixture(scope="session")
def factory():
return Factory(
content_from_file=content_from_file,
spec_from_file=spec_from_file,
spec_from_url=spec_from_url,
)
3 changes: 1 addition & 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,6 @@
from flask import make_response

from openapi_core.contrib.flask.decorators import FlaskOpenAPIViewDecorator
from openapi_core.spec import Spec
from openapi_core.validation.request.datatypes import Parameters


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

@pytest.fixture
def decorator(self, spec):
Expand Down
3 changes: 1 addition & 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,6 @@
from flask import make_response

from openapi_core.contrib.flask.views import FlaskOpenAPIView
from openapi_core.spec import Spec


class TestFlaskOpenAPIView:
Expand All @@ -14,7 +13,7 @@ class TestFlaskOpenAPIView:
@pytest.fixture
def spec(self, factory):
specfile = "contrib/flask/data/v3.0/flask_factory.yaml"
return Spec.create(factory.spec_from_file(specfile))
return 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,6 @@

from openapi_core.contrib.requests import RequestsOpenAPIRequest
from openapi_core.contrib.requests import RequestsOpenAPIResponse
from openapi_core.spec import Spec
from openapi_core.validation.request import openapi_request_validator
from openapi_core.validation.response import openapi_response_validator

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

@responses.activate
def test_response_validator_path_pattern(self, spec):
Expand Down
Loading