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

Relative file path references not supported? #70

Closed
cmvanb opened this issue Aug 15, 2023 · 3 comments
Closed

Relative file path references not supported? #70

cmvanb opened this issue Aug 15, 2023 · 3 comments

Comments

@cmvanb
Copy link

cmvanb commented Aug 15, 2023

Hi,

I've inherited some code using the old RefResolver (4.17) version of jsonschema, I'm working on updating it to use the new referencing library.

Our JSON schemas contain references like this:

"network": {
  "$ref": "file:../networks/network_asset.json"
},

I've constructed a Registry object with a retrieve function, which is passed to the validator.
(For context, schema_base_path is the directory path to the primary schema, from which relative references are resolved.)

def retrieve_schema(uri: str):
    reference_path = urlparse(uri).path[1:]
    path = schema_base_path / reference_path
    contents = read_json_file(path)
    return Resource.from_contents(contents)

registry = Registry(retrieve=retrieve_schema)
Draft7Validator(schema_json, registry=registry).validate(json_to_validate)

However, referencing appears to ignore the relative file path ... In the above example, retrieve_schema receives the following URI: file:///networks/network_asset.json. In testing, I discovered that file:./networks/network_asset.json and file:networks/network_asset.json resolve to an identical URI. This prevents me from resolving the relative path to the reference...

I narrowed it down to the lookup function in referencing/_core.py, line 581:

if ref.startswith("#"):
    uri, fragment = self._base_uri, ref[1:]
else:
    uri, fragment = urldefrag(urljoin(self._base_uri, ref))

Does referencing support relative file path references? If so, how can I configure that?

@Julian
Copy link
Member

Julian commented Aug 23, 2023

Hey!

Relative file:// URIs don't actually "really" exist regardless of referencing! (Specifically they don't exist in RFC8089, as well as as you saw, if you call urllib.parse.urljoin("file:../networks/network_asset.json", "bar") you don't get back something that looks relative)). When an implementation that needs to resolve that reference sees the URI there, it's supposed to resolve it against some base URI, which is why you see the behavior you noted.

You're aware as well hopefully that even if they did exist, that relative reference would likely be interpreted relative to the working directory not the file location where the URI is located itself. It's super fragile.

The above being said though, if I understand your question, you could simply transform the path in your retrieve function no? I.e. ignore that it's absolute, and join it to the path where your schemas live before opening the file?

@cmvanb
Copy link
Author

cmvanb commented Aug 25, 2023

Hi Julian,

I wasn't aware that relative file URIs aren't spec compliant!

I have refactored our schema to eliminate them and use a base path to locate them.

Thanks for your reply! I think we can close this issue.

@cmvanb cmvanb closed this as completed Aug 25, 2023
@Julian
Copy link
Member

Julian commented Aug 25, 2023

Glad to hear it thanks for the follow up.

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

2 participants