web-dev-qa-db-ja.com

pythonでyamlドキュメントを検証する

XMLの利点の1つは、XSDに対してドキュメントを検証できることです。 YAMLにはこの機能がないため、開いたYAMLドキュメントがアプリケーションで期待される形式であることをどのように検証できますか?

50
Jon

Rx を試してください。Python実装です。JSONおよびYAMLで動作します。

Rxサイトから:

「WebサービスにAPIを追加するとき、回線を介して送信するデータのエンコード方法を選択する必要があります。XMLはこのための一般的な選択肢の1つですが、非常に難解で扱いにくいものになります。多くのWebサービス作成者は、 XMLについて考え、代わりに、現代のプログラミング言語の一般的なデータ構造、つまりJSONとYAMLに対応するいくつかの単純なデータ型を提供する形式を選択します。

残念ながら、これらの形式は複雑なデータ構造を簡単にやり取りできますが、検証のためのシステムがありません。 XMLにはXMLスキーマとRELAX NGがありますが、これらは複雑で、時には混乱を招く標準です。 JSONによって提供される種類のデータ構造にはあまり移植性がありません。データエンコーディングとしてXMLを避けたい場合は、最初のXMLを検証するためにXMLをさらに記述することはおそらく魅力的ではありません。

Rxは、JSONスタイルのデータ構造と一致するデータ検証システムを提供することを目的としており、JSON自体と同様に簡単に操作できます。」

12
Lior

JSONとYAMLは非常によく似ているため、 JSON-Schema を使用して、YAMLのかなりのサブセットを検証できます。コードスニペットを次に示します( PyYAML および jsonschema がインストールされている必要があります):

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'

これに関する1つの問題は、スキーマが複数のファイルにまたがっており、"$ref"他のファイルを参照するには、それらの他のファイルはJSONである必要があると思います。しかし、おそらくそれを回避する方法があります。私のプロジェクトでは、JSONファイルを使用してスキーマを指定し、インスタンスはYAMLです。

29
Jack Kelly

はい-検証をサポートすることは、多くの重要なユースケースにとって不可欠です。例参照 YAMLとスキーマ検証の重要性"Stuart Gunter

既に述べたように、さまざまな言語で利用可能な Rx と、RubyおよびJavaの場合) Kwalify があります。

PyYAMLの説明も参照してください: YAMLSchemaDiscussion

関連する取り組みは JSON Schema であり、IETF標準化アクティビティさえありました( draft-zyp-json-schema-03-JSONドキュメントの構造と意味を記述するためのJSONメディアタイプ

9
nealmcb

これらはよく見えます。 yamlパーサーは構文エラーを処理でき、これらのライブラリーの1つはデータ構造を検証できます。

5
Gringo Suave

Cerberus は、優れたドキュメントで非常に信頼性が高く、簡単に使用できます。

基本的な実装例を次に示します。

my_yaml.yaml

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

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)$'
                    }
                }
            }
        }
    }
}

PyYaml を使用してyamlドキュメントをロードする:

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

Yamlファイルの評価は簡単です:

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

Cerberusは不可知論的なデータ検証ツールであり、JSON、XMLなど、YAML以外の形式をサポートできることを忘れないでください。

私も同じ状況です。 YAMLの要素を検証する必要があります。

最初に、「PyYAMLタグ」が最良かつ簡単な方法であると考えました。しかし、後にYAMLのスキーマを実際に定義する「PyKwalify」を使用することにしました。

PyYAMLタグ:

YAMLファイルにはタグのサポートがあり、データタイプの前にこの基本的なチェックを強制できます。 (例)整数の場合-!! int "123"

PyYAMLの詳細: http://pyyaml.org/wiki/PyYAMLDocumentation#Tags これは良いことですが、これをエンドユーザーに公開しようとすると混乱を招く可能性があります。 YAMLのスキーマを定義するためにいくつかの調査を行いました。基本的なデータ型チェックのために、対応するスキーマでYAMLを検証できるという考え方です。また、IPアドレスなどのカスタム検証でも、ランダムな文字列を追加できます。そのため、YAMLをシンプルで読みやすくするために、スキーマを個別に保持できます。

リンクを投稿できません。スキーマの説明を表示するには、「YAM'LのGoogleスキーマ」をご覧ください。

PyKwalify:

この目的に役立つPyKwalifyというパッケージがあります。 https://pypi.python.org/pypi/pykwalify

このパッケージは私の要件に最適です。ローカル設定で小さな例を使用してこれを試しましたが、動作しています。サンプルスキーマファイルを示します。

#sample schema

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

このスキーマの有効なYAMLファイル

---
Emp:
    name:   "abc"
    email:  "[email protected]"
    age:    yy
    birth:  "xx/xx/xxxx"

ありがとう

YAMLドキュメントをdictとしてロードし、ライブラリschemaを使用してチェックできます。

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)
1
flipback

既存のjson関連のpythonライブラリ)をラップして、yamlでも使用できるようにしています

結果のpythonライブラリは主にラップ...

  • jsonschema-json-schemaファイルに対するjsonファイルのバリデーターで、yaml形式のjson-schemaファイルに対するyamlファイルの検証をサポートするためにラップされます。

  • jsonpath-ng-JSONPathの実装で、JSONPathファイルでyamlの選択を直接サポートするようにラップされています。

... githubで利用可能です:

https://github.com/yaccob/ytools

pipを使用してインストールできます。

pip install ytools

検証の例(from https://github.com/yaccob/ytools#validation ):

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

まだ箱から出していないのは、yaml形式の外部スキーマに対しても検証することです。

ytoolsは、これまでに存在しなかったものを提供していません-既存のソリューションのアプリケーションをより柔軟で便利なものにするだけです。

0
yaccob

Pythonのyaml libを使用して、ロードしたファイルのmessage/char/line/fileを表示できます。

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

エラーメッセージはexc.problemからアクセスできます。

アクセスexc.problem_markを取得して<yaml.error.Mark>オブジェクト。

このオブジェクトを使用すると、属性にアクセスできます

  • 名前
  • カラム
  • ライン

したがって、問題への独自のポインターを作成できます。

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

python解決策を知りません。ただし、 kwalify というYAMLのRubyスキーマ検証ツールがあります。 pythonライブラリに出会わなければ、サブプロセスを使用してアクセスできるはずです。

0
ars