Skip to main content

JSON/YAML homoiconic templating language

Project description

JSON/YAML homoiconic templating language

Github Actions Downloads PyPI version

python3 -m pip install jinsi

Jinsi is a templating engine that uses YAML/JSON syntax, i.e. it is homoiconic. Never mess with indentation again.

Most template engines are a poor choice for templating YAML/JSON, which is why Jinsi is embedded in the document as native YAML/JSON syntax.

Example:

::let:
  foo: Hello
  bar: World
value: <<foo>> <<bar>>

Yields:

value: Hello World

Since Jinsi is basically independent from the syntax it works natively in JSON (or any other dialect which uses the same data model) too:

{
  "::let": {
    "foo": "Hello",
    "bar": "World"
  },
  "value": "<<foo>> <<bar>>"
}

Jinsi was inspired by AWS Cloudformation templates, which are also homoiconic and feature builtin functions (with more limited scope though). As I am using it to ease my DevOps woes it supports Cloudformation's Bang-Syntax (!Sub) natively.

Jinsi comes as a command line tool, but you can use it as a library for reading/writing YAML/JSON files too.

Usage:

jinsi template.yaml foo=bar qux=quuz

The above invocation will set $foo to Jane and $qux to Jim:

value: Hello <<$foo>>

...would result in value: Hello Jane.

I am also using it to template Kubernetes YAML files. Both kustomize as well as helm (which uses Go Templates 😖) do not cut it for me. My developer life has been happier ever since. I could imagine using it with salt, too (Jinja templates + YAML is just a PITA). Here's an example which configures an ingress resource using aws load balancer controller

::let:
  $name: web-application
  $subdomain: dashboard
  $domain: example.com
  $services:
    - users
    - messages
    - backoffice

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: <<$subdomain>>
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/group.name: <<$domain>>
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/listen-ports:
      ::json_serialize:
        - HTTPS: 443
        - HTTP: 80
    alb.ingress.kubernetes.io/actions.ssl-redirect:
      ::json_serialize:
        Type: redirect
        RedirectConfig:
          Protocol: HTTPS
          Port: '443'
          StatusCode: HTTP_301
spec:
  rules:
    - host: <<$subdomain>>.<<$domain>>
      http:
        paths:
          ::concat:
            - - path: /*
                backend:
                  serviceName: ssl-redirect
                  servicePort: use-annotation
            - ::each $services as $service:
                path: '/<<$service>>/*'
                backend:
                  serviceName: <<$service>>-service
                  servicePort: 80
            - - path: '/*'
                backend:
                  serviceName: <<$name>>
                  servicePort: 80

Usage via CLI

python3 -m jinsi -  # read from stdin
python3 -m jinsi -j -  # read from stdin, render as json
python3 -m jinsi file1.yaml file2.yaml

Examples

Cloudformation Template

YAML input:

::let:
  user:
    ::object:
      - ::titlecase:
          ::get: $user.username
      - Type: AWS::IAM::User
        Properties:
          UserName:
            ::get: $user.username
          Groups:
            - Administrators
          LoginProfile:
            Password:
              ::get: $user.password
              ::else: default
            PasswordResetRequired: Yes
  users:
    ::merge:
      ::each $ as $user:
        ::call user:

Resources:
  ::call users:
    - username: jim
      password: one
    - username: jack
      password: two
    - username: johnny

Rendered output:

Resources:
  Jack:
    Properties:
      Groups:
      - Administrators
      LoginProfile:
        Password: two
        PasswordResetRequired: true
      UserName: jack
    Type: AWS::IAM::User
  Jim:
    Properties:
      Groups:
      - Administrators
      LoginProfile:
        Password: one
        PasswordResetRequired: true
      UserName: jim
    Type: AWS::IAM::User
  Johnny:
    Properties:
      Groups:
      - Administrators
      LoginProfile:
        Password: default
        PasswordResetRequired: true
      UserName: johnny
    Type: AWS::IAM::User

Some fancy shit, too 🥸

This is just an example to show how complex a template can be. Also note: The fibonacci function is defined recursively. This would blow up and values upto 50 could not be computed. Since Jinsi is purely functional, functions are mappings and can be cached. This is why the computation returns quickly (at all).

python3 -m jinsi max=50 -

YAML input:

::let:
  fib:
    ::when:
      ::get: $n == 0 or $n == 1
    ::then:
      ::get: $n
    ::else:
      ::add:
        - ::call fib:
            $n:
              ::get: $n - 1
        - ::call fib:
            $n:
              ::get: $n - 2
  fibs:
    ::range_exclusive:
      - 0
      - ::get: $max
        ::else: 10

result:
  ::each fibs as $n:
    ::call: fib

Rendered output:

result:
- 0
- 1
- 1
- 2
- 3
- 5
- 8
- 13
- 21
- 34
- 55
- 89
- 144
- 233
- 377
- 610
- 987
- 1597
- 2584
- 4181
- 6765
- 10946
- 17711
- 28657
- 46368
- 75025
- 121393
- 196418
- 317811
- 514229
- 832040
- 1346269
- 2178309
- 3524578
- 5702887
- 9227465
- 14930352
- 24157817
- 39088169
- 63245986
- 102334155
- 165580141
- 267914296
- 433494437
- 701408733
- 1134903170
- 1836311903
- 2971215073
- 4807526976
- 7778742049

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jinsi-0.19.1.tar.gz (30.0 kB view details)

Uploaded Source

Built Distribution

jinsi-0.19.1-py3-none-any.whl (29.6 kB view details)

Uploaded Python 3

File details

Details for the file jinsi-0.19.1.tar.gz.

File metadata

  • Download URL: jinsi-0.19.1.tar.gz
  • Upload date:
  • Size: 30.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.8.3 requests/2.28.1 setuptools/65.6.3 requests-toolbelt/0.9.1 tqdm/4.64.1 CPython/3.8.5

File hashes

Hashes for jinsi-0.19.1.tar.gz
Algorithm Hash digest
SHA256 96627b521b2cf8518709fcdf18743b6012d252881441baa71a0d5b348680c675
MD5 63b0ca8f0ecb282abe8ac72fd819f780
BLAKE2b-256 62939f19541a8095249e7e44778943d804b705959e2f908e7c94b81610d53c10

See more details on using hashes here.

File details

Details for the file jinsi-0.19.1-py3-none-any.whl.

File metadata

  • Download URL: jinsi-0.19.1-py3-none-any.whl
  • Upload date:
  • Size: 29.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.8.3 requests/2.28.1 setuptools/65.6.3 requests-toolbelt/0.9.1 tqdm/4.64.1 CPython/3.8.5

File hashes

Hashes for jinsi-0.19.1-py3-none-any.whl
Algorithm Hash digest
SHA256 59bb46c15a2c80289fcc026ac384be3c1c1ca5137e10f361e46afd455a8d326f
MD5 8fa0299513cca05f757ed0e1119a4fda
BLAKE2b-256 8cb71d7e475787ee2264e7d9473f1253867da6f9c417cb552521a1aca1470908

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page