Metadata-Version: 2.1
Name: wzlight
Version: 0.1.3
Summary: Light asynchronous wrapper for COD Warzone API
Home-page: https://github.com/matthieuvion/wzlight
License: MIT
Keywords: warzone,API,asynchronous,httpx
Author: Matthieu Vion
Author-email: viomatthieu@gmail.com
Requires-Python: >=3.10,<4.0
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Requires-Dist: async-lru (>=1.0.3,<2.0.0)
Requires-Dist: backoff (>=2.1.2,<3.0.0)
Requires-Dist: httpx[http2] (>=0.23.0,<0.24.0)
Requires-Dist: jupyterlab (>=3.4.3,<4.0.0)
Requires-Dist: python-dotenv (>=0.20.0,<0.21.0)
Project-URL: Repository, https://github.com/matthieuvion/wzlight
Description-Content-Type: text/markdown


# wzlight

[![MIT License](https://img.shields.io/apm/l/atomic-design-ui.svg?)](https://github.com/tterb/atomic-design-ui/blob/master/LICENSEs)
[![made-with-python](https://img.shields.io/badge/Made%20with-Python-1f425f.svg)](https://www.python.org/)


`wzlight` is an asynchronous Python wrapper for the Call of Duty API
that focuses on Warzone endpoints.

## Features

- Asynchronous with help of HTTPX, the HTTP client library
- Light : only centered around the few GET methods to collect Warzone stats
- Handle SSO auth. the (now) only available way to connect to the API

## Installation

```bash
  # with pip
  pip install wzlight
```
```bash
  # with Poetry
  poetry add wzlight
```

    
## Client usage

```
import os
import asyncio
from pprint import pprint

from dotenv import load_dotenv

from wzlight import Api


async def main():

    load_dotenv()
    sso = os.environ["SSO"]
    username = "amadevs#1689"
    platform = "battle"

    # Initialize Api/client httpx.session
    # SSO value can be found inspecting your browser while logging-in to callofduty.com

    api = Api(sso)

    # Get a player's profile

    profile = await api.GetProfile(platform, username)
    pprint(profile, depth=2)

    # Get last 20 recent matches
    # Another client method allows to specify start/end timestamsps

    recent_matches = await api.GetRecentMatches(platform, username)
    recent_matches_short = [match for match in recent_matches[:2]]
    pprint(recent_matches_short, depth=3)

    # Get 1000 last played matchId, platform, matchType (id), timestamp

    matches = await api.GetMatches(platform, username)
    matches_short = [match for match in matches[:5]]
    pprint(matches_short)

    # Get detailed stats about a match, given a matchId

    match_details = await api.GetMatch(platform, matchId=3196515799358056305)
    match_details_short = [player for player in match_details[:2]]
    pprint(match_details_short, depth=3)

if __name__ == "__main__":
    asyncio.run(main())
```
### Focus : example of a concurrent run

```
    # On match details endpoint, given a list of matchIds

    # COD API is unofficial and undocumented, rate limits / restrictions are not known
    # However you should --at least, handle some concurrency limits e.g for fetching a batch of matchs
    # See. httpx.Limits, async.Semaphore or other librairies such as aiometer

    # basic concurrency limit using async.Semaphore :
    
    limit = asyncio.Semaphore(2)

    async def safe_GetMatch(platform, matchId):
        # no more than two concurrent tasks
        async with limit:
            r = await api.GetMatch(platform, matchId)
        if limit.locked():
            print("Concurrency limit reached, waiting ...")
            await asyncio.sleep(1)

    matchIds = [
        11378702801403672847,
        18088202254080399946,
        5850171651963062771,
        6910618934945378397,
        16975576559940046894,
        639235311963231866,
        11887968911271282782,
        7897970481732864368,
    ]

    tasks = []
    for matchId in matchIds:
        tasks.append(safe_GetMatch(platform, matchId))
    await asyncio.gather(*tasks)
    print(len(tasks))
```

## Acknowledgements
![Love](https://img.shields.io/badge/Love-pink?style=flat-square&logo=data:image/svg%2bxml;base64,PHN2ZyByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+R2l0SHViIFNwb25zb3JzIGljb248L3RpdGxlPjxwYXRoIGQ9Ik0xNy42MjUgMS40OTljLTIuMzIgMC00LjM1NCAxLjIwMy01LjYyNSAzLjAzLTEuMjcxLTEuODI3LTMuMzA1LTMuMDMtNS42MjUtMy4wM0MzLjEyOSAxLjQ5OSAwIDQuMjUzIDAgOC4yNDljMCA0LjI3NSAzLjA2OCA3Ljg0NyA1LjgyOCAxMC4yMjdhMzMuMTQgMzMuMTQgMCAwIDAgNS42MTYgMy44NzZsLjAyOC4wMTcuMDA4LjAwMy0uMDAxLjAwM2MuMTYzLjA4NS4zNDIuMTI2LjUyMS4xMjUuMTc5LjAwMS4zNTgtLjA0MS41MjEtLjEyNWwtLjAwMS0uMDAzLjAwOC0uMDAzLjAyOC0uMDE3YTMzLjE0IDMzLjE0IDAgMCAwIDUuNjE2LTMuODc2QzIwLjkzMiAxNi4wOTYgMjQgMTIuNTI0IDI0IDguMjQ5YzAtMy45OTYtMy4xMjktNi43NS02LjM3NS02Ljc1em0tLjkxOSAxNS4yNzVhMzAuNzY2IDMwLjc2NiAwIDAgMS00LjcwMyAzLjMxNmwtLjAwNC0uMDAyLS4wMDQuMDAyYTMwLjk1NSAzMC45NTUgMCAwIDEtNC43MDMtMy4zMTZjLTIuNjc3LTIuMzA3LTUuMDQ3LTUuMjk4LTUuMDQ3LTguNTIzIDAtMi43NTQgMi4xMjEtNC41IDQuMTI1LTQuNSAyLjA2IDAgMy45MTQgMS40NzkgNC41NDQgMy42ODQuMTQzLjQ5NS41OTYuNzk3IDEuMDg2Ljc5Ni40OS4wMDEuOTQzLS4zMDIgMS4wODUtLjc5Ni42My0yLjIwNSAyLjQ4NC0zLjY4NCA0LjU0NC0zLjY4NCAyLjAwNCAwIDQuMTI1IDEuNzQ2IDQuMTI1IDQuNSAwIDMuMjI1LTIuMzcgNi4yMTYtNS4wNDggOC41MjN6Ii8+PC9zdmc+)  
Inspiration (heavily) came from :  
Also check those links if your need documentation on how the API works
 - [EthanC/CallofDuty.py](https://github.com/EthanC/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](https://github.com/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](https://github.com/valtov/WarzoneStats) : very clean synch. Python wrapper by the creator of wzstats.gg

## License

[MIT](https://choosealicense.com/licenses/mit/)

