openapi-core icon indicating copy to clipboard operation
openapi-core copied to clipboard

SpecFactory doesn't keep scope state resulting in unresolvable relative references

Open ghost opened this issue 6 years ago • 4 comments

I have a set of files that form a spec that fully validates with openapi-spec-validator. It can find all references, but openapi-core cannot and after much debugging I figured out why. The various generators that are started in the SpecFactory, specifically the PathsGenerator and everything it drives, only keep reference to the top-level spec_url. When you trace through openapi-spec-validator, you see that with every file change the derefencer.resolver_manager.resolver._scopes_stack increases and the current location is appended to it and used to resolve any references. But these generators do not do anything with the scope, so cannot resolve the relative path references and the base_uri always remains the same.

ghost avatar Sep 10 '18 20:09 ghost

I added test cases that show the problem, but not sure how to proceed from here. Would appreciate any pointers to why this is failing.

ghost avatar Sep 11 '18 08:09 ghost

So in openapi_spec_validator, we have a decorator that wraps the dereferencer and sets ['x-scope'] before diving in further. The generators in openapi_core do not have a similar mechanism and the basic error is here:

  1. OperationsGenerator.generate() dereferences the path.
  2. Before returning, Dereferencer.dereference() from openapi_spec_validator, exits the context and calls finally() which resets the scope.
  3. Now the parameter list needs to be resolved at the yield statement in generate. The parameter list (from debugger) looks like this in my case: <class 'list'>: [{'$ref': '../../common/parameters.yaml#/pagination-page'}, {'$ref': '../../common/parameters.yaml#/pagination-size'}, {'$ref': './parameters.yaml#/ordering'}] and path is <class 'dict'>: {'$ref': './user-panel/orders/get.yaml'}, finally scope_stack = <class 'list'>: ['file:///home/melvyn/hg/polyrepo/button3d/apidocs/openapi/openapi.yaml'].

So at this point the parameter references do not have the correct scope. But if you put the paths into a separate file, then the operations have the problem, so it's a problem for any generator that is instantiated from a file not in the root directory.

We either need a different dereferencer that checks target for things to deref before returning (not possible imo, since you don't know what the refs objects are) or initialize the generators with a dereferencer that has the correct scope.

ghost avatar Jan 14 '19 17:01 ghost

#157 can potentially solve this issue too

p1c2u avatar Sep 05 '19 20:09 p1c2u

Noting here that this is still an issue for me too.

gjcarneiro avatar Dec 30 '23 15:12 gjcarneiro