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

Is there any possibility to match map key to str or seq? #97

Closed
AKorezin opened this issue May 3, 2017 · 11 comments
Closed

Is there any possibility to match map key to str or seq? #97

AKorezin opened this issue May 3, 2017 · 11 comments

Comments

@AKorezin
Copy link

AKorezin commented May 3, 2017

Hello.
I've tried to create a schema to match this:

- name: Server 1
  ip: 10.0.0.1
- name: Server 2
  ip:
    - 10.0.0.2
    - 10.0.0.3

But I don't really understand how to do that, because matching is only available is seq block.
Is my problem related to the issue #45?

@Grokzen
Copy link
Owner

Grokzen commented Mar 6, 2018

@AKorezin Unless you can post the schema that you are working on, I will not be able to help you with fixing this problem. I think i know what your problem is, but i need to see what you have produced yourself.

@AKorezin
Copy link
Author

AKorezin commented Mar 6, 2018

Schema

type: seq
sequence:
  - type: map
    mapping:
      name:
        type: str
      ip:
        type: seq
        sequence:
          - type: str

validates

- name: Server 1
  ip:
    - 10.0.0.1
- name: Server 2
  ip:
    - 10.0.0.2
    - 10.0.0.3

Schema

type: seq
sequence:
  - type: map
    mapping:
      name:
        type: str
      ip:
        type: str

validates

- name: Server 1
  ip: 10.0.0.1
- name: Server 2
  ip: 10.0.0.2

How to validate this?

- name: Server 1
  ip: 10.0.0.1
- name: Server 2
  ip:
    - 10.0.0.2
    - 10.0.0.3

@Grokzen
Copy link
Owner

Grokzen commented Mar 6, 2018

Okey i think i see what the problem is.

The feature you are talking about matching-rule only works for sequences where you can define multiple paths for a sequence so that you can validate different objects that is inside the list item. The problem is that this feature do not work for map:s because it was not part of the original kwalify schema spec that one value in a map should be possible to validate against multiple schema paths. Even in the original spec, it was not possible to have multiple items in a list, but i added it as it was a feature that was on the backlog for the original kwalify

But, i tried to hack around this problem, but i was not able to solve it with the regex;... feature so i would say right now that your case is not possible to validate to my current knowledge of my own code.

One problem that i am having is how to extend the schema definition to include multiple paths in a good way. There is a suggestion on implementing a kind of directive any.of that could possible help with this problem. But that feature is not in the roadmap right now or in the near future to be implemented as it would stray to far away from the original kwalify syntax and i am not sure i want to go there right now.

It might sound wierd but you maybe would have better luck by trying another validation framework, maybe you will have more luck with jsonschema for example.

@StephenEhmann
Copy link

StephenEhmann commented Apr 2, 2018

I was about to report a new issue but found this first. I did the "hack" that you did and here are the results:
schema -->

matching-rule: 'any'
map:
  regex;(layout):
    type: str
    enum: ['nn', 'nt', 'tn', 'tt']
  regex;(layout):
    seq:
      - type: str
        enum: ['nn', 'nt', 'tn', 'tt']

data passing validation -->

layout:
  - tt
  - tn

data not passing validation -->

layout: nt

When the validation fails I get this message:
ERROR - validation.invalid
ERROR - --- All found errors ---
ERROR - ["Value 'b'nt'' is not a list. Value path: '/layout'"]
Traceback (most recent call last):
File "/home/utils/Python-3.6.1/bin/pykwalify", line 11, in
sys.exit(cli_entrypoint())
File "/home/utils/Python-3.6.1/lib/python3.6/site-packages/pykwalify/cli.py", line 95, in cli_entrypoint
run(parse_cli())
File "/home/utils/Python-3.6.1/lib/python3.6/site-packages/pykwalify/cli.py", line 82, in run
c.validate()
File "/home/utils/Python-3.6.1/lib/python3.6/site-packages/pykwalify/core.py", line 167, in validate
error_msg=u'.\n - '.join(self.validation_errors)))
pykwalify.errors.SchemaError: <SchemaError: error code 2: Schema validation failed:

  • Value 'b'nt'' is not a list. Value path: '/layout'.: Path: '/'>

