| --- |
| title: Internal Portal API |
| emoji: π’ |
| colorFrom: indigo |
| colorTo: blue |
| sdk: docker |
| app_port: 7860 |
| pinned: false |
| --- |
| |
| # Internal Portal API (backend) |
|
|
| FastAPI backend for the internal portal chat app. Provides domain/project |
| management, a chat endpoint backed by **DeepSeek**, and an HR assistant grounded |
| in uploaded documents. |
|
|
| ## Deploy on Hugging Face Spaces |
|
|
| 1. Create a new Space β **Docker** SDK. |
| 2. Push the contents of this `backend/` folder to the Space repo (this README's |
| YAML header configures the Space; `app_port: 7860` matches the Dockerfile). |
| 3. In **Settings β Variables and secrets**, add: |
| - `DEEPSEEK_API_KEY` (secret) β your DeepSeek key |
| - `DEEPSEEK_MODEL` β your exact model id (e.g. the "v4 flash" model string) |
| - `DEEPSEEK_BASE_URL` β optional, defaults to `https://api.deepseek.com` |
| - `ALLOWED_ORIGINS` β your Vercel URL, e.g. `https://your-app.vercel.app` |
| (defaults to `*` for easy first testing) |
| 4. The Space builds and serves at `https://<user>-<space>.hf.space`. |
| |
| Check it's up: `GET https://<space-url>/api/health` β |
| `{"ok": true, "llm_configured": true, "model": "..."}`. |
|
|
| ## Run locally |
|
|
| ```bash |
| cd webapp/backend |
| python -m venv .venv && source .venv/bin/activate |
| pip install -r requirements.txt |
| export DEEPSEEK_API_KEY=sk-... # your key |
| export DEEPSEEK_MODEL=deepseek-chat # or your "v4 flash" model id |
| uvicorn app.main:app --reload --port 7860 |
| ``` |
|
|
| Then open http://localhost:7860 β the backend also serves the static frontend |
| from `../frontend` for convenience, so you can test the whole app from one |
| process locally. |
|
|
| ## Storage note |
|
|
| Data is persisted to a JSON file under `DATA_DIR` (`/data` in Docker). **A free |
| HF Space's disk is ephemeral** β it resets on rebuild/restart. That's fine for |
| development and demos. When durable storage is needed, the `store.py` layer is |
| swappable for a real database without changing the rest of the app. |
|
|