Local Development & Contributing¶
This guide covers how to set up your local environment to write code, modify the database schema, and run the test suite.
We use uv for package management and environment isolation. Do not use standard pip, pipenv, or conda in this repository.
1. Environment Setup¶
Instead of relying on Docker for writing code and running the language server in your IDE, set up a local .venv using uv.
# 1. Install uv (if you haven't already)
curl -LsSf https://astral.sh/uv/install.sh | sh
# 2. Sync dependencies (this automatically creates a .venv)
uv sync
# 3. Activate the virtual environment
source .venv/bin/activate
Because we explicitly defined the PyTorch CPU wheels in pyproject.toml, this sync will be fast and won't download 3GB of unnecessary CUDA binaries to your local machine.
2. Environment Variables¶
Copy the example environment file and customize it:
The .env file contains these required variables:
| Variable | Purpose |
|---|---|
DATABASE_URL |
PostgreSQL connection string for the worker user |
HEXCODE_SALT |
Cryptographic salt for ULPIN hash generation |
POSTGRES_SUPER_PASS |
Superuser password for the postgres role |
DB_WORKER_PASSWORD |
Password for the ulpin_worker database role |
ALLOWED_ORIGINS |
Comma-separated list of allowed CORS origins |
⚠️ Security: Never commit
.envto version control. The.gitignorealready excludes it. The password inscripts/01_init.sqlmust matchDB_WORKER_PASSWORDin your.env— for production, replace the SQL init with a shell script that reads from environment variables.
3. Running the Test Suite¶
We use pytest for unit and integration testing. The test suite is designed to run locally without requiring a dedicated GPU or a live connection to PostGIS and Redis (we mock the database sessions and the Celery broker).
# Run the entire test suite
uv run --env-file .env pytest
# Run tests with verbose output and print statements
uv run --env-file .env pytest -v -s
# Run a specific test file
uv run --env-file .env pytest tests/test_engines.py
Note on Machine Learning Inference¶
You do not need an NVIDIA GPU to run the tests. The YOLOv8 segmentation and Open3D point cloud logic are bypassed/mocked in the test_api.py and test_engines.py files to ensure the CI pipeline runs quickly.
4. Modifying the Database Schema¶
If you need to add a new column to a table or create a new PostGIS geometry index, follow these steps:
- Update the raw SQL definitions in
src/mimi/schema.sql. - Because Docker caches the database initialization, your existing local database will not pick up the changes automatically.
- You must tear down the local database volume and let Docker rebuild it from scratch:
# Stop containers and wipe the database volume
docker compose down -v
# Bring the stack back up (this triggers 01_init.sql and schema.sql)
docker compose up -d
5. Managing Dependencies¶
If you need to add a new library to the project (e.g., boto3 for AWS S3 uploads), do not use pip install. Use uv so it updates the pyproject.toml and lockfile automatically.
# Add a production dependency
uv add boto3
# Add a development dependency (like a new linter)
uv add --dev ruff
# If you manually edit pyproject.toml, regenerate the lockfile
uv lock
Always commit the updated uv.lock file in your pull request.
6. Docker Architecture¶
The docker-compose.yml defines four services:
| Service | Container | Purpose |
|---|---|---|
redis |
ulpin_redis |
Message broker for Celery (with AOF persistence) |
db |
ulpin_db |
PostgreSQL + PostGIS + SFCGAL |
api |
ulpin_api |
FastAPI server (with healthcheck) |
worker |
ulpin_worker |
Celery background worker |
Shared Volumes:
- shared-uploads — mounted at /tmp/mimi_uploads on both api and worker containers to allow file handoff for async processing.
- mimi-postgis-data — persistent database storage.
- mimi-redis-data — persistent Redis AOF storage.
Security Notes:
- PostgreSQL is only exposed on 127.0.0.1:5432 (not all interfaces).
- Redis is not exposed to the host network.
- The API container includes a healthcheck so downstream services wait for it to be ready.
7. Pull Request Guidelines¶
Before submitting a PR to the main branch:
- Ensure all tests pass (
uv run --env-file .env pytest). - Verify you haven't added massive binary files (like raw
.plyscans or.ptmodel weights) to the git history. - Select "Squash and merge" when closing the PR to keep the
mainbranch history clean.