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.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Ddragon not working

Iznardo opened this issue · comments

commented

Ddragon update is using the version 10.10.3208608 but the library is trying to get the json from the old ddragon format (10.10.1)

commented

I confirm, the issue is coming from the way the static data version is created by concatenating the very last part that used always to be .1: version = ".".join(version.split(".")[:2]) + ".1"
Problem is, the match's version isn't directly useable either given it could be different than the one used to timestamp the static data:

>>> m = Match(id=4598304728, region='EUW')
>>> m.version
'10.10.320.3039'

While the current static data version is 10.10.3208608.

Thanks for the extra info on this. So it looks like we're going to have to figure out a better way to identify the static data version that corresponds to a given match.

Maybe we need to use cass.get_versions() to retrieve the available versions from ddragon, and then compare the match.version with the returned versions from ddragon, and somehow choose one.

Lines 59 and 62 in this function need to be changed:

def _choose_staticdata_version(match):

I'll work on a fix after work, but if anyone has code to go from a match version to a ddragon version (given the list of versions in ddragon's version.json file), please let me know.

commented

I didn't think about the fact the current fix I provided would not work in a multithreaded environment and throw a ValueError: generator already executing. Is there a way to use cass.get_versions() in a safe way regarding that?

I'm going to merge your PR anyways. Thank you for doing this, it looks great.

I did a bit of googling and there is a way to make generators thread safe by putting a lock around them. In your code, you don't have control over locking just that one call do you? You'd have to put a lock around the entire match.load()?

commented

Thanks, glad to help.

I guess the user could handle it directly on his end indeed, but personally I'd like to avoid doing so. I was thinking maybe a better way around this would be for cass to build and store a major.minor to static data version map the first time the lookup is needed. What do you think?

I like that. I just made a commit doing that. Thanks again for the PR.

I made a new release of Cass on pypi as well.

commented

That looks good but I was thinking about a full loading of the mapping during cass' init to make sure everything is ready before any concurrent call. As it is right now, the lazy loading is still subject to the generator error in a multithreaded environment, at least in my scenario.

For now, I am calling this function right at the end of apply_settings call:

def init_staticdata_to_version_mapping(region):
    versions = Versions(region=region)
    for v in versions:
        _staticdata_to_version_mapping[".".join(v.split(".")[:2])] = v

It may be overkill for most of the users tho, so I am not sure you'd want a PR for it. Let me know if you do.

Ahh I see what you mean. I think it's good to leave that as something that users can implement if they want. Partly because I'd like to minimize the amount of time it takes to just import Cass. If people don't need the match functionality, for example, this wouldn't be useful for them to load at startup. And thanks again!

commented

Yes, probably better indeed!

Anyways, Riot just went ahead and released another static data that shares the 10.10.x prefix, meaning the mappings we built isn't guaranteed to be correct anymore. Also, it seems that the realms.json isn't updated so core.common.get_latest_version can return the wrong version.

I am using this for now:

def get_latest_version(region: Union[Region, str], endpoint: Optional[str]):
    if endpoint is not None:
        from .staticdata.realm import Realms
        return Realms(region=region).latest_versions[endpoint]
    else:
        from .staticdata.version import Versions
        return Versions(region=region)[0]