Python

How to Read and Write TOML Files Using Python

TOML, short for β€œTom’s Obvious Minimal Language,” is a relatively new and popular file format that focuses on minimal semantics for writing configuration files. The file format has been created by Tom Preston-Werner, the former CEO of GitHub. As of the time this article was written, the first release candidate of version 1.0.0 has been tagged, so the specification is more or less finalized. This article will give a brief introduction to the TOML file format and describe how this file format can be used in Python applications and scripts.

TOML Configuration File Example

The specification for TOML includes use of case-sensitive key-value pairs. Keys are on the left-hand side, while values will on the right-hand side; these terms are separated on either side by an equals sign. The key-value pairs are identical to the variable declaration syntax you will see in most programming languages. You can also define tables and subtables (sections and subsections) in square brackets to keep key-value pairs organized for improved parsing logic and application in your programs. Values can be of string, integer, float, boolean, array, and time and date types. TOML allows use of dot syntax so that you can define a table (section) as β€œtable.subtable” or a key as β€œkey.identifier,” as well. The file extension used for a TOML file is .toml. Below is an abbreviated example of a TOML file:

name = "PC Game"

[default]
profile_name = "Profile"
player_name = "Player"
profile_created = 1979-05-27T07:32:00-08:00
sound = true

[user]

  [user.profile]
  name = "profile1"
  player_name = "player1"
  class = "warrior"

  [user.settings]
  sound = false

[default_inventory]
warrior = [ ["sword", "shield"], ["plate armor", "plate helm"] ]
mage = [["staff", "wand"], ["robe", "hood"]]
items = [
  "health potion",
  "antidote",
  "mana potion"
]

For reference, the same configuration file is written in JSON below:

{
  "name": "PC Game",
  "default": {
    "profile_name": "Profile",
    "player_name": "Player",
    "profile_created": "1979-05-27T15:32:00.000Z",
    "sound": true
  },
  "user": {
    "profile": {
      "name": "profile1",
      "player_name": "player1",
      "class": "warrior"
    },
    "settings": {
      "sound": false
    }
  },
  "default_inventory": {
    "warrior": [
      [
        "sword",
        "shield"
      ],
      [
        "plate armor",
        "plate helm"
      ]
    ],
    "mage": [
      [
        "staff",
        "wand"
      ],
      [
        "robe",
        "hood"
      ]
    ],
    "items": [
      "health potion",
      "antidote",
      "mana potion"
    ]
  }
}

Differences between JSON and INI File Formats

TOML is similar to JSON and INI formats in many ways, with a few differences that can determine which file format you will want to use. The TOML file format emphasizes human readability and appears much cleaner to read. INI files do not support nested sections and nested key-value pairs. Unlike JSON, TOML allows comments (with the # symbol). Long nested data in a JSON file can be written in TOML in just a few lines.

However, it can be confusing to properly identify structure in long nested hierarchies in TOML, while in JSON the structure is much clearer, even though the nested data may appear verbose. TOML is primarily designed for configuration files and not for large structured data sets, while JSON is suitable for any scale of structured data.

The Python TOML Module

Python standard libraries do not currently have any support for parsing TOML data, at the time of writing this article. This may change after TOML version 1.0.0 is released. For the time being, you will have to use a third party Python module called toml. You can install this module in Ubuntu using one of the commands below:

$ sudo apt install python3-toml
$ pip3 install toml

Parsing a TOML File Using Python TOML Module

Parsing a TOML file using the python3-toml module is fairly straightforward. You can either use the β€œtoml.load” method to parse the entire file, or you can use the β€œtoml.loads” method to parse any specific TOML formatted key-value pair. Assuming a β€œdata.toml” file contains the TOML formatted strings mentioned in the example above, the code below will parse and print TOML data as a python dictionary:

#!/usr/bin/env python3
import toml
print (toml.load("data.toml"))

Running the code above will produce the following output:

{'name': 'PC Game', 'default': {'profile_name': 'Profile', 'player_name': 'Player',
'profile_created': datetime.datetime(1979, 5, 27, 7, 32, tzinfo=<toml.tz.TomlTz
object at 0x7f3506b3d850>), 'sound': True}, 'user': {'profile': {'name': 'profile1',
'player_name': 'player1', 'class': 'warrior'}, 'settings': {'sound': False}},
'default_inventory': {'warrior': [['sword', 'shield'], ['plate armor', 'plate helm']],
'mage': [['staff', 'wand'], ['robe', 'hood']], 'items': ['health potion', 'antidote',
'mana potion']}}

Now that you have a python dictionary object, you may implement any logic in your program to handle the dictionary data.

Dumping a Python Dictionary as TOML Formatted Data

A python dictionary can be dumped into TOML formatted strings using the β€œtoml.dumps” method, or the object can be dumped into a file using β€œtoml.dump” method. The example below will convert a dictionary object nito TOML formatted strings:

#!/usr/bin/env python3
import toml
data = toml.load("data.toml")
print (toml.dumps(data))

Running the above code will produce the following output:

name = "PC Game"
[default]
profile_name = "Profile"
player_name = "Player"
profile_created = 1979-05-27T07:32:00-08:00
sound = true

[default_inventory]
warrior = [ [ "sword", "shield",], [ "plate armor", "plate helm",],]
mage = [ [ "staff", "wand",], [ "robe", "hood",],]
items = [ "health potion", "antidote", "mana potion",]

[user.profile]
name = "profile1"
player_name = "player1"
class = "warrior"
[user.settings]
sound = false

To convert a dictionary object into a TOML formatted string and store it in a file, you can use the β€œtoml.dump(dictionary_object, output_file)” method.

Conclusion

A TOML file in simpler terms is just an INI configuration file with better structure and syntax, facilitating easier parsing and better readability. The TOML file format is often compared with the JSON file format, but apart from its use in configuration files, TOML does not have much utility. JSON, on the other hand, is much more versatile and can be used in different use cases requiring any data structure type.

About the author

Nitesh Kumar

I am a freelancer software developer and content writer who loves Linux, open source software and the free software community.