Skip to content

Commit

Permalink
Add more documentation, tests, type hinting.
Browse files Browse the repository at this point in the history
  • Loading branch information
zusorio committed May 12, 2020
1 parent 65c38c3 commit edca30f
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 35 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import pyowapi
# For a single player
player = pyowapi.get_player("Jayne#1447")
print(player.success)
print(player.actual_level)
print(player.private)
print(player.competitive_tank)
Expand All @@ -35,6 +36,8 @@ for single_player in players:
print(player.actual_level)
A player has the following properties
print(player.bnet) # The battletag of the Player
print(player.success) # If the request was successful
print(player.level) # The number in Overwatch without stars calculated in
print(player.prestige) # The number of stars in Overwatch
print(player.actual_level) # The full level with stars calculated in
Expand Down
92 changes: 59 additions & 33 deletions pyowapi/__init__.py
Original file line number Diff line number Diff line change
@@ -1,40 +1,40 @@
import asyncio
import aiohttp
from typing import List
from typing import List, Union


class Player:
def __init__(self, bnet, response):
self.bnet = bnet
self.success = "error" not in response
def __init__(self, bnet: str, response: dict):
self.bnet: str = bnet
self.success: bool = "error" not in response
if self.success:
self.level = response["level"]
self.prestige = response["prestige"]
self.actual_level = self.prestige * 100 + self.level
self.private = response["private"]
self.endorsement = response["endorsement"]
self.level: int = response["level"]
self.prestige: int = response["prestige"]
self.actual_level: int = self.prestige * 100 + self.level
self.private: bool = response["private"]
self.endorsement: int = response["endorsement"]

if not self.private:
self.quickplay_stats = response["competitiveStats"]
self.quickplay_cards = self.quickplay_stats["awards"]["cards"]
self.quickplay_medals = self.quickplay_stats["awards"]["medals"]
self.quickplay_medals_bronze = self.quickplay_stats["awards"]["medalsBronze"]
self.quickplay_medals_silver = self.quickplay_stats["awards"]["medalsSilver"]
self.quickplay_medals_gold = self.quickplay_stats["awards"]["medalsGold"]
self.quickplay_games_won = self.quickplay_stats["games"]["won"]

self.competitive_stats = response["competitiveStats"]
self.competitive_cards = self.competitive_stats["awards"]["cards"]
self.competitive_medals = self.competitive_stats["awards"]["medals"]
self.competitive_medals_bronze = self.competitive_stats["awards"]["medalsBronze"]
self.competitive_medals_silver = self.competitive_stats["awards"]["medalsSilver"]
self.competitive_medals_gold = self.competitive_stats["awards"]["medalsGold"]
self.competitive_games_played = self.competitive_stats["games"]["played"]
self.competitive_games_won = self.competitive_stats["games"]["won"]

self.competitive_tank = False
self.competitive_damage = False
self.competitive_support = False
self.quickplay_stats: dict = response["competitiveStats"]
self.quickplay_cards: int = self.quickplay_stats["awards"]["cards"]
self.quickplay_medals: int = self.quickplay_stats["awards"]["medals"]
self.quickplay_medals_bronze: int = self.quickplay_stats["awards"]["medalsBronze"]
self.quickplay_medals_silver: int = self.quickplay_stats["awards"]["medalsSilver"]
self.quickplay_medals_gold: int = self.quickplay_stats["awards"]["medalsGold"]
self.quickplay_games_won: int = self.quickplay_stats["games"]["won"]

self.competitive_stats: dict = response["competitiveStats"]
self.competitive_cards: int = self.competitive_stats["awards"]["cards"]
self.competitive_medals: int = self.competitive_stats["awards"]["medals"]
self.competitive_medals_bronze: int = self.competitive_stats["awards"]["medalsBronze"]
self.competitive_medals_silver: int = self.competitive_stats["awards"]["medalsSilver"]
self.competitive_medals_gold: int = self.competitive_stats["awards"]["medalsGold"]
self.competitive_games_played: int = self.competitive_stats["games"]["played"]
self.competitive_games_won: int = self.competitive_stats["games"]["won"]

self.competitive_tank: Union[bool, int] = False
self.competitive_damage: Union[bool, int] = False
self.competitive_support: Union[bool, int] = False

if response["ratings"]:
for rating in response["ratings"]:
Expand All @@ -49,7 +49,13 @@ def __repr__(self):
return f"<Player {self.bnet} success: {self.success}>"


async def _get_player_internal(player: str, session):
async def _get_player_internal(player: str, session: aiohttp.ClientSession) -> Player:
"""
Uses an aiohttp session to get a player. This is a coroutine and must be awaited.
:param player: String that is the players battletag
:param session: An aiohttp ClientSession
:return: A Player object
"""
try:
async with session.get(f"https://ow-api.com/v1/stats/pc/eu/{player.replace('#', '-')}/profile") as resp:
data = await resp.json()
Expand All @@ -59,24 +65,44 @@ async def _get_player_internal(player: str, session):


async def _get_player(player: str) -> Player:
"""
This is a coroutine and must be awaited.
:param player: String that is the players battletag
:return: A Player object
"""
async with aiohttp.ClientSession() as session:
result = await _get_player_internal(player, session)
return result


def get_player(player: str):
def get_player(player: str) -> Player:
"""
Automatically creates event loop. Does not work with programs that already have an event loop, await _get_player instead
:param player: String that is the players battletag
:return: A Player object
"""
loop = asyncio.get_event_loop()
result = loop.run_until_complete(_get_player(player))
return result


async def _get_bulk_players(players: list) -> List[Player]:
async def _get_bulk_players(players: List[str]) -> List[Player]:
"""
This is a coroutine and must be awaited.
:param players: List of strings of the players battletags
:return: A list of Player objects
"""
async with aiohttp.ClientSession() as session:
result = await asyncio.gather(*[_get_player_internal(player, session) for player in players])
return result


def get_bulk_players(players: list) -> List[Player]:
def get_bulk_players(players: List[str]) -> List[Player]:
"""
Automatically creates event loop. Does not work with programs that already have an event loop, await _get_bulk_players instead
:param players: List of strings of the players battletags
:return: A list of Player objects
"""
loop = asyncio.get_event_loop()
result = loop.run_until_complete(_get_bulk_players(players))
return result
8 changes: 7 additions & 1 deletion pyowapi/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@


class TestAPI(TestCase):
def test_api_working(self):
def test_single_player(self):
player = pyowapi.get_player("Jayne#1447")
print(player)
self.assertTrue(player.success)
self.assertTrue(isinstance(player.actual_level, int))

def test_multiple_players(self):
players = pyowapi.get_bulk_players(["Jayne#1447"])
for player in players:
self.assertTrue(player.success)
self.assertTrue(isinstance(player.actual_level, int))
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setuptools.setup(
name="pyowapi",
version="0.0.6",
version="1.0.0",
author="Tobias Messner",
author_email="[email protected]",
description="An asynchronous wrapper for ow-api.com using aiohttp",
Expand Down

0 comments on commit edca30f

Please sign in to comment.