Secsie is a configuration language made for speed, beauty, and ease of use.

Overview

secsie-conf

pip3 install secsie-conf

Secsie is a configuration language parser for Python, made for speed and beauty. Instead of writing config files in JSON (don't get me wrong, JSON is FAR better than a lot of other things you could use (cough cough XML)), you can save time writing your config files in secsie.
The secsie language format is very similar to ini, except just a little better. You can use secsie-conf to read .ini files into Python dicts. secsie-conf will NOT write .ini files however, at least at this stage.

Advantages over JSON:

  • easier to read
  • faster to write
  • no special syntax required for strings vs ints, floats, bools, etc.

Secsie Language Contructs

These are the rules of the secsie config language:

  1. Comment lines begin with # or ;, but inline comments can only begin with the octothorpe (#).
  2. Whitespace is ignored everywhere except in key names and section tag names.
  3. A config file consists of sections and attributes(keys and values).
  4. A section ends where the next section begins. Attributes declared before sections are valid.
  5. To begin a section use the following syntax:
[section1]
# attribute lines in this section follow
  1. The syntax for an attribute line is:
key = value
  1. Spaces are not allowed in key names or section tags. Only a-z, A-Z, 0-9 and _ are allowed in section tag names, while special characters are allowed in key names.
  2. Values can consist of any character except #. Leading and trailing whitespace is removed.

INI

secsie-conf can be used to read .ini files, as long as the mode ini is specifed to the parser. The rules of interpretation for .ini files vary slightly.

Differences:

  • Section names are allowed to contain spaces and dashes
  • quoted strings are valid, but the quotes are removed (there is no need to quote string in secsie ;)
    secsie-conf can NOT be used to write .ini files. You can read an .ini file and output it in valid secsie, but you cannot expect valid .ini output.

Valid values

Secsie supports strings, ints, floats, null types, and booleans. All of these types can be written out by themselves and will automatically be converted to the appropriate native type.

Strings:

# Spaces are allowed in string value
string_key = whatever value you want

Ints:

numb = 42  # Automatically converted to int when parsed

Floats:

pi = 3.14159265  # Automatically converted to float when parsed

Booleans:

# True and yes are truthy values (case insensitive)
truth = true
truth2 = True
truth3 = yes
# False and no are falsy values (case insensitive)
untruth = falsE
untruth2 = False
untruth3 = no

Null type (None):

# 'null' is used as the NoneType (case insensitive)
nothing = null

Examples

examples/valid.secsie.conf:

; This is an example of a valid secsie file

before_section = totally okay

# Whitespace don't matter

; Here are examples of how types are interpreted(no keywords are off limits!)
[special_values]
    int = 42
    float = 269.887
    truth = yes
    falsehood = no
    true = true
    ; I don't encourage this but it's valid ;)
    false = FaLSe

    # Null value
    nah = Null

[anotherSection]
    # The indent here is optional, included for readability
    sections = are amazing

Parse result:

{'before_section': 'totally okay', 'special_values': {'int': 42, 'float': 269.887, 'truth': True, 'falsehood': False, 'true': True, 'false': False, 'nah': None}, 'anotherSection': {'sections': 'are amazing'}}

Module Usage

Read a secsie config file as a dict:

import json
import secsie

# To get a dict from a config file
config = secsie.parse_config_file('examples/valid.secsie.conf')
print(json.dumps(config, indent=2))  # For prettyness

Result:

{
  "before_section": "totally okay",
  "special_values": {
    "int": 42,
    "float": 269.887,
    "truth": true,
    "falsehood": false,
    "true": true,
    "false": false,
    "nah": null
  },
  "anotherSection": {
    "sections": "are amazing"
  }
}

Read an .ini file:

import json
import secsie

# This might not work...
config = secsie.parse_config_file('examples/php.ini')

Result:

