Add scouting update endpoint

This commit is contained in:
Cal Corum 2023-11-18 14:45:09 -06:00
parent eb0babc78c
commit d9a63e1949
2 changed files with 108 additions and 54 deletions

View File

@ -23,6 +23,8 @@ router = APIRouter(
prefix='/api/v2/battingcardratings',
tags=['battingcardratings']
)
RATINGS_FILE = 'storage/batting-ratings.csv'
BASIC_FILE = 'storage/batting-basic.csv'
class BattingCardRatingsModel(pydantic.BaseModel):
@ -215,7 +217,7 @@ def get_scouting_dfs(cardset_id: list = None):
@router.get('/scouting')
async def get_card_scouting(team_id: int, ts: str, cardset_id: list = Query(default=None)):
async def get_card_scouting(team_id: int, ts: str):
this_team = Team.get_or_none(Team.id == team_id)
logging.debug(f'Team: {this_team} / has_guide: {this_team.has_guide}')
if this_team is None or ts != this_team.team_hash() or this_team.has_guide != 1:
@ -225,35 +227,6 @@ async def get_card_scouting(team_id: int, ts: str, cardset_id: list = Query(defa
'make sure it is enabled on your team. If you are interested you can pick it up here (thank you!): ' \
'https://ko-fi.com/manticorum/shop'
# all_ratings = BattingCardRatings.select()
# if cardset_id is not None:
# set_players = Player.select(Player.player_id).where(Player.cardset_id << cardset_id)
# set_cards = BattingCard.select(BattingCard.id).where(BattingCard.player << set_players)
# all_ratings = all_ratings.where(BattingCardRatings.battingcard << set_cards)
#
# vl_query = all_ratings.where(BattingCardRatings.vs_hand == 'L')
# vr_query = all_ratings.where(BattingCardRatings.vs_hand == 'R')
#
# vl_vals = [model_to_dict(x) for x in vl_query]
# for x in vl_vals:
# x.update(x['battingcard'])
# x['player_id'] = x['battingcard']['player']['player_id']
# x['player_name'] = x['battingcard']['player']['p_name']
# x['rarity'] = x['battingcard']['player']['rarity']['name']
# x['cardset_id'] = x['battingcard']['player']['cardset']['id']
# x['cardset_name'] = x['battingcard']['player']['cardset']['name']
# del x['battingcard']
# del x['player']
#
# vr_vals = [model_to_dict(x) for x in vr_query]
# for x in vr_vals:
# x['player_id'] = x['battingcard']['player']['player_id']
# del x['battingcard']
#
# vl = pd.DataFrame(vl_vals)
# vr = pd.DataFrame(vr_vals)
# db.close()
if os.path.isfile(f'storage/batting-ratings.csv'):
return FileResponse(
path=f'storage/batting-ratings.csv',
@ -261,12 +234,31 @@ async def get_card_scouting(team_id: int, ts: str, cardset_id: list = Query(defa
# headers=headers
)
output = get_scouting_dfs(cardset_id)
raise HTTPException(status_code=400, detail='Go pester Cal - the scouting file is missing')
@router.post('/calculate/scouting')
async def post_calc_scouting(token: str = Depends(oauth2_scheme)):
if not valid_token(token):
logging.warning(f'Bad Token: {token}')
db.close()
raise HTTPException(
status_code=401,
detail='You are not authorized to calculate card ratings.'
)
logging.warning(f'Re-calculating batting ratings\n\n')
output = get_scouting_dfs()
first = ['player_id', 'player_name', 'cardset_name', 'rarity', 'hand', 'variant']
exclude = first + ['id_vl', 'id_vr', 'vs_hand_vl', 'vs_hand_vr']
output = output[first + [col for col in output.columns if col not in exclude]]
# output = output.sort_values(by=['player_id'])
return Response(content=pd.DataFrame(output).to_csv(index=False), media_type='text/csv')
csv_file = pd.DataFrame(output).to_csv(index=False)
with open(RATINGS_FILE, 'w') as file:
file.write(csv_file)
return Response(content=csv_file, media_type='text/csv')
@router.get('/basic')
@ -278,7 +270,22 @@ async def get_basic_scouting(cardset_id: list = Query(default=None)):
# headers=headers
)
raw_data = get_scouting_dfs(cardset_id)
raise HTTPException(status_code=400, detail='Go pester Cal - the scouting file is missing')
@router.post('/calculate/basic')
async def post_calc_basic(token: str = Depends(oauth2_scheme)):
if not valid_token(token):
logging.warning(f'Bad Token: {token}')
db.close()
raise HTTPException(
status_code=401,
detail='You are not authorized to calculate basic ratings.'
)
logging.warning(f'Re-calculating basic batting ratings\n\n')
raw_data = get_scouting_dfs()
logging.debug(f'output: {raw_data}')
def get_raw_speed(df_data):
@ -455,7 +462,12 @@ async def get_basic_scouting(cardset_id: list = Query(default=None)):
'player_name', 'Rating', 'Contact R', 'Contact L', 'Power R', 'Power L', 'Vision', 'Speed',
'Steal', 'Reaction', 'Arm', 'Fielding', 'hand', 'cardset_name'
]]
return Response(content=output.to_csv(index=True), media_type='text/csv')
csv_file = pd.DataFrame(output).to_csv(index=False)
with open(BASIC_FILE, 'w') as file:
file.write(csv_file)
return Response(content=csv_file, media_type='text/csv')
@router.get('/{ratings_id}')

View File

@ -22,6 +22,8 @@ router = APIRouter(
prefix='/api/v2/pitchingcardratings',
tags=['pitchingcardratings']
)
RATINGS_FILE = 'storage/pitching-ratings.csv'
BASIC_FILE = 'storage/pitching-basic.csv'
class PitchingCardRatingsModel(pydantic.BaseModel):
@ -184,7 +186,7 @@ def get_scouting_dfs(cardset_id: list = None):
@router.get('/scouting')
async def get_card_scouting(team_id: int, ts: str, cardset_id: list = Query(default=None)):
async def get_card_scouting(team_id: int, ts: str):
this_team = Team.get_or_none(Team.id == team_id)
logging.debug(f'Team: {this_team} / has_guide: {this_team.has_guide}')
if this_team is None or ts != this_team.team_hash() or this_team.has_guide != 1:
@ -194,31 +196,66 @@ async def get_card_scouting(team_id: int, ts: str, cardset_id: list = Query(defa
'make sure it is enabled on your team. If you are interested you can pick it up here (thank you!): ' \
'https://ko-fi.com/manticorum/shop'
if os.path.isfile(f'storage/pitching-ratings.csv'):
if os.path.isfile(RATINGS_FILE):
return FileResponse(
path=f'storage/pitching-ratings.csv',
path=RATINGS_FILE,
media_type='text/csv',
# headers=headers
)
output = get_scouting_dfs(cardset_id)
raise HTTPException(status_code=400, detail='Go pester Cal - the scouting file is missing')
@router.post('/calculate/scouting')
async def post_calc_scouting(token: str = Depends(oauth2_scheme)):
if not valid_token(token):
logging.warning(f'Bad Token: {token}')
db.close()
raise HTTPException(
status_code=401,
detail='You are not authorized to calculate card ratings.'
)
logging.warning(f'Re-calculating pitching ratings\n\n')
output = get_scouting_dfs()
first = ['player_id', 'player_name', 'cardset_name', 'rarity', 'hand', 'variant']
exclude = first + ['id_vl', 'id_vr', 'vs_hand_vl', 'vs_hand_vr']
output = output[first + [col for col in output.columns if col not in exclude]]
return Response(content=pd.DataFrame(output).to_csv(index=False), media_type='text/csv')
csv_file = pd.DataFrame(output).to_csv(index=False)
with open(RATINGS_FILE, 'w') as file:
file.write(csv_file)
return Response(content=csv_file, media_type='text/csv')
@router.get('/basic')
async def get_basic_scouting(cardset_id: list = Query(default=None)):
if os.path.isfile(f'storage/pitching-basic.csv'):
async def get_basic_scouting():
if os.path.isfile(BASIC_FILE):
return FileResponse(
path=f'storage/pitching-basic.csv',
path=BASIC_FILE,
media_type='text/csv',
# headers=headers
)
raw_data = get_scouting_dfs(cardset_id)
logging.info(f'output: {raw_data}')
raise HTTPException(status_code=400, detail='Go pester Cal - the scouting file is missing')
@router.post('/calculate/basic')
async def post_calc_basic(token: str = Depends(oauth2_scheme)):
if not valid_token(token):
logging.warning(f'Bad Token: {token}')
db.close()
raise HTTPException(
status_code=401,
detail='You are not authorized to calculate basic ratings.'
)
logging.warning(f'Re-calculating basic pitching ratings\n\n')
raw_data = get_scouting_dfs()
logging.debug(f'output: {raw_data}')
def get_raw_leftcontrol(df_data):
return ((1 - (df_data['obp_vl'] - df_data['avg_vl'])) * 100) + (1 - (df_data['wild_pitch'] / 20))
@ -253,7 +290,7 @@ async def get_basic_scouting(cardset_id: list = Query(default=None)):
raw_series = raw_data.apply(get_raw_fielding, axis=1)
rank_series = raw_series.rank(pct=True)
logging.info(f'max fld: {raw_series.max()} / min fld: {raw_series.min()}')
logging.debug(f'max fld: {raw_series.max()} / min fld: {raw_series.min()}')
raw_data['Fielding'] = round(rank_series * 100)
def get_raw_stamina(df_data):
@ -261,28 +298,28 @@ async def get_basic_scouting(cardset_id: list = Query(default=None)):
rpow = df_data['relief_rating'] if pd.isna(df_data['relief_rating']) else -1
this_pow = spow if spow > rpow else rpow
return (((this_pow * (df_data['obp_vr'] * (2/3))) + (this_pow * (df_data['obp_vl'] / 3))) * 4.5) + this_pow
return (((this_pow * (df_data['obp_vr'] * (2 / 3))) + (this_pow * (df_data['obp_vl'] / 3))) * 4.5) + this_pow
raw_series = raw_data.apply(get_raw_stamina, axis=1)
rank_series = raw_series.rank(pct=True)
raw_data['Stamina'] = round(rank_series * 100)
def get_raw_hit(df_data):
return 1 - (df_data['avg_vr'] * (2/3)) + (df_data['avg_vl'] / 3)
return 1 - (df_data['avg_vr'] * (2 / 3)) + (df_data['avg_vl'] / 3)
raw_series = raw_data.apply(get_raw_hit, axis=1)
rank_series = raw_series.rank(pct=True)
raw_data['H/9'] = round(rank_series * 100)
def get_raw_k(df_data):
return ((df_data['strikeout_vr'] / 108) * (2/3)) + ((df_data['strikeout_vl'] / 108) / 3)
return ((df_data['strikeout_vr'] / 108) * (2 / 3)) + ((df_data['strikeout_vl'] / 108) / 3)
raw_series = raw_data.apply(get_raw_k, axis=1)
rank_series = raw_series.rank(pct=True)
raw_data['K/9'] = round(rank_series * 100)
def get_raw_bb(df_data):
return ((df_data['walk_vr'] / 108) * (2/3)) + ((df_data['walk_vl'] / 108) / 3)
return ((df_data['walk_vr'] / 108) * (2 / 3)) + ((df_data['walk_vl'] / 108) / 3)
raw_series = raw_data.apply(get_raw_bb, axis=1)
rank_series = raw_series.rank(pct=True)
@ -290,7 +327,7 @@ async def get_basic_scouting(cardset_id: list = Query(default=None)):
def get_raw_hr(df_data):
return 1 - (
(((df_data['homerun_vr'] + df_data['bp_homerun_vr']) / 108) * (2/3)) +
(((df_data['homerun_vr'] + df_data['bp_homerun_vr']) / 108) * (2 / 3)) +
(((df_data['homerun_vl'] + df_data['bp_homerun_vl']) / 108) / 3))
raw_series = raw_data.apply(get_raw_hr, axis=1)
@ -305,8 +342,8 @@ async def get_basic_scouting(cardset_id: list = Query(default=None)):
return (
((df_data['H/9'] + df_data['K/9'] + df_data['BB/9'] + df_data['HR/9']) * 5) +
(df_data['Fielding']) + (df_data['Stamina'] * 5) +
(((df_data['Stuff L'] / 3) + (df_data['Stuff R'] * (2/3))) * 4) +
(((df_data['Control L'] / 3) + (df_data['Control R'] * (2/3))) * 2)
(((df_data['Stuff L'] / 3) + (df_data['Stuff R'] * (2 / 3))) * 4) +
(((df_data['Control L'] / 3) + (df_data['Control R'] * (2 / 3))) * 2)
)
else:
return (
@ -324,7 +361,12 @@ async def get_basic_scouting(cardset_id: list = Query(default=None)):
'player_name', 'Rating', 'Control R', 'Control L', 'Stuff R', 'Stuff L', 'Stamina', 'Fielding', 'H/9', 'K/9',
'BB/9', 'HR/9', 'hand', 'cardset_name'
]]
return Response(content=output.to_csv(index=True), media_type='text/csv')
csv_file = pd.DataFrame(output).to_csv(index=False)
with open(BASIC_FILE, 'w') as file:
file.write(csv_file)
return Response(content=csv_file, media_type='text/csv')
@router.get('/{ratings_id}')