Files
photo_booth/CLAUDE.md
T
2026-06-02 22:54:55 +02:00

2.8 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project overview

A two-component photo booth system running on Raspberry Pi:

  1. camera/ — Python/Flask camera server using picamera2 (Raspberry Pi HQ Camera M12). Streams live MJPEG video and exposes a /capture endpoint that saves JPEG snapshots to camera/photos/.
  2. ImmichUploader/ — Laravel 13 PHP application that watches camera/photos/ via inotify, and uploads new photos to a self-hosted Immich instance via its HTTP API, then adds each asset to a specific album.

Running the camera server

cd camera
python main.py

The server listens on port 5000 on all interfaces. Endpoints:

  • GET / — live MJPEG stream viewer
  • GET /video_feed — raw MJPEG stream
  • GET /capture — saves current frame to camera/photos/ and returns JSON

Running the ImmichUploader

cd ImmichUploader
composer run setup    # first-time: installs deps, generates key, runs migrations
composer run dev      # starts all services: web server + queue worker + log viewer + vite

Or run the folder watcher and queue worker individually:

php artisan immich:watch-folder   # watches FOLDER_PATH via inotify, dispatches jobs
php artisan queue:listen --tries=1 --timeout=0   # processes SendToImmichJob

Run tests:

composer run test

Environment variables

ImmichUploader/.env (not the root .env):

  • IMMICH_URL — base URL of the Immich instance (e.g. https://photos.example.com)
  • IMMICH_KEY — Immich API key
  • FOLDER_PATH — absolute path to the photos directory (matches camera/photos/)

The root .env is gitignored and only excluded camera/photos from tracking.

Architecture notes

Camera → Uploader flow:

  1. camera/main.py writes a JPEG to camera/photos/<timestamp>.jpg on /capture
  2. WatchFolder artisan command (inotify_add_watch on IN_CLOSE_WRITE | IN_MOVED_TO) detects the new file
  3. Dispatches SendToImmichJob to the database queue
  4. The queue worker runs SendToImmichJob::handle() which POSTs the image to /api/assets then adds it to the hardcoded album via PUT /api/albums/{albumId}/assets

Hardcoded values in SendToImmichJob.php:

  • $albumId — Immich album ID where photos are added
  • $id (deviceAssetId) — fixed UUID used as the Immich device asset identifier

camera/ directory structure: The camera/ directory is itself a Python venv (has pyvenv.cfg), but the actual venv used by the app is camera/myenv/ (contains Flask). picamera2 is available from the system Python installation.

ImmichUploader uses SQLite (default, database/database.sqlite) for the queue, cache, and sessions — no separate database process needed.