saemstunes commited on
Commit
1f82b5a
·
verified ·
1 Parent(s): a69100a

Create railway_app.py

Browse files
Files changed (1) hide show
  1. railway_app.py +130 -161
railway_app.py CHANGED
@@ -1,88 +1,67 @@
1
  import os
2
- import logging
3
  from fastapi import FastAPI, HTTPException, Depends
4
  from fastapi.middleware.cors import CORSMiddleware
5
  from fastapi.responses import JSONResponse
6
  from pydantic import BaseModel
7
- import uvicorn
8
- from typing import List, Optional, Dict, Any
9
- import json
10
  import time
11
- import asyncio
12
- from contextlib import asynccontextmanager
13
- import psutil
14
- import GPUtil
15
 
16
- # Import our AI system
17
- from saems_ai_system import SaemsTunesAISystem
 
 
18
 
19
  # Configuration
20
  class Config:
 
 
 
21
  PORT = int(os.getenv("PORT", 8000))
22
- MODEL_DIR = os.getenv("MODEL_DIR", "./models")
23
- LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO")
24
- MAX_REQUEST_SIZE = int(os.getenv("MAX_REQUEST_SIZE", 1024 * 1024)) # 1MB
25
 
26
  # Request/Response models
27
  class ChatRequest(BaseModel):
28
  message: str
 
29
  conversation_id: Optional[str] = None
30
- model_profile: Optional[str] = "fast"
31
- temperature: Optional[float] = 0.7
32
- max_tokens: Optional[int] = 300
33
 
34
  class ChatResponse(BaseModel):
35
  response: str
36
- conversation_id: str
37
  processing_time: float
 
 
38
  model_used: str
39
- tokens_used: int
40
 
41
  class HealthResponse(BaseModel):
42
  status: str
43
- models_loaded: int
44
- memory_usage: float
45
- uptime: float
46
-
47
- class PerformanceStats(BaseModel):
48
- total_requests: int
49
- average_response_time: float
50
- models_available: List[str]
51
- system_health: Dict[str, Any]
52
-
53
- # Global AI system instance
54
- ai_system = None
55
-
56
- @asynccontextmanager
57
- async def lifespan(app: FastAPI):
58
- # Startup
59
- global ai_system
60
- print("🚀 INITIALIZING SAEM'S TUNES AI PRODUCTION SYSTEM")
61
-
62
- # Initialize AI system
63
- ai_system = SaemsTunesAISystem()
64
-
65
- # Load models in background
66
- async def load_models():
67
- ai_system.load_models()
68
- print("✅ MODELS LOADED SUCCESSFULLY")
69
-
70
- asyncio.create_task(load_models())
71
-
72
- yield # Application runs here
73
-
74
- # Shutdown
75
- print("🛑 SHUTTING DOWN AI SYSTEM")
76
- if ai_system:
77
- # Cleanup resources
78
- pass
79
 
80
  # Create FastAPI application
81
  app = FastAPI(
82
  title="Saem's Tunes AI API",
83
- description="Production AI API for Saem's Tunes music platform",
84
  version="1.0.0",
85
- lifespan=lifespan
 
86
  )
87
 
88
  # CORS middleware
@@ -94,131 +73,121 @@ app.add_middleware(
94
  allow_headers=["*"],
95
  )
96
 
97
- # Middleware for logging and monitoring
98
- @app.middleware("http")
99
- async def log_requests(request, call_next):
100
- start_time = time.time()
101
-
102
- response = await call_next(request)
103
-
104
- process_time = time.time() - start_time
105
- logging.info(f"{request.method} {request.url.path} - {response.status_code} - {process_time:.2f}s")
106
-
107
- response.headers["X-Process-Time"] = str(process_time)
108
- return response
109
-
110
- # Routes
111
- @app.get("/")
112
  async def root():
113
- return {
114
- "message": "Saem's Tunes AI API",
115
- "version": "1.0.0",
116
- "status": "operational",
117
- "documentation": "/docs"
118
- }
119
-
120
- @app.get("/health")
121
- async def health_check() -> HealthResponse:
122
- if not ai_system or not ai_system.models:
123
- return HealthResponse(
124
- status="initializing",
125
- models_loaded=0,
126
- memory_usage=psutil.virtual_memory().percent,
127
- uptime=time.time() - start_time
128
- )
129
 
130
  return HealthResponse(
131
  status="healthy",
132
- models_loaded=len(ai_system.models),
133
- memory_usage=psutil.virtual_memory().percent,
134
- uptime=time.time() - start_time
 
 
 
 
 
 
 
 
 
 
 
135
  )
136
 
137
- @app.post("/chat", response_model=ChatResponse)
 
 
 
 
 
138
  async def chat_endpoint(request: ChatRequest):
139
- if not ai_system or not ai_system.models:
140
- raise HTTPException(status_code=503, detail="AI system still initializing")
141
-
142
  try:
