This directory provides a ready-to-use template for Python development using Nix flakes and direnv in geckoforge.
- Python 3.14.2: Latest stable Python with modern features
- KERI Support: Pre-configured with cryptographic libraries (libsodium, blake3)
- Testing: pytest with async support, coverage reporting
- Type Checking: mypy with strict configuration
- Auto-activation: direnv automatically loads environment when entering directory
# Copy this template to your project directory
cp -r ~/git/geckoforge/examples/python-nix-direnv ~/git/my-project
cd ~/git/my-projectdirenv allowThe first load takes 1-2 minutes to build the Nix environment. Subsequent loads are instant (cached by nix-direnv).
# Check Python version
python --version
# Output: Python 3.14.2
# Check installed packages
pip list
# Verify virtual environment
echo $VIRTUAL_ENV
# Output: /path/to/project/.venv# Create your package structure
mkdir -p src/my_package tests
# Write some code
cat > src/my_package/__init__.py << 'EOF'
"""My awesome package."""
__version__ = "0.1.0"
def greet(name: str) -> str:
"""Greet someone."""
return f"Hello, {name}!"
EOF
# Write a test
cat > tests/test_my_package.py << 'EOF'
from my_package import greet
def test_greet():
assert greet("World") == "Hello, World!"
EOF
# Run tests
pytest
# Type check
mypy src/python-nix-direnv/
├── .envrc # direnv configuration (loads flake.nix)
├── flake.nix # Nix environment definition
├── flake.lock # Locked dependency versions (auto-generated)
├── requirements.txt # Python dependencies
├── pytest.ini # pytest configuration
├── mypy.ini # Type checker configuration
├── README.md # This file
├── .gitignore # Git ignore rules (create this)
├── .venv/ # Virtual environment (auto-created, ignored by git)
└── src/ # Your source code (create this)
└── my_package/
├── __init__.py
└── ...
Simple one-liner that tells direnv to use the Nix flake:
use flakeDefines the Nix development environment:
- Python 3.14.2 interpreter
- Cryptographic libraries (libsodium, blake3)
- Build tools (gcc, make, pkg-config)
shellHookthat creates.venvand installs packages
Python packages installed via pip:
- KERI libraries: keripy, hio
- Testing: pytest, pytest-asyncio, pytest-mock, pytest-cov
- Type checking: mypy
- Utilities: requests, msgpack, cbor2
Add your project dependencies here and run direnv reload to install them.
pytest configuration:
- Test discovery patterns
- Async test support (
asyncio_mode = auto) - Code coverage settings
- Custom markers (slow, integration, unit, keri)
Type checker configuration:
- Strict type checking enabled
- Ignores missing type stubs for KERI libraries
- Relaxed rules for test files
# 1. Add to requirements.txt
echo "fastapi>=0.104.0" >> requirements.txt
# 2. Reload environment (automatically installs)
direnv reload
# 3. Verify installation
pip list | grep fastapi# Run all tests
pytest
# Run specific test file
pytest tests/test_my_package.py
# Run with coverage
pytest --cov=src --cov-report=html
# View coverage report
xdg-open htmlcov/index.html
# Run only fast tests (exclude slow ones)
pytest -m "not slow"
# Run specific marker
pytest -m keri# Check entire project
mypy .
# Check specific directory
mypy src/my_package/
# Strict mode
mypy --strict src/
# Show error codes
mypy --show-error-codes src/# Lint with ruff (fast)
ruff check .
# Auto-fix issues
ruff check --fix .
# Format code
ruff format .This template is pre-configured for KERI development with:
- libsodium: Ed25519 and X25519 cryptography
- blake3: Fast cryptographic hashing
- keripy: Core KERI protocol implementation
- hio: Async I/O framework
# example_keri.py
from keri.app import habbing
def create_identifier(name: str) -> str:
"""Create a new KERI identifier."""
with habbing.Habitat(name=name, temp=True) as hab:
hab.makeInception()
return hab.pre
if __name__ == "__main__":
aid = create_identifier("myapp")
print(f"Created identifier: {aid}")Run it:
python example_keri.pySee docs/keri-development.md for comprehensive KERI guide.
Edit flake.nix:
systemDeps = with pkgs; [
python313 # Change to python313 or python312
python313Packages.pip
# ...
];Then reload: direnv reload
For packages requiring C libraries, add to flake.nix:
systemDeps = with pkgs; [
python314
# Add your libraries
postgresql # PostgreSQL client library
openssl # OpenSSL
zlib # Compression
# Existing libs...
];- Add poetry to
flake.nix:
systemDeps = with pkgs; [
python314
poetry
# ...
];- Replace
shellHookinflake.nix:
shellHook = ''
export POETRY_VIRTUALENVS_IN_PROJECT=true
if [ ! -d .venv ]; then
poetry install
fi
echo "Poetry environment ready!"
'';- Create
pyproject.tomlinstead ofrequirements.txt
# Check direnv status
direnv status
# Reload manually
direnv reload
# Check for errors in flake.nix
nix flake check# Check if virtual environment exists
ls -la .venv/bin/python
# Manually recreate
rm -rf .venv
direnv reload- Restart VS Code
- Command Palette → "Python: Select Interpreter"
- Choose
.venv/bin/python
If you see "cannot find -lsodium" or similar:
- Verify library in
flake.nixundersystemDeps - Check
LD_LIBRARY_PATHis set inshellHook - Reload:
direnv reload
Create .gitignore:
# Virtual environment
.venv/
__pycache__/
*.pyc
# Testing
.pytest_cache/
.coverage
htmlcov/
# Type checking
.mypy_cache/
# direnv
.direnv/
# Nix
result
result-*Initialize git:
git init
git add .
git commit -m "Initial commit from python-nix-direnv template"geckoforge's VS Code is pre-configured for this workflow. Just open the project:
code .Features automatically work:
- Python interpreter detection (
.venv/bin/python) - pytest test discovery and execution
- mypy type checking
- IntelliSense with installed packages
- Debugging
- Read Python Development Guide
- For KERI projects: KERI Development Guide
- Review Home-Manager modules: Nix Modules Usage
For issues or questions:
- Check Python Development Troubleshooting
- Review geckoforge documentation in
docs/ - File an issue in the geckoforge repository
Happy coding! 🐍