Skip to content

Commit

Permalink
Added locale optional query parameter on heroes, roles and gamemodes …
Browse files Browse the repository at this point in the history
…routes (#10)
  • Loading branch information
Valentin Porchet authored Jan 25, 2023
1 parent be707a0 commit 748948c
Show file tree
Hide file tree
Showing 19 changed files with 120 additions and 66 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
## 👷 W.I.P. 👷

- Translations for specific heroes pages (will be available using a query parameter)
- Additional data about gamemodes and maps

## Table of contents
Expand Down
5 changes: 3 additions & 2 deletions overfastapi/commands/check_and_update_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,11 @@ def get_request_parser_class(cache_key: str) -> tuple[type, dict]:
)
cache_parser_class = PARSER_CLASSES_MAPPING[parser_class_name]

cache_kwargs["locale"] = uri[1]
if parser_class_name in ["PlayerParser", "PlayerStatsSummaryParser"]:
cache_kwargs = {"player_id": uri[3]}
cache_kwargs["player_id"] = uri[3]
elif parser_class_name == "HeroParser":
cache_kwargs = {"hero_key": uri[3]}
cache_kwargs["hero_key"] = uri[3]

return cache_parser_class, cache_kwargs

Expand Down
7 changes: 4 additions & 3 deletions overfastapi/commands/update_test_fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import requests

