vision.py now dispatches per-model to _call_anthropic or _call_openai -- same prompt, same schema, same cardimage.py measurements either way, only the request/response shape differs. Confirmed the existing GRADING_SCHEMA already satisfies OpenAI's strict-mode requirement (every property listed in required, additionalProperties:false at every level) with no changes. Settings gained a second axis: which server key applies now depends on the selected model's provider, and friends' personal keys are stored per provider (with a one-time migration from the old single-key localStorage slot) since a Claude key and an OpenAI key aren't interchangeable. CARD_GRADER_ADMIN_USER names one username (read from the proxy's forwarded basic-auth header) who alone may write server settings; everyone else keeps the same read-only view CARD_GRADER_LOCK used to give everyone, while still being able to set their own personal key. Deployed here as ninja_hippo. CARD_GRADER_LOCK remains the fallback when no admin is named.
31 lines
1.2 KiB
Docker
31 lines
1.2 KiB
Docker
FROM python:3.12-slim
|
|
|
|
# Logs reach `docker logs` the moment they're printed rather than whenever a
|
|
# buffer happens to flush — without this, a crash can eat the lines that
|
|
# explain it.
|
|
ENV PYTHONUNBUFFERED=1
|
|
|
|
# Only optional deps (see README) — the app itself is stdlib only.
|
|
RUN pip install --no-cache-dir anthropic openai pillow
|
|
|
|
WORKDIR /app
|
|
COPY app.py cardimage.py store.py vision.py ./
|
|
COPY static/ ./static/
|
|
|
|
# grades.db lives here; mount a volume at /data to persist it across
|
|
# container recreates and image updates.
|
|
ENV CARD_GRADER_DB_PATH=/data/grades.db
|
|
ENV PORT=8778
|
|
EXPOSE 8778
|
|
|
|
# nobody:users — Unraid's appdata convention. Running as root inside the
|
|
# container was needless: the app needs exactly one writable path (/data),
|
|
# so give it only that. The host ./data dir must be owned 99:100 to match.
|
|
USER 99:100
|
|
|
|
# python (not curl — slim image doesn't ship it) probing the app's own root.
|
|
# BASE_PATH doesn't affect this: un-prefixed paths still route normally.
|
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
|
CMD ["python3", "-c", "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://127.0.0.1:8778/', timeout=4).status == 200 else 1)"]
|
|
|
|
CMD ["python3", "app.py"]
|