CLAUDE: Migrate backend to UV package management
Migrated from pip to UV (v0.9.7) for faster, more reliable package management. ## Changes ### Package Management - Created `pyproject.toml` with project metadata and dependencies - Generated `uv.lock` for reproducible builds (198KB) - Migrated all dependencies from requirements.txt: - Production: 20 packages (FastAPI, SQLAlchemy, Pydantic, etc.) - Development: 6 packages (pytest, black, mypy, flake8) - Virtual environment moved from `venv/` to `.venv/` (UV default) ### Dockerfile Updates - Updated base image: python:3.11-slim → python:3.13-slim - Added UV installation via official image copy - Development stage: Uses `uv sync --frozen` for all deps - Production stage: Uses `uv sync --frozen --no-dev` for prod only - Commands now use `uv run` prefix for auto-activation - Set UV environment variables: - UV_LINK_MODE=copy (for Docker compatibility) - UV_COMPILE_BYTECODE=1 (performance) - UV_PYTHON_DOWNLOADS=never (use system Python) ### Code Fixes - Fixed Pydantic model circular import in `app/models/game_models.py` - Added runtime import of PositionRating at end of file - Called `model_rebuild()` on LineupPlayerState and GameState - Resolves "not fully defined" errors in tests ### Documentation - Updated `backend/CLAUDE.md` with UV usage: - Package management section with UV commands - Updated all code examples to use `uv run` - Daily development workflow now uses UV - Added dependency management guide (add/remove/update) - Updated virtual environment location (.venv/) ### Project Files - Added `.python-version` (3.13) for UV Python version tracking - Removed UV template files (main.py, README.md) - Kept existing .gitignore (already includes venv/ and .venv/) ## Testing - ✅ All imports work correctly - ✅ 55/55 game model tests passing - ✅ 500+ unit tests passing (same as before migration) - ✅ Test failures are pre-existing (not UV-related) ## Benefits - 10-100x faster dependency resolution - 2-3x faster installation - Better dependency conflict resolution - Single tool for everything (replaces pip, pip-tools, virtualenv) - Reproducible builds with uv.lock ## Migration Path for Team ```bash # One-time: Install UV curl -LsSf https://astral.sh/uv/install.sh | sh # In project cd backend uv sync # Creates .venv and installs everything # Daily usage uv run python -m app.main uv run pytest tests/ -v ``` 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
b15b63fabe
commit
9a9018aab4
1
backend/.python-version
Normal file
1
backend/.python-version
Normal file
@ -0,0 +1 @@
|
||||
3.13
|
||||
@ -123,19 +123,35 @@ Lineup.from_api_data(config, data)
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### Package Management
|
||||
|
||||
This project uses **UV** for fast, reliable package management.
|
||||
|
||||
**Installing UV** (one-time setup):
|
||||
```bash
|
||||
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
```
|
||||
|
||||
**Setting up the project**:
|
||||
```bash
|
||||
cd backend
|
||||
uv sync # Creates .venv and installs all dependencies
|
||||
```
|
||||
|
||||
### Daily Development
|
||||
```bash
|
||||
# Activate virtual environment
|
||||
source venv/bin/activate
|
||||
|
||||
# Start Redis (in separate terminal or use -d for detached)
|
||||
docker compose up -d
|
||||
|
||||
# Run backend with hot-reload
|
||||
python -m app.main
|
||||
# Run backend with hot-reload (UV auto-activates .venv)
|
||||
uv run python -m app.main
|
||||
|
||||
# Backend available at http://localhost:8000
|
||||
# API docs at http://localhost:8000/docs
|
||||
|
||||
# Alternative: Activate .venv manually
|
||||
source .venv/bin/activate
|
||||
python -m app.main
|
||||
```
|
||||
|
||||
### Testing
|
||||
@ -146,7 +162,7 @@ Test the game engine directly without needing a frontend:
|
||||
|
||||
```bash
|
||||
# Start interactive REPL (recommended for rapid testing)
|
||||
python -m terminal_client
|
||||
uv run python -m terminal_client
|
||||
|
||||
# Then interact:
|
||||
⚾ > new_game
|
||||
@ -171,22 +187,22 @@ See `terminal_client/CLAUDE.md` for full documentation.
|
||||
|
||||
```bash
|
||||
# Run all tests
|
||||
pytest tests/ -v
|
||||
uv run pytest tests/ -v
|
||||
|
||||
# Run with coverage
|
||||
pytest tests/ --cov=app --cov-report=html
|
||||
uv run pytest tests/ --cov=app --cov-report=html
|
||||
|
||||
# Run specific test file
|
||||
pytest tests/unit/test_game_engine.py -v
|
||||
uv run pytest tests/unit/test_game_engine.py -v
|
||||
|
||||
# Type checking
|
||||
mypy app/
|
||||
uv run mypy app/
|
||||
|
||||
# Code formatting
|
||||
black app/ tests/
|
||||
uv run black app/ tests/
|
||||
|
||||
# Linting
|
||||
flake8 app/ tests/
|
||||
uv run flake8 app/ tests/
|
||||
```
|
||||
|
||||
## Coding Standards
|
||||
@ -891,8 +907,43 @@ docker-compose up -d # Old command not available
|
||||
|
||||
### Python Environment
|
||||
- **Version**: Python 3.13.3 (not 3.11 as originally planned)
|
||||
- **Virtual Environment**: Located at `backend/venv/`
|
||||
- **Activation**: `source venv/bin/activate` (from backend directory)
|
||||
- **Package Manager**: UV (v0.9.7+) - Fast, reliable Python package management
|
||||
- **Virtual Environment**: Located at `backend/.venv/` (UV default)
|
||||
- **Activation**: `source .venv/bin/activate` (from backend directory)
|
||||
- Or use `uv run <command>` to auto-activate
|
||||
|
||||
### Package Management with UV
|
||||
|
||||
**Add a new dependency**:
|
||||
```bash
|
||||
# Production dependency
|
||||
uv add package-name==1.2.3
|
||||
|
||||
# Development dependency
|
||||
uv add --dev package-name==1.2.3
|
||||
|
||||
# With extras
|
||||
uv add "package[extra]==1.2.3"
|
||||
```
|
||||
|
||||
**Update dependencies**:
|
||||
```bash
|
||||
# Update a specific package
|
||||
uv add package-name@latest
|
||||
|
||||
# Sync dependencies (after pulling pyproject.toml changes)
|
||||
uv sync
|
||||
```
|
||||
|
||||
**Remove a dependency**:
|
||||
```bash
|
||||
uv remove package-name
|
||||
```
|
||||
|
||||
**Key Files**:
|
||||
- `pyproject.toml` - Project metadata and dependencies (commit to git)
|
||||
- `uv.lock` - Locked dependency versions (commit to git)
|
||||
- `.venv/` - Virtual environment (gitignored)
|
||||
|
||||
### Critical Dependencies
|
||||
- **greenlet**: Required for SQLAlchemy async support (must be explicitly installed)
|
||||
|
||||
@ -1,31 +1,35 @@
|
||||
# Backend Dockerfile for Paper Dynasty Game Engine
|
||||
# Multi-stage build for optimized production image
|
||||
|
||||
FROM python:3.11-slim as base
|
||||
FROM python:3.13-slim as base
|
||||
|
||||
# Set environment variables
|
||||
ENV PYTHONUNBUFFERED=1 \
|
||||
PYTHONDONTWRITEBYTECODE=1 \
|
||||
PIP_NO_CACHE_DIR=1 \
|
||||
PIP_DISABLE_PIP_VERSION_CHECK=1
|
||||
UV_LINK_MODE=copy \
|
||||
UV_COMPILE_BYTECODE=1 \
|
||||
UV_PYTHON_DOWNLOADS=never
|
||||
|
||||
# Install system dependencies
|
||||
# Install system dependencies and UV
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
postgresql-client \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install UV
|
||||
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
|
||||
|
||||
# Create app directory
|
||||
WORKDIR /app
|
||||
|
||||
# Development stage
|
||||
FROM base as development
|
||||
|
||||
# Copy requirements
|
||||
COPY requirements.txt requirements-dev.txt ./
|
||||
# Copy dependency files
|
||||
COPY pyproject.toml uv.lock ./
|
||||
|
||||
# Install Python dependencies
|
||||
RUN pip install -r requirements-dev.txt
|
||||
# Install all dependencies (including dev)
|
||||
RUN uv sync --frozen
|
||||
|
||||
# Copy application code
|
||||
COPY . .
|
||||
@ -34,16 +38,16 @@ COPY . .
|
||||
EXPOSE 8000
|
||||
|
||||
# Run with uvicorn reload for development
|
||||
CMD ["python", "-m", "uvicorn", "app.main:socket_app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
|
||||
CMD ["uv", "run", "python", "-m", "uvicorn", "app.main:socket_app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
|
||||
|
||||
# Production stage
|
||||
FROM base as production
|
||||
|
||||
# Copy requirements (production only)
|
||||
COPY requirements.txt ./
|
||||
# Copy dependency files
|
||||
COPY pyproject.toml uv.lock ./
|
||||
|
||||
# Install Python dependencies
|
||||
RUN pip install -r requirements.txt
|
||||
# Install production dependencies only
|
||||
RUN uv sync --frozen --no-dev
|
||||
|
||||
# Create non-root user
|
||||
RUN useradd -m -u 1000 appuser && \
|
||||
@ -63,4 +67,4 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||
CMD curl -f http://localhost:8000/api/health || exit 1
|
||||
|
||||
# Run with production server
|
||||
CMD ["python", "-m", "uvicorn", "app.main:socket_app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]
|
||||
CMD ["uv", "run", "python", "-m", "uvicorn", "app.main:socket_app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]
|
||||
@ -700,6 +700,18 @@ class GameState(BaseModel):
|
||||
)
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# MODEL REBUILD (for forward references)
|
||||
# ============================================================================
|
||||
|
||||
# Import PositionRating at runtime for model rebuild
|
||||
from app.models.player_models import PositionRating # noqa: E402
|
||||
|
||||
# Rebuild models that use forward references
|
||||
LineupPlayerState.model_rebuild()
|
||||
GameState.model_rebuild()
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# EXPORTS
|
||||
# ============================================================================
|
||||
|
||||
48
backend/pyproject.toml
Normal file
48
backend/pyproject.toml
Normal file
@ -0,0 +1,48 @@
|
||||
[project]
|
||||
name = "paper-dynasty-backend"
|
||||
version = "0.1.0"
|
||||
description = "Paper Dynasty Real-Time Game Engine Backend - FastAPI with WebSocket support"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.13"
|
||||
authors = [
|
||||
{ name = "Paper Dynasty Team" }
|
||||
]
|
||||
dependencies = [
|
||||
"aiofiles==24.1.0",
|
||||
"alembic==1.14.0",
|
||||
"asyncpg==0.30.0",
|
||||
"click==8.1.8",
|
||||
"fastapi==0.115.6",
|
||||
"greenlet==3.2.4",
|
||||
"httpx==0.28.1",
|
||||
"passlib[bcrypt]==1.7.4",
|
||||
"pendulum==3.0.0",
|
||||
"psycopg2-binary==2.9.10",
|
||||
"pydantic==2.10.6",
|
||||
"pydantic-settings==2.7.1",
|
||||
"python-dotenv==1.0.1",
|
||||
"python-jose[cryptography]==3.3.0",
|
||||
"python-multipart==0.0.20",
|
||||
"python-socketio==5.11.4",
|
||||
"redis==5.2.1",
|
||||
"rich==13.9.4",
|
||||
"sqlalchemy==2.0.36",
|
||||
"uvicorn[standard]==0.34.0",
|
||||
]
|
||||
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
packages = ["app"]
|
||||
|
||||
[dependency-groups]
|
||||
dev = [
|
||||
"black==24.10.0",
|
||||
"flake8==7.1.1",
|
||||
"mypy==1.14.1",
|
||||
"pytest==8.3.4",
|
||||
"pytest-asyncio==0.25.2",
|
||||
"pytest-cov==6.0.0",
|
||||
]
|
||||
1324
backend/uv.lock
generated
Normal file
1324
backend/uv.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user