-
-
Notifications
You must be signed in to change notification settings - Fork 585
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Replace registry with new instance with retrieved resource #1065
Comments
This should happen automatically for at least some cases, but clearly not the one you're showing for some reason. I'll have to check why. |
Just a minor (non-)update on this. I haven't fully made a decision yet (so feedback definitely welcome), but I'm actually second guessing doing any of this automatically. The reason is that if it does happen fully automatically (i.e. if Instead then one could of course cache any requests external to Of course I do agree most users would want the caching behavior normally, so I'm also thinking (even beyond the above, that one could cache using any normal mechanism like
which basically handles loading (in order to be able to ensure it has something cacheable, as loaded JSON may not be) and conversion to a resource, but otherwise essentially does the caching one would normally want. Feedback still welcome, but as I say I'm kind of leaning towards tweaking the |
Thanks for the detailed update. To check that I'm understanding, the decorator you mentioned might be used to allow @eslavich and I have been working on updating ASDF to be compatible with 4.18. Adding the As an alternative, is there a way to define a single |
It wouldn't really notify the
Ah, this is a good point which I'd have to consider. (Yes resources are uncrawled, though you can
I'm missing the question probably, because there certainly is a way to do this, it's the (FWIW this is precisely how the registry in the jsonschema-specifications repository works) |
I think what you're describing works if you know what resources are required before validating (where those resources can be loaded and a complete registry made). For our current attempts at updating ASDF to work with 4.18 we are using retrieve to handle the case where a validation pass encounters a uri for an unknown schema (this API is all new to me, so please let me know if it sounds like we're using it incorrectly). If I modify the example to do what I think is a minimal case for how we're using schema in ASDF (where the top level schema is known prior to validation but the referenced sub-schemas are unknown), the referenced schema do not appear to be retrieved during import jsonschema
import referencing
obj_uri = "https://somewhere.org/foo/obj"
obj_schema = {
"id": obj_uri,
"type" : "object",
"properties" : {
"price" : {"type" : "number"},
},
}
cart_uri = "https://somewhere.org/foo/cart"
cart_schema = {
"id": cart_uri,
"properties": {
"foo": {
"$ref": obj_uri,
},
"bar": {
"$ref": obj_uri,
},
},
}
cart = {"foo": {"price": 1}, "bar": {"price": 2}}
# make a validator with a registry
def retrieve(target_uri):
if target_uri == obj_uri:
schema = obj_schema
elif target_uri == cart_uri:
schema = cart_schema
else:
raise referencing.exceptions.NoSuchResource(f"{target_uri} not found")
resource = referencing.Resource(contents=schema, specification=referencing.jsonschema.DRAFT4)
print(f"{target_uri} retrieved")
return resource
print("Making registry")
registry = (retrieve(cart_uri) @ referencing.Registry(retrieve=retrieve)).crawl()
print("Validating")
validator = jsonschema.validators.Draft4Validator(cart_schema, registry=registry)
validator.validate(cart) Produces the following output: Making registry
https://somewhere.org/foo/cart retrieved
Validating
https://somewhere.org/foo/obj retrieved
https://somewhere.org/foo/obj retrieved |
Got it, yeah ok that's similar to the case from "this ticket", one where you want some unknown URI to be cached. Yeah, as I say I'm leaning towards supporting that by asking you to wrap your Obviously as you say if you know
(ugly smashed on one line but hope it's clear what's going on there) but yeah I'm assuming you're saying you have a bunch of random FWIW the JSON Schema specifications do say to you as an author that you should expect implementations to ask you to show up with the entire bundle of schemas you want to make available (and some implementations will not even do any additional discovery on your behalf). But as I say I want to go a bit beyond that and at least help out on this case with suggesting the right caching if possible. |
This is a fairly simple caching decorator (which just delegates to lru_cache), but it's useful because: * Most dynamic retrievers will probably want this * It saves a small bit of referencing-specific boilerplate, letting users know to return some JSON and the rest is handled (as long as their schemas contain $schema as usual) It also allows for continuing to support use cases that *don't* want caching (by of course not using this decorator) such as when you *do* want to dynamically re-retrieve a URI because it may have changed contents. Some tweaks may still be necessary here, but it does work for the initial example. Refs: python-jsonschema/jsonschema#1065
So I've just added I'm going to close this as being addressed by that, but if you have feedback on it or want to discuss further definitely let me know! In particular, for your original example, if you now instead add the relevant decorator:
You should notice that now repeated lookups do not cause repeated calls to your Thanks for raising, and yeah again please do let me know if you have any more feedback! |
Hi @Julian Thanks for the reply to this issue and sorry for the delay in getting back to this. When I try to run your example with referencing==0.29.0 and jsonschema==4.18.0a9 I get the following error:
Perhaps this is related to the changes in: 1240e68#diff-d38128373c229147d38e1c4707cdecd7e510c14eef80565374fe9a69627e4676R272 |
Hey! No worries -- possibly, that should be pretty easy to fix (and might be a small bug anyhow) -- will have a quick look! Thanks for trying it out, will update you in a bit. |
In other words when someone does *not* do Validator(..., registry=...) This both limits the case which we *do* still perform automatic remote ref retrieval (in a way that still preserves backwards compatibility given that the registry argument did not previously exist, so someone using it must be doing something new) as well as fixes an issue with creating a validator with a registry that has a retrieve function. Previously the latter raised a ValueError (coming from referencing which doesn't want you combining registries unless they agree about retrieval functions. See the added test(s) for details). Fixes the issue mentioned here: #1065 (comment) Refs: #1089
OK this should be fixed and released in a minute, thanks for the follow-up, let me know if you notice anything else! |
Thanks for the fix and quick response :) The examples run without issue on 4.18.0.a10 |
This is a fairly simple caching decorator (which just delegates to lru_cache), but it's useful because: * Most dynamic retrievers will probably want this * It saves a small bit of referencing-specific boilerplate, letting users know to return some JSON and the rest is handled (as long as their schemas contain $schema as usual) It also allows for continuing to support use cases that *don't* want caching (by of course not using this decorator) such as when you *do* want to dynamically re-retrieve a URI because it may have changed contents. Some tweaks may still be necessary here, but it does work for the initial example. Refs: python-jsonschema/jsonschema#1065
Thanks in advance for your help with this.
Is there a way for a validator to replace the registry with a new instance that includes a retrieved resource (to avoid multiple retrievals for the same uri)?
Running the following:
Results in the follow output:
due to
retrieve
being called twice.The text was updated successfully, but these errors were encountered: