Package: wzlight
wzlightwzlightis an asynchronous Python wrapper for the Call of Duty API
that focuses on Warzone endpoints.FeaturesAsynchronous with help of HTTPX, the HTTP client libraryLight : only centered around the few GET methods to collect Warzone statsHandle SSO auth. the (now) only available way to connect to the APIInstallation# with pippipinstallwzlight# with PoetrypoetryaddwzlightClient usageimportosimportasynciofrompprintimportpprintimporthttpxfromdotenvimportload_dotenvfromwzlightimportApiasyncdefmain():load_dotenv()sso=os.environ["SSO"]username="amadevs#1689"platform="battle"# Initialize Api with a SSO token# SSO token can be found in browser while login-in to callofduty.comapi=Api(sso)# Wrapper internal methods are using the httpx async HTTP library# Initially httpx.AsyncClient) was built in its own cls, but letting users define it at app-level --as a context manager,# ensures more robustness and flexibility (custom timeout, limits...) and prevent async loop event errors.# Thus, your main() should follow the preferred approach while working with an async http client:asyncwithhttpx.AsyncClient()ashttpxClient:profile=awaitapi.GetProfile(httpxClient,platform,username)pprint(profile,depth=2)recent_matches=awaitapi.GetRecentMatches(httpxClient,platform,username)recent_matches_short=[matchformatchinrecent_matches[:2]]pprint(recent_matches_short,depth=3)matchStats=awaitapi.GetMatch(httpxClient,platform,matchId=11378702801403672847)pprint(matchStats,depth=1)if__name__=="__main__":asyncio.run(main())Focus : example of a concurrent runimportosimportasynciofrompprintimportpprintimporthttpxfromdotenvimportload_dotenvfromtypingimportAsyncContextManagerfromwzlightimportApiasyncdefmain():load_dotenv()sso=os.environ["SSO"]username="amadevs#1689"platform="battle"# Initialize Api with a SSO tokenapi=Api(sso)# We're running concurrently on match details endpoint, given a list of matchIds# COD API is unofficial and undocumented, rate limits / restrictions are not known# So you should probably --at least, handle some concurrency limits e.g for fetching a batch of matchs# See. httpx.Limits, async.Semaphore or other librairies such as aiometermatchIds=[5850171651963062771,6910618934945378397,16975576559940046894,639235311963231866,11887968911271282782,7897970481732864368,]# enclose api.getMatch into safe_GetMatch that accept a Semaphore threshold arg.limit=asyncio.Semaphore(2)asyncdefsafe_GetMatch(httpxClient,platform,matchId,sema:AsyncContextManager):# No more than two concurrent tasks. If reaches two, wait 1 secasyncwithsema:r=awaitapi.GetMatch(httpxClient,platform,matchId)ifsema.locked():print("Concurrency limit reached, waiting ...")awaitasyncio.sleep(1)returnr# Do not forget to open Client as context manager :asyncwithhttpx.AsyncClient()ashttpxClient:sema=asyncio.Semaphore(2)tasks=[]formatchIdinmatchIds:tasks.append(safe_GetMatch(httpxClient,platform,matchId,sema))results=awaitasyncio.gather(*tasks,return_exceptions=True)returnresultssprint(len(results))if__name__=="__main__":asyncio.run(main())AcknowledgementsInspiration (heavily) came from :Also check those links if your need documentation on how the API worksEthanC/CallofDuty.py: the most complete but now slightly deprecated (mainly the Auth.), async COD client (lot of exploited endpoints and methods + more than WZ)Lierrmm/Node-CallOfDuty: very clean async. wrapper written in NodeJS. Also check their Discord to get a grip on API subtleties and unofficial changes (privacy changes, rate limits etc)valtov/WarzoneStats: very clean synch. Python wrapper by the creator of wzstats.ggLicenseMIT