How to Use Configparser to Parse INI Configuration Files in Python
# Python Configuration File Management with `configparser`
Configuration files offer a **structured** and **readable** way to manage application settings, often more maintainable than relying solely on environment variables.
**INI files**—short for *initialization files*—use a **section-based format** that is easy to read and parse.
Python’s built-in [`configparser` module](https://docs.python.org/3/library/configparser.html) makes working with INI files **straightforward** and **powerful**.
This guide walks you through reading, parsing, and creating `.ini` files with `configparser`.
🔗 [**View the code on GitHub**](https://github.com/balapriyac/python-basics/tree/main/config-management-basics/parsing-ini-files)
---
## Prerequisites
To follow along, ensure you have:
- **Python 3.7+** installed
- Basic knowledge of **Python syntax** and **data structures** (dicts, strings)
- Familiarity with **file I/O** in Python
- A **text editor or IDE**
- Understanding of **configuration files** in applications
> No external packages are required — `configparser` is part of Python’s standard library.
---
## Table of Contents
- [Understanding the INI File Format](#understanding-the-ini-file-format)
- [Basic `ConfigParser` Usage](#basic-configparser-usage)
- [Type Conversion and Default Values](#type-conversion-and-default-values)
- [Creating a Simple Config Manager](#creating-a-simple-config-manager)
- [Working with Multiple Sections](#working-with-multiple-sections)
- [Writing Configuration Files](#writing-configuration-files)
- [Conclusion](#conclusion)
---
## Understanding the INI File Format
INI files group configuration settings into **sections**, each with **key-value pairs**.
This is ideal for applications with multiple components or environments.
### Example: `app.ini`
[database]
host = localhost
port = 5432
username = app_user
password = secure_password
pool_size = 10
ssl_enabled = true
[server]
host = 0.0.0.0
port = 8000
debug = false
[logging]
level = INFO
file = app.log
**Sections:**
- `database`
- `server`
- `logging`
---
## Basic `ConfigParser` Usage
`ConfigParser` can **read**, **parse**, and **access** values in INI files.
import configparser
config = configparser.ConfigParser()
config.read('app.ini')
Access values from sections
db_host = config['database']['host']
db_port = config['database']['port']
print(f"Database: {db_host}:{db_port}")
print(f"Sections: {config.sections()}")
### Steps:
1. **Create** a `ConfigParser` object
2. **Read** the INI file
3. **Access** values using dictionary-like syntax
### Output:Database: localhost:5432
Sections: ['database', 'server', 'logging']
---
## Type Conversion and Default Values
Values in INI files are **strings**, but `ConfigParser` supports automatic type conversion:
import configparser
config = configparser.ConfigParser()
config.read('app.ini')
Automatic type conversion
db_port = config.getint('database', 'port')
ssl_enabled = config.getboolean('database', 'ssl_enabled')
With fallback defaults
max_retries = config.getint('database', 'max_retries', fallback=3)
timeout = config.getfloat('database', 'timeout', fallback=30.0)
print(f"Port: {db_port}, SSL: {ssl_enabled}")
**Benefits:**
- Use `.getint()`, `.getboolean()`, `.getfloat()` for type safety
- `fallback` avoids `KeyError` exceptions
---
## Creating a Simple Config Manager
Encapsulating `ConfigParser` in a **class** can improve validation and usability:
import configparser
from pathlib import Path
class ConfigManager:
def __init__(self, config_file='app.ini'):
if not Path(config_file).exists():
raise FileNotFoundError(f"Config file not found: {config_file}")
self.config = configparser.ConfigParser()
self.config.read(config_file)
def get_database_config(self):
db = self.config['database']
return {
'host': db.get('host'),
'port': db.getint('port'),
'username': db.get('username'),
'password': db.get('password'),
'pool_size': db.getint('pool_size', fallback=5)
}
**Usage:**config = ConfigManager('app.ini')
db_config = config.get_database_config()
print(db_config)
**Example Output:**{'host': 'localhost', 'port': 5432, 'username': 'app_user', 'password': 'secure_password', 'pool_size': 10}
---
## Working with Multiple Sections
Access settings for multiple sections:
import configparser
config = configparser.ConfigParser()
config.read('app.ini')
Dictionary conversion
db_settings = dict(config['database'])
server_settings = dict(config['server'])
Optional section handling
if config.has_section('cache'):
cache_enabled = config.getboolean('cache', 'enabled')
else:
cache_enabled = False
print(f"Database settings: {db_settings}")
print(f"Caching enabled: {cache_enabled}")
**Output:**Database settings: {'host': 'localhost', 'port': '5432', 'username': 'app_user', 'password': 'secure_password', 'pool_size': '10', 'ssl_enabled': 'true'}
Caching enabled: False
---
## Writing Configuration Files
You can also **generate** and **save** INI files:
import configparser
config = configparser.ConfigParser()
Add sections and values
config['database'] = {
'host': 'localhost',
'port': '5432',
'username': 'myapp'
}
config['server'] = {
'host': '0.0.0.0',
'port': '8000',
'debug': 'false'
}
Write to file
with open('generated.ini', 'w') as configfile:
config.write(configfile)
print("Configuration file created!")
---
## Conclusion
**INI files** are:
- **Human-readable**
- Supported by Python’s `configparser`
- Great for grouping settings by component
**Best Practices:**
- Group related settings into **sections**
- Use **type conversion methods** (`getint`, `getboolean`, `getfloat`)
- Set **fallback defaults** for optional keys
- Validate configuration **early** at startup
- Avoid storing sensitive data directly — use templates like `.ini.example`
---
**Next:** Learn how to work with **TOML** files in Python.
Until then — happy coding!