Skip to content

How to build a registry from a simple OpenAPI document dict? #160

Open
@meoyawn

Description

@meoyawn

I'm trying to build a registry

self.registry = Registry().with_resources(
    (f"#/components/schemas/{k}", Resource.from_contents(v, referencing.jsonschema.DRAFT202012)
    for k, v in openapi["components"]["schemas"].items()
)

but then it fails during validation

jsonschema.Draft202012Validator(registry=registry, schema=schema).validate(dict)

with

self = Resource(contents={'oneOf': [{'type': 'object', 'properties': {'status': {'enum': [200]}, 'headers': {'type': 'object'...['mime', 'body']}]}}, 'required': ['status', 'headers', 'body']}]}, _specification=<Specification name='draft2020-12'>)
pointer = '/components/schemas/YtDlInfo'
resolver = Resolver(_base_uri='', _registry=<Registry (25 resources, 5 uncrawled)>)

    def pointer(self, pointer: str, resolver: Resolver[D]) -> Resolved[D]:
        """
        Resolve the given JSON pointer.
    
        Raises:
    
            `exceptions.PointerToNowhere`
    
                if the pointer points to a location not present in the document
    
        """
        if not pointer:
            return Resolved(contents=self.contents, resolver=resolver)
    
        contents = self.contents
        segments: list[int | str] = []
        for segment in unquote(pointer[1:]).split("/"):
            if isinstance(contents, Sequence):
                segment = int(segment)
            else:
                segment = segment.replace("~1", "/").replace("~0", "~")
            try:
>               contents = contents[segment]  # type: ignore[reportUnknownArgumentType]
E               KeyError: 'components'

how do I correctly build a registry from an OpenAPI dict? Docs don't mention this

Thanks

Activity

Julian

Julian commented on Aug 6, 2024

@Julian
Member

I haven't looked at this carefully but two things:

  • Support specifically for the OpenAPI spec is/was planned for but not implemented yet, so it's possible the answer here depends on finishing that work
  • You're tagging the resources with JSON Schema 2020-12, so you're getting behavior for JSON Schema 2020-12, where what you have isn't going to work
  • The reason it won't work is that #/components/schemas/{k} means "look for a components/schemas/k key in this subschema" for each subschema you're looping over -- and that is (probably) incorrect -- you want # to be the parent OpenAPI spec document, as that's presumably the one with the components/schemas sub-properties. So maybe try only adding the parent document and then using $refs to yourSpecDocument#/components/schemas/foo, but whether that works exactly correctly or not depends on any differences in OpenAPI.
rafalkrupinski

rafalkrupinski commented on Sep 1, 2024

@rafalkrupinski

Support for OpenAPI would be greatly appreciated.

nitg16

nitg16 commented on Feb 22, 2025

@nitg16

For anyone who is looking for a solution, this worked for me.

from referencing import Registry, Resource
from referencing.jsonschema import DRAFT202012
from jsonschema import Draft202012Validator

registry = Registry()
# Dump all openapi components as is (don't edit #/components/schemas/Xyz style refs).
parent_schema = {"components": spec['components']}
schema = Resource(contents=parent_schema, specification=DRAFT202012)
registry = registry.with_resource(uri="parent", resource=schema)

# Now validate using:
Draft202012Validator(
    schema={"$ref": "parent#/components/schemas/Xyz"},
    instance={},
    registry=registry
)

# You can name 'parent' anything, probaly filename or url for your spec file if you are cross-referencing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @Julian@meoyawn@rafalkrupinski@nitg16

        Issue actions

          How to build a registry from a simple OpenAPI document dict? · Issue #160 · python-jsonschema/referencing