Configparser Module¶
The configparser module provides facilities for reading and writing configuration files in INI format.
Complexity Reference¶
| Operation | Time | Space | Notes |
|---|---|---|---|
ConfigParser() |
O(1) | O(1) | Create parser |
read(file) |
O(n) | O(n) | n = file size |
read_string(string) |
O(n) | O(n) | Parse string |
write(file) |
O(n) | O(n) | n = config size |
get(section, option) |
O(1) | O(1) | Dict-based lookup; O(n) with interpolation |
getint/getfloat/getboolean |
O(1) | O(1) | O(1) lookup + O(1) conversion |
sections() |
O(n) | O(n) | n = section count |
options(section) |
O(n) | O(n) | n = option count |
Common Operations¶
Reading Configuration Files¶
import configparser
# O(1) - create parser
config = configparser.ConfigParser()
# O(n) where n = file size
files_read = config.read('config.ini')
# O(1) - get value
database_url = config.get('database', 'url')
# O(1) - get with type conversion
debug = config.getboolean('app', 'debug')
port = config.getint('server', 'port')
timeout = config.getfloat('network', 'timeout')
Creating Configuration Programmatically¶
import configparser
# O(1) - create parser
config = configparser.ConfigParser()
# O(1) - add section
config.add_section('database')
# O(1) per option - set values
config.set('database', 'host', 'localhost')
config.set('database', 'port', '5432')
config.set('database', 'name', 'mydb')
# O(1) per option - alternative
config['database'] = {
'host': 'localhost',
'port': '5432'
}
Writing Configuration to File¶
import configparser
config = configparser.ConfigParser()
config['app'] = {'debug': 'true', 'version': '1.0'}
config['db'] = {'host': 'localhost', 'port': '5432'}
# O(n) where n = config size
with open('config.ini', 'w') as f:
config.write(f)
# O(n) - also can get as string
config_str = config.write_string()
Common Use Cases¶
Application Configuration¶
import configparser
import os
def load_config(config_file='config.ini'):
"""Load application configuration - O(n)"""
config = configparser.ConfigParser()
# O(n) to read file
config.read(config_file)
# O(1) per access
return {
'debug': config.getboolean('app', 'debug', fallback=False),
'host': config.get('server', 'host', fallback='localhost'),
'port': config.getint('server', 'port', fallback=8000),
'db_url': config.get('database', 'url'),
}
# Usage - O(n)
config = load_config()
print(f"Debug: {config['debug']}")
Multiple Configuration Files¶
import configparser
def load_configs(*config_files):
"""Load multiple config files - O(n*m)"""
config = configparser.ConfigParser()
# O(n*m) where n = files, m = avg file size
files_read = config.read(config_files)
return config, files_read
# Usage - O(n*m)
config, loaded = load_configs('defaults.ini', 'config.ini', 'local.ini')
print(f"Loaded {len(loaded)} files")
Environment Variable Interpolation¶
import configparser
import os
def create_interpolating_parser(env_vars=None):
"""Create parser with interpolation - O(1)"""
# O(1) - create with interpolation
config = configparser.ConfigParser(
interpolation=configparser.ExtendedInterpolation()
)
# Set defaults - O(k) where k = defaults
if env_vars:
config.read_dict({
'DEFAULT': env_vars
})
return config
# Usage - O(1)
config = create_interpolating_parser({'home': '/home/user'})
config.read_string("""
[paths]
config_dir = ${home}/.config
""")
Configuration Validation¶
import configparser
def validate_config(config_file, required_sections, required_options):
"""Validate configuration - O(n+m)"""
config = configparser.ConfigParser()
# O(n) to read
config.read(config_file)
errors = []
# O(m) to check sections where m = required section count
for section in required_sections:
if not config.has_section(section):
errors.append(f"Missing section: {section}")
else:
# O(k) to check options where k = required option count
for option in required_options.get(section, []):
if not config.has_option(section, option):
errors.append(f"Missing option: {section}.{option}")
return len(errors) == 0, errors
# Usage - O(n+m)
valid, errors = validate_config(
'config.ini',
['database', 'server'],
{'database': ['host', 'port'], 'server': ['host', 'port']}
)
Default Values and Fallbacks¶
import configparser
def get_config_with_defaults(config_file):
"""Get config with sensible defaults - O(n)"""
config = configparser.ConfigParser(
defaults={
'host': 'localhost',
'port': '8000',
'debug': 'false',
'timeout': '30'
}
)
# O(n) to read - overrides defaults
config.read(config_file)
return config
# Usage - O(n)
config = get_config_with_defaults('config.ini')
# O(1) - returns default if not in file
host = config.get('server', 'host')
debug = config.getboolean('app', 'debug')
Dynamic Configuration Sections¶
import configparser
def get_section_dict(config_file, section):
"""Get entire section as dict - O(n)"""
config = configparser.ConfigParser()
# O(n) to read
config.read(config_file)
# O(k) where k = options in section
if config.has_section(section):
return dict(config.items(section))
return {}
# Usage - O(n)
db_config = get_section_dict('config.ini', 'database')
# {'host': 'localhost', 'port': '5432', 'name': 'mydb'}
Performance Tips¶
Cache Config Parser¶
import configparser
class ConfigCache:
"""Cache parsed configuration - O(1) access"""
def __init__(self, config_file):
self.config_file = config_file
self._config = None
def get_config(self):
"""O(1) cached access"""
if self._config is None:
# O(n) first load
self._config = configparser.ConfigParser()
self._config.read(self.config_file)
return self._config
def reload(self):
"""O(n) forced reload"""
self._config = None
return self.get_config()
# Usage - O(1) after first call
cache = ConfigCache('config.ini')
config = cache.get_config() # O(n) first time
config = cache.get_config() # O(1) cached
Use get() with fallback¶
import configparser
# Bad: Multiple lookups and checks - O(k) per check
config = configparser.ConfigParser()
config.read('config.ini')
if config.has_section('app') and config.has_option('app', 'debug'):
debug = config.getboolean('app', 'debug')
else:
debug = False
# Good: Single fallback lookup - O(1)
debug = config.getboolean('app', 'debug', fallback=False)
Lazy Load Sections¶
import configparser
class LazyConfigParser:
"""Load sections on demand - O(1) initial"""
def __init__(self, config_file):
self.config_file = config_file
self._loaded_sections = set()
self._config = configparser.ConfigParser()
def get(self, section, option, fallback=None):
"""O(n) first section load, O(1) thereafter"""
if section not in self._loaded_sections:
# O(n) to load section
self._config.read(self.config_file)
self._loaded_sections.add(section)
return self._config.get(section, option, fallback=fallback)
Version Notes¶
- Python 2.6+: configparser available
- Python 3.x: ConfigParser renamed to configparser
- Python 3.2+: Extended interpolation available
- Python 3.6+: Dict-like access support
Related Documentation¶
- Pathlib Module - Path handling for config files
- Sys Module - sys.argv for config file paths
- JSON Module - Alternative serialization format