Files
Gondulf/docs/standards/development-environment.md
Phil Skentelbery 6d21442705 chore: initialize gondulf project structure
Set up Python project with uv environment management and FastAPI stack.

Project structure:
- src/gondulf/ - Main application package
- tests/ - Test suite directory
- pyproject.toml - Project configuration with dependencies
- README.md - Project documentation
- uv.lock - Dependency lock file

Dependencies configured:
- FastAPI + Uvicorn for web framework
- SQLAlchemy for database ORM
- pytest + coverage for testing
- ruff, black, mypy, flake8 for code quality
- Development environment using uv direct execution model

All project standards reviewed and implemented per:
- /docs/standards/coding.md
- /docs/standards/testing.md
- /docs/standards/git.md
- /docs/standards/development-environment.md
- /docs/standards/versioning.md
2025-11-20 10:42:10 -07:00

7.5 KiB

Development Environment Standard

Overview

This document defines the standard development environment setup and workflow for the IndieAuth server project. We use uv for Python virtual environment management and package installation, following a direct execution model that eliminates the need for environment activation.

Prerequisites

System Requirements

  • Python: 3.10 or higher
  • Git: 2.25 or higher
  • SQLite: 3.35 or higher (usually included with Python)

Installing uv

uv is available for all major platforms. Install using one of these methods:

Linux/macOS (recommended):

curl -LsSf https://astral.sh/uv/install.sh | sh

Using pip (alternative):

pip install uv

Using Homebrew (macOS):

brew install uv

After installation, verify:

uv --version

Project Setup

Initial Setup (First Time)

  1. Clone the repository:
git clone <repository-url> gondulf-indieauth
cd gondulf-indieauth
  1. Create virtual environment with uv:
uv venv

This creates a .venv directory in the project root.

  1. Install dependencies:
uv pip sync requirements.txt

Or if using pyproject.toml:

uv pip install -e .

Daily Development Workflow

IMPORTANT: You do NOT need to activate the virtual environment. Use uv run to execute commands within the environment context.

Using uv Direct Execution

Core Concept

Instead of activating/deactivating virtual environments, we use uv's direct execution commands. This approach:

  • Eliminates activation state confusion
  • Works consistently across all shells
  • Makes commands explicit and clear
  • Simplifies CI/CD pipelines

Common Development Commands

Running Python scripts:

# Instead of: python script.py
uv run python script.py

Starting the development server:

# Instead of: python -m uvicorn main:app --reload
uv run uvicorn main:app --reload

Running tests:

# Instead of: pytest
uv run pytest

# With coverage:
uv run pytest --cov=src --cov-report=term-missing

Interactive Python shell:

# Instead of: python
uv run python

Running linters and formatters:

# Instead of: ruff check .
uv run ruff check .

# Format code:
uv run ruff format .

Package Management

Installing packages:

# Instead of: pip install package
uv pip install package

# Install with extras:
uv pip install "package[extra]"

# Install development dependencies:
uv pip install -r requirements-dev.txt

Upgrading packages:

# Instead of: pip install --upgrade package
uv pip install --upgrade package

Listing installed packages:

# Instead of: pip list
uv pip list

Freezing dependencies:

# Instead of: pip freeze > requirements.txt
uv pip freeze > requirements.txt

Syncing with lock file:

# Ensures exact versions from lock file:
uv pip sync requirements.txt

IDE Configuration

VS Code

  1. Open VS Code settings (.vscode/settings.json)
  2. Configure Python interpreter:
{
    "python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
    "python.terminal.activateEnvironment": false
}

Setting activateEnvironment to false prevents VS Code from auto-activating, maintaining our direct execution model.

PyCharm

  1. Go to Settings → Project → Python Interpreter
  2. Click gear icon → Add
  3. Choose "Existing environment"
  4. Browse to: <project-root>/.venv/bin/python
  5. Uncheck "Activate virtualenv" in terminal settings

Other IDEs

Point the interpreter to .venv/bin/python and disable automatic activation if the option exists.

Common Workflows

Starting a New Feature

  1. Ensure dependencies are up to date:
uv pip sync requirements.txt
  1. Create feature branch:
git checkout -b feature/your-feature-name
  1. Run tests to ensure clean state:
uv run pytest

Adding a New Dependency

  1. Install the package:
uv pip install new-package
  1. Update requirements file:
uv pip freeze > requirements.txt
  1. Commit both changes:
git add requirements.txt
git commit -m "Add new-package to dependencies"

Running the Application

Development mode with auto-reload:

uv run uvicorn src.main:app --reload --host 127.0.0.1 --port 8000

Production-like mode:

uv run uvicorn src.main:app --host 0.0.0.0 --port 8000

Running Tests

All tests:

uv run pytest

Specific test file:

uv run pytest tests/test_auth.py

With coverage report:

uv run pytest --cov=src --cov-report=html --cov-report=term-missing

Watch mode (requires pytest-watch):

uv run ptw

Code Quality Checks

Run all checks (before committing):

# Linting
uv run ruff check .

# Type checking
uv run mypy src

# Security scanning
uv run bandit -r src

# Test coverage
uv run pytest --cov=src --cov-report=term-missing

CI/CD Integration

uv commands work seamlessly in CI/CD pipelines without activation:

GitHub Actions example:

- name: Set up Python
  uses: actions/setup-python@v4
  with:
    python-version: '3.10'

- name: Install uv
  run: pip install uv

- name: Install dependencies
  run: |
    uv venv
    uv pip sync requirements.txt

- name: Run tests
  run: uv run pytest --cov=src

- name: Run linting
  run: uv run ruff check .

Troubleshooting

Command not found errors

Problem: Running python or pytest directly doesn't work. Solution: Always prefix with uv run: uv run python or uv run pytest

Package installation issues

Problem: Package conflicts or resolution errors. Solution: Clear the cache and reinstall:

uv cache clean
uv pip sync requirements.txt

IDE not recognizing packages

Problem: IDE shows import errors despite packages being installed. Solution: Ensure IDE interpreter points to .venv/bin/python, not system Python.

Different behavior between local and CI

Problem: Tests pass locally but fail in CI. Solution: Use uv pip sync instead of uv pip install to ensure exact versions.

Best Practices

  1. Never commit .venv/ - It's already in .gitignore
  2. Always use uv run for command execution
  3. Keep requirements.txt updated when adding/removing packages
  4. Use uv pip sync for reproducible environments
  5. Document any special setup in project README
  6. Avoid activation scripts - Use direct execution instead

Benefits of This Approach

  1. Explicit Context: Every command clearly shows it's running in the project environment
  2. No Activation State: Eliminates "which environment am I in?" confusion
  3. Shell Agnostic: Same commands work in bash, zsh, fish, PowerShell, cmd
  4. CI/CD Friendly: Commands are identical in local and automated environments
  5. Faster Execution: uv's Rust implementation provides superior performance
  6. Simpler Onboarding: New developers don't need to learn activation patterns

Quick Reference Card

# Setup (once)
uv venv
uv pip sync requirements.txt

# Daily commands
uv run python script.py           # Run a script
uv run uvicorn src.main:app      # Start server
uv run pytest                     # Run tests
uv run ruff check .              # Lint code
uv pip install package           # Add package
uv pip list                      # List packages
uv run python                    # Interactive shell

Remember: When in doubt, prefix with uv run for Python commands and uv pip for package management.