Skip to main content

Consistent TOML for Python

Project description

# Consistent TOML for Python

[![Build Status](https://travis-ci.org/Jumpscale/python-consistent-toml.svg?branch=master)](https://travis-ci.org/Jumpscale/python-consistent-toml)
[![Python Versions](https://img.shields.io/pypi/pyversions/contoml.svg)](https://pypi-hypernode.com/pypi/contoml)
[![Release](https://img.shields.io/pypi/v/contoml.svg)](https://pypi-hypernode.com/pypi/contoml)
![Wheel](https://img.shields.io/pypi/wheel/contoml.svg)
[![Join the chat at https://gitter.im/Jumpscale/python-consistent-toml](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Jumpscale/python-consistent-toml?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)


A [TOML](https://github.com/toml-lang/toml) serializer/deserializer for Python that tries its best to preserve order of table mappings, formatting of source file, and comments during a deserialize/update/serialize job. This is achieved by preserving the parsed/constructed TOML data structures as lexical tokens internally and having the data manipulations performed directly on the tokens.

## Installation ##
```bash
pip install --upgrade contoml
```

## Usage ##

```python
>>> import contoml

>>> toml_file = contoml.load('sample.toml')

# The anonymous table is accessible using the empty string key on the TOML file
>>> toml_file['']['title']
'TOML Example'

# You can modify table values, add new values, or new tables
>>> toml_file['fruit'][1]['variety'][0]['points'][0]['y'] = 42

>>> toml_file['servers']['alpha']['ip'] = '192.168.0.111'

>>> toml_file['environment'] = {'OS': 'Arch Linux', 'Type': 'GNU/Linux'}

# Or append to an array of tables!
>>> toml_file.array('disks').append({'dev': '/dev/sda', 'cap': '230'})
>>> toml_file.array('disks').append({'dev': '/dev/sdb', 'cap': '120'})

# Optionally you can format the TOML data into a textual structure
>>> toml_file.prettify()

# At any moment, you can drop all the formatting metadata preserved in the
# lodaded TOML file and obtain a primive Python container out of it
>>> toml_file.primitive
{'title': 'TOML Example',
'clients': {'data': [['gamma', 'delta'], [1, 2]],
'hosts': ['alpha', 'omega'],
'key3': 'The quick brown fox jumps over the lazy dog.',
'lines': 'The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n',
'quoted': 'Tom "Dubs" Preston-Werner',
'regex': '<\\i\\c*\\s*>',
'regex2': "I [dw]on't need \\d{2} apples",
'str2': 'The quick brown fox jumps over the lazy dog.',
'str_multiline': 'Roses are red\nViolets are blue',
'str_quoted': 'I\'m a string. "You can quote me". Name\tJosé\nLocation\tSF.',
'winpath': 'C:\\Users\\nodejs\\templates',
'winpath2': '\\\\ServerX\\admin$\\system32\\'},
'database': {'connection_max': 5000,
'enabled': True,
'ports': [8001, 8001, 8002],
'server': '192.168.1.1'},
'disks': [{'cap': '230', 'dev': '/dev/sda'},
{'cap': '120', 'dev': '/dev/sdb'}],
'environment': {'OS': 'Arch Linux', 'Type': 'GNU/Linux'},
'fruit': [{'name': 'apple',
'physical': {'color': 'red', 'shape': 'round'},
'variety': [{'name': 'red delicious'}, {'name': 'granny smith'}]},
{'name': 'banana',
'variety': [{'name': 'plantain',
'points': [{'x': 1, 'y': 42, 'z': 3},
{'x': 7, 'y': 8, 'z': 9},
{'x': 2, 'y': 4, 'z': 8}]}]}],
'owner': {'dob': datetime.datetime(1979, 5, 27, 15, 32, tzinfo=<UTC>),
'name': 'Tom Preston-Werner'},
'servers': {'alpha': {'dc': 'eqdc10', 'ip': '192.168.0.111'},
'beta': {'dc': 'eqdc10', 'ip': '10.0.0.2'}}}

# You can serialize your TOML file back to TOML text at any point
>>> toml_file.dump('updated_sample.toml')
```

This produces the following TOML file:

```toml
# This is a TOML document.

title = "TOML Example"

[owner]
name = "Tom Preston-Werner"
dob = 1979-05-27T07:32:00-08:00 # First class dates

[database]
server = "192.168.1.1"
ports = [ 8001, 8001, 8002 ]
connection_max = 5000
enabled = true

[servers]

# Indentation (tabs and/or spaces) is allowed but not required
[servers.alpha]
ip = "192.168.0.111"
dc = "eqdc10"

[servers.beta]
ip = "10.0.0.2"
dc = "eqdc10"

[clients]
data = [ ["gamma", "delta"], [1, 2] ]

# Line breaks are OK when inside arrays
hosts = [
"alpha",
"omega"
]

str_multiline = """
Roses are red
Violets are blue"""

str_quoted = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."

str2 = """
The quick brown \


fox jumps over \
the lazy dog."""

key3 = """\
The quick brown \
fox jumps over \
the lazy dog.\
"""

# What you see is what you get.
winpath = 'C:\Users\nodejs\templates'
winpath2 = '\\ServerX\admin$\system32\'
quoted = 'Tom "Dubs" Preston-Werner'
regex = '<\i\c*\s*>'

regex2 = '''I [dw]on't need \d{2} apples'''
lines = '''
The first newline is
trimmed in raw strings.
All other whitespace
is preserved.
'''


[[fruit]]
name = "apple"

[fruit.physical]
color = "red"
shape = "round"

[[fruit.variety]]
name = "red delicious"

[[fruit.variety]]
name = "granny smith"

[[fruit]]
name = "banana"

[[fruit.variety]]
name = "plantain"


points = [ { x = 1, y = 42, z = 3 }, # This value is so special to me
{ x = 7, y = 8, z = 9 },
{ x = 2, y = 4, z = 8 } ]


[environment]
Type = "GNU/Linux"
OS = "Arch Linux"

[[disks]]
cap = 230
dev = "/dev/sda"

[[disks]]
cap = 120
dev = "/dev/sdb"

```

Which is equivalent to the following data structure:

```json
{
"": {"title": "TOML Example"},
"owner": {
"name": "Tom Preston-Werner",
"dob": "1979-05-27 15:32:00+00:00"
},
"database": {
"ports": [8001, 8001, 8002],
"enabled": true,
"connection_max": 5000,
"server": "192.168.1.1"
},
"clients": {
"lines": "The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n",
"str_multiline": "Roses are red\nViolets are blue",
"regex": "<\\i\\c*\\s*>",
"winpath": "C:\\Users\\nodejs\\templates",
"data": [
["gamma", "delta"],
[1, 2]
],
"hosts": [
"alpha",
"omega"
],
"key3": "The quick brown fox jumps over the lazy dog.",
"str_quoted": "I'm a string. \"You can quote me\". Name\tJos\u00e9\nLocation\tSF.",
"quoted": "Tom \"Dubs\" Preston-Werner",
"str2": "The quick brown fox jumps over the lazy dog.",
"winpath2": "\\\\ServerX\\admin$\\system32\\",
"regex2": "I [dw]on't need \\d{2} apples"
},
"servers": {
"alpha": {
"dc": "eqdc10",
"ip": "192.168.0.111"
},
"beta": {
"dc": "eqdc10",
"ip": "10.0.0.2"
}
},
"fruit": [
{
"name": "apple",
"variety": [
{
"name": "red delicious"
},
{
"name": "granny smith"
}
],
"physical": {
"shape": "round",
"color": "red"
}
},
{
"name": "banana",
"variety": [
{
"name": "plantain",
"points": [
{"y": 42, "x": 1, "z": 3},
{"y": 8, "x": 7, "z": 9},
{"y": 4, "x": 2, "z": 8}
]
}
]
}
],
"disks": [
{"cap": "230", "dev": "/dev/sda"},
{"cap": "120", "dev": "/dev/sdb"}
],
"environment": {
"Type": "GNU/Linux",
"OS": "Arch Linux"
}
}
```

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

contoml-0.25.tar.gz (38.1 kB view details)

Uploaded Source

Built Distribution

contoml-0.25-py2.py3-none-any.whl (69.9 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file contoml-0.25.tar.gz.

File metadata

  • Download URL: contoml-0.25.tar.gz
  • Upload date:
  • Size: 38.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for contoml-0.25.tar.gz
Algorithm Hash digest
SHA256 23f6667af31c3e2c286be4f741aeaf8e96c640f4915174e21d474edca8e95e75
MD5 beaed9065168a9e878256c7e721c9f76
BLAKE2b-256 a1ef6f0e69d26c906a5424242d7e2a518903cbf183940a6cfc6e0de1e11b1d66

See more details on using hashes here.

File details

Details for the file contoml-0.25-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for contoml-0.25-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 8a15f914b887e26fdb2bc03df6835d183477e0b9822592bed6b3e86af0208260
MD5 ff9d2370cb6588ca4cc6badcd2c37397
BLAKE2b-256 5c90643f48ca85d693ed6cba9c8aa51608c39e1bbad6a7b36b53b15d284df0c4

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