Spaces:
Running
Running
gary-boon
commited on
Commit
·
96a6300
1
Parent(s):
a3e1f56
Add API key authentication
Browse files- Integrated auth.py into model_service.py endpoints
- All endpoints now require X-API-Key header when API_KEY env var is set
- Created setup instructions for HuggingFace Spaces configuration
- README.md +16 -12
- backend/model_service.py +6 -5
- setup-api-key.md +45 -0
README.md
CHANGED
@@ -2,29 +2,33 @@
|
|
2 |
title: Visualisable AI Backend
|
3 |
emoji: 🧠
|
4 |
colorFrom: blue
|
5 |
-
colorTo:
|
6 |
sdk: docker
|
7 |
pinned: false
|
8 |
---
|
9 |
|
10 |
-
# Visualisable.ai Backend
|
11 |
|
12 |
This is the backend service for Visualisable.ai, providing:
|
13 |
-
|
14 |
-
-
|
15 |
-
-
|
|
|
16 |
|
17 |
## API Endpoints
|
18 |
|
19 |
-
- `GET
|
20 |
-
- `
|
21 |
-
- `GET /model/info` -
|
|
|
22 |
- `WebSocket /ws` - Real-time trace streaming
|
23 |
|
24 |
-
##
|
25 |
|
26 |
-
|
27 |
|
28 |
-
|
|
|
|
|
29 |
|
30 |
-
|
|
|
2 |
title: Visualisable AI Backend
|
3 |
emoji: 🧠
|
4 |
colorFrom: blue
|
5 |
+
colorTo: green
|
6 |
sdk: docker
|
7 |
pinned: false
|
8 |
---
|
9 |
|
10 |
+
# Visualisable.ai Backend Service
|
11 |
|
12 |
This is the backend service for Visualisable.ai, providing:
|
13 |
+
|
14 |
+
- Real-time model inference with trace extraction
|
15 |
+
- WebSocket streaming for live visualization
|
16 |
+
- REST API for model information and generation
|
17 |
|
18 |
## API Endpoints
|
19 |
|
20 |
+
- `GET /` - Health check
|
21 |
+
- `GET /health` - Detailed health status
|
22 |
+
- `GET /model/info` - Model architecture details
|
23 |
+
- `POST /generate` - Generate text with traces
|
24 |
- `WebSocket /ws` - Real-time trace streaming
|
25 |
|
26 |
+
## Configuration
|
27 |
|
28 |
+
Set the following secrets in your Space settings:
|
29 |
|
30 |
+
- `API_KEY` (optional) - API key for authentication
|
31 |
+
|
32 |
+
## Frontend
|
33 |
|
34 |
+
The frontend is deployed separately on Vercel. Connect it by setting the backend URL in your frontend environment variables.
|
backend/model_service.py
CHANGED
@@ -3,7 +3,7 @@ Unified Model Service for Visualisable.ai
|
|
3 |
Combines model loading, generation, and trace extraction into a single service
|
4 |
"""
|
5 |
|
6 |
-
from fastapi import FastAPI, WebSocket, WebSocketDisconnect, BackgroundTasks, HTTPException
|
7 |
from fastapi.middleware.cors import CORSMiddleware
|
8 |
from pydantic import BaseModel
|
9 |
import asyncio
|
@@ -15,6 +15,7 @@ import numpy as np
|
|
15 |
import logging
|
16 |
from datetime import datetime
|
17 |
import traceback
|
|
|
18 |
|
19 |
# Configure logging
|
20 |
logging.basicConfig(level=logging.INFO)
|
@@ -440,7 +441,7 @@ async def health():
|
|
440 |
}
|
441 |
|
442 |
@app.get("/model/info")
|
443 |
-
async def model_info():
|
444 |
"""Get detailed information about the loaded model"""
|
445 |
if not manager.model:
|
446 |
raise HTTPException(status_code=503, detail="Model not loaded")
|
@@ -486,7 +487,7 @@ async def model_info():
|
|
486 |
}
|
487 |
|
488 |
@app.post("/generate")
|
489 |
-
async def generate(request: GenerationRequest):
|
490 |
"""Generate text with optional trace extraction"""
|
491 |
result = await manager.generate_with_traces(
|
492 |
prompt=request.prompt,
|
@@ -497,7 +498,7 @@ async def generate(request: GenerationRequest):
|
|
497 |
return result
|
498 |
|
499 |
@app.get("/demos")
|
500 |
-
async def list_demos():
|
501 |
"""List available demo prompts"""
|
502 |
return {
|
503 |
"demos": [
|
@@ -529,7 +530,7 @@ async def list_demos():
|
|
529 |
}
|
530 |
|
531 |
@app.post("/demos/run")
|
532 |
-
async def run_demo(request: DemoRequest):
|
533 |
"""Run a specific demo"""
|
534 |
demos = {
|
535 |
"fibonacci": "def fibonacci(n):\n '''Calculate fibonacci number'''",
|
|
|
3 |
Combines model loading, generation, and trace extraction into a single service
|
4 |
"""
|
5 |
|
6 |
+
from fastapi import FastAPI, WebSocket, WebSocketDisconnect, BackgroundTasks, HTTPException, Depends
|
7 |
from fastapi.middleware.cors import CORSMiddleware
|
8 |
from pydantic import BaseModel
|
9 |
import asyncio
|
|
|
15 |
import logging
|
16 |
from datetime import datetime
|
17 |
import traceback
|
18 |
+
from .auth import verify_api_key
|
19 |
|
20 |
# Configure logging
|
21 |
logging.basicConfig(level=logging.INFO)
|
|
|
441 |
}
|
442 |
|
443 |
@app.get("/model/info")
|
444 |
+
async def model_info(authenticated: bool = Depends(verify_api_key)):
|
445 |
"""Get detailed information about the loaded model"""
|
446 |
if not manager.model:
|
447 |
raise HTTPException(status_code=503, detail="Model not loaded")
|
|
|
487 |
}
|
488 |
|
489 |
@app.post("/generate")
|
490 |
+
async def generate(request: GenerationRequest, authenticated: bool = Depends(verify_api_key)):
|
491 |
"""Generate text with optional trace extraction"""
|
492 |
result = await manager.generate_with_traces(
|
493 |
prompt=request.prompt,
|
|
|
498 |
return result
|
499 |
|
500 |
@app.get("/demos")
|
501 |
+
async def list_demos(authenticated: bool = Depends(verify_api_key)):
|
502 |
"""List available demo prompts"""
|
503 |
return {
|
504 |
"demos": [
|
|
|
530 |
}
|
531 |
|
532 |
@app.post("/demos/run")
|
533 |
+
async def run_demo(request: DemoRequest, authenticated: bool = Depends(verify_api_key)):
|
534 |
"""Run a specific demo"""
|
535 |
demos = {
|
536 |
"fibonacci": "def fibonacci(n):\n '''Calculate fibonacci number'''",
|
setup-api-key.md
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# API Key Setup Instructions
|
2 |
+
|
3 |
+
## Generated API Key
|
4 |
+
```
|
5 |
+
c5fd7c64cf05a6cbfae3a8cdc4edb25fa4735b324489776fdcf114aefba12748
|
6 |
+
```
|
7 |
+
|
8 |
+
## Steps to Add to HuggingFace Spaces:
|
9 |
+
|
10 |
+
1. Go to your HuggingFace Space: https://huggingface.co/spaces/garyboon/visualisable-ai-backend
|
11 |
+
2. Click on "Settings" (gear icon) in the top right
|
12 |
+
3. Scroll down to "Repository secrets"
|
13 |
+
4. Click "New secret"
|
14 |
+
5. Add:
|
15 |
+
- Name: `API_KEY`
|
16 |
+
- Value: `c5fd7c64cf05a6cbfae3a8cdc4edb25fa4735b324489776fdcf114aefba12748`
|
17 |
+
6. Click "Add new secret"
|
18 |
+
|
19 |
+
## Frontend Configuration
|
20 |
+
|
21 |
+
Add this API key to your frontend environment variables:
|
22 |
+
|
23 |
+
### For Vercel:
|
24 |
+
1. Go to your Vercel project settings
|
25 |
+
2. Navigate to Environment Variables
|
26 |
+
3. Add:
|
27 |
+
- Name: `NEXT_PUBLIC_API_KEY`
|
28 |
+
- Value: `c5fd7c64cf05a6cbfae3a8cdc4edb25fa4735b324489776fdcf114aefba12748`
|
29 |
+
|
30 |
+
### For local development:
|
31 |
+
Create `.env.local` in your frontend directory:
|
32 |
+
```
|
33 |
+
NEXT_PUBLIC_API_KEY=c5fd7c64cf05a6cbfae3a8cdc4edb25fa4735b324489776fdcf114aefba12748
|
34 |
+
NEXT_PUBLIC_API_URL=https://garyboon-visualisable-ai-backend.hf.space
|
35 |
+
```
|
36 |
+
|
37 |
+
## Testing the API Key
|
38 |
+
|
39 |
+
Once configured, test with:
|
40 |
+
```bash
|
41 |
+
curl -H "X-API-Key: c5fd7c64cf05a6cbfae3a8cdc4edb25fa4735b324489776fdcf114aefba12748" \
|
42 |
+
https://garyboon-visualisable-ai-backend.hf.space/health
|
43 |
+
```
|
44 |
+
|
45 |
+
Should return the health status if the key is correctly configured.
|