Automatically scan Python projects for environment variables and generate .env-example files
Project description
Env Scanner
🔍 Automatically scan Python projects for environment variables and generate .env-example files.
Features
- 🔎 Automatic Detection: Scans your Python codebase to find all environment variable usage
- 🌐 Framework Support: Works with Django, Flask, FastAPI, Pydantic, and vanilla Python
- 📝 Smart Generation: Creates
.env-examplefiles with intelligent placeholders and comments - 🎯 Multiple Detection Methods: Uses both AST parsing and regex for comprehensive coverage
- 📄 Config File Scanning: Also scans YAML, JSON, TOML, and INI files for env vars
- 🗂️ Smart Grouping: Organizes variables by common prefixes for better readability
- 💡 Contextual Comments: Adds helpful comments based on variable names and usage locations
- ⚡ CLI Interface: Easy-to-use command-line tool
- 🐍 Pure Python: No external dependencies required
Installation
From PyPI (when published)
pip install env-scanner
From Source
git clone https://github.com/ammarmunir4567/env-scanner.git
cd env-scanner
pip install -e .
Quick Start
Command Line
The simplest way to use env-scanner:
# Scan current directory and generate .env-example
env-scanner
# Scan a specific project
env-scanner scan /path/to/your/project
# Just list variables without generating file
env-scanner list
# Preview before saving
env-scanner scan --preview
Python API
from env_scanner import EnvScanner, EnvExampleGenerator
# Create scanner
scanner = EnvScanner(project_path='/path/to/your/project')
# Scan for environment variables
env_vars = scanner.scan_directory()
# Print summary
scanner.print_summary()
# Generate .env-example file
generator = EnvExampleGenerator.from_scanner(scanner)
generator.save()
Supported Frameworks & Patterns
Env Scanner works with all major Python frameworks and patterns. Here's what it detects:
🐍 Standard Python
import os
from os import environ, getenv
# All these patterns are detected
DATABASE_URL = os.environ.get('DATABASE_URL')
API_KEY = os.environ['API_KEY']
SECRET_KEY = os.getenv('SECRET_KEY')
PORT = environ.get('PORT', '8000')
DEBUG = getenv('DEBUG', 'False')
🎯 Django
# django-environ
import environ
env = environ.Env()
DATABASE_URL = env('DATABASE_URL')
DEBUG = env.bool('DEBUG', default=False)
ALLOWED_HOSTS = env.list('ALLOWED_HOSTS')
SECRET_KEY = env.str('SECRET_KEY')
# python-decouple
from decouple import config
SECRET_KEY = config('SECRET_KEY')
DEBUG = config('DEBUG', default=False, cast=bool)
🌶️ Flask
from flask import Flask
app = Flask(__name__)
# Flask config patterns
app.config['DATABASE_URL'] = os.environ.get('DATABASE_URL')
app.config['SECRET_KEY'] = os.getenv('SECRET_KEY')
# Or from current_app
from flask import current_app
db_url = current_app.config['DATABASE_URL']
⚡ FastAPI / Pydantic
from pydantic import BaseSettings, Field
from pydantic_settings import BaseSettings # Pydantic v2
class Settings(BaseSettings):
# Auto-detected from field names
database_url: str
api_key: str
# With explicit env names
secret: str = Field(env='SECRET_KEY')
port: int = Field(default=8000, env='PORT')
class Config:
env_file = '.env'
# Usage
settings = Settings()
📦 python-dotenv
from dotenv import load_dotenv, dotenv_values
# Load variables
load_dotenv()
# Or get specific values
config = dotenv_values(".env")
DATABASE_URL = config.get('DATABASE_URL')
📄 Configuration Files
Env Scanner also scans configuration files for environment variable references:
YAML files:
database:
url: ${DATABASE_URL}
password: ${DB_PASSWORD}
# Or Symfony-style
database:
url: '%env(DATABASE_URL)%'
JSON files:
{
"database": "${DATABASE_URL}",
"api_key": "${API_KEY}"
}
TOML files:
database_url = "${DATABASE_URL}"
api_key = "${API_KEY}"
🔍 Advanced Patterns
# F-strings
message = f"Connecting to {os.environ['DATABASE_URL']}"
# String interpolation
config = f"postgresql://{os.getenv('DB_USER')}:{os.getenv('DB_PASSWORD')}"
# Direct from environ
from os import environ
API_KEY = environ['API_KEY']
CLI Usage
Scan Command
Scan a project and generate .env-example file:
# Basic usage
env-scanner scan
# Specify project path
env-scanner scan /path/to/project
# Custom output location
env-scanner scan --output .env.template
# Exclude specific directories
env-scanner scan --exclude venv,build,dist,node_modules
# Preview before saving
env-scanner scan --preview
# Disable comments
env-scanner scan --no-comments
# Disable grouping by prefix
env-scanner scan --no-grouping
List Command
List all environment variables found without generating a file:
# Basic list
env-scanner list
# Show file locations
env-scanner list --show-locations
# Specific project
env-scanner list /path/to/project
CLI Options
Options:
-h, --help Show help message
-v, --version Show version
--verbose Enable verbose output
Scan/Generate Options:
-o, --output PATH Output path for .env-example file
-e, --exclude DIRS Comma-separated directories to exclude
--no-generate Only scan, don't generate file
--no-comments Don't add descriptive comments
--no-grouping Don't group variables by prefix
--no-header Don't add file header
--preview Preview before saving
--regex-only Use only regex (skip AST parsing)
List Options:
-l, --show-locations Show where variables are used
Python API
EnvScanner
The EnvScanner class scans Python files to detect environment variables:
from env_scanner import EnvScanner
# Initialize scanner
scanner = EnvScanner(
project_path='/path/to/project',
exclude_dirs=['venv', 'build', 'dist'], # Optional
)
# Scan the project
env_vars = scanner.scan_directory()
# Get detailed results
results = scanner.get_results()
print(results['variables']) # List of variable names
print(results['count']) # Number of variables
print(results['locations']) # Dict of variable locations
# Print summary
scanner.print_summary()
EnvExampleGenerator
The EnvExampleGenerator class creates .env-example files:
from env_scanner import EnvExampleGenerator
# From a set of variable names
generator = EnvExampleGenerator(
env_vars={'DATABASE_URL', 'API_KEY', 'SECRET_KEY'},
output_path='.env-example',
add_comments=True,
group_by_prefix=True,
include_header=True
)
# Generate and save
generator.save()
# Or preview first
generator.preview()
# Create from scanner
from env_scanner import EnvScanner
scanner = EnvScanner('.')
scanner.scan_directory()
generator = EnvExampleGenerator.from_scanner(
scanner,
output_path='.env-example'
)
generator.save()
Example Output
For a project using these environment variables:
DATABASE_URL = os.environ.get('DATABASE_URL')
DATABASE_NAME = os.getenv('DATABASE_NAME')
API_KEY = os.environ['API_KEY']
API_SECRET = os.environ.get('API_SECRET')
DEBUG = os.getenv('DEBUG', 'False')
PORT = os.environ.get('PORT', '8000')
Env Scanner generates this .env-example file:
# Environment Variables Configuration
# This file was automatically generated by env-scanner
# Generated on: 2025-10-01 12:00:00
#
# Copy this file to .env and fill in the actual values
# DO NOT commit .env file to version control
# API Configuration
#==================================================
# API key for external service
API_KEY=your_secret_key_here
# API secret for external service
API_SECRET=your_secret_key_here
# DATABASE Configuration
#==================================================
# Database configuration
DATABASE_NAME=your_database_name
# Database configuration
DATABASE_URL=https://example.com
# Other Configuration
#==================================================
# Debug mode (true/false)
DEBUG=false
# Port number
PORT=8000
Configuration
Excluding Directories
By default, these directories are excluded from scanning:
venv,env,.venv,.envnode_modules__pycache__,.gitdist,build,*.egg-info.tox,.pytest_cache,.mypy_cache
Add custom exclusions:
scanner = EnvScanner(
project_path='.',
exclude_dirs=['custom_dir', 'another_dir']
)
Or via CLI:
env-scanner scan --exclude venv,build,custom_dir
Advanced Usage
Custom Variable Detection
Add custom regex patterns for variable detection:
scanner = EnvScanner(
project_path='.',
include_patterns=[
r'config\.get\(["\']([A-Z_]+)["\']', # Custom config pattern
]
)
Programmatic Generation
from env_scanner import EnvScanner, EnvExampleGenerator
# Scan project
scanner = EnvScanner('/path/to/project')
variables = scanner.scan_directory()
# Custom generation
generator = EnvExampleGenerator(
env_vars=variables,
output_path='custom-env-template.txt',
add_comments=True,
group_by_prefix=True
)
# Get content without saving
content = generator.generate_content()
print(content)
# Or save to file
generator.save()
Development
Setup Development Environment
# Clone the repository
git clone https://github.com/ammarmunir4567/env-scanner.git
cd env-scanner
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install in development mode
pip install -e ".[dev]"
Run Tests
# Run all tests
pytest
# Run with coverage
pytest --cov=env_scanner --cov-report=html
# Run specific test file
pytest tests/test_scanner.py
Code Quality
# Format code
black env_scanner tests
# Lint code
flake8 env_scanner tests
# Type checking
mypy env_scanner
How It Works
- Scanning: The scanner walks through your Python project files
- Detection: Uses both AST (Abstract Syntax Tree) parsing and regex to find environment variable access patterns
- Analysis: Identifies variable names and their usage locations
- Generation: Creates a
.env-examplefile with:- Intelligent placeholder values based on variable names
- Descriptive comments for common patterns
- Grouped organization by variable prefixes
- Usage location context
Use Cases
- 🚀 Project Setup: Help new developers understand required environment variables
- 📦 CI/CD: Automatically generate environment templates in deployment pipelines
- 📚 Documentation: Keep environment variable documentation in sync with code
- 🔒 Security: Ensure all required environment variables are documented without exposing secrets
- ♻️ Refactoring: Track environment variable usage across large codebases
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
- 📧 Email: ammarmunir4567@gmail.com
- 🐛 Issues: GitHub Issues
- 💬 Discussions: GitHub Discussions
Acknowledgments
- Inspired by the need for better environment variable management in Python projects
- Built with Python's
astmodule for accurate code parsing - Thanks to all contributors and users!
Made with ❤️ by Ammar Munir
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file env_scanner-0.0.0.tar.gz.
File metadata
- Download URL: env_scanner-0.0.0.tar.gz
- Upload date:
- Size: 40.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c7830b460b1812449228ee4b04558cad73a6c286ba8783a85aff7ebe2b534c07
|
|
| MD5 |
decfb48feab18f0d569ccb4959f6b981
|
|
| BLAKE2b-256 |
9e669424e1ceb56ef32d34941b9ddf9243c5aaf306f9206252537e61f279de13
|
File details
Details for the file env_scanner-0.0.0-py3-none-any.whl.
File metadata
- Download URL: env_scanner-0.0.0-py3-none-any.whl
- Upload date:
- Size: 18.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
10778a4b30fd22df6e6ddd9dfc8054f554351d02913fd2ae29a6d8ae9d4dfe65
|
|
| MD5 |
64477ec4270ef213608b4d77f3ab7d51
|
|
| BLAKE2b-256 |
5060d24d615f9925db5edb89e1a4bceb31424b11db32c38d1e30674e84b857fd
|