ReliefLensDemo / README.md
IngSeb0's picture
Add Hugging Face Space Docker metadata
1fabaeb
|
Raw
History Blame Contribute Delete
12.9 kB
metadata
title: ReliefLens AI
emoji: 🚨
colorFrom: red
colorTo: blue
sdk: docker
app_port: 7860
pinned: false

ReliefLens AI

ReliefLens AI is a multimodal, human-in-the-loop emergency triage demo built for the AMD Developer Hackathon. It accepts public field evidence such as text, image uploads, optional audio, browser location, map-selected location, and textual place references, then produces prioritized incidents with recommended resources, location confidence, and operational explanations.

Public demo

  • Hugging Face Space frontend: https://lablab-ai-amd-developer-hackathon-relieflens-frontend.hf.space
  • AMD FastAPI backend: http://129.212.185.232:8080

Application routes

  • Public portal: /emergencies
  • Private admin: /admin
  • Admin login: /admin/login
  • Admin incident queue: /admin/incidents
  • Admin incident detail: /admin/incidents/[id]
  • Admin telemetry: /admin/telemetry

The public portal is limited to evidence submission and public-safe confirmation details. Sensitive incident management stays behind authenticated admin routes.

What the system does

  • Ingests image, text, optional audio, and location hints
  • Resolves location from the best available source without inventing exact coordinates
  • Produces prioritized incidents with severity, findings, and recommended resources
  • Separates public intake from private incident management
  • Shows admin telemetry for backend health and AMD demo metrics

Location resolution

ReliefLens does not pretend that a photo alone can reveal exact location. Location is resolved in this order:

  1. Browser geolocation, if the user shares it
  2. Manual map click, if the user selects or corrects a point
  3. Image GPS EXIF, if present
  4. Textual location hints such as Santa Ana
  5. Location requires human review when evidence is insufficient

If there is no browser location, no map point, no EXIF GPS, and no usable text location, the incident stays unresolved and requires human review.

Evidence intake behavior

The public /emergencies portal supports:

  • image upload
  • optional audio recording or upload
  • What is happening?
  • Where is this happening?
  • Use my current location
  • map click to adjust or set location
  • Analyze Evidence

Current behavior uses deterministic, rule-based fallback analysis:

  • text, filenames, and location hints drive incident classification
  • audio files are accepted but returned as received_not_transcribed when no ASR model is connected
  • images are inspected only for metadata and optional EXIF GPS
  • the system does not claim real vision inference unless a model is explicitly connected later

Qwen-powered incident analysis

Rescue Evidence Intelligence can analyze submitted evidence with a Qwen model through an OpenAI-compatible API.

Required backend variables:

  • QWEN_BASE_URL
  • QWEN_API_KEY
  • QWEN_MODEL
  • QWEN_ENABLED

Behavior:

  • if QWEN_ENABLED=false, the backend uses the existing rule-based fallback classifier
  • if QWEN_ENABLED=true, the backend attempts Qwen analysis first
  • if the model server times out, returns malformed JSON, or is unavailable, the backend falls back to rule_based_fallback
  • the frontend never receives the API key

The admin dashboard shows:

  • incident type
  • severity
  • confidence
  • detected risks
  • evidence summary
  • recommended resources
  • requires human review
  • analysis provider: qwen or rule_based_fallback

Admin incident management

Authenticated admins can:

  • sign in through /admin/login
  • review the full incident queue
  • inspect detailed evidence metadata
  • update incident status, review state, notes, and assigned team
  • inspect backend and AMD telemetry

Required backend environment variables:

  • ADMIN_USERNAME
  • ADMIN_PASSWORD
  • ADMIN_TOKEN_SECRET
  • ADMIN_TOKEN_EXPIRE_MINUTES

These values must stay on the backend. Do not expose them through NEXT_PUBLIC_* variables or commit secrets to git.

Safety

  • Synthetic demo data only
  • Human-in-the-loop required
  • Not connected to emergency services
  • Not for real-world dispatch
  • AI suggestions are advisory only