", line 1, in File "/home/nbroyles/PycharmProjects/secsie-conf/secsie/__init__.py", line 109, in parse_config_file conf = _write_to_conf_(conf, line, line_number=lineno, section=c_section, mode=mode) File "/home/nbroyles/PycharmProjects/secsie-conf/secsie/__init__.py", line 63, in _write_to_conf_ raise InvalidSyntax(f'Syntax Error on line {line_number}: "{line}" bad section descriptor or value assignment') secsie.InvalidSyntax: Syntax Error on line 955: "[CLI Server]" bad section descriptor or value assignment">
...Traceback (most recent call last):
  File "
     
      "
     , line 1, in <module>
  File "/home/nbroyles/PycharmProjects/secsie-conf/secsie/__init__.py", line 109, in parse_config_file
    conf = _write_to_conf_(conf, line, line_number=lineno, section=c_section, mode=mode)
  File "/home/nbroyles/PycharmProjects/secsie-conf/secsie/__init__.py", line 63, in _write_to_conf_
    raise InvalidSyntax(f'Syntax Error on line {line_number}: "{line}" bad section descriptor or value assignment')
secsie.InvalidSyntax: Syntax Error on line 955: "[CLI Server]" bad section descriptor or value assignment

We can see that this up and broke. Dub tee eff?! Actually, its okay. Spaces aren't allowed in secsie section names, remember? When reading an .ini file, we need to pass the argument mode='ini' to the parse_config_file function, like this:

config = secsie.parse_config_file('examples/php.ini', mode='ini')
print(json.dumps(config, indent=2))
{
  "PHP": {
    "engine": "On",
    "short_open_tag": "Off",
    "precision": 14,
    "output_buffering": 4096,
    "zlib.output_compression": "Off",
    "implicit_flush": "Off",
    "unserialize_callback_func": "",
    "serialize_precision": -1,
    "disable_functions": "pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,",
    "disable_classes": "",
    "zend.enable_gc": "On",
    "zend.exception_ignore_args": "On",
    "expose_php": "Off",
    "max_execution_time": 30,
    "max_input_time": 60,
    "memory_limit": "128M",
    "error_reporting": "E_ALL & ~E_DEPRECATED & ~E_STRICT",
    "display_errors": "Off",
    "display_startup_errors": "Off",
    "log_errors": "On",
    "log_errors_max_len": 1024,
    "ignore_repeated_errors": "Off",
    "ignore_repeated_source": "Off",
    "report_memleaks": "On",
    "variables_order": "GPCS",
    "request_order": "GP",
    "register_argc_argv": "Off",
    "auto_globals_jit": "On",
    "post_max_size": "8M",
    "auto_prepend_file": "",
    "auto_append_file": "",
    "default_mimetype": "text/html",
    "default_charset": "UTF-8",
    "doc_root": "",
    "user_dir": "",
    "enable_dl": "Off",
    "file_uploads": "On",
    "upload_max_filesize": "2M",
    "max_file_uploads": 20,
    "allow_url_fopen": "On",
    "allow_url_include": "Off",
    "default_socket_timeout": 60
  },
  "CLI Server": {
    "cli_server.color": "On"
  },
  "Pdo_mysql": {
    "pdo_mysql.default_socket": ""
  },
  "mail function": {
    "SMTP": "localhost",
    "smtp_port": 25,
    "mail.add_x_header": "Off"
  },
  "ODBC": {
    "odbc.allow_persistent": "On",
    "odbc.check_persistent": "On",
    "odbc.max_persistent": -1,
    "odbc.max_links": -1,
    "odbc.defaultlrl": 4096,
    "odbc.defaultbinmode": 1
  },
  "MySQLi": {
    "mysqli.max_persistent": -1,
    "mysqli.allow_persistent": "On",
    "mysqli.max_links": -1,
    "mysqli.default_port": 3306,
    "mysqli.default_socket": "",
    "mysqli.default_host": "",
    "mysqli.default_user": "",
    "mysqli.default_pw": "",
    "mysqli.reconnect": "Off"
  },
  "mysqlnd": {
    "mysqlnd.collect_statistics": "On",
    "mysqlnd.collect_memory_statistics": "Off"
  },
  "PostgreSQL": {
    "pgsql.allow_persistent": "On",
    "pgsql.auto_reset_persistent": "Off",
    "pgsql.max_persistent": -1,
    "pgsql.max_links": -1,
    "pgsql.ignore_notice": 0,
    "pgsql.log_notice": 0
  },
  "bcmath": {
    "bcmath.scale": 0
  },
  "Session": {
    "session.save_handler": "files",
    "session.use_strict_mode": 0,
    "session.use_cookies": 1,
    "session.use_only_cookies": 1,
    "session.name": "PHPSESSID",
    "session.auto_start": 0,
    "session.cookie_lifetime": 0,
    "session.cookie_path": "/",
    "session.cookie_domain": "",
    "session.cookie_httponly": "",
    "session.cookie_samesite": "",
    "session.serialize_handler": "php",
    "session.gc_probability": 0,
    "session.gc_divisor": 1000,
    "session.gc_maxlifetime": 1440,
    "session.referer_check": "",
    "session.cache_limiter": false,
    "session.cache_expire": 180,
    "session.use_trans_sid": 0,
    "session.sid_length": 26,
    "session.trans_sid_tags": "a",
    "session.sid_bits_per_character": 5
  },
  "Assertion": {
    "zend.assertions": -1
  },
  "Tidy": {
    "tidy.clean_output": "Off"
  },
  "soap": {
    "soap.wsdl_cache_enabled": 1,
    "soap.wsdl_cache_dir": "/tmp",
    "soap.wsdl_cache_ttl": 86400,
    "soap.wsdl_cache_limit": 5
  },
  "ldap": {
    "ldap.max_links": -1
  }
}

