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

Uploaded Source

Built Distribution

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

Uploaded Python 2 Python 3

File details

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

File metadata

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

File hashes

Hashes for contoml-0.26.tar.gz
Algorithm Hash digest
SHA256 a883955bc7e16337102c0c4e9f5acfed57e43c58c01b2605f4f40347e89d3f0e
MD5 f3c409a2ce7947111dbf6c8e7856721f
BLAKE2b-256 aa0da395559b9be635d2675bb26675707e911fda264127b6b1a01c630748f219

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for contoml-0.26-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 510f7fe23629fe67352611fadb0982d35f6e1011712e34655094fa7e5b1b6ade
MD5 42225a9b20a402b418a915fa34fcdad2
BLAKE2b-256 5c54d180ca13dfcf08d7b265766c15652c31db0bff0af96404c0c175eb682cb0

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