You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
3.7 KiB
Python
132 lines
3.7 KiB
Python
from fastapi import FastAPI, Depends, HTTPException
|
|
from sqlalchemy.orm import Session
|
|
from pydantic import BaseModel
|
|
from typing import List, Optional
|
|
import sys
|
|
import os
|
|
|
|
sys.path.append(os.path.join(os.path.dirname(__file__), "../../../shared"))
|
|
from database.connection import get_db
|
|
from database.models import Player, GameSession
|
|
|
|
app = FastAPI(title="Player Service", version="1.0.0")
|
|
|
|
|
|
class PlayerCreate(BaseModel):
|
|
name: str
|
|
email: Optional[str] = None
|
|
|
|
|
|
class PlayerResponse(BaseModel):
|
|
id: int
|
|
name: str
|
|
email: Optional[str] = None
|
|
created_at: str
|
|
|
|
|
|
class PlayerStats(BaseModel):
|
|
player_id: int
|
|
player_name: str
|
|
total_games: int
|
|
best_score: int
|
|
average_score: float
|
|
total_questions_answered: int
|
|
|
|
|
|
@app.get("/health")
|
|
def health_check():
|
|
return {"status": "healthy", "service": "player-service"}
|
|
|
|
|
|
@app.post("/", response_model=PlayerResponse)
|
|
def create_or_get_player(player_data: PlayerCreate, db: Session = Depends(get_db)):
|
|
existing_player = db.query(Player).filter(Player.name == player_data.name).first()
|
|
|
|
if existing_player:
|
|
return PlayerResponse(
|
|
id=existing_player.id,
|
|
name=existing_player.name,
|
|
email=existing_player.email,
|
|
created_at=str(existing_player.created_at)
|
|
)
|
|
|
|
player = Player(name=player_data.name, email=player_data.email)
|
|
db.add(player)
|
|
db.commit()
|
|
db.refresh(player)
|
|
|
|
return PlayerResponse(
|
|
id=player.id,
|
|
name=player.name,
|
|
email=player.email,
|
|
created_at=str(player.created_at)
|
|
)
|
|
|
|
|
|
@app.get("/{player_id}", response_model=PlayerResponse)
|
|
def get_player(player_id: int, db: Session = Depends(get_db)):
|
|
player = db.query(Player).filter(Player.id == player_id).first()
|
|
if not player:
|
|
raise HTTPException(status_code=404, detail="Player not found")
|
|
|
|
return PlayerResponse(
|
|
id=player.id,
|
|
name=player.name,
|
|
email=player.email,
|
|
created_at=str(player.created_at)
|
|
)
|
|
|
|
|
|
@app.get("/{player_id}/stats", response_model=PlayerStats)
|
|
def get_player_stats(player_id: int, db: Session = Depends(get_db)):
|
|
player = db.query(Player).filter(Player.id == player_id).first()
|
|
if not player:
|
|
raise HTTPException(status_code=404, detail="Player not found")
|
|
|
|
sessions = db.query(GameSession).filter(
|
|
GameSession.player_id == player_id,
|
|
GameSession.ended_at.isnot(None)
|
|
).all()
|
|
|
|
if not sessions:
|
|
return PlayerStats(
|
|
player_id=player.id,
|
|
player_name=player.name,
|
|
total_games=0,
|
|
best_score=0,
|
|
average_score=0.0,
|
|
total_questions_answered=0
|
|
)
|
|
|
|
total_games = len(sessions)
|
|
best_score = max(session.total_score for session in sessions)
|
|
average_score = sum(session.total_score for session in sessions) / total_games
|
|
total_questions = sum(session.questions_answered for session in sessions)
|
|
|
|
return PlayerStats(
|
|
player_id=player.id,
|
|
player_name=player.name,
|
|
total_games=total_games,
|
|
best_score=best_score,
|
|
average_score=round(average_score, 2),
|
|
total_questions_answered=total_questions
|
|
)
|
|
|
|
|
|
@app.get("/", response_model=List[PlayerResponse])
|
|
def list_players(limit: int = 50, db: Session = Depends(get_db)):
|
|
players = db.query(Player).limit(limit).all()
|
|
return [
|
|
PlayerResponse(
|
|
id=player.id,
|
|
name=player.name,
|
|
email=player.email,
|
|
created_at=str(player.created_at)
|
|
)
|
|
for player in players
|
|
]
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import uvicorn
|
|
uvicorn.run(app, host="0.0.0.0", port=8003) |