Validando un documento yaml en python

Uno de los beneficios de XML es poder validar un documento contra un XSD. YAML no tiene esta función, entonces, ¿cómo puedo validar que el documento YAML que abro está en el formato esperado por mi aplicación?

Prueba Rx , tiene una implementación en Python. Funciona en JSON y YAML.

Desde el sitio de Rx:

“Al agregar una API a su servicio web, tiene que elegir cómo codificar los datos que envía a través de la línea. XML es una opción común para esto, pero puede volverse arcano y engorroso con bastante rapidez. Muchos autores de servicios web desean evitar pensando en XML, y en su lugar, elija formatos que proporcionen algunos tipos de datos simples que se correspondan con estructuras de datos comunes en los lenguajes de progtwigción modernos. En otras palabras, JSON y YAML.

Desafortunadamente, mientras estos formatos facilitan la transmisión de estructuras de datos complejas, carecen de un sistema para validación. XML tiene esquemas XML y RELAX NG, pero estos son estándares complicados y en ocasiones confusos. No son muy portátiles para el tipo de estructura de datos proporcionada por JSON, y si desea evitar el XML como encoding de datos, escribir más XML para validar el primer XML es probablemente aún menos atractivo.

Rx está destinado a proporcionar un sistema para la validación de datos que coincida con las estructuras de datos de estilo JSON y es tan fácil de trabajar como el propio JSON “.

Dado que JSON y YAML son bestias bastante similares, podrías usar el esquema JSON para validar un subconjunto considerable de YAML. Aquí hay un fragmento de código (necesitarás PyYAML y jsonschema instalados):

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 problema con esto es que si su esquema abarca varios archivos y usa "$ref" para hacer referencia a los otros archivos, entonces esos otros archivos deberán ser JSON, creo. Pero probablemente hay maneras de evitar eso. En mi propio proyecto, estoy jugando con la especificación del esquema usando archivos JSON mientras que las instancias son YAML.

Sí, tener soporte para la validación es vital para muchos casos de uso importantes. Ver, por ejemplo, YAML y la importancia de la Validación de Esquema «Stuart Gunter

Como ya se mencionó, hay Rx , disponible para varios idiomas, y Kwalify para Ruby y Java.

Vea también la discusión de PyYAML : YAMLSchemaDiscussion .

Un esfuerzo relacionado es el esquema JSON , que incluso tuvo alguna actividad de estandarización IETF ( draft-zyp-json-schema-03 – Un tipo de medio JSON para describir la estructura y el significado de los documentos JSON )

Estos se ven bien. El analizador de yaml puede manejar los errores de syntax, y una de estas bibliotecas puede validar las estructuras de datos.

Me parece que Cerberus es muy confiable con gran documentación y fácil de usar.

Aquí hay un ejemplo básico de implementación:

my_yaml.yaml

 name: 'my_name' date: 2017-10-01 metrics: percentage: value: 87 trend: stable 

Definiendo el esquema de validación en 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)$' } } } } } } 

Usando el PyYaml para cargar un documento yaml :

 def __load_doc(): with open(__yaml_path, 'r') as stream: try: return yaml.load(stream) except yaml.YAMLError as exception: raise exception 

Evaluar el archivo yaml es sencillo:

 schema = eval(open('PATH_TO/schema.py', 'r').read()) v = Validator(schema) doc = __load_doc() print v.validate(doc, schema) print v.errors 

Tenga en cuenta que Cerberus es una herramienta de validación de datos independiente, lo que significa que puede admitir formatos que no sean YAML, como JSON, XML, etc.

Estoy en la misma situación. Necesito validar los elementos de YAML.

Primero pensé que ‘Etiquetas PyYAML’ es la mejor y más simple. Pero más tarde decidió ir con ‘PyKwalify’, que en realidad define un esquema para YAML.

Etiquetas PyYAML:

El archivo YAML tiene una etiqueta de soporte donde podemos aplicar estas comprobaciones básicas prefijando el tipo de datos. (por ejemplo) para entero -! int “123”

Más sobre PyYAML: http://pyyaml.org/wiki/PyYAMLDocumentation#Tags Esto es bueno, pero si va a exponerlo al usuario final, puede causar confusión. Hice algunas investigaciones para definir un esquema de YAML. La idea es que podemos validar el YAML con su esquema correspondiente para la verificación del tipo de datos básicos. También incluso nuestras validaciones personalizadas como la dirección IP, cadenas aleatorias se pueden agregar en esto. para que podamos tener nuestro esquema por separado dejando YAML simple y legible.

No puedo publicar más enlaces. Por favor, ‘google schema for YAM’L para ver las discusiones del esquema.

PyKwalify:

Hay un paquete llamado PyKwalify que sirve a este propósito: https://pypi.python.org/pypi/pykwalify

Este paquete se ajusta mejor a mis necesidades. Intenté esto con un pequeño ejemplo en mi configuración local, y está funcionando. Aquí está el archivo de esquema de muestra.

 #sample schema type: map mapping: Emp: type: map mapping: name: type: str required: yes email: type: str age: type: int birth: type: str 

Archivo YAML válido para este esquema

 --- Emp: name: "abc" email: "xyz@gmail.com" age: yy birth: "xx/xx/xxxx" 

Gracias

No estoy al tanto de una solución de python. Pero hay un validador de esquema ruby ​​para YAML llamado kwalify . Debería poder acceder a él mediante un subproceso si no se encuentra con una biblioteca de python.

Puede usar pylon’s yaml lib para mostrar el mensaje / char / line / archivo de su archivo cargado.

 #!/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) 

Se puede acceder al mensaje de error a través de exc.problem

Acceda a exc.problem_mark para obtener un objeto .

Este objeto te permite acceder a los atributos.

  • nombre
  • columna
  • línea

Por lo tanto, puede crear su propio puntero al problema:

 pm = exc.problem_mark print("Your file {} has an issue on line {} at position {}".format(pm.name, pm.line, pm.column)) 

Envolví algunas bibliotecas de python relacionadas con json existentes con el objective de poder usarlas también con yaml .

La biblioteca resultante de python principalmente envuelve …

  • jsonschema : un validador para archivos json contra archivos json-schema , que se envuelve para admitir la validación de archivos yaml contra archivos json-schema formato yaml también.

  • jsonpath-ng : una implementación de JSONPath para python, que se JSONPath para admitir la selección de JSONPath directamente en archivos yaml .

… y está disponible en github:

https://github.com/yaccob/ytools

Se puede instalar utilizando pip :

pip install ytools

Ejemplo de validación (de https://github.com/yaccob/ytools#validation ):

 import ytools ytools.validate("test/sampleschema.yaml", ["test/sampledata.yaml"]) 

Lo que aún no sale de la caja, se está validando contra esquemas externos que también están en formato yaml .

ytools no proporciona nada que no haya existido antes, solo hace que la aplicación de algunas soluciones existentes sea más flexible y conveniente.

Puede cargar el documento YAML como un dictado y usar el esquema de la biblioteca para verificarlo:

 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)