Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
Y

Yamale

> 编程语言
Open source

A schema and validator for YAML.

769 stars0 likes1 views
WebsiteGitHub

About

A schema and validator for YAML.

Yamale (ya·ma·lē)

:warning: Ensure that your schema definitions come from internal or trusted sources. Yamale does not protect against intentionally malicious schemas.

A schema and validator for YAML.

What's YAML? See the current spec here and an introduction to the syntax here.

Requirements

  • Python 3.8+
  • PyYAML
  • ruamel.yaml (optional)

Install

pip

$ pip install yamale
# or to include ruamel.yaml as a dependency
$ pip install yamale[ruamel]

NOTE: Some platforms, e.g., Mac OS, may ship with only Python 2 and may not have pip installed. Installation of Python 3 should also install pip. To preserve any system dependencies on default software, consider installing Python 3 as a local package. Please note replacing system-provided Python may disrupt other software. Mac OS users may wish to investigate MacPorts, homebrew, or building Python 3 from source; in all three cases, Apple's Command Line Tools (CLT) for Xcode may be required. See also developers, below.

Manual

  1. Download Yamale from: https://github.com/23andMe/Yamale/archive/master.zip
  2. Unzip somewhere temporary
  3. Run python setup.py install (may have to prepend sudo)

Usage

Command line

Yamale can be run from the command line to validate one or many YAML files. Yamale will search the directory you supply (current directory is default) for YAML files. Each YAML file it finds it will look in the same directory as that file for its schema, if there is no schema Yamale will keep looking up the directory tree until it finds one. If Yamale can not find a schema it will tell you.

Usage:

…

API

There are several ways to feed Yamale schema and data files. The simplest way is to let Yamale take care of reading and parsing your YAML files.

All you need to do is supply the files' path:

python
# Import Yamale and make a schema object:
import yamale
schema = yamale.make_schema('./schema.yaml')

# Create a Data object
data = yamale.make_data('./data.yaml')

# Validate data against the schema. Throws a ValueError if data is invalid.
yamale.validate(schema, data)

You can pass a string of YAML to make_schema() and make_data() instead of passing a file path by using the content= parameter:

python
data = yamale.make_data(content="""
name: Bill
age: 26
height: 6.2
awesome: True
""")

If data is valid, nothing will happen. However, if data is invalid Yamale will throw a YamaleError with a message containing all the invalid nodes:

python
try:
    yamale.validate(schema, data)
    print('Validation success! ')
except ValueError as e:
    print('Validation failed!\n%s' % str(e))
    exit(1)

and an array of ValidationResult.

python
try:
    yamale.validate(schema, data)
    print('Validation success! ')
except YamaleError as e:
    print('Validation failed!\n')
    for result in e.results:
        print("Error validating data '%s' with '%s'\n\t" % (result.data, result.schema))
        for error in result.errors:
            print('\t%s' % error)
    exit(1)

You can also specify an optional parser if you'd like to use the ruamel.yaml (YAML 1.2 support) instead:

python
# Import Yamale and make a schema object, make sure ruamel.yaml is installed already.
import yamale
schema = yamale.make_schema('./schema.yaml', parser='ruamel')

# Create a Data object
data = yamale.make_data('./data.yaml', parser='ruamel')

# Validate data against the schema same as before.
yamale.validate(schema, data)

Schema

:warning: Ensure that your schema definitions come from internal or trusted sources. Yamale does not protect against intentionally malicious schemas.

To use Yamale you must make a schema. A schema is a valid YAML file with one or more documents inside. Each node terminates in a string which contains valid Yamale syntax. For example, str() represents a String validator.

A basic schema:

yaml
name: str()
age: int(max=200)
height: num()
awesome: bool()

And some YAML that validates:

yaml
name: Bill
age: 26
height: 6.2
awesome: True

Take a look at the Examples section for more complex schema ideas.

Includes

Schema files may contain more than one YAML document (nodes separated by ---). The first document found will be the base schema. Any additional documents will be treated as Includes. Includes allow you to define a valid structure once and use it several times. They also allow you to do recursion.

A schema with an Include validator:

yaml
person1: include('person')
person2: include('person')
---
person:
    name: str()
    age: int()

Some valid YAML:

yaml
person1:
    name: Bill
    age: 70

person2:
    name: Jill
    age: 20

Every root node not in the first YAML document will be treated like an include:

yaml
person: include('friend')
group: include('family')
---
friend:
    name: str()
family:
    name: str()

Is equivalent to:

yaml
person: include('friend')
group: include('family')
---
friend:
    name: str()
---
family:
    name: str()
Recursion

You can get recursion using the Include validator.

This schema:

yaml
person: include('human')
---
human:
    name: str()
    age: int()
    friend: include('human', required=False)

Will validate this data:

yaml
person:
    name: Bill
    age: 50
    friend:
        name: Jill
        age: 20
        friend:
            name: Will
            age: 10
Adding external includes

After you construct a schema you can add extra, external include definitions by calling schema.add_include(dict). This method takes a dictionary and adds each key as another include.

Strict mode