That ^'s a whole PHP configuration file converted to some sexy secsie JSON!

Write a secsie file:

Now that we have the php.ini contents stored in config, let's output it in secsie!

secsie.generate_config_file(config, output_file='examples/php_ini.secsie.conf')

Output (examples/php_ini.secsie.conf):

# php_ini.secsie.conf auto-generated by secsie


[PHP]
	engine = On
	short_open_tag = Off
	precision = 14
	output_buffering = 4096
	zlib.output_compression = Off
	implicit_flush = Off
;	unserialize_callback_func = 
	serialize_precision = -1
	disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
;	disable_classes = 
	zend.enable_gc = On
	zend.exception_ignore_args = On
	expose_php = Off
	max_execution_time = 30
	max_input_time = 60
	memory_limit = 128M
	error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
	display_errors = Off
	display_startup_errors = Off
	log_errors = On
	log_errors_max_len = 1024
	ignore_repeated_errors = Off
	ignore_repeated_source = Off
	report_memleaks = On
	variables_order = GPCS
	request_order = GP
	register_argc_argv = Off
	auto_globals_jit = On
	post_max_size = 8M
;	auto_prepend_file = 
;	auto_append_file = 
	default_mimetype = text/html
	default_charset = UTF-8
;	doc_root = 
;	user_dir = 
	enable_dl = Off
	file_uploads = On
	upload_max_filesize = 2M
	max_file_uploads = 20
	allow_url_fopen = On
	allow_url_include = Off
	default_socket_timeout = 60


[CLIServer]
	cli_server.color = On


[Pdo_mysql]
;	pdo_mysql.default_socket = 


[mailfunction]
	SMTP = localhost
	smtp_port = 25
	mail.add_x_header = Off


[ODBC]
	odbc.allow_persistent = On
	odbc.check_persistent = On
	odbc.max_persistent = -1
	odbc.max_links = -1
	odbc.defaultlrl = 4096
	odbc.defaultbinmode = 1


[MySQLi]
	mysqli.max_persistent = -1
	mysqli.allow_persistent = On
	mysqli.max_links = -1
	mysqli.default_port = 3306
;	mysqli.default_socket = 
;	mysqli.default_host = 
;	mysqli.default_user = 
;	mysqli.default_pw = 
	mysqli.reconnect = Off


[mysqlnd]
	mysqlnd.collect_statistics = On
	mysqlnd.collect_memory_statistics = Off


