ParthSadaria commited on
Commit
df227c8
·
verified ·
1 Parent(s): 3ca7e04

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +194 -0
app.py ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException, Request, Depends, status
2
+ from fastapi.responses import HTMLResponse, JSONResponse
3
+ from fastapi.staticfiles import StaticFiles
4
+ from fastapi.security import HTTPBasic, HTTPBasicCredentials
5
+ from pydantic import BaseModel
6
+ import httpx
7
+ import secrets
8
+ import os
9
+ from typing import List, Dict, Any, Optional
10
+
11
+ # Initialize FastAPI app
12
+ app = FastAPI(title="AI Chat Application")
13
+
14
+ # Mount static files
15
+ app.mount("/static", StaticFiles(directory="static"), name="static")
16
+
17
+ # Security for admin panel
18
+ security = HTTPBasic()
19
+ ADMIN_USERNAME = os.environ.get("ADMIN_USERNAME", "admin")
20
+ ADMIN_PASSWORD = os.environ.get("ADMIN_PASSWORD", "password") # Change in production!
21
+
22
+ # Store active chats and settings in memory
23
+ active_chats = {}
24
+ chat_history = {}
25
+ rules = [
26
+ "Be respectful and helpful",
27
+ "Do not generate harmful content",
28
+ "Provide accurate information"
29
+ ]
30
+ available_models = ["mistral-large-latest", "gemini", "openai-xlarge"]
31
+ current_model = "mistral-large-latest"
32
+
33
+ # API endpoint for the chat
34
+ class ChatMessage(BaseModel):
35
+ message: str
36
+ chat_id: Optional[str] = None
37
+ model: Optional[str] = None
38
+
39
+ class Rule(BaseModel):
40
+ rule: str
41
+
42
+ class ModelRequest(BaseModel):
43
+ model: str
44
+
45
+ def get_admin_user(credentials: HTTPBasicCredentials = Depends(security)):
46
+ is_username_correct = secrets.compare_digest(credentials.username, ADMIN_USERNAME)
47
+ is_password_correct = secrets.compare_digest(credentials.password, ADMIN_PASSWORD)
48
+ if not (is_username_correct and is_password_correct):
49
+ raise HTTPException(
50
+ status_code=status.HTTP_401_UNAUTHORIZED,
51
+ detail="Incorrect username or password",
52
+ headers={"WWW-Authenticate": "Basic"},
53
+ )
54
+ return credentials.username
55
+
56
+ @app.get("/", response_class=HTMLResponse)
57
+ async def read_root():
58
+ with open("index.html", "r") as f:
59
+ return f.read()
60
+
61
+ @app.post("/api/chat")
62
+ async def process_chat(chat_request: ChatMessage):
63
+ # Generate a new chat ID if not provided
64
+ chat_id = chat_request.chat_id or secrets.token_hex(8)
65
+
66
+ # Initialize chat history if it doesn't exist
67
+ if chat_id not in chat_history:
68
+ chat_history[chat_id] = []
69
+
70
+ # Store the message in chat history
71
+ chat_history[chat_id].append({"role": "user", "content": chat_request.message})
72
+
73
+ # Apply rules to message (simplified implementation)
74
+ for rule in rules:
75
+ if rule.startswith("Block:") and rule[6:].lower() in chat_request.message.lower():
76
+ return {"response": "I cannot respond to that due to content rules.", "chat_id": chat_id}
77
+
78
+ # Select model to use
79
+ model_to_use = chat_request.model if chat_request.model in available_models else current_model
80
+
81
+ # Prepare request to external API
82
+ api_request = {
83
+ "model": model_to_use,
84
+ "messages": chat_history[chat_id],
85
+ "temperature": 0.7,
86
+ "max_tokens": 1000
87
+ }
88
+
89
+ # Call external API
90
+ try:
91
+ async with httpx.AsyncClient(timeout=60.0) as client:
92
+ response = await client.post(
93
+ "https://parthsadaria-lokiai.hf.space/chat/completions",
94
+ json=api_request
95
+ )
96
+ response_data = response.json()
97
+
98
+ if "choices" in response_data and len(response_data["choices"]) > 0:
99
+ ai_message = response_data["choices"][0]["message"]["content"]
100
+ chat_history[chat_id].append({"role": "assistant", "content": ai_message})
101
+ return {"response": ai_message, "chat_id": chat_id, "model": model_to_use}
102
+ else:
103
+ error_msg = "No response from AI model"
104
+ chat_history[chat_id].append({"role": "assistant", "content": error_msg})
105
+ return {"response": error_msg, "chat_id": chat_id}
106
+
107
+ except Exception as e:
108
+ error_msg = f"Error communicating with AI service: {str(e)}"
109
+ chat_history[chat_id].append({"role": "assistant", "content": error_msg})
110
+ return {"response": error_msg, "chat_id": chat_id}
111
+
112
+ # Admin panel endpoints
113
+ @app.get("/admin", response_class=HTMLResponse)
114
+ async def admin_panel(username: str = Depends(get_admin_user)):
115
+ html_content = f"""
116
+ <!DOCTYPE html>
117
+ <html>
118
+ <head>
119
+ <title>Admin Panel</title>
120
+ <link rel="stylesheet" href="/static/style.css">
121
+ <script src="/static/script.js"></script>
122
+ </head>
123
+ <body class="admin-page">
124
+ <h1>Admin Panel</h1>
125
+
126
+ <section class="admin-section">
127
+ <h2>Active Model: <span id="current-model">{current_model}</span></h2>
128
+ <select id="model-selector">
129
+ {"".join(f'<option value="{model}">{model}</option>' for model in available_models)}
130
+ </select>
131
+ <button onclick="updateModel()">Update Model</button>
132
+ </section>
133
+
134
+ <section class="admin-section">
135
+ <h2>Rules</h2>
136
+ <ul id="rules-list">
137
+ {"".join(f'<li>{rule} <button onclick="deleteRule({i})">Delete</button></li>' for i, rule in enumerate(rules))}
138
+ </ul>
139
+ <div>
140
+ <input type="text" id="new-rule" placeholder="Add new rule">
141
+ <button onclick="addRule()">Add Rule</button>
142
+ </div>
143
+ </section>
144
+
145
+ <section class="admin-section">
146
+ <h2>Active Chats</h2>
147
+ <ul id="active-chats">
148
+ {"".join(f'<li><a href="#" onclick="viewChat(\'{chat_id}\')">{chat_id}</a></li>' for chat_id in chat_history)}
149
+ </ul>
150
+ <div id="chat-viewer"></div>
151
+ </section>
152
+ </body>
153
+ </html>
154
+ """
155
+ return html_content
156
+
157
+ @app.get("/api/rules")
158
+ async def get_rules(username: str = Depends(get_admin_user)):
159
+ return {"rules": rules}
160
+
161
+ @app.post("/api/rules")
162
+ async def add_rule(rule_request: Rule, username: str = Depends(get_admin_user)):
163
+ rules.append(rule_request.rule)
164
+ return {"status": "success", "rules": rules}
165
+
166
+ @app.delete("/api/rules/{rule_id}")
167
+ async def delete_rule(rule_id: int, username: str = Depends(get_admin_user)):
168
+ if 0 <= rule_id < len(rules):
169
+ rules.pop(rule_id)
170
+ return {"status": "success", "rules": rules}
171
+ raise HTTPException(status_code=404, detail="Rule not found")
172
+
173
+ @app.post("/api/model")
174
+ async def set_model(model_request: ModelRequest, username: str = Depends(get_admin_user)):
175
+ global current_model
176
+ if model_request.model in available_models:
177
+ current_model = model_request.model
178
+ return {"status": "success", "model": current_model}
179
+ raise HTTPException(status_code=400, detail="Invalid model")
180
+
181
+ @app.get("/api/chats")
182
+ async def get_chats(username: str = Depends(get_admin_user)):
183
+ return {"chats": list(chat_history.keys())}
184
+
185
+ @app.get("/api/chats/{chat_id}")
186
+ async def get_chat_history(chat_id: str, username: str = Depends(get_admin_user)):
187
+ if chat_id in chat_history:
188
+ return {"history": chat_history[chat_id]}
189
+ raise HTTPException(status_code=404, detail="Chat not found")
190
+
191
+ # Run the app (for local development)
192
+ if __name__ == "__main__":
193
+ import uvicorn
194
+ uvicorn.run(app, host="0.0.0.0", port=7860)