from overfastapi.common.enums import HeroKey
from overfastapi.common.enums import HeroKey, Locale
from overfastapi.common.helpers import players_ids
from overfastapi.common.logging import logger
from overfastapi.config import (
Expand Down Expand Up @@ -109,14 +109,15 @@ def main():

# Initialize data
route_file_mapping = list_routes_to_update(args)
locale = Locale.ENGLISH_US

# Do the job
test_data_path = f"{TEST_FIXTURES_ROOT_PATH}/html"
with requests.Session() as session:
for route, filepath in route_file_mapping.items():
logger.info(f"Updating {test_data_path}{filepath}...")
logger.info(f"GET {BLIZZARD_HOST}{route}...")
response = session.get(f"{BLIZZARD_HOST}{route}")
logger.info(f"GET {BLIZZARD_HOST}/{locale}{route}...")
response = session.get(f"{BLIZZARD_HOST}/{locale}{route}")
logger.debug(
f"HTTP {response.status_code} / Time : {response.elapsed.total_seconds()}"
)
Expand Down
18 changes: 18 additions & 0 deletions overfastapi/common/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,21 @@ class CompetitiveDivision(StrEnum):
DIAMOND = "diamond"
MASTER = "master"
GRANDMASTER = "grandmaster"


class Locale(StrEnum):
"""Locales supported by Blizzard"""

GERMAN = "de-de"
ENGLISH_EU = "en-gb"
ENGLISH_US = "en-us"
SPANISH_EU = "es-es"
SPANISH_LATIN = "es-mx"
FRENCH = "fr-fr"
ITALIANO = "it-it"
JAPANESE = "ja-jp"
KOREAN = "ko-kr"
POLISH = "pl-pl"
PORTUGUESE_BRAZIL = "pt-br"
RUSSIAN = "ru-ru"
CHINESE_TAIWAN = "zh-tw"
8 changes: 4 additions & 4 deletions overfastapi/config.example.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,16 @@
BLIZZARD_HOST = "https://overwatch.blizzard.com"

# Blizzard home page with some details
HOME_PATH = "/en-us"
HOME_PATH = "/"

# Route for Overwatch heroes pages
HEROES_PATH = "/en-us/heroes"
HEROES_PATH = "/heroes"

# Route for players career pages
CAREER_PATH = "/en-us/career"
CAREER_PATH = "/career"

# Route for searching Overwatch accounts by name
SEARCH_ACCOUNT_PATH = "/en-us/search/account-by-name"
SEARCH_ACCOUNT_PATH = "/search/account-by-name"

############
# CRITICAL ERROR DISCORD WEBHOOK
Expand Down
4 changes: 3 additions & 1 deletion overfastapi/handlers/search_players_request_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from fastapi import Request

from overfastapi.common.cache_manager import CacheManager
from overfastapi.common.enums import Locale
from overfastapi.common.helpers import (
blizzard_response_error_from_request,
overfast_request,
Expand Down Expand Up @@ -128,4 +129,5 @@ def apply_ordering(players: list[dict], order_by: str) -> list[dict]:
@staticmethod
def get_blizzard_url(**kwargs) -> str:
"""URL used when requesting data to Blizzard."""
return f"{BLIZZARD_HOST}{SEARCH_ACCOUNT_PATH}/{kwargs.get('name')}"
locale = Locale.ENGLISH_US
return f"{BLIZZARD_HOST}/{locale}{SEARCH_ACCOUNT_PATH}/{kwargs.get('name')}"
1 change: 0 additions & 1 deletion overfastapi/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
## 👷 W.I.P. 👷
- Translations for specific heroes pages (will be available using a query parameter)
- Additional data about gamemodes and maps
"""

Expand Down
9 changes: 3 additions & 6 deletions overfastapi/parsers/api_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from bs4 import BeautifulSoup

from overfastapi.common.cache_manager import CacheManager
from overfastapi.common.enums import Locale
from overfastapi.common.exceptions import ParserParsingError
from overfastapi.common.helpers import (
blizzard_response_error_from_request,
Expand Down Expand Up @@ -102,18 +103,14 @@ def parse_data(self) -> dict | list[dict]:
raise an error if there is an issue when parsing the data.
"""

@cached_property
def blizzard_root_url(self) -> str:
"""Property containing Root URL for requesting data to Blizzard"""
return f"{BLIZZARD_HOST}{self.root_path}"

def get_blizzard_url(self, **kwargs) -> str:
"""URL used when requesting data to Blizzard. It usually is a concatenation
of root url and query data (kwargs) if the RequestHandler supports it.
For example : single hero page (hero key), player career page
(player id, etc.). Default is just the blizzard root url.
"""
return self.blizzard_root_url
locale = kwargs.get("locale") or Locale.ENGLISH_US
return f"{BLIZZARD_HOST}/{locale}{self.root_path}"

def filter_request_using_query(self, **kwargs) -> dict | list:
"""If the route contains subroutes accessible using GET queries, this method
Expand Down
5 changes: 5 additions & 0 deletions overfastapi/parsers/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,8 @@ def get_hero_role(hero_key: HeroKey) -> Role:
]:
return Role.TANK
return Role.DAMAGE


def get_role_from_icon_url(url: str) -> str:
"""Extracts the role key name from the associated icon URL"""
return url.split("/")[-1].split(".")[0].lower()
7 changes: 4 additions & 3 deletions overfastapi/parsers/hero_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from overfastapi.common.enums import MediaType
from overfastapi.config import HERO_PATH_CACHE_TIMEOUT, HEROES_PATH
from overfastapi.parsers.api_parser import APIParser
from overfastapi.parsers.helpers import get_full_url
from overfastapi.parsers.helpers import get_full_url, get_role_from_icon_url


class HeroParser(APIParser):
Expand All @@ -14,7 +14,7 @@ class HeroParser(APIParser):
timeout = HERO_PATH_CACHE_TIMEOUT

def get_blizzard_url(self, **kwargs) -> str:
return f"{self.blizzard_root_url}/{kwargs.get('hero_key')}"
return f"{super().get_blizzard_url(**kwargs)}/{kwargs.get('hero_key')}"

def parse_data(self) -> dict:
overview_section = self.root_tag.find("blz-page-header", recursive=False)
Expand All @@ -33,12 +33,13 @@ def parse_data(self) -> dict:
def __get_summary(overview_section: Tag) -> dict:
header_section = overview_section.find("blz-header")
extra_list_items = overview_section.find("blz-list").find_all("blz-list-item")

return {
"name": header_section.find("h2").get_text(),
"description": (
header_section.find("p", slot="description").get_text().strip()
),
"role": extra_list_items[0].get_text().lower(),
"role": get_role_from_icon_url(extra_list_items[0].find("image")["href"]),
"location": extra_list_items[1].get_text(),
}

Expand Down
2 changes: 1 addition & 1 deletion overfastapi/parsers/player_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def __init__(self, **kwargs):
self.player_id = kwargs.get("player_id")

def get_blizzard_url(self, **kwargs) -> str:
return f"{self.blizzard_root_url}/{kwargs.get('player_id')}/"
return f"{super().get_blizzard_url(**kwargs)}/{kwargs.get('player_id')}/"

def filter_request_using_query(self, **kwargs) -> dict:
if kwargs.get("summary"):
Expand Down
3 changes: 2 additions & 1 deletion overfastapi/parsers/roles_parser.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Roles Parser module"""
from overfastapi.config import HEROES_PATH_CACHE_TIMEOUT, HOME_PATH
from overfastapi.parsers.api_parser import APIParser
from overfastapi.parsers.helpers import get_role_from_icon_url


class RolesParser(APIParser):
Expand All @@ -23,7 +24,7 @@ def parse_data(self) -> list[dict]:

return [
{
"key": role_div.find("blz-header").find("h2").get_text().lower(),
"key": get_role_from_icon_url(roles_icons[role_index]),
"name": role_div.find("blz-header").find("h2").get_text().capitalize(),
"icon": roles_icons[role_index],
"description": (
Expand Down
7 changes: 4 additions & 3 deletions overfastapi/routers/gamemodes.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""Gamemodes endpoints router : gamemodes list, etc."""
from fastapi import APIRouter, BackgroundTasks, Request
from fastapi import APIRouter, BackgroundTasks, Query, Request

from overfastapi.common.decorators import validation_error_handler
from overfastapi.common.enums import RouteTag
from overfastapi.common.enums import Locale, RouteTag
from overfastapi.common.helpers import routes_responses
from overfastapi.handlers.list_gamemodes_request_handler import (
ListGamemodesRequestHandler,
Expand All @@ -26,7 +26,8 @@
async def list_map_gamemodes(
background_tasks: BackgroundTasks,
request: Request,
locale: Locale = Query(Locale.ENGLISH_US, title="Locale to be displayed"),
) -> list[GamemodeDetails]:
return ListGamemodesRequestHandler(request).process_request(
background_tasks=background_tasks
background_tasks=background_tasks, locale=locale
)
8 changes: 5 additions & 3 deletions overfastapi/routers/heroes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from fastapi import APIRouter, BackgroundTasks, Path, Query, Request

from overfastapi.common.decorators import validation_error_handler
from overfastapi.common.enums import HeroKey, Role, RouteTag
from overfastapi.common.enums import HeroKey, Locale, Role, RouteTag
from overfastapi.common.helpers import routes_responses
from overfastapi.handlers.get_hero_request_handler import GetHeroRequestHandler
from overfastapi.handlers.list_heroes_request_handler import ListHeroesRequestHandler
Expand All @@ -27,9 +27,10 @@ async def list_heroes(
background_tasks: BackgroundTasks,
request: Request,
role: Role | None = Query(None, title="Role filter"),
locale: Locale = Query(Locale.ENGLISH_US, title="Locale to be displayed"),
) -> list[HeroShort]:
return ListHeroesRequestHandler(request).process_request(
background_tasks=background_tasks, role=role
background_tasks=background_tasks, role=role, locale=locale
)


Expand All @@ -48,7 +49,8 @@ async def get_hero(
background_tasks: BackgroundTasks,
request: Request,
hero_key: HeroKey = Path(title="Key name of the hero"),
locale: Locale = Query(Locale.ENGLISH_US, title="Locale to be displayed"),
) -> Hero:
return GetHeroRequestHandler(request).process_request(
background_tasks=background_tasks, hero_key=hero_key
background_tasks=background_tasks, hero_key=hero_key, locale=locale
)
10 changes: 6 additions & 4 deletions overfastapi/routers/roles.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
"""Roles endpoints router : roles list, etc."""

from fastapi import APIRouter, BackgroundTasks, Request
from fastapi import APIRouter, BackgroundTasks, Query, Request

from overfastapi.common.decorators import validation_error_handler
from overfastapi.common.enums import RouteTag
from overfastapi.common.enums import Locale, RouteTag
from overfastapi.common.helpers import routes_responses
from overfastapi.handlers.list_roles_request_handler import ListRolesRequestHandler
from overfastapi.models.heroes import RoleDetail
Expand All @@ -20,8 +20,10 @@
)
@validation_error_handler(response_model=RoleDetail)
async def list_roles(
background_tasks: BackgroundTasks, request: Request
background_tasks: BackgroundTasks,
request: Request,
locale: Locale = Query(Locale.ENGLISH_US, title="Locale to be displayed"),
) -> list[RoleDetail]:
return ListRolesRequestHandler(request).process_request(
background_tasks=background_tasks
background_tasks=background_tasks, locale=locale
)
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "overfast-api"
version = "2.5.0"
version = "2.6.0"
description = "Overwatch API giving data about heroes, maps, and players statistics."
authors = ["TeKrop <tekrop@gmail.com>"]
license = "MIT"
Expand Down
Loading

0 comments on commit 748948c

Please sign in to comment.