Skip to main content

Rio configuration parser

Project description

Rio Config data parser

Rio is a configuration parser for use in common configuration scenarios.

It is similar to TOML and YAML in concept, but is unique in its approach to handling variables and configuration data, with focus on simplicity of declaration of complex data structures.

Features

  • no spacing requirements (ie, 2 spaces in YAML)
  • braces not necessary (ie, json)
  • can add comments inside configuration
  • clean and simple syntax to describe complex data structures
  • ability to create template blocks for repeated options
  • can natively ingest shell environment variables at runtime, including fallback values
  • ability to created nested hashes without excessive notation and spacing

Installation

To install Rio Config, using pip

pip install rio_config

Usage

To parse a rio configuration file and get a dictionary structure of your file:

from rio_config import Rio

rio = Rio()
result = rio.parse_file("myfile.rio")

Rio can handle the following types

  • strings
  • hashes
  • ints
  • floats
  • booleans
  • arrays

To create a basic key:value pair, you need a Header block (top key or Parent key) which is denoted by colon at end

Key:
Value

ie,

Name:
"Joe" 

# equals  {"Name": "Joe"}

To created a nested hash

Parent Key:
child key = child value

Employee:
Name = "Joe"

# equals {"Employee": {"Name": "Joe"}}

double quoting non numeric values is recommended to avoid ambiguous value declaration


Basic Dictionary/Hash

To create a deep hash structure, add a key block declaration of all top keys and a final value, separated by a dot

Rio will create all parent subkeys along the path

first.second.third:
  fourth = value

result

{
"first": {
  "second": {
    "third": {
      "fourth": "value"
      }
    }
  }
}

double spacing the subkey=value is not mandatory but is recommended for readability, ie

first.second.third:
  fourth = value

Escape Character

if the top level key has dot in its name, you can escape parsing it with an escape character '\.'

first.second\.level.third:
  value

result

{
  "first": {
    "second.level": {
      "third": "value"
    }
  }
}

Single Key

If the Parent key has dots in the name and you want to keep it as single key, double quote the parent key

"parent.key.separated.by.dot":
subkey = value

result

{
  "parent.key.separated.by.dot": {
    "subkey": "value"
  }
}

Arrays

To create an array, declare it using brackets, with each element separated by a comma

My List:
  subkey = [first, second, third]

## result 
{
  "My List": {
    "subkey": [
      "first",
      "second",
      "third"
    ]
  }
}

Arrays can also be created using a multiline declaration within a bracket pair

cars:
  names = [
    toyota,
    ferrari,
    chevy
  ]

result

{
  "cars": {
    "names": [
      "toyota",
      "ferrari",
      "chevy"
    ]
  }
}

you can also create an array without a subkey,

my array:
  ['a', 'b', 'c']

result

{
  "my array": [
    "a",
    "b",
    "c"
  ]
}

Child nested subkeys

With Rio you can also create nested subkeys underneath your parent key, by placing a dot in the subkey declaration

config.nginx:
  cache.size = 200
  cache.limit = 190
  cache.clean.size = 5

result

{
  "config": {
    "nginx": {
      "cache": {
        "size": 200,
        "limit": 190,
        "clean": {
          "size": 5
        }
      }
    }
  }
}

To treat a child subkey with dots a single key, wrap it in quotes

config.nginx:
  cache.size = 200
  cache.limit = 190
  "cache.clean.size" = 5

Strings, Ints, Booleans, Floats

Rio will evaluate each value for its type, ie strings, ints, floats, booleans

By default, all values are strings, unless its a raw integer. To treat an integer as a string, double quote it

variables:
  string = this is a string
  real int = 12345
  stringified int = "12345"
  boolean true = True
  boolean false = False
  boolean strinfigied = "True"
  float = 2.34596

result

{
  "variables": {
    "string": "this is a string",
    "real int": 12345,
    "stringified int": "12345",
    "boolean true": true,
    "boolean false": false,
    "boolean strinfigied": "True",
    "float": 2.34596
  }
}

Templates

Templates allow you to reuse configuration data without copying and pasting the same data over and over.

Templates are created by using the @template keyword

@template TemplateName: declares a new template, followed by template variables

@use keyword then instructs the key block to use the variables from the given template, ie

@use = myTemplate

for example, lets say you want to add some Company-specific data to every Employee

(note: double spacing the subkeys is not mandatory but recommended, purely for visual clarity)

@template company:
  name = "Initech"
  address = "123 company drive"
  phone = "200-301-4050"

