ProfessorCEO commited on
Commit
0fc9402
·
verified ·
1 Parent(s): d7d7b4d

Cool Shot Systems

Browse files
Files changed (5) hide show
  1. Dockerfile (1).txt +31 -0
  2. README (4).md +77 -0
  3. auth.py +61 -0
  4. main.py +74 -0
  5. requirements.txt +5 -0
Dockerfile (1).txt ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.11-slim
2
+
3
+ # Set environment variables
4
+ ENV PYTHONDONTWRITEBYTECODE=1
5
+ ENV PYTHONUNBUFFERED=1
6
+
7
+ # Create non-root user for security
8
+ RUN useradd -m -u 1000 appuser
9
+
10
+ WORKDIR /app
11
+
12
+ # Install dependencies first for better caching
13
+ COPY requirements.txt .
14
+ RUN pip install --no-cache-dir --upgrade pip && \
15
+ pip install --no-cache-dir -r requirements.txt
16
+
17
+ # Copy application code
18
+ COPY --chown=appuser:appuser . .
19
+
20
+ # Switch to non-root user
21
+ USER appuser
22
+
23
+ # Hugging Face Spaces runs on port 7860 by default
24
+ EXPOSE 7860
25
+
26
+ # Health check
27
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
28
+ CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:7860/health')" || exit 1
29
+
30
+ # Run the application
31
+ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
README (4).md ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Text Prediction API
3
+ emoji: 📝
4
+ colorFrom: blue
5
+ colorTo: indigo
6
+ sdk: docker
7
+ pinned: false
8
+ license: mit
9
+ app_port: 7860
10
+ ---
11
+
12
+ # Text Prediction API
13
+
14
+ AI-powered text prediction service built with FastAPI.
15
+
16
+ ## Features
17
+
18
+ - 🔐 **Secure Authentication** - JWT Bearer token verification
19
+ - 🚀 **Fast Performance** - Built on FastAPI with async support
20
+ - 📊 **Health Monitoring** - Built-in health check endpoint
21
+ - 🐳 **Docker Ready** - Optimized for Hugging Face Spaces deployment
22
+
23
+ ## API Endpoints
24
+
25
+ ### Health Check
26
+ ```
27
+ GET /health
28
+ ```
29
+ Returns the service health status.
30
+
31
+ ### Prediction
32
+ ```
33
+ POST /predict
34
+ Authorization: Bearer <token>
35
+ Content-Type: application/json
36
+
37
+ {
38
+ "text": "Your input text here"
39
+ }
40
+ ```
41
+
42
+ **Response:**
43
+ ```json
44
+ {
45
+ "prediction": "Processed: Your input text here",
46
+ "confidence": 0.95,
47
+ "input_text": "Your input text here"
48
+ }
49
+ ```
50
+
51
+ ## Environment Variables
52
+
53
+ | Variable | Description | Required |
54
+ |----------|-------------|----------|
55
+ | `JWT_SECRET` | Secret key for JWT token verification | Yes |
56
+ | `ALLOWED_ORIGINS` | Comma-separated list of allowed CORS origins | No |
57
+
58
+ ## Local Development
59
+
60
+ ```bash
61
+ # Install dependencies
62
+ pip install -r requirements.txt
63
+
64
+ # Set environment variables
65
+ export JWT_SECRET=your_secret_key
66
+
67
+ # Run the server
68
+ uvicorn main:app --reload --port 8001
69
+ ```
70
+
71
+ ## Deployment
72
+
73
+ This service is designed to run on Hugging Face Spaces with Docker SDK.
74
+
75
+ 1. Create a new Space with Docker SDK
76
+ 2. Set the `JWT_SECRET` secret in Space settings
77
+ 3. Push this code to the Space repository
auth.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from fastapi import Depends, HTTPException, status
3
+ from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
4
+ from jose import jwt, JWTError
5
+
6
+ security = HTTPBearer()
7
+
8
+ def get_jwt_secret() -> str:
9
+ """Get JWT secret from environment variable."""
10
+ secret = os.getenv("JWT_SECRET")
11
+ if not secret:
12
+ raise HTTPException(
13
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
14
+ detail="JWT_SECRET not configured"
15
+ )
16
+ return secret
17
+
18
+
19
+ def verify_token(credentials: HTTPAuthorizationCredentials = Depends(security)) -> dict:
20
+ """
21
+ Verify Bearer token signature.
22
+ Returns the decoded token payload if valid.
23
+ Raises HTTPException if invalid.
24
+ """
25
+ token = credentials.credentials
26
+ jwt_secret = get_jwt_secret()
27
+
28
+ try:
29
+ # Decode and verify the JWT token
30
+ payload = jwt.decode(
31
+ token,
32
+ jwt_secret,
33
+ algorithms=["HS256"],
34
+ options={"verify_aud": False} # Clerk tokens may not have standard audience
35
+ )
36
+ return payload
37
+ except JWTError as e:
38
+ raise HTTPException(
39
+ status_code=status.HTTP_401_UNAUTHORIZED,
40
+ detail=f"Invalid token: {str(e)}",
41
+ headers={"WWW-Authenticate": "Bearer"},
42
+ )
43
+
44
+
45
+ def get_current_user(token_payload: dict = Depends(verify_token)) -> dict:
46
+ """
47
+ Extract user information from verified token.
48
+ """
49
+ user_id = token_payload.get("sub")
50
+ if not user_id:
51
+ raise HTTPException(
52
+ status_code=status.HTTP_401_UNAUTHORIZED,
53
+ detail="Invalid token: missing user ID",
54
+ headers={"WWW-Authenticate": "Bearer"},
55
+ )
56
+
57
+ return {
58
+ "user_id": user_id,
59
+ "email": token_payload.get("email"),
60
+ "claims": token_payload
61
+ }
main.py ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ from fastapi import FastAPI, Depends, HTTPException
4
+ from fastapi.middleware.cors import CORSMiddleware
5
+ from pydantic import BaseModel
6
+ from auth import get_current_user
7
+
8
+ app = FastAPI(
9
+ title="Text Prediction API",
10
+ description="AI-powered text prediction service",
11
+ version="0.1.0"
12
+ )
13
+
14
+ # Configure CORS - use environment variable for allowed origins in production
15
+ allowed_origins = os.getenv("ALLOWED_ORIGINS", "").split(",") if os.getenv("ALLOWED_ORIGINS") else ["*"]
16
+
17
+ app.add_middleware(
18
+ CORSMiddleware,
19
+ allow_origins=allowed_origins,
20
+ allow_credentials=False,
21
+ allow_methods=["*"],
22
+ allow_headers=["*"],
23
+ )
24
+
25
+
26
+ class TextPredictRequest(BaseModel):
27
+ text: str
28
+
29
+
30
+ class TextPredictResponse(BaseModel):
31
+ prediction: str
32
+ confidence: float
33
+ input_text: str
34
+
35
+
36
+ @app.get("/")
37
+ async def root():
38
+ """Health check endpoint."""
39
+ return {"status": "healthy", "service": "text-api"}
40
+
41
+
42
+ @app.get("/health")
43
+ async def health():
44
+ """Health check endpoint."""
45
+ return {"status": "healthy"}
46
+
47
+
48
+ @app.post("/predict", response_model=TextPredictResponse)
49
+ async def predict(
50
+ request: TextPredictRequest,
51
+ current_user: dict = Depends(get_current_user)
52
+ ):
53
+ """
54
+ Protected endpoint for text prediction.
55
+ Requires valid Bearer token.
56
+ """
57
+ # Placeholder prediction logic
58
+ # In a real application, this would call an ML model
59
+ text = request.text
60
+
61
+ # Simple mock prediction
62
+ prediction = f"Processed: {text[:50]}..." if len(text) > 50 else f"Processed: {text}"
63
+ confidence = 0.95
64
+
65
+ return TextPredictResponse(
66
+ prediction=prediction,
67
+ confidence=confidence,
68
+ input_text=text
69
+ )
70
+
71
+
72
+ if __name__ == "__main__":
73
+ import uvicorn
74
+ uvicorn.run(app, host="0.0.0.0", port=8001)
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ fastapi>=0.109.0
2
+ uvicorn>=0.27.0
3
+ python-jose[cryptography]>=3.3.0
4
+ httpx>=0.26.0
5
+ pydantic>=2.5.0