ChAiMa — Chemical AI Manager
Inventory management for laboratory chemicals: track containers, locations, hazard (GHS/H&P) statements, orders, and group-scoped access — with optional AI label OCR (Gemini) to create containers from a photo.
- API + web UI: FastAPI backend serving a bundled frontend.
- Auth: user accounts, groups, invites (fastapi-users).
- Data: SQLite by default; Postgres supported via a single env var.
Install
From PyPI:
pip install chaima
Or with uv:
uv tool install chaima
Then run the server (binds localhost by default):
chaima run # http://127.0.0.1:8000
chaima run --host 0.0.0.0 # expose on the network
chaima db upgrade head # apply database migrations
Configuration is read from environment variables (prefix CHAIMA_) or a .env
file. Copy .env.example to .env and fill in the values — at minimum set a
real CHAIMA_SECRET_KEY and CHAIMA_ADMIN_PASSWORD before exposing the app.
Docker
The published image is ghcr.io/kirewx/chaima. Database and uploads persist on
the /data volume. Migrations run automatically on container start.
LAN / HTTP (homeserver test)
git clone https://github.com/kirewx/chaima && cd chaima
cp .env.example .env
# Edit .env: set CHAIMA_SECRET_KEY, CHAIMA_ADMIN_PASSWORD, CHAIMA_COOKIE_SECURE=false
docker compose up -d
The app is served on http://<host>:8000. A watchtower container polls GHCR
and auto-updates ChAiMa whenever a new :latest image is published (i.e. on
every push to main). The GHCR package must be public, or Watchtower needs
registry credentials.
Public demo with HTTPS (Caddy)
Set CHAIMA_DOMAIN in .env (and CHAIMA_COOKIE_SECURE=true,
CHAIMA_REQUIRE_SECURE_CONFIG=true), point DNS at the host, open ports 80/443,
then:
docker compose -f docker-compose.yml -f docker-compose.caddy.yml up -d
Caddy obtains and renews a Let's Encrypt certificate automatically.
If the host is behind CGNAT or blocks inbound 80/443, Let's Encrypt can't validate. Use a Cloudflare Tunnel instead — point it at
chaima:8000and drop the Caddy overlay.
Configuration
All variables are prefixed CHAIMA_. See .env.example for the full list.
| Variable | Purpose | Default |
|---|---|---|
CHAIMA_SECRET_KEY |
JWT/login signing key — set a random private value | insecure placeholder |
CHAIMA_ADMIN_EMAIL |
Initial superuser, seeded on first start | admin@example.com |
CHAIMA_ADMIN_PASSWORD |
Initial superuser password | changeme |
CHAIMA_REQUIRE_SECURE_CONFIG |
Refuse to start with default secret/password | false |
CHAIMA_COOKIE_SECURE |
Mark auth cookies HTTPS-only | true |
CHAIMA_DATABASE_URL |
DB URL (SQLite or postgresql+asyncpg://…) |
local SQLite |
CHAIMA_PUBLIC_BASE_URL |
Base URL for invite links | window origin |
CHAIMA_DOMAIN |
Domain for the Caddy overlay | empty |
CHAIMA_GEMINI_API_KEY |
Google AI key for label OCR (optional) | empty (feature off) |
CHAIMA_GEMINI_MODEL |
Gemini model for OCR | gemini-2.5-flash |
To use Postgres instead of SQLite, set e.g.
CHAIMA_DATABASE_URL=postgresql+asyncpg://user:pass@db:5432/chaima (and add a
db service to the compose file).
Development
uv sync # install deps
uv run uvicorn chaima.app:app --reload # dev server with auto-reload
uv run pytest # run the test suite
Migrations:
uv run alembic upgrade head # apply
uv run alembic revision --autogenerate -m "description" # generate
The frontend lives in frontend/ and is built automatically during the package
build (bun/npm via hatch_build.py).
License
See LICENSE.
Metadata
Release files for chaima 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| chaima-0.2.0.tar.gz | 788.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| chaima-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.2 MB
Release files / chaima-0.2.0.tar.gz
| Download URL | chaima-0.2.0.tar.gz |
|---|---|
| Size | 788.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3ffe641270f26affaf425454634f73fb2e7253f6552ceb69b150c04d1cd6142a
|
|
BLAKE2b-256 checksum How to use checksums |
e89e044fb8409d98162cb7718133c318503ae00bb53dbd8e5938a2c1d580ff29
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 9, 2026.
Transparency logRelease files / chaima-0.2.0-py3-none-any.whl
| Download URL | chaima-0.2.0-py3-none-any.whl |
|---|---|
| Size | 412.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
87028bd20f1c1982ee9a9e569e6212eaa9b4a657ed272f2b32d064c3f5251e01
|
|
BLAKE2b-256 checksum How to use checksums |
2f83e2689f31a4a26df214abcd7d98fed4b0aef1eed1d6b9a1d2c55f9c7db993
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 9, 2026.
Transparency log