paper-dynasty-database/app/routers_v2/scouting.py
Cal Corum 8c6a99253b
All checks were successful
Build Docker Image / build (pull_request) Successful in 3m9s
fix: replace 467 manual db.close() calls with middleware (#30)
Add db_session_middleware to main.py that opens the connection at the
start of each request and closes it in a try/finally block, ensuring
connections are always returned even on uncaught exceptions.

Remove all individual db.close() calls from 30 router files in
app/routers_v2/ — the middleware now handles all code paths.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 23:37:24 -06:00

100 lines
3.0 KiB
Python

import csv
from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, Response, Query
from typing import Optional
import logging
import pydantic
import pandas as pd
from ..db_engine import db, model_to_dict, fn, query_to_csv, complex_data_to_csv, Player, BattingCardRatings
from ..dependencies import oauth2_scheme, valid_token, LOG_DATA, int_timestamp
from ..player_scouting import get_player_ids
logging.basicConfig(
filename=LOG_DATA['filename'],
format=LOG_DATA['format'],
level=LOG_DATA['log_level']
)
router = APIRouter(
prefix='/api/v2/scouting',
tags=['scouting']
)
class BattingFiles(pydantic.BaseModel):
vl_basic: str = 'vl-basic.csv'
vl_rate: str = 'vl-rate.csv'
vr_basic: str = 'vr-basic.csv'
vr_rate: str = 'vr-rate.csv'
running: str = 'running.csv'
# def csv_file_to_dataframe(filename: str) -> pd.DataFrame | None:
# with open(filename, 'r', encoding='utf8') as file:
# reader = csv.reader(file)
#
# for row in reader:
@router.get('/playerkeys')
async def get_player_keys(player_id: list = Query(default=None)):
all_keys = []
for x in player_id:
this_player = Player.get_or_none(Player.player_id == x)
if this_player is not None:
this_keys = get_player_ids(this_player.bbref_id, id_type='bbref')
if this_keys is not None:
all_keys.append(this_keys)
return_val = {'count': len(all_keys), 'keys': [
dict(x) for x in all_keys
]}
return return_val
@router.post('/live-update/batting')
def live_update_batting(files: BattingFiles, cardset_id: int, token: str = Depends(oauth2_scheme)):
if not valid_token(token):
logging.warning(f'Bad Token: {token}')
raise HTTPException(
status_code=401,
detail='You are not authorized to initiate live updates.'
)
data = {} # <fg id>: { 'vL': [combined vl stat data], 'vR': [combined vr stat data] }
for row in files.vl_basic:
if row['pa'] >= 20:
data[row['fgid']]['vL'] = row
for row in files.vl_rate:
if row['fgid'] in data.keys():
data[row['fgid']]['vL'].extend(row)
for row in files.vr_basic:
if row['pa'] >= 40 and row['fgid'] in data.keys():
data[row['fgid']]['vR'] = row
for row in files.vr_rate:
if row['fgid'] in data.keys():
data[row['fgid']]['vR'].extend(row)
for x in data.items():
pass
# Create BattingCardRating object for vL
# Create BattingCardRating object for vR
# Read running stats and create/update BattingCard object
return files.dict()
@router.post('/live-update/pitching')
def live_update_pitching(files: BattingFiles, token: str = Depends(oauth2_scheme)):
if not valid_token(token):
logging.warning(f'Bad Token: {token}')
raise HTTPException(
status_code=401,
detail='You are not authorized to initiate live updates.'
)
return files.dict()