Skip to content

Commit 22558c1

Browse files
committed
feat: added new endpoint "Get Clips Download"
1 parent 8f2d52c commit 22558c1

2 files changed

Lines changed: 47 additions & 8 deletions

File tree

twitchAPI/object/api.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
'StreamVacation', 'ChannelStreamSchedule', 'ChannelVIP', 'UserChatColor', 'Chatter', 'GetChattersResponse', 'ShieldModeStatus',
2727
'CharityAmount', 'CharityCampaign', 'CharityCampaignDonation', 'AutoModSettings', 'ChannelFollower', 'ChannelFollowersResult',
2828
'FollowedChannel', 'FollowedChannelsResult', 'ContentClassificationLabel', 'AdSchedule', 'AdSnoozeResponse', 'SendMessageResponse',
29-
'ChannelModerator', 'UserEmotesResponse', 'WarnResponse', 'SharedChatParticipant', 'SharedChatSession']
29+
'ChannelModerator', 'UserEmotesResponse', 'WarnResponse', 'SharedChatParticipant', 'SharedChatSession', 'ClipDownload']
3030

3131

3232
class TwitchUser(TwitchObject):
@@ -884,3 +884,12 @@ class SharedChatSession(TwitchObject):
884884
"""The UTC timestamp when the session was created."""
885885
updated_at: datetime
886886
"""The UTC timestamp when the session was last updated."""
887+
888+
889+
class ClipDownload(TwitchObject):
890+
clip_id: str
891+
"""An ID that uniquely identifies the clip."""
892+
landscape_download_url: Optional[str]
893+
"""The landscape URL to download the clip. This field is None if the URL is not available."""
894+
portrait_download_url: Optional[str]
895+
"""The portrait URL to download the clip. This field is None if the URL is not available."""

twitchAPI/twitch.py

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ async def app_refresh(token: str):
216216
CustomRewardRedemption, ChannelEditor, BlockListEntry, Poll, Prediction, RaidStartResult, ChatBadge, GetChannelEmotesResponse,
217217
GetEmotesResponse, GetEventSubSubscriptionResult, ChannelStreamSchedule, ChannelVIP, UserChatColor, GetChattersResponse, ShieldModeStatus,
218218
CharityCampaign, CharityCampaignDonation, AutoModSettings, ChannelFollowersResult, FollowedChannelsResult, ContentClassificationLabel,
219-
AdSchedule, AdSnoozeResponse, SendMessageResponse, ChannelModerator, UserEmotesResponse, WarnResponse, SharedChatSession)
219+
AdSchedule, AdSnoozeResponse, SendMessageResponse, ChannelModerator, UserEmotesResponse, WarnResponse, SharedChatSession, ClipDownload)
220220
from twitchAPI.type import (
221221
AnalyticsReportType, AuthScope, TimePeriod, SortMethod, VideoType, AuthType, CustomRewardRedemptionStatus, SortOrder,
222222
BlockSourceContext, BlockReason, EntitlementFulfillmentStatus, PollStatus, PredictionStatus, AutoModAction,
@@ -556,12 +556,12 @@ async def _build_result(self,
556556
url_params: dict,
557557
auth_type: AuthType,
558558
auth_scope: List[Union[AuthScope, List[AuthScope]]],
559-
return_type: Type[Sequence[T]],
559+
return_type: Type[List[T]],
560560
body_data: Optional[dict] = None,
561561
split_lists: bool = False,
562562
get_from_data: bool = True,
563563
result_type: ResultType = ResultType.RETURN_TYPE,
564-
error_handler: Optional[Mapping[int, BaseException]] = None) -> Sequence[T]: ...
564+
error_handler: Optional[Mapping[int, BaseException]] = None) -> List[T]: ...
565565

566566
@overload
567567
async def _build_result(self,
@@ -584,12 +584,12 @@ async def _build_result(self,
584584
url_params: dict,
585585
auth_type: AuthType,
586586
auth_scope: List[Union[AuthScope, List[AuthScope]]],
587-
return_type: Type[Sequence[str]],
587+
return_type: Type[List[str]],
588588
body_data: Optional[dict] = None,
589589
split_lists: bool = False,
590590
get_from_data: bool = True,
591591
result_type: ResultType = ResultType.RETURN_TYPE,
592-
error_handler: Optional[Mapping[int, BaseException]] = None) -> Sequence[str]: ...
592+
error_handler: Optional[Mapping[int, BaseException]] = None) -> List[str]: ...
593593

