Compare commits
9 Commits
e437b41ee8
...
f04916b7fd
| Author | SHA1 | Date | |
|---|---|---|---|
| f04916b7fd | |||
| 0d9ac981b8 | |||
| 035a87e0c5 | |||
| 3c6154913a | |||
| 33d498015b | |||
| b0d3ca9add | |||
| 1a0999f332 | |||
| 2c5c650ae7 | |||
| 947f19afbc |
@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "twitchclient"
|
name = "twitchclient"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
description = "Client for Twitch API"
|
description = "Client for Twitch API"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
authors = [
|
authors = [
|
||||||
|
|||||||
@ -29,7 +29,9 @@ class TwitchAPIClient(AioHTTPXClient):
|
|||||||
logger='Twitch API',
|
logger='Twitch API',
|
||||||
)
|
)
|
||||||
|
|
||||||
async def start_commercial(self, access_token: str, broadcaster_id: int):
|
async def start_commercial(
|
||||||
|
self, access_token: str, broadcaster_id: int | str
|
||||||
|
):
|
||||||
req = await self.get(
|
req = await self.get(
|
||||||
'/channels/commercial',
|
'/channels/commercial',
|
||||||
headers={'Authorization': f'Bearer {access_token}'},
|
headers={'Authorization': f'Bearer {access_token}'},
|
||||||
@ -53,7 +55,9 @@ class TwitchAPIClient(AioHTTPXClient):
|
|||||||
case _:
|
case _:
|
||||||
raise s.Error(req.status_code, 'Internal Server Error')
|
raise s.Error(req.status_code, 'Internal Server Error')
|
||||||
|
|
||||||
async def get_ad_schedule(self, access_token: str, broadcaster_id: int):
|
async def get_ad_schedule(
|
||||||
|
self, access_token: str, broadcaster_id: int | str
|
||||||
|
):
|
||||||
req = await self.get(
|
req = await self.get(
|
||||||
'/channels/ads',
|
'/channels/ads',
|
||||||
headers={'Authorization': f'Bearer {access_token}'},
|
headers={'Authorization': f'Bearer {access_token}'},
|
||||||
@ -72,7 +76,9 @@ class TwitchAPIClient(AioHTTPXClient):
|
|||||||
case _:
|
case _:
|
||||||
raise s.Error(req.status_code, 'Internal Server Error')
|
raise s.Error(req.status_code, 'Internal Server Error')
|
||||||
|
|
||||||
async def snooze_next_ad(self, access_token: str, broadcaster_id: int):
|
async def snooze_next_ad(
|
||||||
|
self, access_token: str, broadcaster_id: int | str
|
||||||
|
):
|
||||||
req = await self.post(
|
req = await self.post(
|
||||||
'/channels/ads/schedule/snooze',
|
'/channels/ads/schedule/snooze',
|
||||||
headers={'Authorization': f'Bearer {access_token}'},
|
headers={'Authorization': f'Bearer {access_token}'},
|
||||||
@ -193,7 +199,7 @@ class TwitchAPIClient(AioHTTPXClient):
|
|||||||
raise s.Error(req.status_code, 'Internal Server Error')
|
raise s.Error(req.status_code, 'Internal Server Error')
|
||||||
|
|
||||||
async def get_cheermotes(
|
async def get_cheermotes(
|
||||||
self, access_token: str, broadcaster_id: int | None = None
|
self, access_token: str, broadcaster_id: int | str | None = None
|
||||||
):
|
):
|
||||||
req = await self.get(
|
req = await self.get(
|
||||||
'/bits/cheermotes',
|
'/bits/cheermotes',
|
||||||
@ -243,7 +249,9 @@ class TwitchAPIClient(AioHTTPXClient):
|
|||||||
raise s.Error(req.status_code, 'Internal Server Error')
|
raise s.Error(req.status_code, 'Internal Server Error')
|
||||||
|
|
||||||
async def get_channel_information(
|
async def get_channel_information(
|
||||||
self, access_token: str, broadcaster_id: int | list[int]
|
self,
|
||||||
|
access_token: str,
|
||||||
|
broadcaster_id: int | list[int] | str | list[str],
|
||||||
):
|
):
|
||||||
req = await self.get(
|
req = await self.get(
|
||||||
'/channels',
|
'/channels',
|
||||||
@ -264,9 +272,9 @@ class TwitchAPIClient(AioHTTPXClient):
|
|||||||
async def modify_channel_information(
|
async def modify_channel_information(
|
||||||
self,
|
self,
|
||||||
access_token: str,
|
access_token: str,
|
||||||
broadcaster_id: int,
|
broadcaster_id: int | str,
|
||||||
*,
|
*,
|
||||||
game_id: int | None = None,
|
game_id: int | str | None = None,
|
||||||
broadcaster_language: str | None = None,
|
broadcaster_language: str | None = None,
|
||||||
title: str | None = None,
|
title: str | None = None,
|
||||||
delay: int | None = None,
|
delay: int | None = None,
|
||||||
@ -309,7 +317,7 @@ class TwitchAPIClient(AioHTTPXClient):
|
|||||||
raise s.Error(req.status_code, 'Internal Server Error')
|
raise s.Error(req.status_code, 'Internal Server Error')
|
||||||
|
|
||||||
async def get_channel_editors(
|
async def get_channel_editors(
|
||||||
self, access_token: str, broadcaster_id: int
|
self, access_token: str, broadcaster_id: int | str
|
||||||
):
|
):
|
||||||
req = await self.get(
|
req = await self.get(
|
||||||
'/channels/editors',
|
'/channels/editors',
|
||||||
@ -330,7 +338,7 @@ class TwitchAPIClient(AioHTTPXClient):
|
|||||||
async def get_followed_channels(
|
async def get_followed_channels(
|
||||||
self,
|
self,
|
||||||
access_token: str,
|
access_token: str,
|
||||||
broadcaster_id: int,
|
broadcaster_id: int | str,
|
||||||
*,
|
*,
|
||||||
first: int = 20,
|
first: int = 20,
|
||||||
after: str | None = None,
|
after: str | None = None,
|
||||||
@ -360,7 +368,7 @@ class TwitchAPIClient(AioHTTPXClient):
|
|||||||
async def get_channel_followers(
|
async def get_channel_followers(
|
||||||
self,
|
self,
|
||||||
access_token: str,
|
access_token: str,
|
||||||
broadcaster_id: int,
|
broadcaster_id: int | str,
|
||||||
*,
|
*,
|
||||||
user_id: int | None = None,
|
user_id: int | None = None,
|
||||||
first: int = 20,
|
first: int = 20,
|
||||||
@ -392,7 +400,7 @@ class TwitchAPIClient(AioHTTPXClient):
|
|||||||
async def create_custom_rewards(
|
async def create_custom_rewards(
|
||||||
self,
|
self,
|
||||||
access_token: str,
|
access_token: str,
|
||||||
broadcaster_id: int,
|
broadcaster_id: int | str,
|
||||||
title: str,
|
title: str,
|
||||||
cost: int,
|
cost: int,
|
||||||
*,
|
*,
|
||||||
@ -451,7 +459,7 @@ class TwitchAPIClient(AioHTTPXClient):
|
|||||||
raise s.Error(req.status_code, 'Internal Server Error')
|
raise s.Error(req.status_code, 'Internal Server Error')
|
||||||
|
|
||||||
async def delete_custom_reward(
|
async def delete_custom_reward(
|
||||||
self, access_token: str, broadcaster_id: str, reward_id: str
|
self, access_token: str, broadcaster_id: int | str, reward_id: str
|
||||||
):
|
):
|
||||||
req = await self.delete(
|
req = await self.delete(
|
||||||
'/channel_points/custom_rewards',
|
'/channel_points/custom_rewards',
|
||||||
@ -478,7 +486,7 @@ class TwitchAPIClient(AioHTTPXClient):
|
|||||||
async def get_custom_rewards(
|
async def get_custom_rewards(
|
||||||
self,
|
self,
|
||||||
access_token: str,
|
access_token: str,
|
||||||
broadcaster_id: int,
|
broadcaster_id: int | str,
|
||||||
*,
|
*,
|
||||||
reward_id: str | None = None,
|
reward_id: str | None = None,
|
||||||
only_manageable_rewards: bool = False,
|
only_manageable_rewards: bool = False,
|
||||||
@ -514,7 +522,7 @@ class TwitchAPIClient(AioHTTPXClient):
|
|||||||
async def get_custom_reward_redemption(
|
async def get_custom_reward_redemption(
|
||||||
self,
|
self,
|
||||||
access_token: str,
|
access_token: str,
|
||||||
broadcaster_id: int,
|
broadcaster_id: int | str,
|
||||||
reward_id: str,
|
reward_id: str,
|
||||||
status: Literal['CANCELED', 'FULFILLED', 'UNFULFILLED'],
|
status: Literal['CANCELED', 'FULFILLED', 'UNFULFILLED'],
|
||||||
*,
|
*,
|
||||||
@ -559,7 +567,7 @@ class TwitchAPIClient(AioHTTPXClient):
|
|||||||
async def update_custom_reward(
|
async def update_custom_reward(
|
||||||
self,
|
self,
|
||||||
access_token: str,
|
access_token: str,
|
||||||
broadcaster_id: int,
|
broadcaster_id: int | str,
|
||||||
reward_id: str,
|
reward_id: str,
|
||||||
*,
|
*,
|
||||||
title: str | None = None,
|
title: str | None = None,
|
||||||
@ -623,7 +631,7 @@ class TwitchAPIClient(AioHTTPXClient):
|
|||||||
async def update_redemption_status(
|
async def update_redemption_status(
|
||||||
self,
|
self,
|
||||||
access_token: str,
|
access_token: str,
|
||||||
broadcaster_id: int,
|
broadcaster_id: int | str,
|
||||||
reward_id: int,
|
reward_id: int,
|
||||||
redemption_id: int | list[int],
|
redemption_id: int | list[int],
|
||||||
status: Literal['CANCELED', 'FULFILLED'],
|
status: Literal['CANCELED', 'FULFILLED'],
|
||||||
@ -656,7 +664,7 @@ class TwitchAPIClient(AioHTTPXClient):
|
|||||||
raise s.Error(req.status_code, 'Internal Server Error')
|
raise s.Error(req.status_code, 'Internal Server Error')
|
||||||
|
|
||||||
async def get_charity_campaign(
|
async def get_charity_campaign(
|
||||||
self, access_token: str, broadcaster_id: int
|
self, access_token: str, broadcaster_id: int | str
|
||||||
):
|
):
|
||||||
req = await self.get(
|
req = await self.get(
|
||||||
'/charity/campaigns',
|
'/charity/campaigns',
|
||||||
@ -677,7 +685,7 @@ class TwitchAPIClient(AioHTTPXClient):
|
|||||||
async def get_charity_campaign_donations(
|
async def get_charity_campaign_donations(
|
||||||
self,
|
self,
|
||||||
access_token: str,
|
access_token: str,
|
||||||
broadcaster_id: int,
|
broadcaster_id: int | str,
|
||||||
first: int = 20,
|
first: int = 20,
|
||||||
after: str | None = None,
|
after: str | None = None,
|
||||||
cache_time: int | None = None,
|
cache_time: int | None = None,
|
||||||
@ -712,7 +720,7 @@ class TwitchAPIClient(AioHTTPXClient):
|
|||||||
async def get_chatters(
|
async def get_chatters(
|
||||||
self,
|
self,
|
||||||
access_token: str,
|
access_token: str,
|
||||||
broadcaster_id: int,
|
broadcaster_id: int | str,
|
||||||
moderator_id: int,
|
moderator_id: int,
|
||||||
first: int = 20,
|
first: int = 20,
|
||||||
after: str | None = None,
|
after: str | None = None,
|
||||||
@ -745,3 +753,163 @@ class TwitchAPIClient(AioHTTPXClient):
|
|||||||
|
|
||||||
case _:
|
case _:
|
||||||
raise s.Error(req.status_code, 'Internal Server Error')
|
raise s.Error(req.status_code, 'Internal Server Error')
|
||||||
|
|
||||||
|
async def get_channel_emotes(
|
||||||
|
self,
|
||||||
|
access_token: str,
|
||||||
|
broadcaster_id: int | str,
|
||||||
|
cache_time: int | None = None,
|
||||||
|
):
|
||||||
|
req = await self.get(
|
||||||
|
'/chat/emotes',
|
||||||
|
headers=self.clean_dict(
|
||||||
|
{
|
||||||
|
'Authorization': f'Bearer {access_token}',
|
||||||
|
'X-Cache-TTL': cache_time,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
params={'broadcaster_id': broadcaster_id},
|
||||||
|
)
|
||||||
|
|
||||||
|
match req.status_code:
|
||||||
|
case st.OK:
|
||||||
|
return s.ChannelEmotes.model_validate(req.json())
|
||||||
|
|
||||||
|
case st.BAD_REQUEST | st.UNAUTHORIZED:
|
||||||
|
raise s.Error(req.status_code, req.json()['message'])
|
||||||
|
|
||||||
|
case _:
|
||||||
|
raise s.Error(req.status_code, 'Internal Server Error')
|
||||||
|
|
||||||
|
async def get_global_emotes(
|
||||||
|
self, access_token: str, cache_time: int | None = None
|
||||||
|
):
|
||||||
|
req = await self.get(
|
||||||
|
'/chat/emotes/global',
|
||||||
|
headers=self.clean_dict(
|
||||||
|
{
|
||||||
|
'Authorization': f'Bearer {access_token}',
|
||||||
|
'X-Cache-TTL': cache_time,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
match req.status_code:
|
||||||
|
case st.OK:
|
||||||
|
return s.GlobalEmotes.model_validate(req.json())
|
||||||
|
|
||||||
|
case st.UNAUTHORIZED:
|
||||||
|
raise s.Error(req.status_code, req.json()['message'])
|
||||||
|
|
||||||
|
case _:
|
||||||
|
raise s.Error(req.status_code, 'Internal Server Error')
|
||||||
|
|
||||||
|
async def get_emote_sets(
|
||||||
|
self,
|
||||||
|
access_token: str,
|
||||||
|
emote_set_id: int,
|
||||||
|
cache_time: int | None = None,
|
||||||
|
):
|
||||||
|
req = await self.get(
|
||||||
|
'/chat/emotes/set',
|
||||||
|
headers=self.clean_dict(
|
||||||
|
{
|
||||||
|
'Authorization': f'Bearer {access_token}',
|
||||||
|
'X-Cache-TTL': cache_time,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
params={'emote_set_id': emote_set_id},
|
||||||
|
)
|
||||||
|
|
||||||
|
match req.status_code:
|
||||||
|
case st.OK:
|
||||||
|
return s.EmoteSets.model_validate(req.json())
|
||||||
|
|
||||||
|
case st.BAD_REQUEST | st.UNAUTHORIZED:
|
||||||
|
raise s.Error(req.status_code, req.json()['message'])
|
||||||
|
|
||||||
|
case _:
|
||||||
|
raise s.Error(req.status_code, 'Internal Server Error')
|
||||||
|
|
||||||
|
async def get_channel_chat_badges(
|
||||||
|
self,
|
||||||
|
access_token: str,
|
||||||
|
broadcaster_id: int | str,
|
||||||
|
cache_time: int | None = None,
|
||||||
|
):
|
||||||
|
req = await self.get(
|
||||||
|
'/chat/badges',
|
||||||
|
headers=self.clean_dict(
|
||||||
|
{
|
||||||
|
'Authorization': f'Bearer {access_token}',
|
||||||
|
'X-Cache-TTL': cache_time,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
params={'broadcaster_id': broadcaster_id},
|
||||||
|
)
|
||||||
|
|
||||||
|
match req.status_code:
|
||||||
|
case st.OK:
|
||||||
|
return s.ChannelChatBadges.model_validate(req.json())
|
||||||
|
|
||||||
|
case st.BAD_REQUEST | st.UNAUTHORIZED:
|
||||||
|
raise s.Error(req.status_code, req.json()['message'])
|
||||||
|
|
||||||
|
case _:
|
||||||
|
raise s.Error(req.status_code, 'Internal Server Error')
|
||||||
|
|
||||||
|
async def get_global_chat_badges(
|
||||||
|
self, access_token: str, cache_time: int | None = None
|
||||||
|
):
|
||||||
|
req = await self.get(
|
||||||
|
'/chat/badges/global',
|
||||||
|
headers=self.clean_dict(
|
||||||
|
{
|
||||||
|
'Authorization': f'Bearer {access_token}',
|
||||||
|
'X-Cache-TTL': cache_time,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
match req.status_code:
|
||||||
|
case st.OK:
|
||||||
|
return s.GlobalChatBadges.model_validate(req.json())
|
||||||
|
|
||||||
|
case st.UNAUTHORIZED:
|
||||||
|
raise s.Error(req.status_code, req.json()['message'])
|
||||||
|
|
||||||
|
case _:
|
||||||
|
raise s.Error(req.status_code, 'Internal Server Error')
|
||||||
|
|
||||||
|
async def get_chat_settings(
|
||||||
|
self,
|
||||||
|
access_token: str,
|
||||||
|
broadcaster_id: int | str,
|
||||||
|
moderator_id: int | str | None = None,
|
||||||
|
cache_time: int | None = None,
|
||||||
|
):
|
||||||
|
req = await self.get(
|
||||||
|
'/chat/settings',
|
||||||
|
headers=self.clean_dict(
|
||||||
|
{
|
||||||
|
'Authorization': f'Bearer {access_token}',
|
||||||
|
'X-Cache-TTL': cache_time,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
params=self.clean_dict(
|
||||||
|
{
|
||||||
|
'broadcaster_id': broadcaster_id,
|
||||||
|
'moderator_id': moderator_id,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
match req.status_code:
|
||||||
|
case st.OK:
|
||||||
|
return s.ChatSettings.model_validate(req.json()).data
|
||||||
|
|
||||||
|
case st.BAD_REQUEST | st.UNAUTHORIZED:
|
||||||
|
raise s.Error(req.status_code, req.json()['message'])
|
||||||
|
|
||||||
|
case _:
|
||||||
|
raise s.Error(req.status_code, 'Internal Server Error')
|
||||||
|
|||||||
@ -475,3 +475,91 @@ class Chatters(BaseModel):
|
|||||||
data: list[ChattersData]
|
data: list[ChattersData]
|
||||||
pagination: Pagination | dict[Any, Any] | None = None
|
pagination: Pagination | dict[Any, Any] | None = None
|
||||||
total: int
|
total: int
|
||||||
|
|
||||||
|
|
||||||
|
class ChannelEmoteImages(BaseModel):
|
||||||
|
model_config = ConfigDict(extra='forbid')
|
||||||
|
|
||||||
|
url_1x: str
|
||||||
|
url_2x: str
|
||||||
|
url_4x: str
|
||||||
|
|
||||||
|
|
||||||
|
class ChannelEmote(BaseModel):
|
||||||
|
model_config = ConfigDict(extra='forbid')
|
||||||
|
|
||||||
|
id: int
|
||||||
|
name: str
|
||||||
|
images: ChannelEmoteImages
|
||||||
|
tier: int
|
||||||
|
emote_type: Literal['bitstier', 'follower', 'subscriptions']
|
||||||
|
format: list[Literal['animated', 'static']]
|
||||||
|
scale: list[Literal['1.0', '2.0', '3.0']]
|
||||||
|
theme_mode: list[Literal['dark', 'light']]
|
||||||
|
|
||||||
|
|
||||||
|
class ChannelEmotes(BaseModel):
|
||||||
|
model_config = ConfigDict(extra='forbid')
|
||||||
|
|
||||||
|
data: list[ChannelEmote]
|
||||||
|
template: str
|
||||||
|
|
||||||
|
|
||||||
|
class GlobalEmotes(ChannelEmotes):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class EmoteSets(ChannelEmotes):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ChannelChatBadgesVersion(BaseModel):
|
||||||
|
model_config = ConfigDict(extra='forbid')
|
||||||
|
|
||||||
|
id: str
|
||||||
|
image_url_1x: str
|
||||||
|
image_url_2x: str
|
||||||
|
image_url_4x: str
|
||||||
|
title: str
|
||||||
|
description: str
|
||||||
|
click_action: str | None
|
||||||
|
click_url: str | None
|
||||||
|
|
||||||
|
|
||||||
|
class ChannelChatBadgesData(BaseModel):
|
||||||
|
model_config = ConfigDict(extra='forbid')
|
||||||
|
|
||||||
|
set_id: str
|
||||||
|
versions: list[ChannelChatBadgesVersion]
|
||||||
|
|
||||||
|
|
||||||
|
class ChannelChatBadges(BaseModel):
|
||||||
|
model_config = ConfigDict(extra='forbid')
|
||||||
|
|
||||||
|
data: list[ChannelChatBadgesData]
|
||||||
|
|
||||||
|
|
||||||
|
class GlobalChatBadges(ChannelChatBadges):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ChatSettingsData(BaseModel):
|
||||||
|
model_config = ConfigDict(extra='forbid')
|
||||||
|
|
||||||
|
broadcaster_id: int
|
||||||
|
emote_mode: bool
|
||||||
|
follower_mode: bool
|
||||||
|
follower_mode_duration: int | None
|
||||||
|
moderator_id: int | None = None
|
||||||
|
non_moderator_chat_delay: bool | None = None
|
||||||
|
non_moderator_chat_delay_duration: int | None = None
|
||||||
|
slow_mode: bool
|
||||||
|
slow_mode_wait_time: int | None
|
||||||
|
subscriber_mode: bool
|
||||||
|
unique_chat_mode: bool
|
||||||
|
|
||||||
|
|
||||||
|
class ChatSettings(BaseModel):
|
||||||
|
model_config = ConfigDict(extra='forbid')
|
||||||
|
|
||||||
|
data: list[ChatSettingsData]
|
||||||
|
|||||||
Reference in New Issue
Block a user