143
- # Generate response
144
- result = ai_system.generate_response(
145
- query=request.message,
146
- history=[], # Would load from conversation_id
147
- model_profile=request.model_profile
148
- )
 
 
 
 
 
 
 
 
 
149
 
150
  return ChatResponse(
151
- response=result["response"],
152
- conversation_id=request.conversation_id or generate_conversation_id(),
153
- processing_time=result["processing_time"],
154
- model_used=result["model_used"],
155
- tokens_used=result.get("tokens_used", 0)
156
  )
157
 
 
 
158
  except Exception as e:
159
- logging.error(f"Chat error: {e}")
160
- raise HTTPException(status_code=500, detail="Error processing request")
161
 
162
- @app.get("/models")
163
- async def list_models():
164
- if not ai_system:
165
- return {"models": []}
166
-
167
- models = []
168
- for profile, model in ai_system.models.items():
169
- models.append({
170
- "profile": profile,
171
- "context_size": model.n_ctx(),
172
- "parameters": "3.8B",
173
- "quantization": profile.upper()
174
- })
175
-
176
- return {"models": models}
177
-
178
- @app.get("/performance")
179
- async def get_performance_stats() -> PerformanceStats:
180
- if not ai_system:
181
- return PerformanceStats(
182
- total_requests=0,
183
- average_response_time=0,
184
- models_available=[],
185
- system_health={}
186
- )
187
-
188
- stats = ai_system.performance_monitor.get_performance_stats()
189
-
190
- return PerformanceStats(
191
- total_requests=stats.get("total_inferences", 0),
192
- average_response_time=stats.get("average_time", 0),
193
- models_available=list(ai_system.models.keys()),
194
- system_health={
195
- "memory_percent": psutil.virtual_memory().percent,
196
- "cpu_percent": psutil.cpu_percent(),
197
- "disk_usage": psutil.disk_usage('/').percent
198
- }
199
- )
200
 
201
- @app.post("/feedback")
202
- async def submit_feedback(conversation_id: str, helpful: bool, comments: Optional[str] = None):
203
- # Store feedback for model improvement
204
- logging.info(f"Feedback for {conversation_id}: helpful={helpful}, comments={comments}")
205
- return {"status": "feedback_received"}
 
 
 
 
206
 
207
- # Utility functions
208
- def generate_conversation_id() -> str:
209
- return f"conv_{int(time.time())}_{os.urandom(4).hex()}"
 
 
 
 
210
 
211
- # Global startup time
212
- start_time = time.time()
 
 
 
 
 
213
 
214
- # Railway-specific configuration
 
 
 
 
 
 
 
 
 
 
215
  if __name__ == "__main__":
216
- config = Config()
217
-
218
  uvicorn.run(
219
  app,
220
  host="0.0.0.0",
221
- port=config.PORT,
222
- log_level=config.LOG_LEVEL.lower(),
223
- access_log=True
224
  )
 
1
  import os
2
+ import uvicorn
3
  from fastapi import FastAPI, HTTPException, Depends
4
  from fastapi.middleware.cors import CORSMiddleware
5
  from fastapi.responses import JSONResponse
6
  from pydantic import BaseModel
7
+ from typing import Optional, List, Dict
 
 
8
  import time
9
+ from datetime import datetime
10
+ import logging
 
 
11
 
12
+ from src.ai_system import SaemsTunesAISystem
13
+ from src.supabase_integration import SupabaseIntegration
14
+ from src.security_system import SecuritySystem
15
+ from src.monitoring_system import ComprehensiveMonitor
16
 
17
  # Configuration
18
  class Config:
19
+ SUPABASE_URL = os.getenv("SUPABASE_URL", "")
20
+ SUPABASE_ANON_KEY = os.getenv("SUPABASE_ANON_KEY", "")
21
+ MODEL_NAME = os.getenv("MODEL_NAME", "microsoft/Phi-3.5-mini-instruct")
22
  PORT = int(os.getenv("PORT", 8000))
23
+ ENVIRONMENT = os.getenv("RAILWAY_ENVIRONMENT", "production")
 
 
24
 
25
  # Request/Response models
26
  class ChatRequest(BaseModel):
27
  message: str
28
+ user_id: Optional[str] = "anonymous"
29
  conversation_id: Optional[str] = None
 
 
 
30
 
31
  class ChatResponse(BaseModel):
32
  response: str
 
33
  processing_time: float
34
+ conversation_id: str
35
+ timestamp: str
36
  model_used: str
 
37
 
38
  class HealthResponse(BaseModel):
39
  status: str
40
+ timestamp: str
41
+ version: str
42
+ environment: str
43
+ systems: Dict
44
+ resources: Dict
45
+
46
+ # Setup logging
47
+ logging.basicConfig(level=logging.INFO)
48
+ logger = logging.getLogger(__name__)
49
+
50
+ # Initialize systems
51
+ print("🚀 Initializing Saem's Tunes AI System for Railway...")
52
+
53
+ supabase_integration = SupabaseIntegration(Config.SUPABASE_URL, Config.SUPABASE_ANON_KEY)
54
+ security_system = SecuritySystem()
55
+ monitor = ComprehensiveMonitor()
56
+ ai_system = SaemsTunesAISystem(supabase_integration, security_system, monitor)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
  # Create FastAPI application
