Local Development Setup
Set up Streaklet for local development.
Prerequisites
- Python 3.12+
- Git
- pip (Python package manager)
- Docker (optional, for testing containers)
Clone Repository
Virtual Environment Setup
Create virtual environment:
Activate virtual environment:
# Linux/macOS
source .venv/bin/activate
# Windows (PowerShell)
.venv\Scripts\Activate.ps1
# Windows (CMD)
.venv\Scripts\activate.bat
Verify activation:
Install Dependencies
Development tools:
Database Setup
Run migrations:
This creates data/app.db with the schema.
Verify database:
Environment Configuration
Create .env file (optional):
# .env
APP_TIMEZONE=America/Chicago
DB_PATH=data/app.db
PORT=8080
# Optional: Fitbit integration
# FITBIT_CLIENT_ID=your_client_id
# FITBIT_CLIENT_SECRET=your_client_secret
# APP_SECRET_KEY=your_secure_random_key
Load environment variables:
Running the Development Server
Using dev.sh (Recommended)
This starts uvicorn with auto-reload enabled.
Manual uvicorn
Options:
- --reload - Auto-restart on code changes
- --host 0.0.0.0 - Accept connections from any IP
- --port 8080 - Port to listen on
Access the Application
Open browser to: http://localhost:8080
Running Tests
All Tests
With Coverage
./dev.sh test-cov
# Or manually:
python -m pytest tests/ --cov=app --cov-report=html --cov-report=term
View HTML coverage report:
open htmlcov/index.html # macOS
xdg-open htmlcov/index.html # Linux
start htmlcov/index.html # Windows
Single Test File
Single Test Function
Watch Mode (Requires pytest-watch)
Linting
Check Code
Auto-Fix Issues
CI-Style Check (Critical Errors Only)
This is what CI runs. Must pass for PRs.
Database Migrations
Create New Migration
./dev.sh migrate-new "description"
# Or manually:
alembic revision --autogenerate -m "add new column"
Apply Migrations
Rollback Migration
View Migration History
View Current Version
Docker Development
Build Image
Run Container
docker run -d \
--name streaklet-dev \
-p 8080:8080 \
-v ./data:/data \
-e APP_TIMEZONE=America/Chicago \
streaklet:dev
Run Tests in Docker
docker build -t streaklet:test .
docker run --rm --entrypoint "" --user appuser streaklet:test \
sh -c "PYTHONPATH=. python -m pytest tests/ -v"
Docker Compose Development
Edit files locally; rebuild when needed:
IDE Configuration
VS Code
Recommended Extensions: - Python - Pylance - Ruff
settings.json:
{
"python.defaultInterpreterPath": ".venv/bin/python",
"python.linting.enabled": true,
"python.linting.ruffEnabled": true,
"python.formatting.provider": "none",
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": true
}
}
}
PyCharm
Configure interpreter:
1. Settings → Project → Python Interpreter
2. Add Interpreter → Existing environment
3. Select .venv/bin/python
Enable Ruff:
1. Settings → Tools → External Tools
2. Add tool: ruff check $FilePath$
Debugging
VS Code Debug Configuration
.vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "FastAPI",
"type": "python",
"request": "launch",
"module": "uvicorn",
"args": [
"app.main:app",
"--reload",
"--host", "0.0.0.0",
"--port", "8080"
],
"jinja": true,
"justMyCode": true,
"env": {
"APP_TIMEZONE": "America/Chicago"
}
},
{
"name": "Pytest",
"type": "python",
"request": "launch",
"module": "pytest",
"args": [
"tests/",
"-v"
],
"justMyCode": true
}
]
}
Python Debugger (pdb)
Add breakpoint in code:
Or use built-in breakpoint():
Print Debugging
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
logger.debug(f"Variable value: {variable}")
Common Development Tasks
Reset Database
Seed Test Data
Create a seed script (e.g., seed.py):
from app.database import SessionLocal
from app.services import profiles, tasks
db = SessionLocal()
# Create profiles
profile = profiles.create_profile(db, name="Test User", color="#3b82f6")
# Create tasks
tasks.create_task(db, profile_id=profile.id, title="Test Task", required=True, active=True)
db.close()
Run it:
Clear Cache
Update Dependencies
Troubleshooting
Import Errors
Ensure PYTHONPATH is set:
Database Locked
SQLite locks when accessed by multiple processes:
Port Already in Use
Find process using port 8080:
# Linux/macOS
lsof -i :8080
kill -9 <PID>
# Windows
netstat -ano | findstr :8080
taskkill /PID <PID> /F
Virtual Environment Not Activating
Recreate it:
Tests Failing
- Check database exists:
ls data/app.db - Run migrations:
alembic upgrade head - Clear pytest cache:
rm -rf .pytest_cache - Check environment variables:
env | grep APP_
Git Workflow
See Contributing Guide for detailed Git workflow and commit conventions.
Quick reference:
# Create feature branch
git checkout -b feature/my-feature
# Make changes, commit with conventional commits
git add .
git commit -m "feat: add new feature"
# Push and create PR
git push origin feature/my-feature
Next Steps
- Contributing Guide - How to contribute
- Architecture - Codebase structure
- API Reference - API documentation