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

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)