If I swap the regexs in the schema I get an error on the first data while the second passes
ERROR - validation.invalid
ERROR - --- All found errors ---
ERROR - ["Enum '['tt', 'tn']' does not exist. Path: '/layout'", "Value '['tt', 'tn']' is not of type 'str'. Path: '/layout'"]
Traceback (most recent call last):
File "/home/utils/Python-3.6.1/bin/pykwalify", line 11, in
sys.exit(cli_entrypoint())
File "/home/utils/Python-3.6.1/lib/python3.6/site-packages/pykwalify/cli.py", line 95, in cli_entrypoint
run(parse_cli())
File "/home/utils/Python-3.6.1/lib/python3.6/site-packages/pykwalify/cli.py", line 82, in run
c.validate()
File "/home/utils/Python-3.6.1/lib/python3.6/site-packages/pykwalify/core.py", line 167, in validate
error_msg=u'.\n - '.join(self.validation_errors)))
pykwalify.errors.SchemaError: <SchemaError: error code 2: Schema validation failed:

  • Enum '['tt', 'tn']' does not exist. Path: '/layout'.
  • Value '['tt', 'tn']' is not of type 'str'. Path: '/layout'.: Path: '/'>

I also tested two orderings of the same regex value with a string type and different allowed enums and I got an error with one of the orderings.

I agree that matching-rule is not the same as any_of (which is included in the json-schema which coincidentally I wrote a validator for in C++ but am trying to use pykwalify since I moved to python).

I want to encourage you to think about the simple boolean operators, one_of, any_of, not, etc from json-schema, I found that they were not too hard to implement, just a loop at that node with different control flow based on the rule and using sub-validators to handle/ignore errors properly.

Because this feature does not exist in pykwalify, I will have to write a bunch of special case validation code in my application.

@StephenEhmann
Copy link

@AKorezin this does what you want:

matching: "any"
sequence:
  - type: map
    mapping:
      name:
        type: str
      ip:
        type: seq
        sequence:
          - type: str
  - type: map
    mapping:
      name:
        type: str
      ip:
        type: str

@Grokzen sequences have any_of already implemented, it shouldn't be too hard to extend this to a any_of primitive like this:

map:
  layout:
    any_of:
      - seq:
        - type: str
          enum: ['nn', 'nt', 'tn', 'tt']
      - type: str
        enum: ['nn', 'nt', 'tn', 'tt']

@smarr
Copy link

smarr commented Jun 7, 2018

Having more direct support for this any_of or at least scalar or map would be very useful.
I am just adding a schema for a home grown configuration format.
And a frequently recurring pattern is something like this:

config:
  input_values: JustOneString

---

config:
  input_values:
    - oneString
    - andAnotherOne

This idiom seems very convenient, but because any_of is currently only supported on sequences and not on mappings, it is impossible to express on for more complex examples without going into exploding the schema with a growing number of possible combinations.

@Grokzen
Copy link
Owner

Grokzen commented Jun 7, 2018

I know i like the idea of any_of to be supported on more types. The main issue is that

  1. It is not really part of the original kwalify spec so i "should" not implemented it, even if i have implemented other fields so this is kinda mute.
  2. One of the more major things i do not like with the progression of features that both i and other have added is that this syntax is moving closer and closer to what jsonschema already provides and it only feels like a reimplmentation of that syntax/specification but not doing it as well as them.

@StephenEhmann
Copy link

StephenEhmann commented Jun 7, 2018 via email

@Grokzen
Copy link
Owner

Grokzen commented Jun 7, 2018

Define "good"? :]

But this one by a quick googling https://pypi.org/project/jsonschema/ should work probably.

Note that the main idea of pykwalify was to provide a moving forward solution to people that was embeded with kwalify from the days of old. It was not a solution/spec to be something better then the other leading validation frameworks, specially jsonschema.

@StephenEhmann
Copy link

StephenEhmann commented Jun 7, 2018 via email

@Grokzen
Copy link
Owner

Grokzen commented Jun 7, 2018

@StephenEhmann Ye i know, i probably will update it to make it more clear what the purpose is and what to expect from me regarding this repo.

@Grokzen Grokzen closed this as completed Oct 19, 2019
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

4 participants