meraki-analytics / cassiopeia

An all-inclusive Python framework for the Riot Games League of Legends API. Cass focuses on making the data easy and fun to work with, while providing all the tools necessary to create a website or do data analysis.
MIT License
552 stars 135 forks source link

Summoner Match History Limited to 20 #403

Closed WeldFire closed 2 years ago

WeldFire commented 2 years ago

Hello,

I am coming back to work with Cass since the Cass 3.0/Riot v5 update.

Previously I was able to make a call in the following fashion to get every match for a particular summoner

summoner = cass.get_summoner(name=summoner_name, region="NA")
total_games = len(summoner.match_history)

For some reason now I only get 20 matches back regardless of settings. Documentation seems to still support that it should return all matches and not just the latest 20, but maybe I'm missing something?

kierk commented 2 years ago

In the new Matchv5 the riot API uses start and count for match history and defaults to 0 and 20 respectively. see: https://developer.riotgames.com/apis#match-v5/GET_getMatchIdsByPUUID params. On the most recent master, Cass is mapping the begin_index arg to start and the end_index arg to count. I have been pulling by the max count of 100 and looping for 100 records in the match history at a time (increasing both indexes +100 every loop).

Hope this helps

WeldFire commented 2 years ago

Awesome, while this isn't ideal, that is certainly a good workaround for now, thank you @kierk!

wllyng commented 2 years ago

Hi, myself and another contributor are interested in working on this issue. What would be the best way to get started?

WeldFire commented 2 years ago

Hi, myself and another contributor are interested in working on this issue. What would be the best way to get started?

