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
299 stars 132 forks source link

[Bug]: Response content schema path is unresolvable #858

Closed litteratum closed 3 months ago

litteratum commented 3 months ago

Actual Behavior

I have the following paths:

openapi: 3.1.0
info:
  title: My API
  description: My API
  version: 1.0.0

paths:
  /customer:
    post:
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: response.json

The "response.json" schema exists on the same level as the "api.yaml".

Then I use OpenAPI.from_file_path("apis/api.yaml"). And it fails with:

referencing.exceptions.Unresolvable: response.json

So for some reason, response schema resolution always fails...

Expected Behavior

I expect response schemas to be looked up relative to the API specification file. The same they are looked up for requests (and which works for me).

Steps to Reproduce

  1. Create the following "api.yaml":
    
    openapi: 3.1.0
    info:
    title: My API
    description: My API
    version: 1.0.0

paths: /customer: post: responses: '200': description: OK content: application/json: schema: $ref: response.json

2. Create a "response.json" file with `{}` content.
3. Run the following code:

from openapi_core import OpenAPI

OpenAPI.from_file_path("api.yaml")



### OpenAPI Core Version

0.19.2

### OpenAPI Core Integration

flask

### Affected Area(s)

dependencies, schema

### References

_No response_

### Anything else we need to know?

_No response_

### Would you like to implement a fix?

None
litteratum commented 3 months ago

Update: referencing paths also does not work:

paths:
  /customer:
    $ref: customer.yaml

I see "ValueError: unknown url type: 'customer.yaml'" from the tracelog.

Should it work or do I miss something?

p1c2u commented 3 months ago

You are missing spec_base_uri configuration to make referencing to work. It needs to be explicitly defined (version 0.19.3 will fix the problem).

import os

from openapi_core import Config, OpenAPI

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

config = Config(spec_base_uri=f"file://{SPEC_PATH}")

OpenAPI.from_file_path(SPEC_PATH, config=config)
litteratum commented 3 months ago

@p1c2u, thank you for your support. It indeed solved my issue!