[PostgreSQL]
	pgsql.allow_persistent = On
	pgsql.auto_reset_persistent = Off
	pgsql.max_persistent = -1
	pgsql.max_links = -1
	pgsql.ignore_notice = 0
	pgsql.log_notice = 0


[bcmath]
	bcmath.scale = 0


[Session]
	session.save_handler = files
	session.use_strict_mode = 0
	session.use_cookies = 1
	session.use_only_cookies = 1
	session.name = PHPSESSID
	session.auto_start = 0
	session.cookie_lifetime = 0
	session.cookie_path = /
;	session.cookie_domain = 
;	session.cookie_httponly = 
;	session.cookie_samesite = 
	session.serialize_handler = php
	session.gc_probability = 0
	session.gc_divisor = 1000
	session.gc_maxlifetime = 1440
;	session.referer_check = 
	session.cache_limiter = False
	session.cache_expire = 180
	session.use_trans_sid = 0
	session.sid_length = 26
	session.trans_sid_tags = a
	session.sid_bits_per_character = 5


[Assertion]
	zend.assertions = -1


[Tidy]
	tidy.clean_output = Off


[soap]
	soap.wsdl_cache_enabled = 1
	soap.wsdl_cache_dir = /tmp
	soap.wsdl_cache_ttl = 86400
	soap.wsdl_cache_limit = 5


[ldap]
	ldap.max_links = -1

Blank values were commented out. If you disagree with that, MAKE 'EM NULL!

You might also like...
filetailor is a peer-based configuration management utility for plain-text files such as dotfiles.
filetailor is a peer-based configuration management utility for plain-text files such as dotfiles.

filetailor filetailor is a peer-based configuration management utility for plain-text files (and directories) such as dotfiles. Files are backed up to

An application pulls configuration information from JSON files generated
An application pulls configuration information from JSON files generated

AP Provisioning Automation An application pulls configuration information from JSON files generated by Ekahau and then uses Netmiko to configure the l

KConfig Browser is a graphical application which allows you to modify KDE configuration files found in ~/.config
KConfig Browser is a graphical application which allows you to modify KDE configuration files found in ~/.config

kconfig_browser KConfig Browser is a graphical application which allows you to modify KDE configuration files found in ~/.config Screenshot Why I crea

A slightly opinionated template for iPython configuration for interactive development
A slightly opinionated template for iPython configuration for interactive development

A slightly opinionated template for iPython configuration for interactive development. Auto-reload and no imports for packages and modules in the project.

Organize Django settings into multiple files and directories. Easily override and modify settings. Use wildcards and optional settings files.
Organize Django settings into multiple files and directories. Easily override and modify settings. Use wildcards and optional settings files.

Organize Django settings into multiple files and directories. Easily override and modify settings. Use wildcards in settings file paths and mark setti

A set of Python scripts and notebooks to help administer and configure Workforce projects.

Workforce Scripts A set of Python scripts and notebooks to help administer and configure Workforce projects. Notebooks Several example Jupyter noteboo

🤫 Easily manage configs and secrets in your Python projects (with CLI support)
🤫 Easily manage configs and secrets in your Python projects (with CLI support)

Installation pip install confidential How does it work? Confidential manages secrets for your project, using AWS Secrets Manager. First, store a secr

Generate config files and qr codes for wireguard vpn

wireguard config generator for python Generate config files and qr codes for wireguard vpn You will need to install qrcode and pillow in python and yo

Napalm-vs-openconfig - Comparison of NAPALM and OpenConfig YANG with NETCONF transport

NAPALM vs NETCONF/OPENCONFIG Abstracts Multi vendor network management and autom

Releases(v3.1.1)
Owner
Noah Broyles
Nobody is "too great" to follow others.
Noah Broyles
Dag-bakery - Dag Bakery enables the capability to define Airflow DAGs via YAML.

DAG Bakery - WIP 🔧 dag-bakery aims to simplify our DAG development by removing all the boilerplate and duplicated code when defining multiple DAG cro

Typeform 2 Jan 08, 2022
Dynamic Django settings.

