Uses smite-python API wrapper by Jayden Bailey https://github.com/jaydenkieran/smite-python/blob/master/smite.py
Edit main method before running all cells. Check comments in main method for more.
In [1]:
import json
import os, sys
from smite import SmiteClient, NoResultError # in working directory
from datetime import datetime, timedelta
import pandas as pd
import pickle
In [2]:
def writefile(filename, data):
with open(filename, 'w') as fout:
json.dump(data, fout)
def readfile(filename):
with open(filename, 'r') as fout:
return json.load(fout)
In [4]:
def get_all_items(smite):
# TODO update to be similar to get_all_gods.
# DANGER # I have manually put in total item cost and haven't yet coded a way to do that,
# Updating SMITE_Items_All_Lookup.csv will remove that column and break SmiteRecommender
writefile('SMITE_Items_All.json', smite.get_items())
print("Successfully updated Items_All file. Remember to manually update items lookup file")
def get_all_gods(smite):
# Updates god info from SMITE API and creates lookup file
god_info = smite.get_gods()
writefile('SMITE_data/SMITE_Gods_All.json', god_info)
all_gods = pd.DataFrame(god_info)
lookup = all_gods.loc[:,["Name", 'Pantheon', 'Roles', 'Title', 'Type', 'id', 'godCard_URL', 'godIcon_URL',
'godAbility1_URL', 'godAbility2_URL', 'godAbility3_URL', 'godAbility4_URL', 'godAbility5_URL']]
all_gods.to_csv("SMITE_data/SMITE_Gods_All.csv", index=None)
lookup.to_csv("SMITE_data/SMITE_Gods_All_Lookup.csv", index=None)
print("Successfully updated God lookup file")
def get_IDs(smite, date, game_mode=451, hour=-1):
""" Gets match_ids by date and gamemode from SMITE API.
returns output of check_IDs, a list of valid match ids
Gamemodes:
451 -ConquestLeague (ranked)
426 -Conquest (casual)
440 -Ranked Duel (1v1 joust map)
450 -Joust Ranked (3v3)
date example :20160423
hour=-1 (or 24) all day, or hour=0-23
"""
return(check_IDs(smite.get_match_ids_by_queue(game_mode, date, hour)))
def check_IDs(ids):
""" returns list of valid match ids """
match_ids = []
for match in ids:
if match['Active_Flag'] == 'n':
match_ids.append(match['Match'])
print("Number of failed IDs: {}".format(len(ids)-len(match_ids)))
return(match_ids)
def get_all_match_IDs(smite, start_date, stop_date, game_mode):
"""Get all match IDs for a specific game mode between two dates
date example :20160423
Returns a list of lists, one for each day
"""
all_ids=[]
start = datetime.strptime(str(start_date), "%Y%m%d")
stop = datetime.strptime(str(stop_date), "%Y%m%d")
while start < stop:
start = start + timedelta(days=1) # increase day one by one
date = int(start.strftime("%Y%m%d"))
try:
all_ids.append(get_IDs(smite, date, game_mode, hour=-1))
except NoResultError:
print("No result for", date)
return(all_ids)
In [5]:
def get_match_info(smite, match_ids, raw_folder, sorted_folder):
""" Given list of matches, writes (raw and sorted) csv files of 100 matches each,
labeled by earliest and latest game in YYYYMMDDHHmm-YYYYMMDDHHmm format.
sorted files are sorted by minematch().
Example filename: SMITE_raw_match_201610042230-201610042315
Params:
smite: smite-python SmiteClient object
match_ids: list of valid match_ids
raw_folder: folder (in current directory) to place raw csv files
sorted_folder: folder (in current directory) to place sorted csv files
"""
print("Begun")
df_raw = pd.DataFrame()
df_sorted = pd.DataFrame()
num_matches = 0
tot_num_matches = len(match_ids)
for id in match_ids:
num_matches += 1
# if num_matches%50==0:
# print(num_matches, "of", tot_num_matches)
try:
match = pd.DataFrame(smite.get_match_details(id))
except NoResultError:
print(id, "returned no data")
continue
mined = minematch(match)
df_raw = df_raw.append(match)
df_sorted = df_sorted.append(mined)
# save every 100 matches (raw and sorted)
if num_matches%100==0 or num_matches==tot_num_matches:
# get min/max date for naming file
min_date = pd.to_datetime(df_raw.Entry_Datetime).min().strftime('%Y%m%d%H%M')
max_date = pd.to_datetime(df_raw.Entry_Datetime).max().strftime('%Y%m%d%H%M')
# write files (and reset match dfs)
os.chdir(raw_folder)
df_raw.to_csv('SMITE_raw_match_{}-{}.csv'.format(min_date,max_date), index = False)
os.chdir('..')
df_raw = pd.DataFrame()
os.chdir(sorted_folder)
df_sorted.to_csv('SMITE_sorted_match_{}-{}.csv'.format(min_date,max_date), index = False)
os.chdir('..')
df_sorted = pd.DataFrame()
print('SMITE file written.', num_matches, "written so far." )
if num_matches%250==0:
print("SMITE API usage update:")
print(smite.get_data_used())
print("All match info retrieved.")
def minematch(match):
'''given a dataframe containing all match info, returns a df of relevant information'''
# return None if any god slots are missing, or someone never bought their first relic (afk)
if any(match.GodId==0):
return(None)
if any(match.ActiveId1.isnull()) or any(match.ActiveId1==0):
return(None)
# choose subset of variables to keep
df = match.loc[:,['Entry_Datetime',
'Match',
'name',
'Win_Status',
'GodId',
# 'Reference_Name',
# 'Item_Active_1',
# 'Item_Active_2',
# 'Item_Purch_1',
# 'Item_Purch_2',
# 'Item_Purch_3',
# 'Item_Purch_4',
# 'Item_Purch_5',
# 'Item_Purch_6',
'ActiveId1',
'ActiveId2',
'ItemId1',
'ItemId2',
'ItemId3',
'ItemId4',
'ItemId5',
'ItemId6',
'Gold_Per_Minute',
# 'Time_In_Match_Seconds',
'Minutes'
# 'Kills_First_Blood',
# 'Kills_Fire_Giant',
# 'Kills_Gold_Fury',
# 'Kills_Phoenix',
# 'Mastery_Level',
# 'Conquest_Tier',
# 'Conquest_Wins'
]]
# add Win_Ratio
# df["Conquest_Win_Ratio"]=round(match.Conquest_Wins/(match.Conquest_Wins + match.Conquest_Losses),2)
# change some variable names
df = df.rename(columns={"ActiveId1" : "relic0",
"ActiveId2" : 'relic1',
'Entry_Datetime' : 'match_time',
'name' : "game_mode_name",
'Match' : "match_id",
'Win_Status' : "win",
'GodId' : 'god_id',
'Reference_Name' : "god_name",
'ItemId1' : 'item0',
'ItemId2' : 'item1',
'ItemId3' : 'item2',
'ItemId4' : 'item3',
'ItemId5' : 'item4',
'ItemId6' : 'item5',
# 'Time_In_Match_Seconds' : "duration"
'Minutes' : "duration_min"
})
df.win=df.win.replace({'Winner': True, 'Loser': False})
return(df)
Using smite-python by jaydenkieran as wrapper for SMITE API requests, with smite.py in working directory.
https://github.com/jaydenkieran/smite-python/blob/master/smite.py
Every call to the API is counting as 2 requests, either due to the wrapper or the SMITE API. API method information: http://smite-python.readthedocs.io/en/latest/api.html
SMITE measures time in Universal Time Coordinated (UTC), 8 hours ahead of Pacific time. But Smite API appears to reset request counts at 11:00PM pacific. SMITE API only allows 7500 request a day.
Patch notes happen every 2 weeks on a wednesday. Not sure when they actually go live. Patch 3.21 happened on 11/02/2016, but as of 11/06/2016 ping() still returns patch 3.20 (3.21 on 11/9)
In [18]:
def main():
# edit to choose what main's function should be
get_matches = False # get all match info for a particular day
get_matchIDs = False # get all valid matchids between two dates (could be useful for scraping)
update_gods = False # update if there are new gods/changes
update_items = False # if there are new items/changes
# for get_matches
date = 20161101
hour = -1
raw_folder = 'SMITE_raw'
sorted_folder = 'SMITE_sorted'
# for get_matchIDs
start_date = 20161107
end_date = 20161114
# for both methods
game_mode = 451
# Gamemodes:
# 451 -ConquestLeague (ranked)
# 426 -Conquest (casual)
# 440 -Ranked Duel (1v1 joust map)
# 450 -Joust Ranked (3v3)
# 448 -Joust Casual
# date format: 20141231
# -1 or 24 (all hours)
# 0-23 (1 hour UTC)
####### Initialize Smite API connection #######
# import config
config = readfile('config')
key = config['smite']['smitekey{}'.format(1)] # Micah's key
devID = config['smite']['smitedevID{}'.format(1)] # Micah's devID
smite = SmiteClient(devID,key)
print(smite.ping())
############### main method ########################
# update item and god files in wd
if update_gods:
get_all_gods(smite)
if update_items:
get_all_items(smite)
if get_matches:
match_ids = get_IDs(smite, date, game_mode, hour)
get_match_info(smite, match_ids, raw_folder, sorted_folder)
if get_matchIDs:
all_match_ids = get_all_match_IDs(smite, start_date, end_date, game_mode)
if game_mode == 451:
mode = 'ranked'
elif game_mode == 426:
mode = 'casual'
elif game_mode == 450:
mode = 'joust_ranked'
elif game_mode == 440:
mode = 'duel_ranked'
else:
mode = 'othermodes'
pickle.dump(all_match_ids, open("SMITE_data/{}_match_ids_{}-{}.p".format(mode, start_date, end_date), "wb"))
if __name__ == '__main__':
main()
In [6]:
"""
# Configure for interactions with Smite API outside of main method
config = readfile('config')
key = config['smite']['smitekey{}'.format(1)] # Micah's key
devID = config['smite']['smitedevID{}'.format(1)] # Micah's devID
smite = SmiteClient(devID,key)
print(smite.ping())
"""
In [1]:
"""
#failed_matches_list = pickle.load(open("SMITE_data/failed_match_list.p", "rb"))
len(failed_matches_list)
raw_folder = 'SMITE_scraped_raw_joust'
sorted_folder = 'SMITE_scraped_parsed_joust'
get_match_info(smite, failed_matches_list, raw_folder, sorted_folder)
"""
Out[1]: