Skip to content

Commit 3bbcdaa

Browse files
committed
Add config-utils CLI tool project
- Create new uvx-compatible CLI tool for capturing configurations - Implement capture-env command to export environment variables to YAML - Implement capture-django-settings command to export Django settings to YAML - Add comprehensive README with installation and usage instructions - Include project structure with pyproject.toml for proper packaging
1 parent b3b959a commit 3bbcdaa

4 files changed

Lines changed: 313 additions & 0 deletions

File tree

config-utils/README.md

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# config-utils
2+
3+
A CLI tool for capturing environment variables and Django settings in YAML format.
4+
5+
## Features
6+
7+
- **capture-env**: Capture all environment variables and export them to YAML
8+
- **capture-django-settings**: Capture Django project settings and export them to YAML
9+
10+
## Installation
11+
12+
### Using uvx (Recommended)
13+
14+
Run the tool directly without installation:
15+
16+
```bash
17+
uvx --from . config-utils capture-env
18+
```
19+
20+
### Using pip
21+
22+
Install from the local directory:
23+
24+
```bash
25+
pip install .
26+
```
27+
28+
Or install in editable mode for development:
29+
30+
```bash
31+
pip install -e .
32+
```
33+
34+
### For Django support
35+
36+
Install with Django optional dependencies:
37+
38+
```bash
39+
pip install ".[django]"
40+
```
41+
42+
## Usage
43+
44+
### Capture Environment Variables
45+
46+
Capture all environment variables to a YAML file:
47+
48+
```bash
49+
config-utils capture-env
50+
```
51+
52+
This will create `env_config.yaml` with all your environment variables.
53+
54+
#### Options
55+
56+
- `-o, --output PATH`: Specify output file path (default: `env_config.yaml`)
57+
- `-f, --format`: Output format, yaml or yml (default: `yaml`)
58+
59+
#### Examples
60+
61+
```bash
62+
# Capture to custom file
63+
config-utils capture-env -o my_env.yaml
64+
65+
# Capture with yml extension
66+
config-utils capture-env -o config.yml -f yml
67+
```
68+
69+
### Capture Django Settings
70+
71+
Capture Django project settings to a YAML file:
72+
73+
```bash
74+
config-utils capture-django-settings
75+
```
76+
77+
This will create `django_settings.yaml` with all Django settings.
78+
79+
#### Options
80+
81+
- `-o, --output PATH`: Specify output file path (default: `django_settings.yaml`)
82+
- `-f, --format`: Output format, yaml or yml (default: `yaml`)
83+
- `-s, --settings`: Django settings module (e.g., `myproject.settings`)
84+
85+
#### Examples
86+
87+
```bash
88+
# Using DJANGO_SETTINGS_MODULE environment variable
89+
export DJANGO_SETTINGS_MODULE=myproject.settings
90+
config-utils capture-django-settings
91+
92+
# Specifying settings module via command line
93+
config-utils capture-django-settings -s myproject.settings
94+
95+
# Custom output file
96+
config-utils capture-django-settings -o my_django_config.yaml -s myproject.settings
97+
```
98+
99+
### Using with uvx
100+
101+
You can run the tool directly without installation:
102+
103+
```bash
104+
# From the project directory
105+
uvx --from . config-utils capture-env
106+
107+
# With options
108+
uvx --from . config-utils capture-env -o custom.yaml
109+
110+
# Django settings
111+
uvx --from . config-utils capture-django-settings -s myproject.settings
112+
```
113+
114+
## Requirements
115+
116+
- Python >= 3.8
117+
- click >= 8.0.0
118+
- pyyaml >= 6.0
119+
- Django >= 3.2 (optional, for capture-django-settings)
120+
121+
## Development
122+
123+
### Setup
124+
125+
```bash
126+
# Clone or navigate to the project directory
127+
cd config-utils
128+
129+
# Install in editable mode with development dependencies
130+
pip install -e .
131+
```
132+
133+
### Project Structure
134+
135+
```
136+
config-utils/
137+
├── config_utils/
138+
│ ├── __init__.py
139+
│ └── cli.py
140+
├── pyproject.toml
141+
└── README.md
142+
```
143+
144+
## License
145+
146+
MIT License
147+
148+
## Contributing
149+
150+
Contributions are welcome! Please feel free to submit a Pull Request.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"""config-utils: CLI tool for capturing environment variables and Django settings."""
2+
3+
__version__ = "0.1.0"

config-utils/config_utils/cli.py

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
"""CLI commands for config-utils."""
2+
3+
import os
4+
import sys
5+
import yaml
6+
from pathlib import Path
7+
import click
8+
9+
10+
@click.group()
11+
@click.version_option()
12+
def main():
13+
"""config-utils: Capture environment variables and Django settings."""
14+
pass
15+
16+
17+
@main.command()
18+
@click.option(
19+
'--output',
20+
'-o',
21+
default='env_config.yaml',
22+
help='Output file path (default: env_config.yaml)',
23+
type=click.Path(),
24+
)
25+
@click.option(
26+
'--format',
27+
'-f',
28+
type=click.Choice(['yaml', 'yml'], case_sensitive=False),
29+
default='yaml',
30+
help='Output format (default: yaml)',
31+
)
32+
def capture_env(output, format):
33+
"""Capture all environment variables and store them in YAML format."""
34+
try:
35+
# Get all environment variables
36+
env_vars = dict(os.environ)
37+
38+
# Ensure output path is Path object
39+
output_path = Path(output)
40+
41+
# Write to YAML file
42+
with open(output_path, 'w') as f:
43+
yaml.dump(env_vars, f, default_flow_style=False, sort_keys=True)
44+
45+
click.echo(f"✓ Captured {len(env_vars)} environment variables to {output_path}")
46+
47+
except Exception as e:
48+
click.echo(f"✗ Error: {str(e)}", err=True)
49+
sys.exit(1)
50+
51+
52+
@main.command()
53+
@click.option(
54+
'--output',
55+
'-o',
56+
default='django_settings.yaml',
57+
help='Output file path (default: django_settings.yaml)',
58+
type=click.Path(),
59+
)
60+
@click.option(
61+
'--format',
62+
'-f',
63+
type=click.Choice(['yaml', 'yml'], case_sensitive=False),
64+
default='yaml',
65+
help='Output format (default: yaml)',
66+
)
67+
@click.option(
68+
'--settings',
69+
'-s',
70+
help='Django settings module (e.g., myproject.settings)',
71+
envvar='DJANGO_SETTINGS_MODULE',
72+
)
73+
def capture_django_settings(output, format, settings):
74+
"""Capture Django settings and store them in YAML format.
75+
76+
Requires Django to be installed and DJANGO_SETTINGS_MODULE to be set,
77+
or pass it via --settings option.
78+
"""
79+
try:
80+
# Set Django settings module if provided
81+
if settings:
82+
os.environ['DJANGO_SETTINGS_MODULE'] = settings
83+
84+
# Check if DJANGO_SETTINGS_MODULE is set
85+
if 'DJANGO_SETTINGS_MODULE' not in os.environ:
86+
click.echo(
87+
"✗ Error: DJANGO_SETTINGS_MODULE not set. "
88+
"Use --settings option or set the environment variable.",
89+
err=True
90+
)
91+
sys.exit(1)
92+
93+
# Import Django
94+
try:
95+
import django
96+
from django.conf import settings as django_settings
97+
except ImportError:
98+
click.echo(
99+
"✗ Error: Django is not installed. "
100+
"Install it with: pip install django",
101+
err=True
102+
)
103+
sys.exit(1)
104+
105+
# Setup Django
106+
django.setup()
107+
108+
# Get all Django settings
109+
settings_dict = {}
110+
for setting in dir(django_settings):
111+
# Skip private/magic attributes
112+
if setting.isupper():
113+
try:
114+
value = getattr(django_settings, setting)
115+
# Convert non-serializable types to strings
116+
if not isinstance(value, (str, int, float, bool, list, dict, type(None))):
117+
value = str(value)
118+
settings_dict[setting] = value
119+
except Exception as e:
120+
settings_dict[setting] = f"<Error retrieving value: {str(e)}>"
121+
122+
# Ensure output path is Path object
123+
output_path = Path(output)
124+
125+
# Write to YAML file
126+
with open(output_path, 'w') as f:
127+
yaml.dump(settings_dict, f, default_flow_style=False, sort_keys=True)
128+
129+
click.echo(f"✓ Captured {len(settings_dict)} Django settings to {output_path}")
130+
131+
except Exception as e:
132+
click.echo(f"✗ Error: {str(e)}", err=True)
133+
sys.exit(1)
134+
135+
136+
if __name__ == '__main__':
137+
main()

config-utils/pyproject.toml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[build-system]
2+
requires = ["hatchling"]
3+
build-backend = "hatchling.build"
4+
5+
[project]
6+
name = "config-utils"
7+
version = "0.1.0"
8+
description = "CLI tool for capturing environment variables and Django settings"
9+
readme = "README.md"
10+
requires-python = ">=3.8"
11+
dependencies = [
12+
"click>=8.0.0",
13+
"pyyaml>=6.0",
14+
]
15+
16+
[project.optional-dependencies]
17+
django = ["django>=3.2"]
18+
19+
[project.scripts]
20+
config-utils = "config_utils.cli:main"
21+
22+
[tool.hatch.build.targets.wheel]
23+
packages = ["config_utils"]

0 commit comments

Comments
 (0)