Reduce the number of API calls in Twitch integration (#128996)

This commit is contained in:
Jason Parker 2024-10-24 13:51:19 -04:00 committed by GitHub
parent f91a1363cb
commit bf63b0993d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 27 additions and 15 deletions

View file

@ -4,7 +4,7 @@ from dataclasses import dataclass
from datetime import datetime, timedelta
from twitchAPI.helper import first
from twitchAPI.object.api import FollowedChannelsResult, TwitchUser, UserSubscription
from twitchAPI.object.api import FollowedChannel, Stream, TwitchUser, UserSubscription
from twitchAPI.twitch import Twitch
from twitchAPI.type import TwitchAPIException, TwitchResourceNotFound
@ -81,12 +81,24 @@ class TwitchCoordinator(DataUpdateCoordinator[dict[str, TwitchUpdate]]):
self.session.token["refresh_token"],
False,
)
data = {}
data: dict[str, TwitchUpdate] = {}
streams: dict[str, Stream] = {
s.user_id: s
async for s in self.twitch.get_followed_streams(
user_id=self.current_user.id, first=100
)
}
follows: dict[str, FollowedChannel] = {
f.broadcaster_id: f
async for f in await self.twitch.get_followed_channels(
user_id=self.current_user.id, first=100
)
}
for channel in self.users:
followers = await self.twitch.get_channel_followers(channel.id)
stream = await first(self.twitch.get_streams(user_id=[channel.id], first=1))
stream = streams.get(channel.id)
follow = follows.get(channel.id)
sub: UserSubscription | None = None
follows: FollowedChannelsResult | None = None
try:
sub = await self.twitch.check_user_subscription(
user_id=self.current_user.id, broadcaster_id=channel.id
@ -95,10 +107,7 @@ class TwitchCoordinator(DataUpdateCoordinator[dict[str, TwitchUpdate]]):
LOGGER.debug("User is not subscribed to %s", channel.display_name)
except TwitchAPIException as exc:
LOGGER.error("Error response on check_user_subscription: %s", exc)
else:
follows = await self.twitch.get_followed_channels(
self.current_user.id, broadcaster_id=channel.id
)
data[channel.id] = TwitchUpdate(
channel.display_name,
followers.total,
@ -108,11 +117,11 @@ class TwitchCoordinator(DataUpdateCoordinator[dict[str, TwitchUpdate]]):
stream.started_at if stream else None,
stream.thumbnail_url if stream else None,
channel.profile_image_url,
sub is not None if sub else None,
bool(sub),
sub.is_gift if sub else None,
{"1000": 1, "2000": 2, "3000": 3}.get(sub.tier) if sub else None,
follows is not None and follows.total > 0,
follows.data[0].followed_at if follows and follows.total else None,
bool(follow),
follow.followed_at if follow else None,
stream.viewer_count if stream else None,
)
return data

View file

@ -111,8 +111,8 @@ def twitch_mock() -> Generator[AsyncMock]:
mock_client.return_value.get_followed_channels.return_value = TwitchIterObject(
"get_followed_channels.json", FollowedChannel
)
mock_client.return_value.get_streams.return_value = get_generator(
"get_streams.json", Stream
mock_client.return_value.get_followed_streams.return_value = get_generator(
"get_followed_streams.json", Stream
)
mock_client.return_value.check_user_subscription.return_value = (
UserSubscription(

View file

@ -1,9 +1,11 @@
[
{
"broadcaster_id": 123,
"broadcaster_login": "internetofthings",
"followed_at": "2023-08-01"
},
{
"broadcaster_id": 456,
"broadcaster_login": "homeassistant",
"followed_at": "2023-08-01"
}

View file

@ -1,5 +1,6 @@
[
{
"user_id": 123,
"game_name": "Good game",
"title": "Title",
"thumbnail_url": "stream-medium.png",

View file

@ -21,8 +21,8 @@ async def test_offline(
hass: HomeAssistant, twitch_mock: AsyncMock, config_entry: MockConfigEntry
) -> None:
"""Test offline state."""
twitch_mock.return_value.get_streams.return_value = get_generator_from_data(
[], Stream
twitch_mock.return_value.get_followed_streams.return_value = (
get_generator_from_data([], Stream)
)
await setup_integration(hass, config_entry)