-
-
Notifications
You must be signed in to change notification settings - Fork 592
Eterna2/fix relative ref #595
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
Eterna2/fix relative ref #595
Conversation
Codecov Report
@@ Coverage Diff @@
## master #595 +/- ##
==========================================
- Coverage 95.64% 94.29% -1.36%
==========================================
Files 20 20
Lines 2436 2472 +36
Branches 308 309 +1
==========================================
+ Hits 2330 2331 +1
- Misses 93 122 +29
- Partials 13 19 +6 |
Codecov Report
@@ Coverage Diff @@
## master #595 +/- ##
==========================================
- Coverage 95.64% 95.34% -0.31%
==========================================
Files 20 20
Lines 2436 2472 +36
Branches 308 309 +1
==========================================
+ Hits 2330 2357 +27
- Misses 93 101 +8
- Partials 13 14 +1 |
can't figure out why coverage for diff is not 100%. My 2nd unit test shld have covered it. |
Thanks a lot for trying to tackle this! Does this work properly with requests? If so, I'm really more inclined at this point to just drop support for urllib entirely and make requests fully required -- the conditional dependency is... like 7 years old at this point, back when it wasn't necessarily the case that requests was a good idea to depend on. |
Actually, my implementation does not use request (but there is no issue using request either). It is more of a fallback logic (cuz I do not want to change too much of ur code), it will only attempt to try:
# need to reimplement this if u r deprecating urllib
scheme, network, path, qs, frag = urlsplit(self.base_uri)
path = "/".join(path.split("/")[0:-1]) # base path
# need to reimplement this if u r deprecating urllib
base_url = urlunsplit((scheme, network, path, qs, frag))
# this part can be easily replaced with request instead
with urlopen(urljoin(base_url, uri)) as url:
result = json.loads(url.read().decode("utf-8")) I made this PR with minimal change to ur codebase. Just my 2 cent, if u are going to deprecate Then we have a simple function to try the handlers with some fallback logics, because how I am doing it in this PR is to try Not working code, but some idea, what I meant. handlers_fallback = [std_handler, relative_file_handler, relative_remote_handler]
def get_std_handlers(uri, custom_handlers={}):
if uri[0] == "#":
return local_ref_handler
schema = get_schema(uri)
handlers = {**default_handlers, **custom_handlers}
return handlers .get(schema, file_handler)
def std_handler(uri, base_uri=""):
handler = get_std_handlers(uri)
return handler(uri, base_uri=base_uri)
def request_handler(uri, base_uri=""):
return request.get(uri).json()
def local_ref_handler(uri, base_uri=""):
return definitions[_get_definition_key(uri)]
def file_handler(uri, base_uri=""):
file_path = strip_protocol_if_any(uri)
with open(file_path) as fin:
return json.load(fin)
def relative_file_handler(uri, base_uri=""):
ref_path = os.path.join(strip_protocol_if_any(base_uri), strip_protocol_if_any(uri))
return file_handler(ref_path)
def relative_remote_handler(uri, base_uri=""):
base_url = get_base_url(base_uri)
url = "%s/%s" % (base_url, strip_protocol_if_any(uri))
return request_handler(url)
def handle_ref(handlers, handler_kwargs, index=0):
if index >= len(handlers):
raise Exception("Unable to resolve ref")
try:
return handlers[index](**handler_kwargs)
except Exception:
return handle_ref(handlers, handler_kwargs, index=index+1) |
Sorry so are you saying then that the issue doesn't exist when requests is installed? I'm not sure I follow the rest of your comment, since:
That wouldn't be any major refactoring, it'd literally just delete the entire |
I should say I'm separately not very keen to do any kind of fallback logic / chaining -- it's easy to tell what's a remote ref and what's a local one, so we shouldn't really need any try/excepting or if/elsing, so will need to try to understand what the motivation is there. |
This also looks pretty similar to #531, where I seem to have asked the exact same question :) |
This is different from #531. #531 is asking to support The use case is mostly when u do not want to publish ur schema (i.e. http/https) and only wish to retrieve it from local fs (i.e. u want to reuse some of the definitions in other json schema).
So the feature request is: if The current implementation does not support this:
And there are multiple ways to go about doing this:
or u can just do a fallack, which i did in this PR. The relative ref will never hit ur request |
Got it thanks -- that makes sense, but is this really that hard to do currently? If it's really just for development, just invent your own scheme, and include a handler for it? I.e.:
|
This is a PR. U can see my fix here. It isn't hard, and it is officially in the spec (relative ref I mean). Your approach is doable but not elegant, as in it feels hackish. Cuz the main use case here is validation as part of our unit test/ci process. Would be hackish if we write a custom handler with a custom protocol for all our projects just to support relative ref. Regardless of urllib support of otherwise, the fix is relatively simple, it is just falling back to local relative fs -> remote relative fs. All about path manipulation, not much on io. |
The behavior in the PR is definitely not in the spec, so I'm trying to narrow down exactly what/which issue is in the spec that you're trying to fix here. The spec definitely does not say "every time you see a ref, try cascading through first resolving it absolutely, then assume it's a local path, ..." It has rules about what you assume the base URI is for schemas that forgot to declare it, so fully believe there's something to fix there, but yeah that's what I was referring to above about not having fallback behavior. |
The other thing I meant to mention here is whether you're really asking about loading schemas that don't specify their base URI and then not telling
if you want the base URI to resolve relative to the current working directory, or some other one.
|
Yeah this is what I meant and needed. Thanks! Will this work recursively? As in this schema loads another schema which loads another schema? All the schemas are in the same folder but does not have a $id defined. Because my usecase is a pretty complex set of config files that I need to validate for multiple projects. |
Yes it will.
EDIT: As long as each one specifies further refs in a way relative to their own path.
…On Sat, Aug 24, 2019, 11:26 Eterna2 ***@***.***> wrote:
Yeah this is what I meant and needed. Thanks!
Will this work recursively? As in this schema loads another schema which
loads another schema? All the schemas are in the same folder but does not
have a $id defined.
Because my usecase is a pretty complex set of config files that I need to
validate for multiple projects.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#595>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AACQQXQ6APHSCIFPSUFZU3DQGD5EXANCNFSM4IMLOR2A>
.
|
0fa89d2ab Merge pull request #595 from json-schema-org/ether/cousins-reverse 2b1f711d1 Merge pull request #598 from flaksp/patch-1 104f9f98f Merge pull request #599 from tristanpenman/main 209ba6404 Add Valijson to 'Who Uses the Test Suite' 47bf107c5 Fix typo in comment of "order of evaluation: $id and $anchor and $ref" suite dee0edadc Merge pull request #597 from json-schema-org/contributing f54f00a29 Explicitly mention that one approval doesn't override other concerns. e17668ec3 Add additional notes about writing good tests. a6520db44 Add in a contributors document outlining the repo's process. julian@Airm 6ce9bc4ce Merge pull request #596 from json-schema-org/steering 8defd7588 Add a note about the future TSC. b9bb50bcd also test allOf schemas presented in the reverse order git-subtree-dir: json git-subtree-split: 0fa89d2ab6df07d7afabace3a07362c5eedbd70f
Fix #570