59
  app = FastAPI(
60
  title="Saem's Tunes AI API",
61
+ description="Backup AI API for Saem's Tunes music platform",
62
  version="1.0.0",
63
+ docs_url="/docs",
64
+ redoc_url="/redoc"
65
  )
66
 
67
  # CORS middleware
 
73
  allow_headers=["*"],
74
  )
75
 
76
+ # Health check endpoint
77
+ @app.get("/", response_model=HealthResponse)
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  async def root():
79
+ """Root endpoint with health information"""
80
+ import psutil
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
 
82
  return HealthResponse(
83
  status="healthy",
84
+ timestamp=datetime.now().isoformat(),
85
+ version="1.0.0",
86
+ environment=Config.ENVIRONMENT,
87
+ systems={
88
+ "supabase": supabase_integration.is_connected(),
89
+ "security": True,
90
+ "monitoring": True,
91
+ "ai_system": True
92
+ },
93
+ resources={
94
+ "cpu_percent": psutil.cpu_percent(),
95
+ "memory_percent": psutil.virtual_memory().percent,
96
+ "disk_percent": psutil.disk_usage('/').percent
97
+ }
98
  )
99
 
100
+ @app.get("/health", response_model=HealthResponse)
101
+ async def health_check():
102
+ """Health check endpoint"""
103
+ return await root()
104
+
105
+ @app.post("/api/chat", response_model=ChatResponse)
106
  async def chat_endpoint(request: ChatRequest):
107
+ """Main chat endpoint for React frontend"""
 
 
108
  try:
109
+ if not request.message.strip():
110
+ raise HTTPException(status_code=400, detail="Message cannot be empty")
111
+
112
+ # Security check
113
+ security_result = security_system.check_request(request.message, request.user_id)
114
+ if security_result.get("is_suspicious", False):
115
+ raise HTTPException(
116
+ status_code=429,
117
+ detail="Request blocked for security reasons"
118
+ )
119
+
120
+ # Process query
121
+ start_time = time.time()
122
+ response = ai_system.process_query(request.message, request.user_id, request.conversation_id)
123
+ processing_time = time.time() - start_time
124
 
125
  return ChatResponse(
126
+ response=response,
127
+ processing_time=processing_time,
128
+ conversation_id=request.conversation_id or f"conv_{int(time.time())}",
129
+ timestamp=datetime.now().isoformat(),
130
+ model_used=Config.MODEL_NAME
131
  )
132
 
133
+ except HTTPException:
134
+ raise
135
  except Exception as e:
136
+ logger.error(f"Chat endpoint error: {e}")
137
+ raise HTTPException(status_code=500, detail="Internal server error")
138
 
139
+ @app.get("/api/models")
140
+ async def get_models():
141
+ """Get available models information"""
142
+ return {
143
+ "available_models": ["microsoft/Phi-3.5-mini-instruct"],
144
+ "current_model": Config.MODEL_NAME,
145
+ "quantization": "Q4_K_M",
146
+ "context_length": 4096,
147
+ "parameters": "3.8B"
148
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
 
150
+ @app.get("/api/stats")
151
+ async def get_stats():
152
+ """Get system statistics"""
153
+ return {
154
+ "total_requests": len(monitor.inference_metrics),
155
+ "average_response_time": monitor.get_average_response_time(),
156
+ "error_rate": monitor.get_error_rate(),
157
+ "uptime": monitor.get_uptime()
158
+ }
159
 
160
+ # Error handlers
161
+ @app.exception_handler(HTTPException)
162
+ async def http_exception_handler(request, exc):
163
+ return JSONResponse(
164
+ status_code=exc.status_code,
165
+ content={"error": exc.detail}
166
+ )
167
 
168
+ @app.exception_handler(Exception)
169
+ async def general_exception_handler(request, exc):
170
+ logger.error(f"Unhandled exception: {exc}")
171
+ return JSONResponse(
172
+ status_code=500,
173
+ content={"error": "Internal server error"}
174
+ )
175
 
176
+ # Startup event
177
+ @app.on_event("startup")
178
+ async def startup_event():
179
+ """Initialize systems on startup"""
180
+ print("✅ Saem's Tunes AI API is ready!")
181
+ print(f"📍 Environment: {Config.ENVIRONMENT}")
182
+ print(f"🔗 Supabase: {'Connected' if supabase_integration.is_connected() else 'Disconnected'}")
183
+ print(f"🤖 Model: {Config.MODEL_NAME}")
184
+ print(f"🌐 API docs: http://localhost:{Config.PORT}/docs")
185
+
186
+ # Main entry point
187
  if __name__ == "__main__":
 
 
188
  uvicorn.run(
189
  app,
190
  host="0.0.0.0",
191
+ port=Config.PORT,
192
+ log_level="info"
 
193
  )