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

Uploaded Source

Built Distribution

jinsi-0.14.1-py3-none-any.whl (27.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: jinsi-0.14.1.tar.gz
  • Upload date:
  • Size: 24.8 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.50.2 CPython/3.8.5

File hashes

Hashes for jinsi-0.14.1.tar.gz
Algorithm Hash digest
SHA256 2e1fe009d2010273b0c7d126216cc68b9e1b0796a0c61e053e6aa9be9fbc62b3
MD5 e204808f38a4c8330c90cee14da4e1a4
BLAKE2b-256 ce3cff7bf4824b5d3f37a436fff19bf3d2c39995182c9e25f84126b545ef3603

See more details on using hashes here.

File details

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

File metadata

  • Download URL: jinsi-0.14.1-py3-none-any.whl
  • Upload date:
  • Size: 27.9 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.50.2 CPython/3.8.5

File hashes

Hashes for jinsi-0.14.1-py3-none-any.whl
Algorithm Hash digest
SHA256 dc93d76202a0ddd900fd659d1e42f6ee53005ae4bd27f09aa0b8cae84b4e8efc
MD5 b69596ec4af320df5b23bee782edc4e8
BLAKE2b-256 f33be64a1f367fd609ca2521d274a6eb465e049b269c995fcc545b1957a43b71

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