-
-
Notifications
You must be signed in to change notification settings - Fork 591
Reference to local files (with relative/no path) doesn't work #98
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
Comments
Hey! The ref resolution code is pretty simple. Mostly it just delegates. I haven't looked at it in a bit, but what I'd assume is going on is that relative refs will be resolved relative to the working directory, not relative to the schema file they came from. Is that the behavior you're seeing? If not, I'll give this a try later when I get to a computer. This at least should be documented, but I have to think about which is correct. Oh and if you want you can use the |
I suspect this would probably work if the base uri was set to |
I figured I could write my own resolver if I really wanted too or add a handler, but as I said, I am not sure whether it should work out of the box or not (i.e. does the spec allow this or not). The store option seems a little hacky as I won't ever have actual URIs, but that could work and would be fairly easy indeed. @Julian the code uses urllib2.urlopen which doesn't support relative paths at all, no matter what the current working directory is and if I omit the file:// it doesn't want to do anything. urllib.urlopen would work though, at least if the right working directory is set @gazpachoking "wherever" would have to be absolute as well then? :-/ Obviously the references should be relative to the current file, but as the code uses a json object directly and doesn't read the file itself, we don't know where the current file is. Without changing that it would be fairly complicated to change that I guess. And changing that would break backwards compatibility... |
Yeah, you are going to have to specify the absolute path that relative paths should be judged on no matter what, as jsonschema is not the one loading from the disk, so it doesn't know what the location of the schema is. I think something of this nature will work:
|
Whether there could/should be a better way, not sure. Maybe @Julian has some input on that. |
I'm also making another tool right now to make dealing with json references easier (mostly outside of json schema, but it could be used with it as well) https://github.com/gazpachoking/jsonref It isn't quite ready for use yet, but it will have the advantage of also handling refs that are not subschemas.
|
If urllib does not resolve things without schemes, that would seem to JSON Schema doesn't define any special semantics for "$ref" other than I think you'd need to have some other canonical name for the resource |
@Julian Would it be good for |
Well it's not like it requires much effort to instantiate a resolver :p... (Keeping stuff separate is good if we need/want to change the API in some
|
Yep, sounds fine. |
Thank you for your help! I got it to work now:
Not sure what people who do define |
Glad you got it working :). That looks about right to me. |
Hi, I really hope you can help me with it. After reading this post, I am assuming that I have to have absolute path somewhere(like in the resolver..) if I wanna use relative path for $ref? Thank you in advance! |
Thanks to sblask for his previous RefResolver approach. Here is my file based scope relative example. This code runs if the schemas are placed in the correct schemas subfolders. The key is using bootstrap schema to start the uri_root relative schema path and all other $ref paths are scope relative so require "../folder/schema.json" format. **************************************************import jsonschema schema_root = "/myapp/schemas"
bootstrap schema is used so that all "$ref"s in the schema files are scope relative (so uses "../folder/schema.json" access)
""" from file schemas/types/int.json
from file schemas/types/unicode.json
from file schemas/types/YorN.json
from file schemas/types/optYorN.json (contains scope relative paths using ../)
from file schemas/builtins/UUID.json
""" top_validate(3, json_schema_pathname('types','int')) uuid = {'hex': 'f9cc22e0df7b4857ac346e9bf9df3da2', '_classname': 'UUID', '_classtype': 'builtin'} top_validate(uuid, json_schema_pathname('builtins','UUID')) all others pass validation except these two purposeful errors.
""" Failed validating u'type' in schema: On instance: Failed validating u'pattern' in schema[u'properties'][u'hex']: On instance[u'hex']: |
@sblask Has the best answer so far. Here's a slight modification that more closely conforms to the intent of the source.
|
I spent the better part of a morning struggling with this on Windows, so thought I'd share in case anyone else runs into the same issue. @sblask solution works well, with the one caveat that the I got it working with this. with open(os.path.join(absolute_path_to_base_directory, base_filename)) as file_object:
schema = json.load(file_object)
resolver = jsonschema.RefResolver('file:///' + absolute_path_to_base_directory.replace("\\", "/") + '/', schema)
jsonschema.Draft4Validator(schema, resolver=resolver).validate(data) The extra forward-slash still doesn't make much sense, without it, I'm getting this. jsonschema.exceptions.RefResolutionError: <urlopen error file not on local host> And I haven't yet tested it on other platforms. |
What is the value of your 'absolute_path_to_base_directory'? Is it missing an initial |
I recently encountered this issue but what solved it for me was giving RefResolver the whole filename including the extension, not just the directory.
|
see python-jsonschema/jsonschema#98 took boring generic things (eg uuid) into definitions.json, and also separated email and sms notification objects into respective files
Some changes as suggested in: python-jsonschema/jsonschema#98
I had a hard time figuring this out myself, and I kept googling into this github issue. (The solution is pretty much what @clenk says above.) Here's a SO Q&A which covers it: https://stackoverflow.com/questions/53968770/how-to-set-up-local-file-references-in-python-jsonschema-document Hopefully this helps someone in the future. |
Hi, I have the same issue but I was not planning to write my own Python script and more in favor of using the command line and having a parameter. Is there in Draft7 (I am based on that one) a way to override the base_uri ? |
Probably reasonable to open an issue to discuss whether the CLI needs a way
to specify base URI.
Include a suggestion and/or what you're trying if you can.
…On Fri, Mar 20, 2020, 11:48 koteez ***@***.***> wrote:
Hi, I have the same issue but I was not planning to write my own Python
script and more in favor of using the command line and having a parameter.
Is there is Draft7 (I am based on that one) a way to override the base_uri ?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#98 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AACQQXRNEQ67GIRPDUBL2FLRIOF4DANCNFSM4AFB4D7Q>
.
|
The solution is inspired from this answer: python-jsonschema/jsonschema#98 (comment)
Add a script to validate configurations against the schema. Use https://github.com/Julian/jsonschema to perform the json validation. The script is intended to be run from a continuous integration environment or by configuration/schema developers. A key assumption/feature of the script is that its users will always prefer to resolve relative references to the local filesystem. As such, the script computes a base URI that points to the filesystem and instructs the validator to use that in place of whatever base_uri it derives from the global $id attribute. For additional reading see: https://json-schema.org/understanding-json-schema/structuring.html#the-id-property python-jsonschema/jsonschema#98 Without any options the script assumes it is being run from an entity-manager source distribution and attempts to find the schema and configuration files relative to the location of the script. Alternatively, the script can validate arbitrary json files against arbitrary schema: ./validate-configs.py -s foo.schema.json -c test1.json -c test2.json By default the validation stops as soon as a configuration does not validate. Use -k to override this behavior and validate as many configurations as possible. Provide an option to instruct the script to ignore a list of configurations that are expected to fail validation to be used in continuous integration setups - similar in concept to xfail mechanisms provided by most build systems with unit test support. Change-Id: I7d67a54993a6d5e00daf552d9d350c80411b997b Signed-off-by: Brad Bishop <[email protected]>
Add a script to validate configurations against the schema. Use https://github.com/Julian/jsonschema to perform the json validation. The script is intended to be run from a continuous integration environment or by configuration/schema developers. A key assumption/feature of the script is that its users will always prefer to resolve relative references to the local filesystem. As such, the script computes a base URI that points to the filesystem and instructs the validator to use that in place of whatever base_uri it derives from the global $id attribute. For additional reading see: https://json-schema.org/understanding-json-schema/structuring.html#the-id-property python-jsonschema/jsonschema#98 Without any options the script assumes it is being run from an entity-manager source distribution and attempts to find the schema and configuration files relative to the location of the script. Alternatively, the script can validate arbitrary json files against arbitrary schema: ./validate-configs.py -s foo.schema.json -c test1.json -c test2.json By default the validation stops as soon as a configuration does not validate. Use -k to override this behavior and validate as many configurations as possible. Provide an option to instruct the script to ignore a list of configurations that are expected to fail validation to be used in continuous integration setups - similar in concept to xfail mechanisms provided by most build systems with unit test support. Change-Id: I7d67a54993a6d5e00daf552d9d350c80411b997b Signed-off-by: Brad Bishop <[email protected]>
Hi, is it also possible to load all schema files in jsonschema, independently of their location in the directory structure on disk, and independently of whether they are actually served on network addressable locations over https? Then have jsonschema resolve $refs just by resolving against $id? See https://json-schema.org/understanding-json-schema/structuring.html : " Even though schemas are identified by URIs, those identifiers are not necessarily network-addressable. They are just identifiers. Generally, implementations don’t make HTTP requests (https://) or read from the file system (file://) to fetch schemas. Instead, they provide a way to load schemas into an internal schema database. When a schema is referenced by it’s URI identifier, the schema is retrieved from the internal schema database. |
I am trying to create a json schema (draft 4) which uses definitions from another file and includes them using $ref. I don't have any URL set up for the definitions file and I wasn't planning on doing that. I thought "$ref": "definitions.json#a_definition" (definitions.json lying in the same directory) would be enough, but I get a "No such file or directory" error.
I am not sure this should work, but this: http://code.google.com/p/jsonschema2pojo/wiki/Reference#$ref suggests it should ("$ref" : "user.json"). Googling/reading the draft didn't get me anywhere.
Using file://absolute/path/to/json/file does work, but that would be super ugly. Is there a better way to do what I want to do? Or is this something that needs fixing?
The text was updated successfully, but these errors were encountered: