Feature: Asynchronous validators#565
Feature: Asynchronous validators#565rmedaer wants to merge 20 commits intopython-jsonschema:masterfrom
Conversation
|
Hi! Thanks so much for trying to tackle this. I need to spend some time reading through exactly what you're trying to make work, but I can say from a first look that this as is looks like a backwards incompatible change -- so at least, there's that to work through. E.g., existing validators, that previously only dealt with exceptions, now might be being passed through your new sentinel objects. Will try to have a closer look though. |
You're welcome ! ;-)
I'm not sure there is incompatible change. Here is an explanation of the way it works. I hope it will help you (or anyone) to understand the mechanism and how to use it... My idea is to use a kind of generator-based coroutine. It's basically a way to pause/break code execution using the Hopefully in @Julian's jsonschema implementation, the validation is a big generator which iterates recursively on each schema keyword. Here are illustrations of code flow with asynchronous validator compared to synchronous one: |
|
Thanks! That diagram is helpful. Apologies for still not getting a chance to look through this more carefully then, but trust me I haven't forgotten it. |
|
Hi Julian, Did you have some times to review this merge request ? Is there anything I can do to help you ? Kind regards, |
|
Hi! Yes I did have a chance to review, and so sorry again about the delay
-- will follow up with some comments on it soon -- I think in terms of
priority I wanted to get support for the new draft out first (I know I said
that last time :/) but I definitely haven't forgotten about this.
…On Fri, Oct 18, 2019 at 2:25 AM Raphaël Medaer ***@***.***> wrote:
Hi Julian,
Did you have some times to review this merge request ? Is there anything I
can do to help you ?
Kind regards,
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#565>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AACQQXSMMSY6ARWM3UZHRITQPFJGFANCNFSM4HO34XFA>
.
|
|
So I'm finally getting at least a moment to even read through this -- first most basic question -- I see you implemented it for anyOf -- is your initial goal specifically for "compound" validators? i.e. anyOf, allOf, oneOf? And you're trying to get the event loop a chance to run in between each of the branches? Or is there some other reason anyOf is special here? |
I had to do changes for "compound" validators because of following kind of code branching: errs = list(validator.descend(instance, subschema, schema_path=index))
if not errs:
breakIndeed, if an
It's exactly what I'm doing with the I also implemented it for For |
|
Hi @Julian, Do you need more details for this pull request ? Can I help you in any way ? |
|
Hi @rmedaer -- really sorry this keeps dragging, but still have too many things on my plate -- the next short term goal for I hope after that I can finally think about whether I agree with the approach here or not. Sorry again... too many things, too little time :( |
|
The one other thing that occurs to me immediately though is -- If the only long operation you're interrupting here is Which is part of what makes it not immediately obvious to me that this is the correct approach -- it doesn't actually get us very much async -- e.g., there still wouldn't be an easy way to inject in asyncronous ref resolution. The only real internal async thing this would do is let event loops run in between iterations of any/oneOf, which doesn't seem like a huge win if you don't have the other stuff over just running the event loop between iterations of (All of which I meant to elaborate on at some point but yeah see above on not enough time :( :( ) |
|
@rmedaer any thoughts? |
|
Hi @Julian
Not sure I fully understand. What do you mean by "fairly easy to implement externally as a normal function to start" ? Would you mean that we should have a equivalent to
Actually I'm not interrupting
I can implement asynchronous ref resolution (and others) if needed. This PR is a first step in async validation. Btw, if we decide to go to async (and lazy-loaded) ref resolution, we will need this PR anyway.
Apologize if I misspoke. With this PR you can use async "anywhere" with "any validator". Not only between iterations of any/oneOf. For instance: async def async_validator(validator, value, instance, schema):
await asyncio.sleep(0)
if not value:
yield exceptions.ValidationError(u"Async whoops!")
all_validators = dict(validators.Draft7Validator.VALIDATORS)
all_validators['async_valid'] = async_validator
validator = validators.create(
meta_schema=validators.Draft7Validator.META_SCHEMA,
validators=all_validators,
)({})
instance = {}
schema = {
{
"type": "object",
"properties": {
"example": {
u"async_valid": True
}
}
},
}
errors = [e async for e in validator.async_iter_errors(instance, schema)] |
Implementing mechanism explained in python-jsonschema#499 (comment) to introduce async validators. I refactored bufferized validator such as `anyOf` and `oneOf` to pipe AsyncValidationBreakpoint until async_iter_errors. If iter_errors is called (instead of async_iter_errors) and async validator is called, it will raise AsyncValidationBreakpoint which is a SchemaError.
Codecov Report
@@ Coverage Diff @@
## master #565 +/- ##
==========================================
- Coverage 94.98% 94.87% -0.11%
==========================================
Files 18 19 +1
Lines 2433 2498 +65
Branches 309 321 +12
==========================================
+ Hits 2311 2370 +59
- Misses 101 103 +2
- Partials 21 25 +4 |
|
Hi @Julian , I try to fix the tests, however in list of interpreters there is still |
|
@rmedaer will try to make some time in the next week or two to give this another pass -- thanks truly again for being on top of it. On the py2 thing specifically, |
|
Hi @Julian ,
Did you had some time to a new pass ? |
|
Hey @rmedaer thanks for being so on top of this... I did, but honestly it hasn't yet sat fully well with me as-is given that it handles only the validator side and not the ref resolution side. I still don't really have a full idea of what to do about that yet. Would love to see comments from any other users certainly who want this or otherwise have an opinion. |
1047a1aa Merge pull request #565 from json-schema-org/update-test-schema 7967a87b Merge pull request #566 from json-schema-org/tidy-unevaluatedItems b45a7878 Remove unnecessary type validation from unevaluatedItems tests. 2b536c02 Update the test schema to Draft 2020, and fix a bug in it. git-subtree-dir: json git-subtree-split: 1047a1aa225bab43c50978555a990bfff81f6023


This (WIP) pull-request contains a new feature ! It allows user to write (custom) asynchronous validators.
It has been already discussed in #499 . It is here an attempt to integrate the mechanism without having to rewrite the whole library.