diff --git a/tests/test_client.py b/tests/test_client.py index 1457352..5c3ad8f 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -150,6 +150,20 @@ async def test_events(client: Client) -> None: await client.fetch_event('fake-event-id') +@pytest.mark.anyio +async def test_flexes(client: Client) -> None: + flexes = await client.fetch_flexes() + assert len(flexes) > 0 + + flex_id = flexes[0].uuid + flex = await client.fetch_flex(str(flex_id)) + assert flex is not None + assert flex_id == flex.uuid + + with pytest.raises(NotFound): + await client.fetch_flex('fake-flex-id') + + @pytest.mark.anyio async def test_game_modes(client: Client) -> None: game_modes = await client.fetch_game_modes() diff --git a/valorant/client.py b/valorant/client.py index 9ef40c3..897ca5b 100644 --- a/valorant/client.py +++ b/valorant/client.py @@ -38,6 +38,7 @@ from .models.contracts import Contract from .models.currencies import Currency from .models.events import Event +from .models.flex import Flex from .models.game_modes import Equippable as GameModeEquippable, GameMode from .models.gear import Gear from .models.level_borders import LevelBorder @@ -241,6 +242,18 @@ async def fetch_events(self, *, language: LanguageOption | None = None) -> list[ events = Response[list[Event]].model_validate(data) return events.data + # flex + + async def fetch_flex(self, uuid: str, /, *, language: LanguageOption | None = None) -> Flex | None: + data = await self.http.get_flex(uuid, language=language or self.language) + flex = Response[Flex].model_validate(data) + return flex.data + + async def fetch_flexes(self, *, language: LanguageOption | None = None) -> list[Flex]: + data = await self.http.get_all_flex(language=language or self.language) + flexes = Response[list[Flex]].model_validate(data) + return flexes.data + # game_modes async def fetch_game_mode(self, uuid: str, /, *, language: LanguageOption | None = None) -> GameMode | None: diff --git a/valorant/http.py b/valorant/http.py index 60eb88d..c7a6b76 100644 --- a/valorant/http.py +++ b/valorant/http.py @@ -271,6 +271,20 @@ def get_event(self, uuid: str, *, language: str | None = None) -> Response[Any]: # - + def get_all_flex(self, *, language: str | None = None) -> Response[Any]: + params = {} + if language: + params['language'] = language + return self.request(Route('GET', '/flex'), params=params) + + def get_flex(self, uuid: str, *, language: str | None = None) -> Response[Any]: + params = {} + if language: + params['language'] = language + return self.request(Route('GET', '/flex/{uuid}', uuid=uuid), params=params) + + # - + def get_game_modes(self, *, language: str | None = None) -> Response[Any]: params = {} if language: diff --git a/valorant/models/contracts.py b/valorant/models/contracts.py index e0d39c3..1f96c9f 100644 --- a/valorant/models/contracts.py +++ b/valorant/models/contracts.py @@ -48,13 +48,14 @@ from .buddies import Level as BuddyLevel from .currencies import Currency from .events import Event + from .flex import Flex from .player_cards import PlayerCard from .player_titles import PlayerTitle from .seasons import Season from .sprays import Spray from .weapons import Level as SkinLevel - RewardItemType: TypeAlias = SkinLevel | BuddyLevel | Currency | PlayerCard | PlayerTitle | Spray + RewardItemType: TypeAlias = SkinLevel | BuddyLevel | Currency | PlayerCard | PlayerTitle | Spray | Flex log = logging.getLogger(__name__) @@ -80,7 +81,8 @@ async def fetch_item(self, *, client: Client) -> RewardItemType | None: # noqa: return await client.fetch_spray(str(self.uuid)) if self.type is RewardType.currency: return await client.fetch_currency(str(self.uuid)) - # TODO: add reward type totem? + if self.type is RewardType.totem: + return await client.fetch_flex(str(self.uuid)) log.warning('Unknown reward type: %s', self.type) return None diff --git a/valorant/models/flex.py b/valorant/models/flex.py new file mode 100644 index 0000000..2d67f9a --- /dev/null +++ b/valorant/models/flex.py @@ -0,0 +1,14 @@ +from __future__ import annotations + +from pydantic import Field + +from .base import BaseUUIDModel +from .localization import LocalizedField + + +class Flex(BaseUUIDModel): + # uuid: str + display_name: str | LocalizedField = Field(alias='displayName') + display_name_all_caps: str | LocalizedField = Field(alias='displayNameAllCaps') + display_icon: str = Field(alias='displayIcon') + asset_path: str = Field(alias='assetPath')