https://github.com/megalus/stela
Organize your project settings and secrets with ease
https://github.com/megalus/stela
configuration dotenv python secrets settings
Last synced: about 2 months ago
JSON representation
Organize your project settings and secrets with ease
- Host: GitHub
- URL: https://github.com/megalus/stela
- Owner: megalus
- License: mit
- Created: 2020-03-22T15:43:59.000Z (about 6 years ago)
- Default Branch: main
- Last Pushed: 2026-04-25T14:10:07.000Z (about 2 months ago)
- Last Synced: 2026-04-25T16:14:26.447Z (about 2 months ago)
- Topics: configuration, dotenv, python, secrets, settings
- Language: Python
- Homepage: https://megalus.github.io/stela/
- Size: 2.35 MB
- Stars: 6
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
Easily manage your application settings and secrets
## Welcome to Stela
[Stela](https://en.wikipedia.org/wiki/Stele) were the "information
files" of ancient times. This library helps you manage your project
settings and secrets with ease, using a simple and consistent approach.
### What is Stela?
Stela is a Python library that simplifies how you handle:
- **Settings**: Non-sensitive values that can be committed to your repository (API URLs, timeouts, etc.)
- **Secrets**: Sensitive values that should not be committed (passwords, tokens, etc.)
- **Environment-specific configurations**: Different values for development, testing, and production
### TL;DR
1. In a new project run `pip install stela`
2. On terminal, run `stela init --default --no-confirm`
3. Uncomment the `MY_SECRET` line in `.env`
4. Add `from stela import env` and run `print(env.MY_SECRET)` in your code
5. Uncomment the `MY_SECRET` line in `.env.local` and get the code again.
6. Add `export MY_SECRET=memory_value` in your terminal and get the code again.
New to multi-environment setups? Start with the Quick Setup guide: https://megalus.github.io/stela/quick_setup/
### Install
```shell
pip install stela
```
### Development
```bash
# Define your VIRTUAL_ENV location. For example: export VIRTUAL_ENV=$(pwd)
uv sync --active --group dev
make ci
```
### Documentation
For detailed documentation, visit: https://megalus.github.io/stela/
### Key Features
1. **Learn once, use everywhere** - Works with any Python project or framework
2. **Separate settings from secrets** - Use multiple dotenv files to organize your configuration
3. **Environment-specific settings** - Easily switch between development, testing, and production environments
4. **Simple API** - Access your settings with `from stela import env`
5. **Extensible** - Not limited to dotenv files, can load settings from any source (AWS Parameter Store, Vault, etc.)
## Quick Start Guide
### Step 1: Initialize Your Project
Run the Stela initialization command to set up your project:
```bash
stela init --default
```
This creates four files:
- `.env` - Store your default settings (will be committed to git)
- `.env.local` - Store your secrets (will be ignored by git)
- `.stela` - Stela configuration file
- Updates `.gitignore` to exclude sensitive files
### Step 2: Configure Your Settings and Secrets
Add your settings to `.env`:
```ini
# .env - This file WILL be committed to your repository
# Store default settings and fake credentials here
API_URL="http://localhost:8000"
DB_URL="db://fake_user:fake_password@local_db:0000/name"
```
Add your real secrets to `.env.local`:
```ini
# .env.local - This file will NOT be committed (ignored by git)
# Store real credentials and secrets here
DB_URL="db://real_user:real_password@real_db:0000/name"
```
### Step 3: Access Your Settings in Code
Use the simple API to access your settings and secrets:
```python
# my_script.py
from stela import env
# Access your settings with dot notation
API_URL = env.API_URL # http://localhost:8000
DATABASE_URL = env.DB_URL # db://real_user:real_password@real_db:0000/name
```
Stela automatically loads values from `.env` first, then overrides them with values from `.env.local`.
### Precedence at a glance
When the same key is defined in multiple places, Stela resolves it using this order (top wins):
1. Value already present in the process environment (os.environ). Stela will not overwrite existing env vars.
2. .env.{environment}.local
3. .env.{environment}
4. .env.local
5. .env
If a key is missing everywhere, Stela raises a StelaValueError by default (configurable).
## Environment-Specific Configuration
Stela makes it easy to manage different environments (development, testing, production):
### Step 1: Create Environment-Specific Files
Create a file for each environment:
```ini
# .env.development
API_URL="http://localhost:8000"
# .env.production
API_URL="https://api.example.com"
```
### Step 2: Set the Environment
Set the `STELA_ENV` environment variable to specify which environment to use:
```bash
# For development
export STELA_ENV=development
# For production
export STELA_ENV=production
```
### Step 3: Access Your Settings
Your code remains the same, but Stela will load the appropriate values:
```python
from stela import env
# Will be "http://localhost:8000" when STELA_ENV=development
# Will be "https://api.example.com" when STELA_ENV=production
API_URL = env.API_URL
```
## Advanced: Custom Data Sources
Stela isn't limited to dotenv files. You can load settings from any source:
### Step 1: Configure a Final Loader
Add a final loader in your `.stela` configuration file:
```ini
# .stela
[stela]
final_loader = "path.to.my.final_loader"
```
### Step 2: Create Your Loader Function
```python
# my_loaders.py
from typing import Any
from stela.config import StelaOptions
def final_loader(options: StelaOptions, env_data: dict[str, Any]) -> dict[str, Any]:
"""Load settings from a custom source and merge into env_data.
Args:
options: Stela configuration options (includes current_environment).
env_data: Data already loaded from dotenv files.
Returns:
Updated data dictionary.
"""
# Example: pretend we fetched data from an external source
external = {"API_TIMEOUT": "5", "FEATURE_FLAG": "true"}
# Merge/override values
env_data.update(external)
return env_data
```
### Step 3: Use Your Settings as Usual
```python
from stela import env
# Values can come from dotenv files or your custom source
API_URL = env.API_URL
DB_PASSWORD = env.DB_PASSWORD
API_TIMEOUT = env.API_TIMEOUT # From custom loader
```
## Need Help?
- **Documentation**: For detailed guides and examples, visit [the documentation](https://megalus.github.io/stela/)
- **Issues**: Found a bug? Have a question? [Open an issue](https://github.com/megalus/stela/issues)
- **Contribute**: Pull requests are welcome!