Constance - Dynamic Django settings A Django app for storing dynamic settings in pluggable backends (Redis and Django model backend built in) with an

Jazzband 1.5k Jan 04, 2023
Python YAML Environment (ymlenv) by Problem Fighter Library

In the name of God, the Most Gracious, the Most Merciful. PF-PY-YMLEnv Documentation Install and update using pip: pip install -U PF-PY-YMLEnv Please

Problem Fighter 2 Jan 20, 2022
Load Django Settings from Environmental Variables with One Magical Line of Code

DjEnv: Django + Environment Load Django Settings Directly from Environmental Variables features modify django configuration without modifying source c

Daniel J. Dufour 28 Oct 01, 2022
Pydantic-ish YAML configuration management.

Pydantic-ish YAML configuration management.

Dribia Data Research 18 Oct 27, 2022
Configuration Extractor for EXE4J PE files

EXE4J Configuration Extractor This script helps reverse engineering Portable Executable files created with EXE4J by extracting their configuration dat

Karsten Hahn 6 Jun 29, 2022
A lightweight Traits like module

Traitlets home https://github.com/ipython/traitlets pypi-repo https://pypi.org/project/traitlets/ docs https://traitlets.readthedocs.io/ license Modif

IPython 532 Dec 27, 2022
Flexible Python configuration system. The last one you will ever need.

OmegaConf Description Project Code quality Docs and support OmegaConf is a hierarchical configuration system, with support for merging configurations

Omry Yadan 1.4k Jan 02, 2023
Inject your config variables into methods, so they are as close to usage as possible

Inject your config variables into methods, so they are as close to usage as possible

GDWR 7 Dec 14, 2022
Python-dotenv reads key-value pairs from a .env file and can set them as environment variables.

python-dotenv Python-dotenv reads key-value pairs from a .env file and can set them as environment variables. It helps in the development of applicati

Saurabh Kumar 5.5k Jan 04, 2023
Tools to assist with the configuration and maintenance of fapolicyd.

Tools to assist with the configuration and maintenance of fapolicyd.

Concurrent Technologies Corporation (CTC) 7 Dec 27, 2022
sqlconfig: manage your config files with sqlite

sqlconfig: manage your config files with sqlite The problem Your app probably has a lot of configuration in git. Storing it as files in a git repo has

Pete Hunt 4 Feb 21, 2022
environs is a Python library for parsing environment variables.

environs: simplified environment variable parsing environs is a Python library for parsing environment variables. It allows you to store configuration

Steven Loria 920 Jan 04, 2023
A helper for organizing Django project settings by relying on well established programming patterns.

django-configurations django-configurations eases Django project configuration by relying on the composability of Python classes. It extends the notio

Jazzband 955 Jan 05, 2023
Config files for my GitHub profile.

Hacked This is a python base script from which you can hack or clone any person's facebook friendlist or followers accounts which have simple password

2 Dec 10, 2021
Generate config files and qr codes for wireguard vpn

wireguard config generator for python Generate config files and qr codes for wireguard vpn You will need to install qrcode and pillow in python and yo

18 Dec 02, 2022
Django-environ allows you to utilize 12factor inspired environment variables to configure your Django application.

Django-environ django-environ allows you to use Twelve-factor methodology to configure your Django application with environment variables. import envi

Daniele Faraglia 2.7k Jan 03, 2023
ConfZ is a configuration management library for Python based on pydantic.

ConfZ – Pydantic Config Management ConfZ is a configuration management library for Python based on pydantic. It easily allows you to load your configu

Zühlke 164 Dec 27, 2022
Organize Django settings into multiple files and directories. Easily override and modify settings. Use wildcards and optional settings files.

Organize Django settings into multiple files and directories. Easily override and modify settings. Use wildcards in settings file paths and mark setti

Nikita Sobolev 942 Jan 05, 2023
A compact library for Python 3.10x that allows users to configure their SimPads real-time

SimpadLib v1.0.6 What is this? This is a python library programmed by Ashe Muller that allows users to interface directly with their SimPad devices, a

Ashe Muller 2 Jan 08, 2022