MyPal / README.md
KhaledSalehKL1's picture
Add demo, repo, and X links to Space README
c07408a verified
|
Raw
History Blame Contribute Delete
4.3 kB
metadata
title: MyPal (9XAIPal)
emoji: πŸ“š
colorFrom: blue
colorTo: indigo
sdk: docker
app_port: 7860
pinned: false
license: mit

9XAIPal β€” local-first reading companion

Single-container Hugging Face Space deployment. A plain FastAPI app (app.py) mounts the real 9XAIPal backend API at /api/v1 and serves the compiled React UI at / (SPA with client-side routing) β€” all on port 7860.

Layout

Path Purpose
app.py FastAPI entrypoint (API + SPA, port 7860)
Dockerfile Builds the image; bakes in the Ollama embedder
start.sh Boot script: Redis, Ollama, then supervisord (API + Celery worker + optional local Postgres)
supervisord.conf Process supervisor config: keeps API + worker alive
requirements.txt Python dependencies
app/ 9XAIPal backend package
dist/ Compiled React UI

Links

Configuration (set as Space Secrets / Variables)

All config is read from environment variables β€” no .env file is bundled. Set these under Settings β†’ Variables and secrets:

  • OLLAMA_BASE_URL, OLLAMA_API_KEY β€” chat/VLM backend (Ollama Cloud)
  • CHAT_MODEL, VLM_MODEL β€” must match an exact tag served by your OLLAMA_BASE_URL. If the endpoint lists gemma4:31b and not gemma4:31b-cloud, set CHAT_MODEL=gemma4:31b and VLM_MODEL=gemma4:31b.
  • EMBEDDING_PROVIDER=ollama, EMBEDDING_BASE_URL=http://localhost:11434, EMBEDDING_MODEL=qwen3-embedding β€” embeddings run on the in-container Ollama (the 31B chat model lives on Ollama Cloud, which hosts no embedding models, so a small embedding model is baked into the image and served locally)
  • HF_TOKEN / HUGGING_FACE_HUB_TOKEN β€” model-weight downloads
  • Database β€” POSTGRES_HOST, POSTGRES_PORT, POSTGRES_DB, POSTGRES_USER, POSTGRES_PASSWORD, PGSSLMODE=require. The Space container disk is ephemeral, so this deployment points at an external managed Postgres (Supabase, with pgvector) so uploaded papers persist across restarts/rebuilds. Use Supabase's session-mode connection pooler host (aws-0-<region>.pooler.supabase.com:5432, user postgres.<project-ref>) β€” the direct db.<ref>.supabase.co host is IPv6-only and unreachable from the IPv4-only Space container.
  • (optional) OPENAI_API_KEY / ANTHROPIC_API_KEY / GEMINI_API_KEY / … for cloud fallback

Note: start.sh boots Redis and an in-container Ollama (for embeddings), then launches supervisord to keep the FastAPI app and a Celery worker alive. PostgreSQL runs externally (managed) whenever POSTGRES_HOST is set to a non-local host β€” the bundled in-container Postgres is started only as a fallback for local/no-external-DB runs, and its data is ephemeral. Redis here is just an ephemeral cache/queue.

PDF extraction: the image enables the PyMuPDF text-only fallback by default (ALLOW_PYMUPDF_FALLBACK=1) so uploads process immediately without baking several gigabytes of MinerU + torch into the image. For higher-fidelity output (OCR, tables, equations, figures), install mineru[pipeline]>=3.2.0, torch, torchvision, and scipy>=1.17.1 in requirements.txt and set ALLOW_PYMUPDF_FALLBACK=0 (or unset) in the Space variables.

Self-healing: the container has a Docker HEALTHCHECK on /healthz and an in-app watchdog that detects stuck ingestion jobs. If a paper hangs in queued / extracting / chunking / embedding / summarizing for too long, the watchdog revokes the stuck Celery task, cleans up partial state, and re-dispatches the job so processing completes.