refactor: migrate to uv package manager with pyproject.toml
This commit is contained in:
@@ -8,3 +8,5 @@ data/
|
|||||||
*.md
|
*.md
|
||||||
.env
|
.env
|
||||||
.venv/
|
.venv/
|
||||||
|
venv/
|
||||||
|
uv.lock
|
||||||
|
|||||||
57
CLAUDE.md
Normal file
57
CLAUDE.md
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
FFmpeg Worker is a dockerized REST API service that executes arbitrary FFmpeg commands. Jobs are submitted via API, processed sequentially by a background worker, and clients poll for status/progress.
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run with Docker (recommended)
|
||||||
|
docker-compose up -d --build
|
||||||
|
|
||||||
|
# Install dependencies locally (requires uv: https://docs.astral.sh/uv/)
|
||||||
|
uv sync
|
||||||
|
|
||||||
|
# Run tests (excludes integration test)
|
||||||
|
uv run pytest tests/ -v --ignore=tests/test_integration.py
|
||||||
|
|
||||||
|
# Run single test
|
||||||
|
uv run pytest tests/test_api.py::test_create_job -v
|
||||||
|
|
||||||
|
# Run integration test (requires Docker running)
|
||||||
|
uv run pytest tests/test_integration.py -v -s
|
||||||
|
|
||||||
|
# Run locally (requires ffmpeg installed)
|
||||||
|
uv run uvicorn app.main:app --reload
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
**Request Flow:**
|
||||||
|
1. `POST /jobs` → creates Job, stores in JobStore, enqueues job_id in JobQueue
|
||||||
|
2. Background `worker_loop` dequeues job_id, runs FFmpeg, updates job status/progress
|
||||||
|
3. `GET /jobs/{id}` → polls job status and real-time progress
|
||||||
|
|
||||||
|
**Key Components:**
|
||||||
|
- `app/main.py` - FastAPI app with lifespan manager that starts/stops worker
|
||||||
|
- `app/queue.py` - JobQueue (asyncio.Queue wrapper), run_ffmpeg(), worker_loop()
|
||||||
|
- `app/ffmpeg.py` - Command parsing, path resolution, progress parsing, ffprobe duration
|
||||||
|
- `app/models.py` - Pydantic models (Job, JobStatus, Progress, CreateJobRequest, JobResponse)
|
||||||
|
- `app/store.py` - In-memory JobStore (dict-based)
|
||||||
|
|
||||||
|
**File Path Handling:**
|
||||||
|
- API accepts relative paths (e.g., `input/video.mp4`)
|
||||||
|
- `resolve_paths()` converts to absolute using DATA_PATH environment variable
|
||||||
|
- Output files returned as relative paths
|
||||||
|
|
||||||
|
## Environment Variables
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| DATA_PATH | /data | Mount point for media files |
|
||||||
|
| FFMPEG_TIMEOUT | 3600 | Max job duration in seconds |
|
||||||
|
| HOST | 0.0.0.0 | Server bind address |
|
||||||
|
| PORT | 8000 | Server port |
|
||||||
11
Dockerfile
11
Dockerfile
@@ -1,16 +1,19 @@
|
|||||||
FROM python:3.14-slim
|
FROM python:3.14-slim
|
||||||
|
|
||||||
# Install FFmpeg
|
# Install FFmpeg and curl (for uv installation)
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y --no-install-recommends ffmpeg && \
|
apt-get install -y --no-install-recommends ffmpeg curl && \
|
||||||
apt-get clean && \
|
apt-get clean && \
|
||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Install uv
|
||||||
|
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Install Python dependencies
|
# Install Python dependencies
|
||||||
COPY requirements.txt .
|
COPY pyproject.toml .
|
||||||
RUN pip install --no-cache-dir -r requirements.txt
|
RUN uv pip install --system --no-cache .
|
||||||
|
|
||||||
# Copy application
|
# Copy application
|
||||||
COPY app/ ./app/
|
COPY app/ ./app/
|
||||||
|
|||||||
30
pyproject.toml
Normal file
30
pyproject.toml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
[project]
|
||||||
|
name = "ffmpeg-worker"
|
||||||
|
version = "1.0.0"
|
||||||
|
description = "Dockerized FFmpeg worker with REST API"
|
||||||
|
requires-python = ">=3.12"
|
||||||
|
dependencies = [
|
||||||
|
"fastapi>=0.123.0",
|
||||||
|
"uvicorn[standard]>=0.38.0",
|
||||||
|
"pydantic>=2.12.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[project.optional-dependencies]
|
||||||
|
dev = [
|
||||||
|
"pytest>=8.3.0",
|
||||||
|
"pytest-asyncio>=0.24.0",
|
||||||
|
"httpx>=0.28.1",
|
||||||
|
"requests>=2.32.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.pytest.ini_options]
|
||||||
|
asyncio_mode = "auto"
|
||||||
|
testpaths = ["tests"]
|
||||||
|
|
||||||
|
[tool.uv]
|
||||||
|
dev-dependencies = [
|
||||||
|
"pytest>=8.3.0",
|
||||||
|
"pytest-asyncio>=0.24.0",
|
||||||
|
"httpx>=0.28.1",
|
||||||
|
"requests>=2.32.0",
|
||||||
|
]
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
fastapi==0.123.0
|
|
||||||
uvicorn[standard]==0.38.0
|
|
||||||
pydantic==2.12.5
|
|
||||||
pytest==8.3.0
|
|
||||||
pytest-asyncio==0.24.0
|
|
||||||
httpx==0.28.1
|
|
||||||
requests==2.32.0
|
|
||||||
Reference in New Issue
Block a user