employees.Joe:
  @use = company
  department = "sales"

employees.Bill:
  @use = company
  department = "engineering"

result:

{
  "employees": {
    "Joe": {
      "name": "Initech",
      "address": "123 company drive",
      "phone": "200-301-4050",
      "department": "sales"
    },
    "Bill": {
      "name": "Initech",
      "address": "123 company drive",
      "phone": "200-301-4050",
      "department": "engineering"
    }
  }
}

to overwrite a template's variable with a custom value, simply provide a new variable with same name

for example, if you want Bill's phone number to be 111-111-1111 instead of the phone number from the template, you can add a new variable called "phone" which will override the previous value coming from the template

@template company:
  name = Initech
  address = "123 company drive"
  phone = "200-301-4050"

employees.Joe:
  @use = company
  department = "sales"

employees.Bill:
  @use = company
  department = "engineering"
  phone = "111-111-1111"

result

{
  "employees": {
    "Joe": {
      "name": "Initech",
      "address": "123 company drive",
      "phone": "200-301-4050",
      "department": "sales"
    },
    "Bill": {
      "name": "Initech",
      "address": "123 company drive",
      "phone": "111-111-1111",
      "department": "engineering"
    }
  }
}

You can also combine multiple templates in one config block

@template evens:
  even_numbers = [2,4,6,8]

@template odds:
  odd_numbers = [1,3,5,7]

@template words:
  hello = world
  bunch of words = [
    sunflower,
    gunpowder,
    beer
  ]

combined stuff:
  @use = evens
  @use = odds
  @use = words

result will contain all your template variables

{
  "combined stuff": {
    "even_numbers": [
      2,
      4,
      6,
      8
    ],
    "odd_numbers": [
      1,
      3,
      5,
      7
    ],
    "hello": "world",
    "bunch of words": [
      "sunflower",
      "gunpowder",
      "beer"
    ]
  }
}

Multiline Comments

comments or text spanning multiple lines can be written using the single quote troika

mycomment:
  comment = '''
  this 
  is 
  a comment
  that    spans

  many

  lines
  '''

result

{
"mycomment": {
  "comment": "\nthis \nis \na comment\nthat    spans\n\nmany\n\nlines\n"
  }
}

Environment Variables

to process a shell environment variable, provide @env flag

database.credential:
  password = @env DB_PASSWORD

this will translate a shell variable $DB_PASSWORD

if the variable is not set, the value will be NULL

to pass a default fallback value if env variable isnt set, provide a default using the double pipe OR symbol

database.credential:
  password = @env DB_PASSWORD || abracadabra123

result

{
"database": {
  "credential": {
    "password": "abracadabra123"
    }
  }
}
export DB_PASSWORD="cheese-is-yummy991"
{
"database": {
  "credential": {
    "password": "cheese-is-yummy991"
    }
  }
}

Comments

Comments within the configuration data can be added with # symbol

# this is a comment
key:
  value  # this is also a comment

Comments are not processed during final output


Testing

pip install pytest

shell> cd tests

shell> pytest -sv run_tests.py


Packaging

python3 -m pip install --upgrade pip setuptools wheel build twine
python3 -m build
python3 -m pip install twine
python3 -m twine upload dist/*

TO DO:

  • add single variables ie $var = joe use var,

    name = $var
    
  • add For loops

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

rio_config-0.1.3.tar.gz (10.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rio_config-0.1.3-py3-none-any.whl (8.2 kB view details)

Uploaded Python 3

File details

Details for the file rio_config-0.1.3.tar.gz.

File metadata

  • Download URL: rio_config-0.1.3.tar.gz
  • Upload date:
  • Size: 10.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for rio_config-0.1.3.tar.gz
Algorithm Hash digest
SHA256 f6b1d505abe9ef08e72b65d0c26cf507d0062d3b26385d31587351a9f27d1881
MD5 23d50a64fddcb6475946b7a8fe151b73
BLAKE2b-256 2c0fa3e14bb37a6abdc2e57013207d7ec9f2fc6a33bd8a6004b78c29c1f538a2

See more details on using hashes here.

File details

Details for the file rio_config-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: rio_config-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 8.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for rio_config-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 85462f869259173d9555bd5113f00a73ec5c2459796b176c7dd3bd51d459b033
MD5 9560692c9474d41d8b02f413821620f6
BLAKE2b-256 22c05633c8d7523f293088495826697492ac73fd1cc974dcc2c91e1283e3c16d

See more details on using hashes here.

Supported by

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