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.17.2.tar.gz (30.7 kB view details)

Uploaded Source

Built Distribution

jinsi-0.17.2-py3-none-any.whl (29.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: jinsi-0.17.2.tar.gz
  • Upload date:
  • Size: 30.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.6.1 requests/2.25.1 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.62.2 CPython/3.8.5

File hashes

Hashes for jinsi-0.17.2.tar.gz
Algorithm Hash digest
SHA256 7b61688c50bc84c7cf21f29d47d57337210292338fad4bdea11dbfd616d47f8a
MD5 423a898a0c05c3ab306db833905325b1
BLAKE2b-256 f1c0c5b2a077b4e4e2acbbce9cdfe20f44da3362cc461808d7e86fb2ac28bbcc

See more details on using hashes here.

File details

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

File metadata

  • Download URL: jinsi-0.17.2-py3-none-any.whl
  • Upload date:
  • Size: 29.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.6.1 requests/2.25.1 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.62.2 CPython/3.8.5

File hashes

Hashes for jinsi-0.17.2-py3-none-any.whl
Algorithm Hash digest
SHA256 48a3b3758f64297589a045bd2c976790b73050358516d8d643b5901f3cb70433
MD5 51f47fdb2595b697b73dc9b403dee78b
BLAKE2b-256 5cd758d42a143467d9571642e12c6168149108e85c61a5efa6864d99715a8408

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