594594
@overload
595595
async def _build_result(self,
@@ -611,12 +611,12 @@ async def _build_result(self,
611611
url_params: dict,
612612
auth_type: AuthType,
613613
auth_scope: List[Union[AuthScope, List[AuthScope]]],
614-
return_type: Union[Type[T], None, Type[Sequence[T]], Type[dict], Type[str], Type[Sequence[str]]],
614+
return_type: Union[Type[T], None, Type[List[T]], Type[dict], Type[str], Type[List[str]]],
615615
body_data: Optional[dict] = None,
616616
split_lists: bool = False,
617617
get_from_data: bool = True,
618618
result_type: ResultType = ResultType.RETURN_TYPE,
619-
error_handler: Optional[Mapping[int, BaseException]] = None) -> Union[T, None, int, str, Sequence[T], dict, str, Sequence[str]]:
619+
error_handler: Optional[Mapping[int, BaseException]] = None) -> Union[T, None, int, str, List[T], dict, str, List[str]]:
620620
async with ClientSession(timeout=self.session_timeout) as session:
621621
_url = build_url(self.base_url + url, url_params, remove_none=True, split_lists=split_lists)
622622
response = await self._api_request(method, session, _url, auth_type, auth_scope, data=body_data)
@@ -4221,3 +4221,33 @@ async def get_shared_chat_session(self, broadcaster_id: str) -> Optional[SharedC
42214221
'broadcaster_id': broadcaster_id
42224222
}
42234223
return await self._build_result('GET', 'shared_chat/session', param, AuthType.EITHER, [], SharedChatSession)
4224+
4225+
async def get_clips_download(self,
4226+
editor_id: str,
4227+
broadcaster_id: str,
4228+
clip_ids: List[str]) -> List[ClipDownload]:
4229+
"""Provides URLs to download the video file(s) for the specified clips.
4230+
4231+
Requires User or App Authentication with :const:`~twitchAPI.type.AuthScope.EDITOR_MANAGE_CLIPS` or :const:`~twitchAPI.type.AuthScope.CHANNEL_MANAGE_CLIPS`\n
4232+
For detailed documentation, see here: https://dev.twitch.tv/docs/api/reference#get-clips-download
4233+
4234+
:param editor_id: The User ID of the editor for the channel you want to download a clip for.
4235+
If using the broadcaster’s auth token, this is the same as broadcaster_id. This must match the user_id in the user access token.
4236+
:param broadcaster_id: The ID of the broadcaster you want to download clips for.
4237+
:param clip_ids: List of clip IDs to download. Up to 10 allowed.
4238+
:raises ~twitchAPI.type.TwitchAPIException: if the request was malformed
4239+
:raises ~twitchAPI.type.UnauthorizedException: if user authentication is not set or invalid
4240+
:raises ~twitchAPI.type.TwitchAuthorizationException: if the used authentication token became invalid and a re authentication failed
4241+
:raises ~twitchAPI.type.TwitchBackendException: if the Twitch API itself runs into problems
4242+
:raises ~twitchAPI.type.TwitchAPIException: if a Query Parameter is missing or invalid
4243+
:raises ValueError: if clips_ids has more than 10 entries"""
4244+
if isinstance(clip_ids, list) and len(clip_ids) > 10:
4245+
raise ValueError('clip_ids has to be less than 10 entries long')
4246+
param = {
4247+
"editor_id": editor_id,
4248+
"broadcaster_id": broadcaster_id,
4249+
"clip_id": clip_ids
4250+
}
4251+
return await self._build_result('GET', 'clips/downloads', param, AuthType.EITHER,
4252+
[[AuthScope.CHANNEL_MANAGE_CLIPS, AuthScope.EDITOR_MANAGE_CLIPS]], List[ClipDownload],
4253+
split_lists=True)

0 commit comments

Comments
 (0)