L'un des avantages de XML est de pouvoir valider un document par rapport à un fichier XSD. YAML n’ayant pas cette fonctionnalité, comment puis-je valider que le document YAML que j’ouvre est au format attendu par mon application?
Essayez Rx , il a une implémentation Python. Cela fonctionne sur JSON et YAML.
Depuis le site Rx:
"Lors de l'ajout d'une API à votre service Web, vous devez choisir le mode de codage des données que vous envoyez sur la ligne. XML est un choix courant, mais il peut rapidement devenir complexe et fastidieux. Beaucoup d'auteurs de services Web veulent éviter de penser à XML, mais choisissent plutôt des formats qui fournissent quelques types de données simples correspondant aux structures de données communes des langages de programmation modernes, à savoir JSON et YAML.Malheureusement, bien que ces formats facilitent la transmission de structures de données complexes, ils n’ont pas de système de validation. XML a XML Schemas et RELAX NG, mais ce sont des normes compliquées et parfois déroutantes. Ils ne sont pas très portables pour le type de structure de données fourni par JSON, et si vous voulez éviter XML en tant que codage de données, écrire plus de XML pour valider le premier XML est probablement encore moins attrayant.
Rx est conçu pour fournir un système de validation des données qui correspond aux structures de données de style JSON et est aussi facile à utiliser que JSON lui-même. " </ Blockquote>
Étant donné que JSON et YAML sont des bêtes très similaires, vous pouvez utiliser JSON-Schema pour valider un sous-ensemble important de YAML. Voici un extrait de code (vous aurez besoin de PyYAML et jsonschema installed):
from jsonschema import validate
import yaml
schema = """
type: object
properties:
testing:
type: array
items:
enum:
- this
- is
- a
- test
"""
good_instance = """
testing: ['this', 'is', 'a', 'test']
"""
validate(yaml.load(good_instance), yaml.load(schema)) # passes
# Now let's try a bad instance...
bad_instance = """
testing: ['this', 'is', 'a', 'bad', 'test']
"""
validate(yaml.load(bad_instance), yaml.load(schema))
# Fails with:
# ValidationError: 'bad' is not one of ['this', 'is', 'a', 'test']
#
# Failed validating 'enum' in schema['properties']['testing']['items']:
# {'enum': ['this', 'is', 'a', 'test']}
#
# On instance['testing'][3]:
# 'bad'
Un problème avec ceci est que si votre schéma s'étend sur plusieurs fichiers et que vous utilisez "$ref"
pour référencer les autres fichiers, ceux-ci devront être JSON, je pense. Mais il y a probablement des moyens de contourner cela. Dans mon propre projet, je joue avec la spécification du schéma à l'aide de fichiers JSON, tandis que les instances sont YAML.
Oui, le support de validation est essentiel pour de nombreux cas d'utilisation importants. Voir par exemple YAML et l'importance de la validation de schéma «Stuart Gunter
Comme déjà mentionné, il existe Rx , disponible pour différentes langues, et Kwalify pour Ruby et Java.
Voir aussi la discussion sur PyYAML: YAMLSchemaDiscussion .
Un effort connexe est Schéma JSON , qui a même eu une activité de normalisation IETF ( draft-zyp-json-schema-03 - Un type de support JSON pour décrire la structure et la signification des documents JSON )
Celles-ci ont l'air bien. L'analyseur yaml peut gérer la syntaxe erorrs et l'une de ces bibliothèques peut valider les structures de données.
Je trouve Cerberus très fiable, avec une excellente documentation et une utilisation simple.
Voici un exemple d'implémentation de base:
my_yaml.yaml
:
name: 'my_name'
date: 2017-10-01
metrics:
percentage:
value: 87
trend: stable
Définir le schéma de validation dans schema.py
:
{
'name': {
'required': True,
'type': 'string'
},
'date': {
'required': True,
'type': 'date'
},
'metrics': {
'required': True,
'type': 'dict',
'schema': {
'percentage': {
'required': True,
'type': 'dict',
'schema': {
'value': {
'required': True,
'type': 'number',
'min': 0,
'max': 100
}
'trend': {
'type': 'string',
'nullable': True,
'regex': '^(?i)(down|equal|up)$'
}
}
}
}
}
}
Utilisation de PyYaml pour charger un document yaml
:
def __load_doc():
with open(__yaml_path, 'r') as stream:
try:
return yaml.load(stream)
except yaml.YAMLError as exception:
raise exception
L'évaluation du fichier yaml est simple:
schema = eval(open('PATH_TO/schema.py', 'r').read())
v = Validator(schema)
doc = __load_doc()
print v.validate(doc, schema)
print v.errors
N'oubliez pas que Cerberus est un outil de validation de données agnostique, ce qui signifie qu'il peut prendre en charge d'autres formats que YAML, tels que JSON, XML, etc.
Je suis dans la même situation. Je dois valider les éléments de YAML.
Au début, je pensais que les balises PyYAML étaient la meilleure et la plus simple. Mais plus tard, a décidé d’utiliser «PyKwalify», qui définit en réalité un schéma pour YAML.
Le fichier YAML a un support de balise où nous pouvons appliquer ces vérifications de base en préfixant le type de données. (par exemple) pour un entier - !! int "123"
Plus sur PyYAML: http://pyyaml.org/wiki/PyYAMLDocumentation#Tags .__ C'est bien, mais si vous allez exposer cela à l'utilisateur final, vous risquez de créer une confusion. J'ai fait des recherches pour définir un schéma de YAML. L'idée est que nous pouvons valider le YAML avec son schéma correspondant pour la vérification du type de données de base. Même nos validations personnalisées comme l'adresse IP, des chaînes aléatoires peuvent également être ajoutées. afin que nous puissions avoir notre schéma séparément, laissant YAML simple et lisible.
Je ne peux pas poster plus de liens. S'il vous plaît 'Schéma Google pour YAM'L pour afficher les discussions de schéma.
Il existe un paquet appelé PyKwalify qui sert cet objectif: https://pypi.python.org/pypi/pykwalify
Ce forfait correspond le mieux à mes besoins. J'ai essayé cela avec un petit exemple dans ma configuration locale et ça marche. Voici le fichier de schéma d'exemple.
#sample schema
type: map
mapping:
Emp:
type: map
mapping:
name:
type: str
required: yes
email:
type: str
age:
type: int
birth:
type: str
Fichier YAML valide pour ce schéma
---
Emp:
name: "abc"
email: "[email protected]"
age: yy
birth: "xx/xx/xxxx"
Merci
J'ai enveloppé certaines bibliothèques python liées à JSON existantes visant à pouvoir les utiliser avec yaml
ainsi.
La bibliothèque python résultante enveloppe principalement ...
jsonschema
- un validateur pour les fichiers json
par rapport aux fichiers json-schema
, étant encapsulé pour permettre la validation des fichiers yaml
par rapport aux fichiers json-schema
au format yaml
-.
jsonpath-ng
- implémentation de JSONPath
pour python, encapsulée pour prendre en charge la sélection JSONPath
directement sur les fichiers yaml
.
... et est disponible sur github:
https://github.com/yaccob/ytools
Il peut être installé en utilisant pip
:
pip install ytools
Exemple de validation (from https://github.com/yaccob/ytools#validation ):
import ytools
ytools.validate("test/sampleschema.yaml", ["test/sampledata.yaml"])
Ce que vous n’obtenez pas encore, c’est valider contre les schémas externes au format yaml
.
ytools
ne fournit rien de ce qui n’existait pas auparavant - cela rend simplement l’application de certaines solutions existantes plus flexible et plus pratique.
Vous pouvez charger un document YAML en tant que dict et utiliser library schema pour le vérifier:
from schema import Schema, And, Use, Optional, SchemaError
import yaml
schema = Schema(
{
'created': And(datetime.datetime),
'author': And(str),
'email': And(str),
'description': And(str),
Optional('tags'): And(str, lambda s: len(s) >= 0),
'setup': And(list),
'steps': And(list, lambda steps: all('=>' in s for s in steps), error='Steps should be array of string '
'and contain "=>" to separate'
'actions and expectations'),
'teardown': And(list)
}
)
with open(filepath) as f:
data = yaml.load(f)
try:
schema.validate(data)
except SchemaError as e:
print(e)
Vous pouvez utiliser yaml lib de python pour afficher le message/char/ligne/fichier du fichier chargé.
#!/usr/bin/env python
import yaml
with open("example.yaml", 'r') as stream:
try:
print(yaml.load(stream))
except yaml.YAMLError as exc:
print(exc)
Le message d'erreur est accessible via exc.problem
Accédez à exc.problem_mark
pour obtenir un objet <yaml.error.Mark>
.
Cet objet vous permet d'accéder aux attributs
Vous pouvez donc créer votre propre pointeur sur le problème:
pm = exc.problem_mark
print("Your file {} has an issue on line {} at position {}".format(pm.name, pm.line, pm.column))
Je ne suis pas au courant d'une solution Python. Mais il existe un validateur de schéma Ruby pour YAML appelé kwalify . Vous devriez pouvoir y accéder en utilisant un sous-processus si vous ne rencontrez pas de bibliothèque python.