Download the current master branch (since I'm unsure if this has been pushed to pip yet) and install via pip to your machine

Then you can loop through the match history 100 records at a time using code similar to this rough draft I made to get your full match history again:

def get_full_match_history(summoner):
    total_matches = 0
    fetched_records = 1
    full_history = None

    while fetched_records > 0:
        history = cass.get_match_history(
                continent = summoner.region.continent, 
                region = summoner.region, 
                platform = summoner.region.platform, 
                puuid = summoner.puuid, 
                begin_index = total_matches, 
                end_index = total_matches+100)

        if full_history is None:
            full_history = history
        else:
            full_history.extend(history)

        fetched_records = len(history)
        total_matches = total_matches + fetched_records

    return full_history

(Please note there are probably more Pythonic and efficient ways to do this) #

Weebywoo commented 2 years ago

No matter how high end_index is, as long as it's in the range of 0 -100, I always get a list of 20 games. Whenever end_index - begin_index < 21 I get the following error message:

Traceback (most recent call last):
  File "D:\SOFTWARE\Python392\lib\runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "D:\SOFTWARE\Python392\lib\runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "D:\DATA\Code\Python\League of Legends Stats\lol_support_stats\__main__.py", line 32, in <module>
    main()
  File "D:\DATA\Code\Python\League of Legends Stats\lol_support_stats\__main__.py", line 25, in main
    print(len(match_history))
  File "D:\SOFTWARE\Python392\lib\site-packages\merakicommons\container.py", line 363, in __len__
    self._generate_more()
  File "D:\SOFTWARE\Python392\lib\site-packages\merakicommons\container.py", line 380, in _generate_more
    for _ in self:
  File "D:\SOFTWARE\Python392\lib\site-packages\merakicommons\container.py", line 355, in __iter__
    yield next(self)
  File "D:\SOFTWARE\Python392\lib\site-packages\merakicommons\container.py", line 368, in __next__
    value = next(self._generator)
  File "D:\SOFTWARE\Python392\lib\site-packages\cassiopeia\datastores\ghost.py", line 454, in generate_matchlists
    _earliest_dt_in_current_match_history = matchrefdata.creation
AttributeError: 'MatchReferenceData' object has no attribute 'creation'

The code I used is quite simple:

summoner = cassiopeia.Summoner(name=summoner_name, region="EUW")
match_history = cassiopeia.get_match_history(
    continent=summoner.region.continent,
    region=summoner.region,
    platform=summoner.region.platform,
    puuid=summoner.puuid,
    begin_index=0,
    end_index=20)
print(len(match_history))

Using these parameters on the website @kierk mention, I get the desired amount of games. I'm using Cassiopeia 5.0.1, is this a known issue?

I apologize, if my question / complaint is worded incorrectly or was sent in the wrong place.

WeldFire commented 2 years ago

Yeah, I get that issue too :/

I resorted to manually removing that line, but never spent time fully understanding why it was there.

I created this issue #404 which has instructions to temporarily fix that bug. I was hoping we could get it repaired in a more permanent way but it looks like it still has gotten any traction yet :(

dillonplunkett commented 2 years ago

@WeldFire, were you able to get the looping approach to work? I'm using the latest master and finding that I get the most recent 20 matches regardless of what value I pass to begin_index (or end_index, for that matter).

jjmaldonis commented 2 years ago

Hey all, this is probably the biggest issue with Cass at the moment. I haven't used the Riot API in a long time. We would love for someone to contribute a fix for this. We will get to it at some point but life has been busy lately. Hopefully we will have some time soon.

WeldFire commented 2 years ago

Hey Dillonplunkett, yes the example I provided worked. Were you on the latest Master branch?

dillonplunkett commented 2 years ago

Hey Dillonplunkett, yes the example I provided worked. Were you on the latest Master branch?

I'm on the latest master branch and just copied your snippet to test after some very minimal preamble code:

import cassiopeia as cass

with open("credentials.txt", "r") as f:
    api_key = f.readline().strip()
cass.set_riot_api_key(api_key)

summoner = cass.Summoner(name="some_summoner_name", region="NA")

But I just get the most recent 20 matches on each iteration of the loop. (I didn't remove that line you mention in #404, but that's only relevant to the issue created by trying to fetch fewer than 21 matches.)

Not sure what's going on.

WeldFire commented 2 years ago

Not sure what's going on.

Hmm lemme try really quick in a new venv

404 still appears to be necessary for me, I'm not sure I follow what you are trying to do with the recent 20 matches.

Was able to get the following to work: (Make sure to replace your RGAPI key!)

API_KEY="RGAPI-"
mkdir -p /tmp/cass_test
cd /tmp/cass_test
git clone https://github.com/meraki-analytics/cassiopeia.git
python3 -m venv env
source env/bin/activate
echo "Comment out lines 691 - 707"
sed -i '691,707d' /tmp/cass_test/cassiopeia/cassiopeia/datastores/ghost.py
cd cassiopeia
python setup.py install
cd ../
cat <<EOF > test.py
import cassiopeia as cass

cass.set_riot_api_key("$API_KEY")

summoner = cass.Summoner(name="weldfire", region="NA")

def get_full_match_history(summoner):
    total_matches = 0
    fetched_records = 1
    full_history = None

    while fetched_records > 0:
        history = cass.get_match_history(
                continent = summoner.region.continent, 
                region = summoner.region, 
                platform = summoner.region.platform, 
                puuid = summoner.puuid, 
                begin_index = total_matches, 
                end_index = total_matches+100)

        if full_history is None:
            full_history = history
        else:
            full_history.extend(history)

        fetched_records = len(history)
        total_matches = total_matches + fetched_records

    return full_history

full_match_history = get_full_match_history(summoner)
print(f'Finished pulling {summoner.name}, they had {len(full_match_history)} games on this account')

EOF
python test.py

Should provide you with something like this:

(env) weldfire@weldfire:/tmp/cass_test$ python test.py
Making call: https://na1.api.riotgames.com/lol/summoner/v4/summoners/by-name/weldfire
Making call: https://americas.api.riotgames.com/lol/match/v5/matches/by-puuid/WKgRTiwSszzYqD7RQoIxLskkr3dT3sX_BSwlSWf-Z4kf0U7Uqa96TPnRSpqrUJyXBB6OpsanMN5pRg/ids?start=0&count=100
Making call: https://americas.api.riotgames.com/lol/match/v5/matches/by-puuid/WKgRTiwSszzYqD7RQoIxLskkr3dT3sX_BSwlSWf-Z4kf0U7Uqa96TPnRSpqrUJyXBB6OpsanMN5pRg/ids?start=100&count=100
Making call: https://americas.api.riotgames.com/lol/match/v5/matches/by-puuid/WKgRTiwSszzYqD7RQoIxLskkr3dT3sX_BSwlSWf-Z4kf0U7Uqa96TPnRSpqrUJyXBB6OpsanMN5pRg/ids?start=200&count=100
Making call: https://americas.api.riotgames.com/lol/match/v5/matches/by-puuid/WKgRTiwSszzYqD7RQoIxLskkr3dT3sX_BSwlSWf-Z4kf0U7Uqa96TPnRSpqrUJyXBB6OpsanMN5pRg/ids?start=300&count=100
Making call: https://americas.api.riotgames.com/lol/match/v5/matches/by-puuid/WKgRTiwSszzYqD7RQoIxLskkr3dT3sX_BSwlSWf-Z4kf0U7Uqa96TPnRSpqrUJyXBB6OpsanMN5pRg/ids?start=400&count=100
Making call: https://americas.api.riotgames.com/lol/match/v5/matches/by-puuid/WKgRTiwSszzYqD7RQoIxLskkr3dT3sX_BSwlSWf-Z4kf0U7Uqa96TPnRSpqrUJyXBB6OpsanMN5pRg/ids?start=500&count=100
Making call: https://americas.api.riotgames.com/lol/match/v5/matches/by-puuid/WKgRTiwSszzYqD7RQoIxLskkr3dT3sX_BSwlSWf-Z4kf0U7Uqa96TPnRSpqrUJyXBB6OpsanMN5pRg/ids?start=600&count=100
Making call: https://americas.api.riotgames.com/lol/match/v5/matches/by-puuid/WKgRTiwSszzYqD7RQoIxLskkr3dT3sX_BSwlSWf-Z4kf0U7Uqa96TPnRSpqrUJyXBB6OpsanMN5pRg/ids?start=700&count=100
Making call: https://americas.api.riotgames.com/lol/match/v5/matches/by-puuid/WKgRTiwSszzYqD7RQoIxLskkr3dT3sX_BSwlSWf-Z4kf0U7Uqa96TPnRSpqrUJyXBB6OpsanMN5pRg/ids?start=800&count=100
Making call: https://americas.api.riotgames.com/lol/match/v5/matches/by-puuid/WKgRTiwSszzYqD7RQoIxLskkr3dT3sX_BSwlSWf-Z4kf0U7Uqa96TPnRSpqrUJyXBB6OpsanMN5pRg/ids?start=900&count=100
Making call: https://americas.api.riotgames.com/lol/match/v5/matches/by-puuid/WKgRTiwSszzYqD7RQoIxLskkr3dT3sX_BSwlSWf-Z4kf0U7Uqa96TPnRSpqrUJyXBB6OpsanMN5pRg/ids?start=991&count=100
Finished pulling WeldFire, they had 991 games on this account
WeldFire commented 2 years ago

Any luck @dillonplunkett?

dillonplunkett commented 2 years ago

Sorry, I'm only seeing this now because I didn't get a notification about your edit, only the original message, so I didn't realize you'd followed up. Yes! Once I comment out the lines that you flag in #404, the looping approach works. Thank you!

WeldFire commented 2 years ago

Ah, sorry about that. I'm happy to help!

j4n7 commented 2 years ago

Thank you @WeldFire for all your advice.

To sum up, all the steps you need to avoid match history being limited to 20:

  1. Update Cassiopeia to its latest version with this command: pip install git+https://github.com/meraki-analytics/cassiopeia.git If you already have it installed you can force an upgrade adding this flag at the end of the previous command: --upgrade

  2. Go to .../site-packages/cassiopeia/datastores/ghost.py and comment out lines 690 to 707.

WeldFire commented 2 years ago

Thank you @WeldFire for all your advice.

To sum up, all the steps you need to avoid match history being limited to 20:

  1. Update Cassiopeia to its latest version with this command: pip install git+https://github.com/meraki-analytics/cassiopeia.git If you already have it installed you can force an upgrade adding this flag at the end of the previous command: --upgrade
  2. Go to .../site-packages/cassiopeia/datastores/ghost.py and comment out lines 690 to 707.

Happy to help! Yep, that should be enough to get more than 20 results from the match history query!

jjmaldonis commented 2 years ago

Thanks all! This is one of the best threads I've read - thanks for all the info and the fixes. It was very helpful when going through this.

WeldFire commented 2 years ago

Happy to help!