python-openapi / openapi-core

Openapi-core is a Python library that adds client-side and server-side support for the OpenAPI v3.0 and OpenAPI v3.1 specification.
BSD 3-Clause "New" or "Revised" License
287 stars 131 forks source link

[Bug]: `_validate_reference` cannot resolve $ref with a relative file path #852

Closed chantera closed 2 weeks ago

chantera commented 3 weeks ago

Actual Behavior

openapi.validate_response raises jsonschema.exceptions._WrappedReferencingError when the response schema defined in a different file includes $ref that refers to a schema in another file.

Expected Behavior

The validator should not raise the error for $ref. I ensured no spec-related error occured when openapi.check_spec() called.

Steps to Reproduce

openapi.yaml

openapi: "3.0.0"
info:
  title: sample
  version: "0.1"
paths:
  /books:
    $ref: "./paths/books.yaml"

paths/books.yaml

get:
  responses:
    "200":
      description: OK
      content:
        application/json:
          schema:
            type: array
            items:
              $ref: "../schemas/book.yaml#/Book"

schemas/book.yaml

Book:
  type: object
  properties:
    id:
      $ref: "#/BookId"
    title:
      type: string
BookId:
  type: string

validate.py

import json
import os

import openapi_core
import openapi_core.testing

SPEC_PATH = os.path.join(os.path.dirname(__file__), "openapi.yaml")

openapi = openapi_core.OpenAPI.from_file_path(
    SPEC_PATH,
    config=openapi_core.Config(spec_base_uri=f"file://{SPEC_PATH}"),
)
openapi.check_spec()  # ensure the spec is valid

request = openapi_core.testing.MockRequest(
    host_url="", method="GET", path="/books"
)
response = openapi_core.testing.MockResponse(
    data=json.dumps([{"id": "BOOK:01", "title": "Test Book"}]).encode()
)
openapi.validate_request(request)
openapi.validate_response(request, response)  # raises error

Run:

$ python validate.py

OpenAPI Core Version

3.0.0,3.1.0

OpenAPI Core Integration

Nothing

Affected Area(s)

validation

References

No response

Anything else we need to know?

No response

Would you like to implement a fix?

Yes