alaselababatunde commited on
Commit
8f057f3
·
1 Parent(s): 2f0d434
Files changed (3) hide show
  1. Dockerfile +34 -0
  2. app.py +115 -0
  3. requirements.txt +4 -0
Dockerfile ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ==============================================================
2
+ # Tech Disciples AI Backend — Dockerfile
3
+ # ==============================================================
4
+
5
+ # Use lightweight official Python image
6
+ FROM python:3.11-slim
7
+
8
+ # Set environment variables
9
+ ENV PYTHONDONTWRITEBYTECODE=1 \
10
+ PYTHONUNBUFFERED=1 \
11
+ APP_HOME=/app
12
+
13
+ # Set work directory
14
+ WORKDIR $APP_HOME
15
+
16
+ # System dependencies
17
+ RUN apt-get update && apt-get install -y \
18
+ git \
19
+ && rm -rf /var/lib/apt/lists/*
20
+
21
+ # Copy requirement file first (for caching)
22
+ COPY requirements.txt .
23
+
24
+ # Install Python dependencies
25
+ RUN pip install --no-cache-dir -r requirements.txt
26
+
27
+ # Copy application files
28
+ COPY . .
29
+
30
+ # Expose port for FastAPI
31
+ EXPOSE 8000
32
+
33
+ # Run the FastAPI app with Uvicorn
34
+ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
app.py ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ==============================================================
2
+ # Tech Disciples AI Backend — Optimized Stable Release
3
+ # ==============================================================
4
+
5
+ import os
6
+ import logging
7
+ import torch
8
+ from fastapi import FastAPI, Request, Header, HTTPException
9
+ from fastapi.responses import JSONResponse
10
+ from pydantic import BaseModel
11
+ from transformers import pipeline
12
+
13
+ # ==============================================================
14
+ # Logging Setup
15
+ # ==============================================================
16
+ logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
17
+ logger = logging.getLogger("Tech Disciples AI")
18
+
19
+ # ==============================================================
20
+ # FastAPI App Initialization
21
+ # ==============================================================
22
+ app = FastAPI(title="Tech Disciples AI")
23
+
24
+ @app.get("/")
25
+ async def root():
26
+ return {"status": "Tech Disciples AI Backend is running and stable."}
27
+
28
+ # ==============================================================
29
+ # Authentication Configuration
30
+ # ==============================================================
31
+ PROJECT_API_KEY = os.getenv("PROJECT_API_KEY", "techdisciplesai404")
32
+
33
+ def check_auth(authorization: str | None):
34
+ """Validates Bearer token for authorized access."""
35
+ if not PROJECT_API_KEY:
36
+ return
37
+ if not authorization or not authorization.startswith("Bearer "):
38
+ raise HTTPException(status_code=401, detail="Missing bearer token")
39
+ token = authorization.split(" ", 1)[1]
40
+ if token != PROJECT_API_KEY:
41
+ raise HTTPException(status_code=403, detail="Invalid token")
42
+
43
+ # ==============================================================
44
+ # Global Exception Handler
45
+ # ==============================================================
46
+ @app.exception_handler(Exception)
47
+ async def global_exception_handler(request: Request, exc: Exception):
48
+ logger.error(f"Unhandled error: {exc}")
49
+ return JSONResponse(status_code=500, content={"error": str(exc)})
50
+
51
+ # ==============================================================
52
+ # Request Models
53
+ # ==============================================================
54
+ class ChatRequest(BaseModel):
55
+ query: str
56
+
57
+ # ==============================================================
58
+ # Hugging Face Configuration
59
+ # ==============================================================
60
+ HF_TOKEN = os.getenv("HUGGINGFACEHUB_API_TOKEN")
61
+
62
+ if not HF_TOKEN:
63
+ logger.warning("⚠️ No Hugging Face token found. Some gated models may fail to load.")
64
+ else:
65
+ logger.info("✅ Hugging Face token detected.")
66
+
67
+ # Device selection
68
+ device = 0 if torch.cuda.is_available() else -1
69
+ logger.info(f"🧠 Using device: {'GPU' if device == 0 else 'CPU'}")
70
+
71
+ # ==============================================================
72
+ # Model Pipeline Initialization
73
+ # ==============================================================
74
+ try:
75
+ chat_pipe = pipeline(
76
+ "text-generation",
77
+ model="mradermacher/Baptist-Christian-Bible-Expert-v2.0-12B-i1-GGUF",
78
+ token=HF_TOKEN,
79
+ device=device,
80
+ )
81
+ logger.info("✅ Conversational model successfully loaded.")
82
+ except Exception as e:
83
+ chat_pipe = None
84
+ logger.error(f"❌ Failed to load model pipeline: {e}")
85
+
86
+ # ==============================================================
87
+ # Helper Functions
88
+ # ==============================================================
89
+ def run_conversational(pipe, prompt: str) -> str:
90
+ """Executes text generation safely and returns formatted output."""
91
+ if not pipe:
92
+ return "⚠️ Model pipeline not initialized."
93
+
94
+ try:
95
+ output = pipe(prompt, max_new_tokens=200, temperature=0.3, do_sample=True)
96
+ if isinstance(output, list) and output:
97
+ return output[0].get("generated_text", str(output))
98
+ return str(output)
99
+ except Exception as e:
100
+ logger.error(f"Conversational pipeline error: {e}")
101
+ return f"⚠️ Model error: {e}"
102
+
103
+ # ==============================================================
104
+ # API Endpoints
105
+ # ==============================================================
106
+ @app.post("/ai-chat")
107
+ async def ai_chat(req: ChatRequest, authorization: str | None = Header(None)):
108
+ """Handles conversational AI chat requests."""
109
+ check_auth(authorization)
110
+ reply = run_conversational(chat_pipe, req.query)
111
+ return {"reply": reply}
112
+
113
+ # ==============================================================
114
+ # END OF FILE
115
+ # ==============================================================
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ fastapi
2
+ uvicorn[standard]
3
+ torch
4
+ transformers