A production-ready template for Python projects that use HashiCorp Vault for secrets management.
- Overview
- Features
- Quick Start
- Project Structure
- Technology Stack
- Development Workflow
- Configuration
- Testing
- Code Quality
- Troubleshooting
- Contributing
This template provides a complete, production-ready foundation for Python applications that require secure secrets management using HashiCorp Vault. It includes automated testing, code quality checks, and a streamlined development workflow with git hooks.
- π Secure: Vault integration for secrets management (no hardcoded credentials)
- π Production-Ready: Pinned dependencies, security scanning, automated quality checks
- β Quality-First: Automated linting, type checking, formatting, and testing via pre-commit hooks
- π¦ Template-Based: Easy to customize and adapt for new projects
- π οΈ Developer-Friendly: Interactive setup, comprehensive documentation, Makefile commands
- β HashiCorp Vault integration for secure secrets storage
- β Automatic secret fetching and environment variable injection
- β Security vulnerability scanning with Bandit
- β No hardcoded credentials in codebase
- β Interactive setup script with guided configuration
- β Git pre-commit hooks for automated quality checks
- β Makefile for common development tasks
- β Virtual environment management
- β Hot-reload development workflow
- β Ruff - Fast Python linter and formatter
- β mypy - Static type checking
- β pytest - Comprehensive testing framework
- β Bandit - Security issue detection
- β
Automated secret injection via
bin/runscript - β Production-ready configuration
- β Pinned dependencies for reproducible builds
-
Clone or copy this template to your project directory:
git clone <repository-url> my-project cd my-project
-
Run the interactive setup script:
chmod +x bin/setup ./bin/setup
The installer will:
- Initialize git repository (if needed)
- Configure git user settings (interactive)
- Create Python virtual environment
- Install all dependencies
- Set up pre-commit hooks
- Configure Vault settings (interactive)
-
Run your application:
./bin/run python main.py
Or use the Makefile:
make run
python-vault/
βββ .agent/ # Antigravity AI assistant configuration
β βββ prompts/ # Custom prompts for code generation
β β βββ README.md
β β βββ readme-blueprint-generator.prompt.md
β β βββ vault-secret-documenter.prompt.md
β βββ workflows/ # Development workflows
βββ bin/ # Executable scripts
β βββ setup # Interactive project setup
β βββ run # Vault-integrated command runner
βββ config/ # Configuration files
β βββ vault.conf # Vault mount point and secret name
βββ hooks/ # Git hooks
β βββ pre-commit # Automated quality checks
βββ tests/ # Test files (pytest)
β βββ __init__.py
β βββ test_main.py
βββ .bandit # Bandit security scanner config
βββ .gitignore # Git ignore patterns
βββ main.py # Main application entry point
βββ Makefile # Common development commands
βββ requirements.txt # Production dependencies (pinned)
βββ requirements-dev.txt # Development dependencies
βββ LICENSE # MIT License
βββ README.md # This file
- Python 3.13+ - Primary programming language
- HashiCorp Vault - Secrets management and secure storage
- Bash - Automation scripts and tooling
- requests (β₯2.32.0, <3.0.0) - HTTP library for API calls
- ruff (β₯0.14.0, <1.0.0) - Fast Python linter and formatter
- mypy (β₯1.19.0, <2.0.0) - Static type checker
- pytest (β₯9.0.0, <10.0.0) - Testing framework
- bandit (β₯1.9.0, <2.0.0) - Security vulnerability scanner
- Git - Version control with automated hooks
- Make - Build automation and task runner
- Write code in
main.py(or create additional.pyfiles as needed) - Write tests in
tests/following thetest_*.pynaming convention - Run your code with Vault integration:
./bin/run python main.py # or make run - Run tests:
./bin/run python -m pytest # or make test
- Commit changes - pre-commit hook runs automatically:
- Linting with auto-fix (ruff)
- Code formatting (ruff)
- Type checking (mypy)
- Security scanning (bandit)
- All tests (pytest)
make help # Show all available commands
make setup # Run initial project setup
make run # Run the application (with Vault)
make test # Run all tests
make lint # Run linting checks
make format # Format code
make clean # Remove venv, caches, and temporary filesProduction dependencies:
echo "package-name>=1.0.0,<2.0.0" >> requirements.txt
./bin/run pip install -r requirements.txtDevelopment dependencies:
echo "dev-package>=1.0.0,<2.0.0" >> requirements-dev.txt
./bin/run pip install -r requirements-dev.txtThe project uses config/vault.conf to specify Vault settings:
VAULT_MOUNT="python-vault"
VAULT_SECRET_NAME="demo"Option 1: Interactive (Recommended)
./bin/setupFollow the prompts to configure your Vault mount point and secret name.
Option 2: Manual
# Edit config/vault.conf directly
vim config/vault.confThe bin/run script uses these environment variables:
VAULT_ADDR- Vault server address (default:http://127.0.0.1:8200)VAULT_TOKEN- Authentication token (default:rootfor dev)
Add secrets to Vault:
vault kv put python-vault/demo \
api_key="your-api-key" \
db_pass="your-password" \
region="us-west-2"Access secrets in Python:
import os
api_key = os.environ.get("api_key")
db_pass = os.environ.get("db_pass")
region = os.environ.get("region")The bin/run script automatically:
- Starts Vault dev server (if not running)
- Enables the KV mount point
- Fetches all secrets from the configured path
- Exports them as environment variables
- Runs your command with secrets available
# Run all tests
./bin/run python -m pytest
# Run specific test file
./bin/run python -m pytest tests/test_main.py
# Run with verbose output
./bin/run python -m pytest -v
# Run with coverage
./bin/run python -m pytest --cov=srcOr use the Makefile:
make testCreate test files in tests/ following the test_*.py naming convention:
# tests/test_my_feature.py
from main import main
def test_main():
"""Test the main function."""
# Your test code here
assert Truetests/
βββ __init__.py
βββ test_main.py # Tests for main.py
βββ test_integration.py # Integration tests
βββ fixtures/ # Test fixtures and data
βββ sample_data.json
The pre-commit hook automatically runs:
- Ruff Linting - Fast Python linter with auto-fix
- Ruff Formatting - Consistent code style
- mypy - Static type checking
- Bandit - Security vulnerability scanning
- pytest - All tests must pass
# Linting
./bin/run python -m ruff check .
./bin/run python -m ruff check --fix . # Auto-fix issues
# Formatting
./bin/run python -m ruff format .
# Type checking
./bin/run python -m mypy .
# Security scanning
./bin/run python -m bandit -r .
# All tests
./bin/run python -m pytestOr use Makefile shortcuts:
make lint # Run linting
make format # Format code- Type hints - Use type annotations for all functions
- Docstrings - Document all public functions and classes
- Error handling - Use proper exception handling
- Security - Never hardcode secrets or credentials
- Testing - Write tests for all new features
Solution: Install Vault from https://www.vaultproject.io/downloads
# macOS
brew install vault
# Linux
wget https://releases.hashicorp.com/vault/1.15.0/vault_1.15.0_linux_amd64.zip
unzip vault_1.15.0_linux_amd64.zip
sudo mv vault /usr/local/bin/Solution: Configure git:
git config user.name "Your Name"
git config user.email "[email protected]"Solution: Ensure:
- Vault is running:
vault status - Mount point exists:
vault secrets list - Secret exists:
vault kv get python-vault/demo - Token has read permissions
Debug steps:
# Check Vault status
vault status
# List secret engines
vault secrets list
# Read secret directly
vault kv get python-vault/demo
# Check token capabilities
vault token capabilities python-vault/demoSolution: Run checks manually to see detailed errors:
./bin/run python -m pytest
./bin/run python -m ruff check .
./bin/run python -m mypy .
./bin/run python -m bandit -r .Solution: Recreate the virtual environment:
rm -rf venv/
python3 -m venv venv
./bin/run pip install -r requirements-dev.txt- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Run quality checks:
make lint && make test - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
- Follow existing code style (enforced by ruff)
- Add tests for new features
- Update documentation as needed
- Ensure all quality checks pass
- Keep commits atomic and well-described
All submissions require review. We use GitHub pull requests for this purpose:
- Automated checks must pass (linting, tests, security)
- Code review by at least one maintainer
- Documentation must be updated if needed
- Tests must cover new functionality
This project is licensed under the MIT License - see the LICENSE file for details.
- HashiCorp Vault - Secrets management
- Ruff - Fast Python linter
- pytest - Testing framework
- mypy - Static type checker
Made with πͺ by Unamata Sanatarai