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

Generated schema is not compatible with jsonschema's referencing #1329

Open
stefanofusai opened this issue Nov 12, 2024 · 0 comments
Open

Generated schema is not compatible with jsonschema's referencing #1329

stefanofusai opened this issue Nov 12, 2024 · 0 comments

Comments

@stefanofusai
Copy link

I've currently implemented schema validation of API responses in my tests using python-jsonschema's RefResolver. Everything works perfectly!

from typing import Any

import openapi_schema_validator
from drf_spectacular.settings import spectacular_settings
from jsonschema import RefResolver
from openapi_schema_validator import OAS31Validator


@cache
def _get_schema(
    api_version: str = "v4",  # See: https://drf-spectacular.readthedocs.io/en/latest/faq.html#i-get-an-empty-schema-or-endpoints-are-missing
) -> dict[str, Any]:
    generator_class = spectacular_settings.DEFAULT_GENERATOR_CLASS
    generator = generator_class(api_version=api_version)
    return generator.get_schema(request=None, public=True)


def validate_schema(
    instance: dict[str, Any],
    *,
	version: str,
    path: str,
    method: str,
    response: str,
    content: str = "application/json",
) -> None:
    schema = _get_schema(version)

    try:
        _methods = schema["paths"][path]

    except KeyError:  # pragma: no cover (should never happen)
        msg = f"Path {path} not found in schema"
        raise ValueError(msg) from None

    try:
        _responses = _methods[method]

    except KeyError:  # pragma: no cover (should never happen)
        msg = f"Method {method} not found in schema"
        raise ValueError(msg) from None

    try:
        _content = _responses["responses"][response]["content"]

    except KeyError:  # pragma: no cover (should never happen)
        msg = f"Response {response} not found in schema"
        raise ValueError(msg) from None

    try:
        _schema = _content[content]["schema"]

    except KeyError:  # pragma: no cover (should never happen)
        msg = f"Content {content} not found in schema"
        raise ValueError(msg) from None

    # TODO: migrate to referencing lib
    openapi_schema_validator.validate(
        instance=instance,
        schema=_schema,
        cls=OAS31Validator,
        resolver=RefResolver.from_schema(schema),
    )

I use it as such:

validate_schema(response.json(), version=version, path=reverse("foo:bar"), method="get", response="200")

As described here, I'm now looking to migrate to the referencing library with code that looks like this:

resource = Resource.from_contents(schema, default_specification=DRAFT202012)
registry = Registry().with_resource("", resource)
openapi_schema_validator.validate(instance, _schema, registry=registry)

But I'm getting the following error: jsonschema.exceptions._WrappedReferencingError: PointerToNowhere: '/components/schemas/Foo' does not exist within {'$ref': '#/components/schemas/Foo'}

After asking for help in python-openapi (here) and python-jsonschema (here) it seems to me like it may be an issue with the generated schema and it's structure (which is generated by drf-spectacular)

Unfortunately I'm not an expert on this topic, so could you point me in the right direction and figure out where the issue may be?
Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant