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
350 lines
7.5 KiB
Markdown
350 lines
7.5 KiB
Markdown
# 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 <repository-url> 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: `<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:**
|
|
```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. |