By default Yamale will provide errors for extra elements present in lists and maps that are not covered by the schema. With strict mode disabled (using the --no-strict command line option), additional elements will not cause any errors. In the API, strict mode can be toggled by passing the strict=True/False flag to the validate function.

It is possible to mix strict and non-strict mode by setting the strict=True/False flag in the include validator, setting the option only for the included validators.

Validators

Here are all the validators Yamale knows about. Every validator takes a required keyword telling Yamale whether or not that node must exist. By default every node is required. Example: str(required=False)

You can also require that an optional value is not None by using the none keyword. By default Yamale will accept None as a valid value for a key that's not required. Reject None values with none=False in any validator. Example: str(required=False, none=False).

Some validators take keywords and some take arguments, some take both. For instance the enum() validator takes one or more constants as arguments and the required keyword: enum('a string', 1, False, required=False)

String - str(min=int, max=int, equals=string, starts_with=string, ends_with=string, matches=regex, exclude=string, ignore_case=False, multiline=False, dotall=False)

Validates strings.

  • keywords
    • min: len(string) >= min
    • max: len(string) = min
    • max: int = min
    • max: num = min
    • max: date = min
    • max: time = min
    • max: len(list) = min
    • max: len(map) <= max

Examples:

  • map(): Validates any map
  • map(str(), int()): Only validates maps whose values are strings or integers.
  • map(str(), key=int()): Only validates maps whose keys are integers and values are strings. 1: one would be valid but '1': one would not.
  • map(str(), min=1): Only validates a non-empty map.

IP Address - ip()

Validates IPv4 and IPv6 addresses.

  • keywords
    • version: 4 or 6; explicitly force IPv4 or IPv6 validation

Examples:

  • ip(): Allows any valid IPv4 or IPv6 address
  • ip(version=4): Allows any valid IPv4 address
  • ip(version=6): Allows any valid IPv6 address

MAC Address - mac()

Validates MAC addresses.

Examples:

  • mac(): Allows any valid MAC address

SemVer (Semantic Versioning) - semver()

Validates Semantic Versioning strings.

Examples:

  • semver(): Allows any valid SemVer string

Any - any([validators])

Validates against a union of types. Use when a node must contain one and only one of several types. It is valid if at least one of the listed validators is valid. If no validators are given, accept any value.

  • arguments: validators to test values with (if none is given, allow any value; if one or more are given, one must be present)

Examples:

  • any(int(), null()): Validates either an integer or a null value.
  • any(num(), include('vector')): Validates either a number or an included 'vector' type.
  • any(str(min=3, max=3),str(min=5, max=5),str(min=7, max=7)): validates to a string that is exactly 3, 5, or 7 characters long
  • any(): Allows any value.

Subset - subset([validators], allow_empty=False)

Validates against a subset of types. Unlike the Any validator, this validators allows one or more of several types. As such, it automatically validates against a list. It is valid if all values can be validated against at least one validator.

  • arguments: validators to test with (at least one; if none is given, a ValueError exception will be raised)
  • keywords:
    • allow_empty: Allow the subset to be empty (and is, therefore, also optional). This overrides the required flag.

Examples:

  • subset(int(), str()): Validators against an integer, a string, or a list of either.
  • subset(int(), str(), allow_empty=True): Same as above, but allows the empty set and makes the subset optional.

Include - include(include_name)

Validates included structures. Must supply the name of a valid include.

  • arguments: single name of a defined include, surrounded by quotes.

Examples:

  • include('person')

Custom validators

It is also possible to add your own custom validators. This is an advanced topic, but here is an example of adding a Date validator and using it in a schema as date()

python
import yamale
import datetime
from yamale.validators import DefaultValidators, Validator

class Date(Validator):
    """ Custom Date validator """
    tag = 'date'

    def _is_valid(self, value):
        return isinstance(value, datetime.date)

validators = DefaultValidators.copy()  # This is a dictionary
validators[Date.tag] = Date
schema = yamale.make_schema('./schema.yaml', validators=validators)
# Then use `schema` as normal

Examples

:warning: Ensure that your schema definitions come from internal or trusted sources. Yamale does not protect against intentionally malicious schemas.

Using keywords

Schema:

yaml
optional: str(required=False)
optional_min: int(min=1, required=False)
min: num(min=1.5)
max: int(max=100)

Valid Data:

yaml
optional_min: 10
min: 1.6
max: 100

Includes and recursion

Schema:

yaml
customerA: include('customer')
customerB: include('customer')
recursion: include('recurse')
---
customer:
    name: str()
    age: int()
    custom: include('custom_type')

custom_type:
    integer: int()

recurse:
    level: int()
    again: include('recurse', required=False)

Valid Data:

yaml
customerA:
    name: bob
    age: 900
    custom:
        integer: 1
customerB:
    name: jill
    age: 1
    custom:
        integer: 3
recursion:
    level: 1
    again:
        level: 2
        again:
            level: 3
            again:
                level: 4

Lists

Schema:

yaml
list_with_two_types: list(str(), include('variant'))
questions: list(include('question'))
---
variant:
  rsid: str()
  name: str()

question:
  choices: list(include('ch

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

Pythonpythonschemayaml

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言