Usage
The Erbsland Configuration Language Parser is designed to be simple to use out of the box. It comes with sensible defaults and a flexible interface that makes working with configuration values both straightforward and powerful.
Here is a minimal example of loading a document and accessing a typed value:
import erbsland.conf as elcl
# Load a configuration file
doc = elcl.load("configuration.elcl")
# Access a typed value with a fallback default
port = doc.get_int("server.port", default=1234)
The goal of the library is to make parsing and accessing configuration values as easy as possible—with minimal boilerplate code and maximum clarity.
Let’s get started!
No Time to Read?
If you’d like to dive right in, here’s a complete quick-start example. It demonstrates:
Loading a configuration file
Accessing required and optional values
Iterating over sections and lists
Using type-safe getters (
get_int
,get_text
,get_list
)Handling errors gracefully
import erbsland.conf as elcl
def parse_configuration(file_name: str):
doc = elcl.load(file_name)
# Access required values and check the type.
server_name = doc.get_text("main.server.name")
# Provide a default if the value is optional.
port = doc.get_int("main.server.port", default=8080)
# Iterating over section lists naturally.
for client_value in doc["client"]:
name = client_value.get_text("name")
ip = client_value.get_text("ip")
port = client_value.get_int("port", default=9000)
# Reading values from optional sections.
if filter_value := client_value.get("filter", default=None):
# Requiring lists of specific types.
keywords = filter_value.get_list("keywords", str)
# ...
# ...
# ...
def main():
try:
parse_configuration("quick-intro.elcl")
# ... running the application ...
exit(0)
except elcl.Error as e:
print("Error reading the configuration.")
print(e.to_text(elcl.ErrorOutput.FILENAME_ONLY | elcl.ErrorOutput.USE_LINES))
exit(1)
if __name__ == "__main__":
main()
This example expects a configuration file like the one below:
--[ Main ]-------------------------------------------------------------------
Listener : Enabled
Polling Interval : 1000 ms
--[ Main . Server ]----------------------------------------------------------
Name : "host01.example.com"
Port : 8080
-*[ Client ]*----------------------------------------------------------------
Name : "client01"
IP : "192.168.1.10"
-*[ Client ]*----------------------------------------------------------------
Name : "client02"
IP : "192.168.1.11"
Port : 9100
----[ .Filter ]--------------------------------------------------------------
Keywords :
* "tree"
* "leaf"
* "branch"
* "flower"
-*[ Client ]*----------------------------------------------------------------
Name : "client03"
IP : "192.168.1.12"
Port : 9170
You can visualize the configuration above as the following tree:
<Document> => Document()
├───main => SectionWithNames()
│ ├───listener => Boolean(true)
│ ├───polling_interval => TimeDelta(1000,millisecond)
│ └───server => SectionWithNames()
│ ├───name => Text("host01.example.com")
│ └───port => Integer(8080)
└───client => SectionList()
├───[0] => SectionWithNames()
│ ├───name => Text("client01")
│ └───ip => Text("192.168.1.10")
├───[1] => SectionWithNames()
│ ├───name => Text("client02")
│ ├───ip => Text("192.168.1.11")
│ ├───port => Integer(9100)
│ └───filter => SectionWithNames()
│ └───keywords => ValueList()
│ ├───[0] => Text("tree")
│ ├───[1] => Text("leaf")
│ ├───[2] => Text("branch")
│ └───[3] => Text("flower")
└───[2] => SectionWithNames()
├───name => Text("client03")
├───ip => Text("192.168.1.12")
└───port => Integer(9170)
Need More Help?