Metadata-Version: 2.1
Name: jinja2-jsonschema
Version: 0.2.1
Summary: JSON/YAML schema validation within Jinja2 templates
Home-page: https://github.com/copier-org/jinja2-jsonschema
License: MIT
Keywords: jinja,jinja2,extension,jsonschema,json,yaml
Author: Sigurd Spieckermann
Author-email: sigurd.spieckermann@gmail.com
Requires-Python: >=3.7.2
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.7
Provides-Extra: yaml
Requires-Dist: jinja2 (>=3.0.0)
Requires-Dist: jsonschema (>=4.0.0)
Requires-Dist: pyyaml (>=6.0.0) ; extra == "yaml"
Requires-Dist: typing-extensions (>=3.7.4) ; python_version < "3.8"
Project-URL: Repository, https://github.com/copier-org/jinja2-jsonschema
Description-Content-Type: text/markdown

# JSON Schema Validation within Jinja2 Templates

[![Tests](https://img.shields.io/github/actions/workflow/status/copier-org/jinja2-jsonschema/tests.yml?branch=main&label=Tests&labelColor=333&logo=github&style=flat-square)](https://github.com/copier-org/jinja2-jsonschema/actions?query=branch%3Amain)
[![Python versions](https://img.shields.io/pypi/pyversions/jinja2-jsonschema?label=Python&logo=python&logoColor=%23959DA5&style=flat-square)](https://pypi.org/project/jinja2-jsonschema)
[![PyPI](https://img.shields.io/pypi/v/jinja2-jsonschema?label=PyPI&logo=pypi&logoColor=%23959DA5&style=flat-square)](https://pypi.org/project/jinja2-jsonschema)
[![Code style: Black](https://img.shields.io/badge/Code%20Style-Black-000000.svg?style=flat-square)](https://github.com/psf/black)
[![Linter: Ruff](https://img.shields.io/badge/-Ruff-261230.svg?labelColor=grey&logo=ruff&logoColor=D7FF64&style=flat-square)](https://github.com/charliermarsh/ruff)
[![Type-checker: mypy](https://img.shields.io/badge/mypy-strict-2A6DB2.svg?style=flat-square)](http://mypy-lang.org)

A [Jinja2 extension][jinja-extensions] providing a [Jinja2 filter][jinja-filter] and a [Jinja2 test][jinja-test] for validating data against a JSON/YAML schema within [Jinja2][jinja] templates.

## Installation

* With [`pip`](https://pip.pypa.io):

    ```shell
    pip install jinja2-jsonschema

    # ... or with YAML support
    pip install jinja2-jsonschema[yaml]
    ```

* With [`poetry`][poetry]:

    ```shell
    poetry add jinja2-jsonschema

    # ... or with YAML support
    poetry add jinja2-jsonschema -E yaml
    ```

* With [`pdm`][pdm]:

    ```shell
    pdm add jinja2-jsonschema

    # ... or with YAML support
    pdm add jinja2-jsonschema[yaml]
    ```

* With [`pipx`][pipx] (injected into the `pipx`-managed virtual env of a package):

    ```shell
    pipx inject PACKAGE jinja2-jsonschema

    # ... or with YAML support
    pipx inject PACKAGE jinja2-jsonschema[yaml]
    ```

## Usage

The extension provides:

* A Jinja2 filter which receives a schema file path or schema object as input and returns a [`jsonschema.ValidationError`][python-jsonschema-validationerror] object when validation fails and an empty string (`""`) otherwise.
* A Jinja2 test which receives a schema file path or schema object as input and returns `False` when validation fails and `True` otherwise.

The [JSON Schema dialect][jsonschema-dialect] is inferred from the `$schema` field in the JSON Schema document and, when omitted, defaults to the [latest dialect supported by the installed `jsonschema` library][python-jsonschema-features]. Both local and remote schemas are supported including [schema references][jsonschema-ref] and [JSON Pointers][jsonschema-jsonpointer].

Local schema files are loaded via a [Jinja2 loader](https://jinja.palletsprojects.com/en/latest/api/#loaders) in which case configuring the Jinja2 environment with a loader is mandatory.

Some example usage of the JSON Schema validation filter and test is this:

```python
from jinja2 import Environment
from jinja2 import FileSystemLoader


env = Environment(
    # Register a loader (only necessary when using local schema files).
    loader=FileSystemLoader("/path/to/templates"),
    # Register the extension.
    extensions=["jinja2_jsonschema.JsonSchemaExtension"],
)

# Example using an inline schema object.
template = env.from_string("{{ age | jsonschema({'type': 'integer', 'minimum': 0}) }}")
template.render(age=30)  # OK
template.render(age=-1)  # ERROR
template = env.from_string("{{ age is jsonschema({'type': 'integer', 'minimum': 0}) }}")
template.render(age=30)  # --> `True`
template.render(age=-1)  # --> `False`

# Example using a local schema file.
template = env.from_string("{{ age | jsonschema('age.json') }}")
template.render(age=30)  # OK
template.render(age=-1)  # ERROR
template = env.from_string("{{ age is jsonschema('age.json') }}")
template.render(age=30)  # --> `True`
template.render(age=-1)  # --> `False`

# Example using a remote schema file.
template = env.from_string("{{ age | jsonschema('https://example.com/age.json') }}")
template.render(age=30)  # OK
template.render(age=-1)  # ERROR
template = env.from_string("{{ age is jsonschema('https://example.com/age.json') }}")
template.render(age=30)  # --> `True`
template.render(age=-1)  # --> `False`
```

## Usage with Copier

The extension integrates nicely with [Copier][copier], e.g. for validating complex JSON/YAML answers in the Copier questionnaire. For this, add the extension as a [Jinja2 extension in `copier.yml`][copier-jinja-extensions] and use the Jinja2 filter in the `validator` field of a Copier [question][copier-questions]. For instance:

```yaml
_jinja_extensions:
  - jinja2_jsonschema.JsonSchemaExtension

complex_question:
  type: json # or `yaml`
  validator: "{{ complex_question | jsonschema('schemas/complex.json') }}"
```

In this example, a local schema file `schemas/complex.json` is used whose path is relative to the template root. To prevent copying schema files to the generated project, they should be either [excluded][copier-exclude]

```diff
+_exclude:
+  - schemas/
 _jinja_extensions:
   - jinja2_jsonschema.JsonSchemaExtension
```

or the project template should be located in a [subdirectory][copier-subdirectory] such as `template/`:

```diff
+_subdirectory_: template
 _jinja_extensions:
   - jinja2_jsonschema.JsonSchemaExtension
```

Finally, template consumers need to install the extension along with Copier. For instance with `pipx`:

```shell
pipx install copier
pipx inject copier jinja2-jsonschema
```

## Contributions

Contributions are always welcome via filing [issues](https://github.com/copier-org/jinja2-jsonschema/issues) or submitting [pull requests](https://github.com/copier-org/jinja2-jsonschema/pulls). Please check the [contribution guide][contribution-guide] for more details.

[contribution-guide]: https://github.com/copier-org/jinja2-jsonschema/blob/main/CONTRIBUTING.md
[copier]: https://github.com/copier-org/copier
[copier-exclude]: https://copier.readthedocs.io/en/stable/configuring/#exclude
[copier-jinja-extensions]: https://copier.readthedocs.io/en/stable/configuring/#jinja_extensions
[copier-questions]: https://copier.readthedocs.io/en/stable/configuring/#questions
[copier-subdirectory]: https://copier.readthedocs.io/en/stable/configuring/#subdirectory
[jinja]: https://jinja.palletsprojects.com
[jinja-extensions]: https://jinja.palletsprojects.com/en/latest/extensions/
[jinja-filter]: https://jinja.palletsprojects.com/en/latest/templates/#filters
[jinja-test]: https://jinja.palletsprojects.com/en/latest/templates/#tests
[jsonschema]: https://json-schema.org
[jsonschema-dialect]: https://json-schema.org/understanding-json-schema/reference/schema.html#schema
[jsonschema-ref]: https://json-schema.org/understanding-json-schema/structuring.html#ref
[jsonschema-jsonpointer]: https://json-schema.org/understanding-json-schema/structuring.html#json-pointer
[pdm]: https://pdm.fming.dev
[pip]: https://pip.pypa.io
[pipx]: https://pypa.github.io/pipx
[poetry]: https://python-poetry.org
[python-jsonschema-features]: https://python-jsonschema.readthedocs.io/en/stable/#features
[python-jsonschema-validationerror]: https://python-jsonschema.readthedocs.io/en/stable/api/jsonschema/exceptions/#jsonschema.exceptions.ValidationError

