Spaces:
Sleeping
Sleeping
Redis + Websocket
Browse files
app.py
CHANGED
|
@@ -8,11 +8,12 @@ from bson.objectid import ObjectId
|
|
| 8 |
import redis
|
| 9 |
import json
|
| 10 |
from redis.exceptions import RedisError
|
| 11 |
-
from pydantic import BaseModel
|
|
|
|
| 12 |
|
| 13 |
# Initialize FastAPI app
|
| 14 |
app = FastAPI()
|
| 15 |
-
socket_manager = SocketManager(app=app)
|
| 16 |
|
| 17 |
# Add CORS middleware
|
| 18 |
app.add_middleware(
|
|
@@ -34,6 +35,14 @@ db = client["test"]
|
|
| 34 |
pdf_collection = db["PdfDetails"]
|
| 35 |
voter_collection = db["Voters"]
|
| 36 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
# Pydantic models for request validation
|
| 38 |
class VoterRegistration(BaseModel):
|
| 39 |
name: str
|
|
@@ -45,6 +54,13 @@ class VoteRequest(BaseModel):
|
|
| 45 |
file_id: str
|
| 46 |
vote_count: Optional[int] = 1
|
| 47 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
@app.post("/upload-files")
|
| 49 |
async def upload_file(
|
| 50 |
title: str = Form(...),
|
|
@@ -141,35 +157,60 @@ async def vote_by_voter(vote_request: VoteRequest):
|
|
| 141 |
|
| 142 |
@app.get("/get-voter")
|
| 143 |
async def get_voter(voter_id: str):
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
'
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
|
| 165 |
@socket_manager.on('connect')
|
| 166 |
-
async def handle_connect():
|
| 167 |
-
print('Client connected')
|
| 168 |
|
| 169 |
@socket_manager.on('disconnect')
|
| 170 |
-
async def handle_disconnect():
|
| 171 |
-
print('Client disconnected')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 172 |
|
| 173 |
-
if
|
| 174 |
import uvicorn
|
| 175 |
uvicorn.run(app, host="0.0.0.0", port=5000)
|
|
|
|
| 8 |
import redis
|
| 9 |
import json
|
| 10 |
from redis.exceptions import RedisError
|
| 11 |
+
from pydantic import BaseModel, validator
|
| 12 |
+
from pymongo.errors import ConnectionFailure
|
| 13 |
|
| 14 |
# Initialize FastAPI app
|
| 15 |
app = FastAPI()
|
| 16 |
+
socket_manager = SocketManager(app=app, cors_allowed_origins="*", mount_location="/socket.io")
|
| 17 |
|
| 18 |
# Add CORS middleware
|
| 19 |
app.add_middleware(
|
|
|
|
| 35 |
pdf_collection = db["PdfDetails"]
|
| 36 |
voter_collection = db["Voters"]
|
| 37 |
|
| 38 |
+
# Kiểm tra kết nối MongoDB khi khởi động
|
| 39 |
+
try:
|
| 40 |
+
# The ismaster command is cheap and does not require auth.
|
| 41 |
+
client.admin.command('ismaster')
|
| 42 |
+
except ConnectionFailure:
|
| 43 |
+
print("Server not available")
|
| 44 |
+
raise
|
| 45 |
+
|
| 46 |
# Pydantic models for request validation
|
| 47 |
class VoterRegistration(BaseModel):
|
| 48 |
name: str
|
|
|
|
| 54 |
file_id: str
|
| 55 |
vote_count: Optional[int] = 1
|
| 56 |
|
| 57 |
+
class Config:
|
| 58 |
+
@validator('vote_count')
|
| 59 |
+
def validate_vote_count(cls, v):
|
| 60 |
+
if v <= 0:
|
| 61 |
+
raise ValueError('Vote count must be greater than 0')
|
| 62 |
+
return v
|
| 63 |
+
|
| 64 |
@app.post("/upload-files")
|
| 65 |
async def upload_file(
|
| 66 |
title: str = Form(...),
|
|
|
|
| 157 |
|
| 158 |
@app.get("/get-voter")
|
| 159 |
async def get_voter(voter_id: str):
|
| 160 |
+
try:
|
| 161 |
+
# Check cache
|
| 162 |
+
try:
|
| 163 |
+
cached_voter = redis_client.get(f'voter:{voter_id}')
|
| 164 |
+
if cached_voter:
|
| 165 |
+
return json.loads(cached_voter)
|
| 166 |
+
except RedisError as redis_err:
|
| 167 |
+
print(f"Redis error: {redis_err}")
|
| 168 |
+
# Continue without cache if Redis fails
|
| 169 |
+
pass
|
| 170 |
+
|
| 171 |
+
voter = voter_collection.find_one({'_id': ObjectId(voter_id)})
|
| 172 |
+
if not voter:
|
| 173 |
+
raise HTTPException(status_code=404, detail="Voter not found")
|
| 174 |
+
|
| 175 |
+
voter_data = {
|
| 176 |
+
'status': 'ok',
|
| 177 |
+
'name': voter['name'],
|
| 178 |
+
'group': voter['group'],
|
| 179 |
+
'role': voter['role'],
|
| 180 |
+
'number_of_votes': voter['number_of_votes']
|
| 181 |
+
}
|
| 182 |
+
|
| 183 |
+
# Try to save to cache
|
| 184 |
+
try:
|
| 185 |
+
redis_client.setex(f'voter:{voter_id}', CACHE_EXPIRE_TIME, json.dumps(voter_data))
|
| 186 |
+
except RedisError as redis_err:
|
| 187 |
+
print(f"Redis caching error: {redis_err}")
|
| 188 |
+
# Continue even if caching fails
|
| 189 |
+
pass
|
| 190 |
+
|
| 191 |
+
return voter_data
|
| 192 |
+
except Exception as e:
|
| 193 |
+
raise HTTPException(status_code=500, detail=str(e))
|
| 194 |
|
| 195 |
@socket_manager.on('connect')
|
| 196 |
+
async def handle_connect(sid, environ):
|
| 197 |
+
print(f'Client connected: {sid}')
|
| 198 |
|
| 199 |
@socket_manager.on('disconnect')
|
| 200 |
+
async def handle_disconnect(sid):
|
| 201 |
+
print(f'Client disconnected: {sid}')
|
| 202 |
+
|
| 203 |
+
@app.get("/")
|
| 204 |
+
async def index():
|
| 205 |
+
return {'status': 'ok', 'message': 'Server is running'}
|
| 206 |
+
|
| 207 |
+
@app.on_event("shutdown")
|
| 208 |
+
async def shutdown_event():
|
| 209 |
+
# Close MongoDB connection
|
| 210 |
+
client.close()
|
| 211 |
+
# Close Redis connection
|
| 212 |
+
redis_client.close()
|
| 213 |
|
| 214 |
+
if _name_ == "_main_":
|
| 215 |
import uvicorn
|
| 216 |
uvicorn.run(app, host="0.0.0.0", port=5000)
|