Security limitations

  • The hackathon MVP uses bearer token authentication for /api/admin/*
  • The frontend stores the admin access token in sessionStorage
  • This is acceptable for the demo, but production should use HTTPS end-to-end and secure HttpOnly cookies
  • Admin credentials must be configured from backend environment variables, not frontend code

Architecture

Local development:

Next.js frontend -> /backend rewrite proxy -> FastAPI backend

Hugging Face Space deployment:

Hugging Face Docker Space -> nginx on :7860 -> Next.js frontend -> AMD FastAPI backend -> AMD Qwen OpenAI-compatible endpoint

The browser does not call localhost:8080, 127.0.0.1:8080, the AMD FastAPI public IP, or the AMD Qwen endpoint directly from client-side code. Local frontend requests use /backend. The Hugging Face Space build uses same-origin /api, which nginx proxies to the AMD FastAPI backend at runtime.

Backend endpoints

  • GET /health
  • GET /api/demo/incidents
  • GET /api/demo/scenario
  • POST /api/demo/run
  • POST /api/evidence/intake
  • GET /api/evidence/status/{tracking_code}
  • POST /api/demo/analyze-image
  • POST /api/admin/login
  • GET /api/admin/me
  • GET /api/admin/incidents
  • GET /api/admin/incidents/{incident_id}
  • PATCH /api/admin/incidents/{incident_id}
  • GET /api/admin/telemetry
  • GET /api/amd/performance

Local development

Backend

cd backend
set ADMIN_USERNAME=admin
set ADMIN_PASSWORD=admin123
set ADMIN_TOKEN_SECRET=local-dev-secret-change-me
set ADMIN_TOKEN_EXPIRE_MINUTES=720
set QWEN_ENABLED=false
python -m pytest tests -v
python -m uvicorn main:app --host 0.0.0.0 --port 8080 --reload

Run locally with Qwen disabled:

  • keep QWEN_ENABLED=false
  • the backend will use the rule-based fallback pipeline

Run locally with Qwen through vLLM or another OpenAI-compatible server:

cd backend
set QWEN_BASE_URL=http://127.0.0.1:8000/v1
set QWEN_API_KEY=token-abc123
set QWEN_MODEL=Qwen/Qwen2.5-7B-Instruct
set QWEN_ENABLED=true
python -m uvicorn main:app --host 0.0.0.0 --port 8080 --reload

Frontend

cd frontend
npm install
npm run build
npm run dev

Local frontend environment file:

NEXT_PUBLIC_API_URL=/backend
NEXT_PUBLIC_API_BASE_URL=/backend
NEXT_PUBLIC_BACKEND_URL=/backend
BACKEND_ORIGIN=http://localhost:8080

Local proxy checks:

  • http://localhost:3000/backend/health
  • http://localhost:3000/admin/login

Local admin login test credentials:

  • username: admin
  • password: admin123

Deployment to AMD Cloud

Recommended topology:

  • AMD VM: FastAPI backend on :8080
  • AMD VM: external Qwen OpenAI-compatible endpoint on :8000
  • Hugging Face Space: public container on :7860

On the AMD VM:

git clone https://github.com/<your-org-or-user>/ReliefLensAI.git
cd ReliefLensAI
bash scripts/deploy_backend_amd.sh
cp backend/.env.example backend/.env

Edit backend/.env for your VM. Minimum values:

APP_ENV=production
DEBUG=false
DEMO_MODE=false
STORAGE_PATH=./data
CORS_ORIGINS=https://YOUR_SPACE.hf.space

QWEN_ENABLED=true
QWEN_BASE_URL=http://127.0.0.1:8000/v1
QWEN_API_KEY=amd-qwen-demo-key
QWEN_MODEL=Qwen/Qwen2-7B-Instruct

ADMIN_USERNAME=admin
ADMIN_PASSWORD=admin123
ADMIN_TOKEN_SECRET=relieflens-demo-secret-change-this
ADMIN_TOKEN_EXPIRE_MINUTES=720

Then start the backend:

bash scripts/start_backend_amd.sh
curl http://127.0.0.1:8080/health
curl http://129.212.185.232:8080/health

If Qwen is running separately on the same VM, verify it first:

curl http://127.0.0.1:8000/v1/models -H "Authorization: Bearer amd-qwen-demo-key"

Deployment to Hugging Face Docker Space

The repository now includes a root Dockerfile for a single Hugging Face Docker Space container.

Container behavior:

  • Next.js frontend runs internally on 127.0.0.1:3000
  • nginx exposes only port 7860
  • / routes to the Next.js frontend
  • /api/* routes to the AMD FastAPI backend via BACKEND_ORIGIN
  • /health routes to ${BACKEND_ORIGIN}/health

Public browser behavior:

  • the browser calls same-origin /api in the Hugging Face Space build
  • no Qwen secret is exposed to the frontend bundle
  • the Space does not call Qwen directly
  • Qwen credentials stay only on the AMD backend environment

Space variables:

  • NEXT_PUBLIC_API_URL=/api
  • NEXT_PUBLIC_API_BASE_URL=/api
  • NEXT_PUBLIC_BACKEND_URL=/api
  • BACKEND_ORIGIN=http://129.212.185.232:8080

Do not put QWEN_API_KEY, admin credentials, or token secrets in any NEXT_PUBLIC_* variable or Hugging Face frontend variable.

Build and push flow:

  1. Push this repository to the Hugging Face Space repo.
  2. Configure the Space variables above.
  3. Wait for the Docker build to finish.
  4. Test:
    • https://YOUR_SPACE.hf.space/health
    • https://YOUR_SPACE.hf.space/api/demo/incidents
    • https://YOUR_SPACE.hf.space/emergencies

The Space container uses the root Dockerfile and serves the full app on port 7860.

Deployment flow:

  1. Create a Docker Space on Hugging Face.
  2. Push this repository root to the Space repository.
  3. Configure these Variables:
    • NEXT_PUBLIC_API_URL=/api
    • NEXT_PUBLIC_API_BASE_URL=/api
    • NEXT_PUBLIC_BACKEND_URL=/api
    • BACKEND_ORIGIN=http://129.212.185.232:8080
  4. Wait for the Docker build.
  5. Validate:
    • https://YOUR_SPACE.hf.space/health
    • https://YOUR_SPACE.hf.space/api/demo/incidents
    • https://YOUR_SPACE.hf.space/admin/login

Hugging Face Space + AMD Qwen Deployment

This deployment mode keeps both Qwen and FastAPI on AMD infrastructure while Hugging Face hosts only the public UI and reverse proxy.

Architecture:

Hugging Face Docker Space -> nginx on :7860 -> Next.js on :3000 -> AMD FastAPI on :8080 -> AMD Qwen OpenAI-compatible endpoint

Required AMD backend runtime variables:

  • QWEN_ENABLED=true
  • QWEN_BASE_URL=http://127.0.0.1:8000/v1
  • QWEN_MODEL=Qwen/Qwen2-7B-Instruct
  • QWEN_API_KEY=amd-qwen-demo-key

Required Hugging Face Space variables:

  • NEXT_PUBLIC_API_URL=/api
  • NEXT_PUBLIC_API_BASE_URL=/api
  • NEXT_PUBLIC_BACKEND_URL=/api
  • BACKEND_ORIGIN=http://129.212.185.232:8080

Optional local Docker smoke test before pushing to Hugging Face:

docker build -t relieflens-space .
docker run --rm -p 7860:7860 \
  -e NEXT_PUBLIC_API_URL=/api \
  -e NEXT_PUBLIC_API_BASE_URL=/api \
  -e NEXT_PUBLIC_BACKEND_URL=/api \
  -e BACKEND_ORIGIN=http://129.212.185.232:8080 \
  relieflens-space

Then test:

  • http://localhost:7860/health
  • http://localhost:7860/api/demo/incidents
  • http://localhost:7860/admin/login

Final deployment checklist

  1. Verify Qwen on AMD:
    • curl http://127.0.0.1:8000/v1/models -H "Authorization: Bearer amd-qwen-demo-key"
  2. Start AMD backend:
    • bash scripts/start_backend_amd.sh
  3. Verify AMD backend locally:
    • curl http://127.0.0.1:8080/health
  4. Verify AMD backend publicly:
    • curl http://129.212.185.232:8080/health
  5. Configure Hugging Face Space variables:
    • NEXT_PUBLIC_API_URL=/api
    • NEXT_PUBLIC_API_BASE_URL=/api
    • NEXT_PUBLIC_BACKEND_URL=/api
    • BACKEND_ORIGIN=http://129.212.185.232:8080
  6. Push to a new Docker Space.
  7. Test:
    • https://SPACE.hf.space/health
    • https://SPACE.hf.space/api/demo/incidents
    • https://SPACE.hf.space/emergencies
  8. Submit the seeded flood report and verify the admin dashboard shows analysis_provider=qwen.

Known limitations

  • Qwen analysis depends on a reachable OpenAI-compatible model server returning valid JSON
  • If Qwen is disabled or fails, the system falls back to rule-based analysis
  • Audio is accepted but not transcribed unless an ASR model is connected later
  • EXIF GPS is only available for images that actually contain GPS metadata
  • Text-location resolution is intentionally conservative and does not invent precise coordinates
  • Map clicks are user-provided hints, not verified GPS
  • Human review remains mandatory for operational use

Flood demo case

To test the seeded flood case in the admin dashboard or API, use evidence like:

  • Evidence text: A severe flash flood is affecting a residential area. Streets are partially flooded, several vehicles are stuck, and people may be trapped inside nearby buildings. Water level appears to be rising quickly after heavy rainfall.
  • Image findings: Flooded urban street, muddy water reaching residential entrances, stuck cars, people moving to higher ground.
  • Audio transcript: No audio uploaded.
  • Location: browser geolocation with confidence=0.90

Expected result:

  • incident_type=flood
  • severity=critical
  • priority=P0
  • requires_human_review=true
  • provider qwen when available, otherwise rule_based_fallback