Ben Chuanlong Du's Blog

It is never too late to learn.

Hands on the Python Library tomlkit

Things on this page are fragmentary and immature notes/thoughts of the author. Please read with your own judgement!

Tips & Traps

  1. Please refer to Parse TOML File in Python for general tips on parsing TOML in Python.

Installatoion

In [1]:
!pip3 install tomlkit
Defaulting to user installation because normal site-packages is not writeable
Requirement already satisfied: tomlkit in /usr/local/lib/python3.8/dist-packages (0.10.2)
In [2]:
from pathlib import Path
import tomlkit
In [4]:
?tomlkit.loads
Signature: tomlkit.loads(string: Union[str, bytes]) -> tomlkit.toml_document.TOMLDocument
Docstring:
Parses a string into a TOMLDocument.

Alias for parse().
File:      /usr/local/lib/python3.8/dist-packages/tomlkit/api.py
Type:      function
In [5]:
?tomlkit.dumps
Signature: tomlkit.dumps(data: collections.abc.Mapping, sort_keys: bool = False) -> str
Docstring: Dumps a TOMLDocument into a string.
File:      /usr/local/lib/python3.8/dist-packages/tomlkit/api.py
Type:      function

Parse TOML

In [6]:
toml_string = """
    # This is a TOML document.
    title = "TOML Example"

    [owner.info]
    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]

    [servers.alpha]
    ip = "10.0.0.1"
    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"
    ]
    """
In [7]:
dic = tomlkit.loads(toml_string)
dic
Out[7]:
{'title': 'TOML Example', 'owner': {'info': {'name': 'Tom Preston-Werner', 'dob': DateTime(1979, 5, 27, 7, 32, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=57600), '-08:00'))}}, 'database': {'server': '192.168.1.1', 'ports': [8001, 8001, 8002], 'connection_max': 5000, 'enabled': True}, 'servers': {'alpha': {'ip': '10.0.0.1', 'dc': 'eqdc10'}, 'beta': {'ip': '10.0.0.2', 'dc': 'eqdc10'}}, 'clients': {'data': [['gamma', 'delta'], [1, 2]], 'hosts': ['alpha', 'omega']}}

tomlkit does not have a method to parse a TOML file directly. However, you can read a TOML file as text and then parse it.

In [9]:
dic = tomlkit.loads(Path("pyproject.toml").read_text())
dic
Out[9]:
{'tool': {'poetry': {'name': 'xinstall', 'version': '0.51.1', 'description': 'Easy Cross-platform Installation and Configuration of Apps.', 'authors': ['Benjamin Du <longendu@yahoo.com>'], 'license': 'MIT', 'readme': 'readme.md', 'repository': 'https://github.com/legendu-net/xinstall', 'keywords': ['installation', 'configuration', 'cross-platform'], 'scripts': {'xinstall': 'xinstall:main.main'}, 'dependencies': {'python': '>=3.7.1,<4', 'distro': '>=1.5.0', 'tqdm': '>=4.48.2', 'findspark': '>=1.4.2', 'requests': '>=2.25.0', 'packaging': '>=20.4', 'tomlkit': '>=0.7.0', 'dulwich': '>=0.20.24'}, 'dev-dependencies': {'pytest': '>=3.0', 'pylint': '>=2.4.4', 'pytype': {'version': '>=2020.08.10', 'python': '<3.9'}, 'yapf': '>=0.32.0', 'coverage': '>=5.3', 'deepdiff': '>=5.2.3'}}, 'pylint': {'master': {'ignore': '.venv,.ipynb_checkpoints', 'unsafe-load-any-extension': 'no', 'load-plugins': 'pylint.extensions.docparams', 'extension-pkg-whitelist': 'numpy,cv2,pyspark', 'generated-members': 'sqlite3.*,cv2.*,pyspark.*', 'ignored-modules': 'pyspark.sql.functions'}, 'messages_control': {'disable': 'C0103,C0200,C0301,C0302,C0303,C0330,R0801,R0902,R0903,R0904,R0911,R0912,R0913,R0914,W0621,W0622,W0702,W0703,W1116,W9012,W9016'}, 'typecheck': {'ignored-classes': 'Namespace'}}, 'yapf': {'based_on_style': 'facebook', 'column_limit': '88'}, 'yapfignore': {'ignore_patterns': ['*/.ipynb_checkpoints/']}}, 'build-system': {'requires': ['poetry>=1.0.0'], 'build-backend': 'poetry.masonry.api'}}

Dump an Object to a TOML String

In [10]:
print(tomlkit.dumps(tomlkit.loads(toml_string)))
    # This is a TOML document.
    title = "TOML Example"

    [owner.info]
    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]

    [servers.alpha]
    ip = "10.0.0.1"
    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"
    ]
    

tomlkit does not have a method to dump an object into a TOML file directly. However, you can first dump an object into a string and then write the string into a TOML file.

In [11]:
with Path("/tmp/j.toml").open("w") as fout:
    fout.write(tomlkit.dumps(dic))

More

In [ ]:
from tomlkit import comment
from tomlkit import document
from tomlkit import nl
from tomlkit import table

doc = document()
doc.add(comment("This is a TOML document."))
doc.add(nl())
doc.add("title", "TOML Example")
# Using doc["title"] = "TOML Example" is also possible

owner = table()
owner.add("name", "Tom Preston-Werner")
owner.add("organization", "GitHub")
owner.add("bio", "GitHub Cofounder & CEO\nLikes tater tots and beer.")
owner.add("dob", datetime(1979, 5, 27, 7, 32, tzinfo=utc))
owner["dob"].comment("First class dates? Why not?")

# Adding the table to the document
doc.add("owner", owner)

database = table()
database["server"] = "192.168.1.1"
database["ports"] = [8001, 8001, 8002]
database["connection_max"] = 5000
database["enabled"] = True

doc["database"] = database
In [ ]:
 

Comments