# 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):** ```bash curl -LsSf https://astral.sh/uv/install.sh | sh ``` **Using pip (alternative):** ```bash pip install uv ``` **Using Homebrew (macOS):** ```bash brew install uv ``` After installation, verify: ```bash uv --version ``` ## Project Setup ### Initial Setup (First Time) 1. **Clone the repository:** ```bash git clone gondulf-indieauth cd gondulf-indieauth ``` 2. **Create virtual environment with uv:** ```bash uv venv ``` This creates a `.venv` directory in the project root. 3. **Install dependencies:** ```bash uv pip sync requirements.txt ``` Or if using pyproject.toml: ```bash 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:** ```bash # Instead of: python script.py uv run python script.py ``` **Starting the development server:** ```bash # Instead of: python -m uvicorn main:app --reload uv run uvicorn main:app --reload ``` **Running tests:** ```bash # Instead of: pytest uv run pytest # With coverage: uv run pytest --cov=src --cov-report=term-missing ``` **Interactive Python shell:** ```bash # Instead of: python uv run python ``` **Running linters and formatters:** ```bash # Instead of: ruff check . uv run ruff check . # Format code: uv run ruff format . ``` ### Package Management **Installing packages:** ```bash # 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:** ```bash # Instead of: pip install --upgrade package uv pip install --upgrade package ``` **Listing installed packages:** ```bash # Instead of: pip list uv pip list ``` **Freezing dependencies:** ```bash # Instead of: pip freeze > requirements.txt uv pip freeze > requirements.txt ``` **Syncing with lock file:** ```bash # 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: ```json { "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: `/.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:** ```bash uv pip sync requirements.txt ``` 2. **Create feature branch:** ```bash git checkout -b feature/your-feature-name ``` 3. **Run tests to ensure clean state:** ```bash uv run pytest ``` ### Adding a New Dependency 1. **Install the package:** ```bash uv pip install new-package ``` 2. **Update requirements file:** ```bash uv pip freeze > requirements.txt ``` 3. **Commit both changes:** ```bash git add requirements.txt git commit -m "Add new-package to dependencies" ``` ### Running the Application **Development mode with auto-reload:** ```bash uv run uvicorn src.main:app --reload --host 127.0.0.1 --port 8000 ``` **Production-like mode:** ```bash uv run uvicorn src.main:app --host 0.0.0.0 --port 8000 ``` ### Running Tests **All tests:** ```bash uv run pytest ``` **Specific test file:** ```bash uv run pytest tests/test_auth.py ``` **With coverage report:** ```bash uv run pytest --cov=src --cov-report=html --cov-report=term-missing ``` **Watch mode (requires pytest-watch):** ```bash uv run ptw ``` ### Code Quality Checks **Run all checks (before committing):** ```bash # 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:** ```yaml - 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: ```bash 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 ```bash # 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.