1512 lines
30 KiB
Python
1512 lines
30 KiB
Python
from datetime import datetime
|
|
from typing import Any, Literal, TypedDict
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field
|
|
|
|
from . import scopes
|
|
from .eventsub import subscriptions as sub
|
|
|
|
|
|
class BaseSchema(BaseModel):
|
|
model_config = ConfigDict(extra='forbid')
|
|
|
|
|
|
class Error(Exception):
|
|
status_code: int
|
|
error: str
|
|
|
|
def __init__(self, status_code: int, error: str) -> None:
|
|
self.status_code = status_code
|
|
self.error = error
|
|
super().__init__(f'{status_code}: {error}')
|
|
|
|
|
|
class ClientError(Error):
|
|
pass
|
|
|
|
|
|
class InternalError(Error):
|
|
pass
|
|
|
|
|
|
class Pagination(BaseSchema):
|
|
cursor: str
|
|
|
|
|
|
class AppAccessToken(BaseSchema):
|
|
access_token: str
|
|
expires_in: int
|
|
token_type: Literal['bearer']
|
|
|
|
|
|
class UserAccessToken(BaseSchema):
|
|
access_token: str
|
|
refresh_token: str
|
|
scope: list[scopes.Any]
|
|
expires_in: int
|
|
token_type: Literal['bearer']
|
|
|
|
|
|
class AccessTokenValidation(BaseSchema):
|
|
client_id: str
|
|
login: str
|
|
scopes: list[scopes.Any]
|
|
user_id: int
|
|
expires_in: int
|
|
|
|
|
|
class StartCommercialData(BaseSchema):
|
|
length: int
|
|
message: str
|
|
retry_after: int
|
|
|
|
|
|
class StartCommercial(BaseSchema):
|
|
data: list[StartCommercialData]
|
|
|
|
|
|
class AdScheduleData(BaseSchema):
|
|
next_ad_at: datetime | None
|
|
last_ad_at: datetime | None
|
|
duration: int
|
|
preroll_free_time: int
|
|
snooze_count: int
|
|
snooze_refresh_at: datetime
|
|
|
|
|
|
class AdSchedule(BaseSchema):
|
|
data: list[AdScheduleData]
|
|
|
|
|
|
class SnoozeNextAdData(BaseSchema):
|
|
snooze_count: int
|
|
snooze_refresh_at: datetime
|
|
next_ad_at: datetime
|
|
|
|
|
|
class SnoozeNextAd(BaseSchema):
|
|
data: list[SnoozeNextAdData]
|
|
|
|
|
|
class DateRange(BaseSchema):
|
|
started_at: datetime
|
|
ended_at: datetime
|
|
|
|
|
|
class ExtensionAnalyticsData(BaseSchema):
|
|
extension_id: str
|
|
URL: str
|
|
type: str
|
|
date_range: DateRange
|
|
|
|
|
|
class ExtensionAnalytics(BaseSchema):
|
|
data: list[ExtensionAnalyticsData]
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
|
|
|
|
class GameAnalyticsData(BaseSchema):
|
|
game_id: int
|
|
URL: str
|
|
type: str
|
|
date_range: DateRange
|
|
|
|
|
|
class GameAnalytics(BaseSchema):
|
|
data: list[GameAnalyticsData]
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
|
|
|
|
class BitsLeaderboardData(BaseSchema):
|
|
user_id: int
|
|
user_login: str
|
|
user_name: str
|
|
rank: int
|
|
score: int
|
|
|
|
|
|
class BitsLeaderboard(BaseSchema):
|
|
data: list[BitsLeaderboardData]
|
|
date_range: DateRange
|
|
total: int
|
|
|
|
|
|
class CheermotesImageAnimated(BaseSchema):
|
|
field_1: str = Field(..., alias='1')
|
|
field_1_5: str = Field(..., alias='1.5')
|
|
field_2: str = Field(..., alias='2')
|
|
field_3: str = Field(..., alias='3')
|
|
field_4: str = Field(..., alias='4')
|
|
|
|
|
|
class CheermotesImageStatic(BaseSchema):
|
|
field_1: str = Field(..., alias='1')
|
|
field_1_5: str = Field(..., alias='1.5')
|
|
field_2: str = Field(..., alias='2')
|
|
field_3: str = Field(..., alias='3')
|
|
field_4: str = Field(..., alias='4')
|
|
|
|
|
|
class CheermotesImage(BaseSchema):
|
|
animated: CheermotesImageAnimated
|
|
static: CheermotesImageStatic
|
|
|
|
|
|
class CheermotesImages(BaseSchema):
|
|
light: CheermotesImage
|
|
dark: CheermotesImage
|
|
|
|
|
|
class CheermotesTier(BaseSchema):
|
|
min_bits: int
|
|
id: Literal['1', '100', '500', '1000', '5000', '10000', '100000']
|
|
color: str
|
|
can_cheer: bool
|
|
show_in_bits_card: bool
|
|
images: CheermotesImages
|
|
|
|
|
|
class CheermotesData(BaseSchema):
|
|
prefix: str
|
|
tiers: list[CheermotesTier]
|
|
type: Literal[
|
|
'global_first_party',
|
|
'global_third_party',
|
|
'channel_custom',
|
|
'display_only',
|
|
'sponsored',
|
|
]
|
|
order: int
|
|
last_updated: datetime
|
|
is_charitable: bool
|
|
|
|
|
|
class Cheermotes(BaseSchema):
|
|
data: list[CheermotesData]
|
|
|
|
|
|
class ExtensionProductCost(BaseSchema):
|
|
amount: int
|
|
type: Literal['bits']
|
|
|
|
|
|
class ExtensionProductData(BaseSchema):
|
|
domain: str
|
|
sku: str
|
|
cost: ExtensionProductCost
|
|
inDevelopment: bool
|
|
displayName: str
|
|
expiration: str
|
|
broadcast: bool
|
|
|
|
|
|
class ExtensionTransactionsData(BaseSchema):
|
|
id: str
|
|
timestamp: datetime
|
|
broadcaster_id: int
|
|
broadcaster_login: str
|
|
broadcaster_name: str
|
|
user_id: int
|
|
user_login: str
|
|
user_name: str
|
|
product_type: Literal['BITS_IN_EXTENSION']
|
|
product_data: ExtensionProductData
|
|
|
|
|
|
class ExtensionTransactions(BaseSchema):
|
|
data: list[ExtensionTransactionsData]
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
|
|
|
|
class ContentClassificationLabel(TypedDict):
|
|
id: Literal[
|
|
'DebatedSocialIssuesAndPolitics',
|
|
'DrugsIntoxication',
|
|
'SexualThemes',
|
|
'ViolentGraphic',
|
|
'Gambling',
|
|
'ProfanityVulgarity',
|
|
]
|
|
is_enabled: bool
|
|
|
|
|
|
class ChannelInformation(BaseSchema):
|
|
broadcaster_id: int
|
|
broadcaster_login: str
|
|
broadcaster_name: str
|
|
broadcaster_language: str
|
|
game_name: str
|
|
game_id: int | str
|
|
title: str
|
|
delay: int
|
|
tags: list[str]
|
|
content_classification_labels: list[str]
|
|
is_branded_content: bool
|
|
|
|
|
|
class ChannelsInformation(BaseSchema):
|
|
data: list[ChannelInformation]
|
|
|
|
|
|
class ChannelEditor(BaseSchema):
|
|
user_id: int
|
|
user_name: str
|
|
created_at: datetime
|
|
|
|
|
|
class ChannelEditors(BaseSchema):
|
|
data: list[ChannelEditor]
|
|
|
|
|
|
class FollowedChannel(BaseSchema):
|
|
broadcaster_id: int
|
|
broadcaster_login: str
|
|
broadcaster_name: str
|
|
followed_at: datetime
|
|
|
|
|
|
class FollowedChannels(BaseSchema):
|
|
data: list[FollowedChannel]
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
total: int
|
|
|
|
|
|
class ChannelFollower(BaseSchema):
|
|
user_id: int
|
|
user_login: str
|
|
user_name: str
|
|
followed_at: datetime
|
|
|
|
|
|
class ChannelFollowers(BaseSchema):
|
|
data: list[ChannelFollower]
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
total: int
|
|
|
|
|
|
class CustomRewardImage(BaseSchema):
|
|
url_1x: str
|
|
url_2x: str
|
|
url_4x: str
|
|
|
|
|
|
class MaxPerStreamSetting(BaseSchema):
|
|
is_enabled: bool
|
|
max_per_stream: int
|
|
|
|
|
|
class MaxPerUserPerStreamSetting(BaseSchema):
|
|
is_enabled: bool
|
|
max_per_user_per_stream: int
|
|
|
|
|
|
class GlobalCooldownSetting(BaseSchema):
|
|
is_enabled: bool
|
|
global_cooldown_seconds: int
|
|
|
|
|
|
class CustomReward(BaseSchema):
|
|
broadcaster_id: int
|
|
broadcaster_login: str
|
|
broadcaster_name: str
|
|
id: str
|
|
title: str
|
|
prompt: str
|
|
cost: int
|
|
is_paused: bool
|
|
is_in_stock: bool
|
|
background_color: str
|
|
is_enabled: bool
|
|
is_user_input_required: bool
|
|
should_redemptions_skip_request_queue: bool
|
|
redemptions_redeemed_current_stream: int | None
|
|
cooldown_expires_at: datetime | None
|
|
image: CustomRewardImage | None
|
|
default_image: CustomRewardImage
|
|
max_per_stream_setting: MaxPerStreamSetting
|
|
max_per_user_per_stream_setting: MaxPerUserPerStreamSetting
|
|
global_cooldown_setting: GlobalCooldownSetting
|
|
|
|
|
|
class CustomRewards(BaseSchema):
|
|
data: list[CustomReward]
|
|
|
|
|
|
class CustomRewardRedemptionReward(BaseSchema):
|
|
id: str
|
|
title: str
|
|
prompt: str
|
|
cost: int
|
|
|
|
|
|
class CustomRewardRedemption(BaseSchema):
|
|
id: int
|
|
broadcaster_id: int
|
|
broadcaster_login: str
|
|
broadcaster_name: str
|
|
user_id: int
|
|
user_login: str
|
|
user_name: str
|
|
user_input: str
|
|
status: Literal['CANCELED', 'FULFILLED', 'UNFULFILLED']
|
|
redeemed_at: datetime
|
|
reward: CustomRewardRedemptionReward
|
|
|
|
|
|
class CustomRewardRedemptions(BaseSchema):
|
|
data: list[CustomRewardRedemption]
|
|
|
|
|
|
class CharityCampaignCurrentAmount(BaseSchema):
|
|
amount: int
|
|
decimal_places: int
|
|
currency: str
|
|
|
|
|
|
class CharityCampaignTargetAmount(BaseSchema):
|
|
value: int
|
|
decimal_places: int
|
|
currency: str
|
|
|
|
|
|
class CharityCampaignData(BaseSchema):
|
|
id: str
|
|
broadcaster_id: int
|
|
broadcaster_login: str
|
|
broadcaster_name: str
|
|
charity_name: str
|
|
charity_description: str
|
|
charity_logo: str
|
|
charity_website: str
|
|
current_amount: CharityCampaignCurrentAmount
|
|
target_amount: CharityCampaignTargetAmount
|
|
|
|
|
|
class CharityCampaign(BaseSchema):
|
|
data: list[CharityCampaignData]
|
|
|
|
|
|
class CharityDonationAmount(BaseSchema):
|
|
value: int
|
|
decimal_places: int
|
|
currency: str
|
|
|
|
|
|
class CharityDonation(BaseSchema):
|
|
id: str
|
|
campaign_id: str
|
|
user_id: int
|
|
user_login: str
|
|
user_name: str
|
|
amount: CharityDonationAmount
|
|
|
|
|
|
class CharityDonations(BaseSchema):
|
|
data: list[CharityDonation]
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
|
|
|
|
class ChattersData(BaseSchema):
|
|
user_id: int
|
|
user_login: str
|
|
user_name: str
|
|
|
|
|
|
class Chatters(BaseSchema):
|
|
data: list[ChattersData]
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
total: int
|
|
|
|
|
|
class ChannelEmoteImages(BaseSchema):
|
|
url_1x: str
|
|
url_2x: str
|
|
url_4x: str
|
|
|
|
|
|
class ChannelEmote(BaseSchema):
|
|
id: int
|
|
name: str
|
|
images: ChannelEmoteImages
|
|
tier: int
|
|
emote_type: Literal[
|
|
'none',
|
|
'bitstier',
|
|
'follower',
|
|
'subscriptions',
|
|
'channelpoints',
|
|
'rewards',
|
|
'hypetrain',
|
|
'prime',
|
|
'turbo',
|
|
'smilies',
|
|
'globals',
|
|
'owl2019',
|
|
'twofactor',
|
|
'limitedtime',
|
|
]
|
|
format: list[Literal['animated', 'static']]
|
|
scale: list[Literal['1.0', '2.0', '3.0']]
|
|
theme_mode: list[Literal['dark', 'light']]
|
|
|
|
|
|
class ChannelEmotes(BaseSchema):
|
|
data: list[ChannelEmote]
|
|
template: str
|
|
|
|
|
|
class GlobalEmotes(ChannelEmotes):
|
|
pass
|
|
|
|
|
|
class EmoteSets(ChannelEmotes):
|
|
pass
|
|
|
|
|
|
class ChannelChatBadgesVersion(BaseSchema):
|
|
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(BaseSchema):
|
|
set_id: str
|
|
versions: list[ChannelChatBadgesVersion]
|
|
|
|
|
|
class ChannelChatBadges(BaseSchema):
|
|
data: list[ChannelChatBadgesData]
|
|
|
|
|
|
class GlobalChatBadges(ChannelChatBadges):
|
|
pass
|
|
|
|
|
|
class ChatSettingsData(BaseSchema):
|
|
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(BaseSchema):
|
|
data: list[ChatSettingsData]
|
|
|
|
|
|
class SharedChatSessionParticipant(BaseSchema):
|
|
broadcaster_id: int
|
|
|
|
|
|
class SharedChatSessionData(BaseSchema):
|
|
session_id: str
|
|
host_broadcaster_id: int
|
|
participants: list[SharedChatSessionParticipant]
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
|
|
class SharedChatSession(BaseSchema):
|
|
data: list[SharedChatSessionData]
|
|
|
|
|
|
class UserEmotes(ChannelEmotes):
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
|
|
|
|
class MessageDropReason(BaseSchema):
|
|
code: str
|
|
message: str
|
|
|
|
|
|
class MessageData(BaseSchema):
|
|
message_id: str
|
|
is_sent: bool
|
|
drop_reason: MessageDropReason | None = None
|
|
|
|
|
|
class Message(BaseSchema):
|
|
data: list[MessageData]
|
|
|
|
|
|
class UserChatColorData(BaseSchema):
|
|
user_id: int
|
|
user_login: str
|
|
user_name: str
|
|
color: str
|
|
|
|
|
|
class UserChatColor(BaseSchema):
|
|
data: list[UserChatColorData]
|
|
|
|
|
|
class Clip(BaseSchema):
|
|
id: str
|
|
url: str
|
|
embed_url: str
|
|
broadcaster_id: int
|
|
broadcaster_name: str
|
|
creator_id: int
|
|
creator_name: str
|
|
video_id: str
|
|
game_id: int
|
|
language: str
|
|
title: str
|
|
view_count: int
|
|
created_at: datetime
|
|
thumbnail_url: str
|
|
duration: float
|
|
vod_offset: int | None
|
|
is_featured: bool
|
|
|
|
|
|
class Clips(BaseSchema):
|
|
data: list[Clip]
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
|
|
|
|
class ClipDownload(BaseSchema):
|
|
clip_id: str
|
|
landscape_download_url: str | None
|
|
portrait_download_url: str | None
|
|
|
|
|
|
class ClipsDownloads(BaseSchema):
|
|
data: list[ClipDownload]
|
|
|
|
|
|
class Conduit(BaseSchema):
|
|
id: str
|
|
shard_count: int
|
|
|
|
|
|
class Conduits(BaseSchema):
|
|
data: list[Conduit]
|
|
|
|
|
|
class ConduitShardTransportWebhook(BaseSchema):
|
|
method: Literal['webhook']
|
|
callback: str
|
|
|
|
|
|
class ConduitShardTransportWebsocket(BaseSchema):
|
|
method: Literal['websocket']
|
|
session_id: str
|
|
connected_at: datetime
|
|
disconnected_at: datetime
|
|
|
|
|
|
class ConduitShard(BaseSchema):
|
|
id: str
|
|
status: Literal[
|
|
'enabled',
|
|
'webhook_callback_verification_pending',
|
|
'webhook_callback_verification_failed',
|
|
'notification_failures_exceeded',
|
|
'websocket_disconnected',
|
|
'websocket_failed_ping_pong',
|
|
'websocket_received_inbound_traffic',
|
|
'websocket_internal_error',
|
|
'websocket_network_timeout',
|
|
'websocket_network_error',
|
|
'websocket_failed_to_reconnect',
|
|
]
|
|
transport: ConduitShardTransportWebhook | ConduitShardTransportWebsocket
|
|
|
|
|
|
class ConduitShards(BaseSchema):
|
|
data: list[ConduitShard]
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
|
|
|
|
class UpdateConduitShardTransportWebhook(TypedDict):
|
|
method: Literal['webhook']
|
|
callback: str | None
|
|
session_id: str | None
|
|
|
|
|
|
class UpdateConduitShardTransportWebsocket(TypedDict):
|
|
method: Literal['websocket']
|
|
session_id: str | None
|
|
|
|
|
|
class UpdateConduitShard(TypedDict):
|
|
id: str
|
|
transport: (
|
|
UpdateConduitShardTransportWebhook
|
|
| UpdateConduitShardTransportWebsocket
|
|
)
|
|
|
|
|
|
class UpdateConduitShardsError(BaseSchema):
|
|
id: str
|
|
message: str
|
|
code: str
|
|
|
|
|
|
class UpdateConduitShards(ConduitShards):
|
|
errors: list[UpdateConduitShardsError]
|
|
|
|
|
|
class ContentClassificationLabelModel(BaseSchema):
|
|
id: Literal[
|
|
'DebatedSocialIssuesAndPolitics',
|
|
'DrugsIntoxication',
|
|
'SexualThemes',
|
|
'ViolentGraphic',
|
|
'Gambling',
|
|
'ProfanityVulgarity',
|
|
'MatureGame',
|
|
]
|
|
description: str
|
|
name: str
|
|
|
|
|
|
class ContentClassificationLabels(BaseSchema):
|
|
data: list[ContentClassificationLabelModel]
|
|
|
|
|
|
class DropEntitlement(BaseSchema):
|
|
id: str
|
|
benefit_id: str
|
|
timestamp: datetime
|
|
user_id: int
|
|
game_id: int
|
|
fulfillment_status: Literal['CLAIMED', 'FULFILLED']
|
|
last_updated: datetime
|
|
|
|
|
|
class DropsEntitlements(BaseSchema):
|
|
data: list[DropEntitlement]
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
|
|
|
|
class UpdateDropsEntitlementsData(BaseSchema):
|
|
status: Literal[
|
|
'INVALID_ID', 'NOT_FOUND', 'SUCCESS', 'UNAUTHORIZED', 'UPDATE_FAILED'
|
|
]
|
|
ids: list[str]
|
|
|
|
|
|
class UpdateDropsEntitlements(BaseSchema):
|
|
data: list[UpdateDropsEntitlementsData]
|
|
|
|
|
|
class ExtensionConfigurationSegmentData(BaseSchema):
|
|
segment: Literal['broadcaster', 'developer', 'global']
|
|
broadcaster_id: int
|
|
content: str
|
|
version: str
|
|
|
|
|
|
class ExtensionConfigurationSegment(BaseSchema):
|
|
data: list[ExtensionConfigurationSegmentData]
|
|
|
|
|
|
class ExtensionLiveChannel(BaseSchema):
|
|
broadcaster_id: int
|
|
broadcaster_name: str
|
|
game_name: str
|
|
game_id: int
|
|
title: str
|
|
|
|
|
|
class ExtensionLiveChannels(BaseSchema):
|
|
data: list[ExtensionLiveChannel]
|
|
paginaiton: Pagination | dict[Any, Any] | None = None
|
|
|
|
|
|
class ExtensionSecret(BaseSchema):
|
|
content: str
|
|
active_at: datetime
|
|
expires_at: datetime
|
|
|
|
|
|
class ExtensionSecretData(BaseSchema):
|
|
format_version: int
|
|
secrets: list[ExtensionSecret]
|
|
|
|
|
|
class ExtensionSecrets(BaseSchema):
|
|
data: list[ExtensionSecretData]
|
|
|
|
|
|
class ExtensionViewsMobile(BaseSchema):
|
|
viewer_url: str
|
|
|
|
|
|
class ExtensionViewsPanel(BaseSchema):
|
|
viewer_url: str
|
|
height: int
|
|
can_link_external_content: bool
|
|
|
|
|
|
class ExtensionViewsVideoOverlay(BaseSchema):
|
|
viewer_url: str
|
|
can_link_external_content: bool
|
|
|
|
|
|
class ExtensionViewsComponent(BaseSchema):
|
|
viewer_url: str
|
|
aspect_width: int
|
|
aspect_height: int
|
|
aspect_ratio_x: int
|
|
aspect_ratio_y: int
|
|
autoscale: bool
|
|
scale_pixels: int
|
|
target_height: int
|
|
size: int
|
|
zoom: bool
|
|
zoom_pixels: int
|
|
can_link_external_content: bool
|
|
|
|
|
|
class ExtensionViews(BaseSchema):
|
|
mobile: ExtensionViewsMobile
|
|
panel: ExtensionViewsPanel
|
|
video_overlay: ExtensionViewsVideoOverlay
|
|
component: ExtensionViewsComponent
|
|
|
|
|
|
class Extension(BaseSchema):
|
|
author_name: str
|
|
bits_enabled: bool
|
|
can_install: bool
|
|
configuration_location: Literal['hosted', 'custom', 'none']
|
|
description: str
|
|
eula_tos_url: str
|
|
has_chat_support: bool
|
|
icon_url: str
|
|
icon_urls: dict[str, str]
|
|
id: str
|
|
name: str
|
|
privacy_policy_url: str
|
|
request_identity_link: bool
|
|
screenshot_urls: list[str]
|
|
state: Literal[
|
|
'Approved',
|
|
'AssetsUploaded',
|
|
'Deleted',
|
|
'Deprecated',
|
|
'InReview',
|
|
'InTest',
|
|
'PendingAction',
|
|
'Rejected',
|
|
'Released',
|
|
]
|
|
subscriptions_support_level: Literal['none', 'optional']
|
|
summary: str
|
|
support_email: str
|
|
version: str
|
|
viewer_summary: str
|
|
views: ExtensionViews
|
|
allowlisted_config_urls: list[str]
|
|
allowlisted_panel_urls: list[str]
|
|
|
|
|
|
class Extensions(BaseSchema):
|
|
data: list[Extension]
|
|
|
|
|
|
class ExtensionBitsProductCost(BaseSchema):
|
|
amount: int
|
|
type: Literal['bits']
|
|
|
|
|
|
class ExtensionBitsProduct(BaseSchema):
|
|
sku: str
|
|
cost: ExtensionBitsProductCost
|
|
in_development: bool
|
|
display_name: str
|
|
expiration: datetime
|
|
is_broadcast: bool
|
|
|
|
|
|
class ExtensionBitsProducts(BaseSchema):
|
|
data: list[ExtensionBitsProduct]
|
|
|
|
|
|
class EventsubBaseSubscriptions(BaseSchema):
|
|
data: list[sub.Any]
|
|
total: int
|
|
total_cost: int
|
|
max_total_cost: int
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
|
|
|
|
class EventsubWebsocketDisconnectSubscriptions(EventsubBaseSubscriptions):
|
|
disconnected_at: datetime
|
|
|
|
|
|
class EventsubWebsocketConnectSubscriptions(EventsubBaseSubscriptions):
|
|
connected_at: datetime
|
|
|
|
|
|
class EventsubSubscription(BaseSchema):
|
|
data: (
|
|
EventsubWebsocketDisconnectSubscriptions
|
|
| EventsubWebsocketConnectSubscriptions
|
|
| EventsubBaseSubscriptions
|
|
)
|
|
|
|
|
|
class EventsubSubscriptions(BaseSchema):
|
|
data: list[
|
|
EventsubSubscription
|
|
| EventsubWebsocketConnectSubscriptions
|
|
| EventsubBaseSubscriptions
|
|
]
|
|
|
|
|
|
class Game(BaseSchema):
|
|
id: int
|
|
name: str
|
|
box_art_url: str
|
|
igdb_id: int | str
|
|
|
|
|
|
class Games(BaseSchema):
|
|
data: list[Game]
|
|
paginaiton: Pagination | dict[Any, Any] | None = None
|
|
|
|
|
|
class CreatorGoal(BaseSchema):
|
|
id: str
|
|
broadcaster_id: int
|
|
broadcaster_login: str
|
|
broadcaster_name: str
|
|
type: Literal[
|
|
'follower',
|
|
'subscription',
|
|
'subscription_count',
|
|
'new_subscription',
|
|
'new_subscription_count',
|
|
]
|
|
description: str
|
|
current_amount: int
|
|
target_amount: int
|
|
created_at: datetime
|
|
|
|
|
|
class CreatorGoals(BaseSchema):
|
|
data: list[CreatorGoal]
|
|
|
|
|
|
class TopContribution(BaseSchema):
|
|
user_id: int
|
|
user_login: str
|
|
user_name: str
|
|
type: Literal['bits', 'other', 'subscription']
|
|
total: int
|
|
|
|
|
|
class SharedTrainParticipant(BaseSchema):
|
|
broadcaster_user_id: int
|
|
broadcaster_user_login: str
|
|
broadcaster_user_name: str
|
|
|
|
|
|
class HypeTrainCurrent(BaseSchema):
|
|
id: str
|
|
broadcaster_user_id: int
|
|
broadcaster_user_login: str
|
|
broadcaster_user_name: str
|
|
level: int
|
|
total: int
|
|
progress: int
|
|
goal: int
|
|
top_contributions: list[TopContribution]
|
|
shared_train_participants: list[SharedTrainParticipant]
|
|
started_at: datetime
|
|
expires_at: datetime
|
|
type: Literal['trasure', 'golden_kappa', 'regular']
|
|
|
|
|
|
class HypeTrainAllTimeHigh(BaseModel):
|
|
level: int
|
|
total: int
|
|
achieved_at: datetime
|
|
|
|
|
|
class HypeTrainSharedAllTimeHigh(BaseModel):
|
|
level: int
|
|
total: int
|
|
achieved_at: datetime
|
|
|
|
|
|
class HypeTrain(BaseSchema):
|
|
current: HypeTrainCurrent
|
|
all_time_high: HypeTrainAllTimeHigh
|
|
shared_all_time_high: HypeTrainSharedAllTimeHigh
|
|
|
|
|
|
class HypeTrainStatus(BaseSchema):
|
|
data: list[HypeTrain]
|
|
|
|
|
|
class AutomodStatusData(BaseSchema):
|
|
msg_id: int
|
|
is_permitted: bool
|
|
|
|
|
|
class AutomodStatus(BaseSchema):
|
|
data: list[AutomodStatusData]
|
|
|
|
|
|
class AutomodSettingsData(BaseSchema):
|
|
broadcaster_id: int
|
|
moderator_id: int
|
|
overall_level: int | None
|
|
disability: int
|
|
aggression: int
|
|
sexuality_sex_or_gender: int
|
|
misogyny: int
|
|
bullying: int
|
|
swearing: int
|
|
race_ethnicity_or_religion: int
|
|
sex_based_terms: int
|
|
|
|
|
|
class AutomodSettings(BaseSchema):
|
|
data: list[AutomodSettingsData]
|
|
|
|
|
|
class BannedUser(BaseSchema):
|
|
user_id: int
|
|
user_login: str
|
|
user_name: str
|
|
expires_at: datetime | str
|
|
created_at: datetime
|
|
reason: str
|
|
moderator_id: int
|
|
moderator_login: str
|
|
moderator_name: str
|
|
|
|
|
|
class BannedUsers(BaseSchema):
|
|
data: list[BannedUser]
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
|
|
|
|
class BanUserData(BaseSchema):
|
|
broadcaster_id: int
|
|
moderator_id: int
|
|
user_id: int
|
|
created_at: datetime
|
|
end_time: datetime | None
|
|
|
|
|
|
class BanUser(BaseSchema):
|
|
data: list[BanUserData]
|
|
|
|
|
|
class UnbanRequest(BaseSchema):
|
|
id: str
|
|
broadcaster_id: int
|
|
broadcaster_login: str
|
|
broadcaster_name: str
|
|
moderator_id: int
|
|
moderator_login: str
|
|
moderator_name: str
|
|
user_id: int
|
|
user_login: str
|
|
user_name: str
|
|
text: str
|
|
status: Literal[
|
|
'approved', 'denied', 'pending', 'acknowledged', 'canceled'
|
|
]
|
|
created_at: datetime
|
|
resolved_at: datetime | None
|
|
resolution_text: str | None
|
|
|
|
|
|
class UnbanRequests(BaseSchema):
|
|
data: list[UnbanRequest]
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
|
|
|
|
class BlockedTerm(BaseSchema):
|
|
broadcaster_id: int
|
|
moderator_id: int
|
|
id: str
|
|
text: str
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
expires_at: datetime | None
|
|
|
|
|
|
class BlockedTerms(BaseSchema):
|
|
data: list[BlockedTerm]
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
|
|
|
|
class ModeratedChannel(BaseSchema):
|
|
broadcaster_id: int
|
|
broadcaster_login: str
|
|
broadcaster_name: str
|
|
|
|
|
|
class ModeratedChannels(BaseSchema):
|
|
data: list[ModeratedChannel]
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
|
|
|
|
class Moderator(BaseSchema):
|
|
user_id: int
|
|
user_login: str
|
|
user_name: str
|
|
|
|
|
|
class Moderators(BaseSchema):
|
|
data: list[Moderator]
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
|
|
|
|
class VIP(BaseSchema):
|
|
user_id: int
|
|
user_login: str
|
|
user_name: str
|
|
|
|
|
|
class VIPs(BaseSchema):
|
|
data: list[VIP]
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
|
|
|
|
class ShieldModeStatusData(BaseSchema):
|
|
moderator_id: int
|
|
moderator_login: str
|
|
moderator_name: str
|
|
is_active: bool
|
|
last_activated_at: datetime
|
|
|
|
|
|
class ShieldModeStatus(BaseSchema):
|
|
data: list[ShieldModeStatusData]
|
|
|
|
|
|
class UserWarn(BaseSchema):
|
|
broadcaster_id: int
|
|
user_id: int
|
|
moderator_id: int
|
|
reason: str
|
|
|
|
|
|
class UserWarns(BaseSchema):
|
|
data: list[UserWarn]
|
|
|
|
|
|
class PollChoice(BaseSchema):
|
|
id: str
|
|
title: str
|
|
votes: int
|
|
channel_points_votes: int
|
|
|
|
|
|
class Poll(BaseSchema):
|
|
id: str
|
|
broadcaster_id: int
|
|
broadcaster_name: str
|
|
broadcaster_login: str
|
|
title: str
|
|
choices: list[PollChoice]
|
|
channel_points_voting_enabled: bool
|
|
channel_points_per_vote: int
|
|
status: Literal[
|
|
'ACTIVE', 'COMPLETED', 'TERMINATED', 'ARCHIVED', 'MODERATED', 'INVALID'
|
|
]
|
|
duration: int
|
|
started_at: datetime
|
|
ended_at: datetime | None
|
|
|
|
|
|
class Polls(BaseSchema):
|
|
data: list[Poll]
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
|
|
|
|
class PredictionTopPredictor(BaseSchema):
|
|
user_id: int
|
|
user_login: str
|
|
user_name: str
|
|
channel_points_used: int
|
|
channel_points_won: int
|
|
|
|
|
|
class PredictionOutcome(BaseSchema):
|
|
id: str
|
|
title: str
|
|
users: int
|
|
channel_points: int
|
|
top_predictors: list[PredictionTopPredictor]
|
|
color: Literal['BLUE', 'PINK']
|
|
|
|
|
|
class Prediction(BaseSchema):
|
|
id: str
|
|
broadcaster_id: int
|
|
broadcaster_name: str
|
|
broadcaster_login: str
|
|
title: str
|
|
winning_outcome_id: str | None
|
|
outcomes: list[PredictionOutcome]
|
|
prediction_window: int
|
|
status: Literal['ACTIVE', 'CANCELED', 'LOCKED', 'RESOLVED']
|
|
created_at: datetime
|
|
ended_at: datetime | None
|
|
locked_at: datetime | None
|
|
|
|
|
|
class Predictions(BaseSchema):
|
|
data: list[Prediction]
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
|
|
|
|
class Raid(BaseSchema):
|
|
created_at: datetime
|
|
is_mature: bool
|
|
|
|
|
|
class Raids(BaseSchema):
|
|
data: list[Raid]
|
|
|
|
|
|
class ScheduleVacation(BaseSchema):
|
|
start_time: datetime
|
|
end_time: datetime
|
|
|
|
|
|
class ScheduleSegmentCategory(BaseSchema):
|
|
id: str
|
|
name: str
|
|
|
|
|
|
class ScheduleSegment(BaseSchema):
|
|
id: str
|
|
start_time: datetime
|
|
end_time: datetime
|
|
title: str
|
|
canceled_until: datetime | None
|
|
category: ScheduleSegmentCategory
|
|
is_recurring: bool
|
|
|
|
|
|
class Schedule(BaseSchema):
|
|
broadcaster_id: int
|
|
broadcaster_login: str
|
|
broadcaster_name: str
|
|
vacation: ScheduleVacation | None
|
|
segments: list[ScheduleSegment]
|
|
|
|
|
|
class Schedules(BaseSchema):
|
|
data: list[Schedule]
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
|
|
|
|
class Category(BaseSchema):
|
|
id: int | str
|
|
name: str
|
|
box_art_url: str
|
|
|
|
|
|
class Categories(BaseSchema):
|
|
data: list[Category]
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
|
|
|
|
class Channel(BaseSchema):
|
|
broadcaster_language: str
|
|
broadcaster_login: str
|
|
display_name: str
|
|
game_id: int | str
|
|
game_name: str
|
|
id: int
|
|
is_live: bool
|
|
tags: list[str]
|
|
thumbnail_url: str
|
|
title: str
|
|
started_at: datetime | None
|
|
|
|
|
|
class Channels(BaseSchema):
|
|
data: list[Channel]
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
|
|
|
|
class StreamKey(BaseSchema):
|
|
stream_key: str
|
|
|
|
|
|
class StreamKeys(BaseSchema):
|
|
data: list[StreamKey]
|
|
|
|
|
|
class Stream(BaseSchema):
|
|
id: int
|
|
user_id: int
|
|
user_name: str
|
|
user_login: str
|
|
game_id: int | str
|
|
game_name: str
|
|
type: Literal['live']
|
|
title: str
|
|
tags: list[str]
|
|
tag_ids: list[str] = Field(..., deprecated=True)
|
|
viewer_count: int
|
|
started_at: datetime
|
|
language: str
|
|
thumbnail_url: str
|
|
is_mature: bool
|
|
|
|
|
|
class Streams(BaseSchema):
|
|
data: list[Stream]
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
|
|
|
|
class BaseStreamMarker(BaseSchema):
|
|
id: str
|
|
created_at: datetime
|
|
description: str
|
|
position_seconds: int
|
|
|
|
|
|
class StreamMarker(BaseStreamMarker):
|
|
URL: str
|
|
|
|
|
|
class CreateStreamMarkers(BaseSchema):
|
|
data: list[BaseStreamMarker]
|
|
|
|
|
|
class StreamMarkerVideo(BaseSchema):
|
|
video_id: int
|
|
markers: list[StreamMarker]
|
|
|
|
|
|
class StreamMarkersData(BaseSchema):
|
|
user_id: int
|
|
user_login: str
|
|
user_name: str
|
|
videos: list[StreamMarkerVideo]
|
|
|
|
|
|
class StreamMarkers(BaseSchema):
|
|
data: list[StreamMarkersData]
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
|
|
|
|
class Subscription(BaseSchema):
|
|
broadcaster_id: int
|
|
broadcaster_login: str
|
|
broadcaster_name: str
|
|
gifter_id: int | None = None
|
|
gifter_login: str | None = None
|
|
gifter_name: str | None = None
|
|
is_gift: bool
|
|
tier: Literal['1000', '2000', '3000']
|
|
|
|
|
|
class BroadcasterSubscription(Subscription):
|
|
plan_name: str
|
|
user_id: int
|
|
user_login: str
|
|
user_name: str
|
|
|
|
|
|
class BroadcasterSubscriptions(BaseSchema):
|
|
data: list[BroadcasterSubscription]
|
|
pagination: Pagination | dict[Any, Any] | None = None
|
|
total: int
|
|
points: int
|
|
|
|
|
|
class UserSubscription(BaseSchema):
|
|
data: list[Subscription]
|
|
|
|
|
|
class ChannelTeam(BaseSchema):
|
|
id: int
|
|
broadcaster_id: int
|
|
broadcaster_login: str
|
|
broadcaster_name: str
|
|
background_image_url: str | None
|
|
banner: str | None
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
info: str
|
|
thumbnail_url: str
|
|
team_name: str
|
|
team_display_name: str
|
|
|
|
|
|
class ChannelTeams(BaseSchema):
|
|
data: list[ChannelTeam]
|
|
|
|
|
|
class TeamUser(BaseSchema):
|
|
user_id: int
|
|
user_login: str
|
|
user_name: str
|
|
|
|
|
|
class Team(BaseSchema):
|
|
id: int
|
|
users: list[TeamUser]
|
|
background_image_url: str | None
|
|
banner: str | None
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
info: str
|
|
thumbnail_url: str
|
|
team_name: str
|
|
team_display_name: str
|
|
|
|
|
|
class Teams(BaseSchema):
|
|
data: list[Team]
|
|
|
|
|
|
class User(BaseSchema):
|
|
id: int
|
|
login: str
|
|
display_name: str
|
|
type: Literal['admin', 'global_mod', 'staff', '']
|
|
broadcaster_type: Literal['partner', 'affiliate', '']
|
|
description: str | None
|
|
profile_image_url: str
|
|
offline_image_url: str
|
|
email: str | None = None
|
|
created_at: datetime
|
|
view_count: int = Field(..., deprecated=True)
|
|
|
|
|
|
class Users(BaseSchema):
|
|
data: list[User]
|
|
|
|
|
|
class AuthorizationByUser(BaseSchema):
|
|
user_id: int
|
|
user_login: str
|
|
user_name: str
|
|
scopes: list[scopes.Any]
|
|
|
|
|
|
class AuthorizationsByUser(BaseSchema):
|
|
data: list[AuthorizationByUser]
|
|
|
|
|
|
class UserBlock(BaseSchema):
|
|
user_id: int
|
|
user_login: str
|
|
display_name: str
|
|
|
|
|
|
class UserBlockList(BaseSchema):
|
|
data: list[UserBlock]
|
|
|
|
|
|
class UserExtension(BaseSchema):
|
|
id: str
|
|
version: str
|
|
name: str
|
|
can_activate: bool
|
|
type: list[Literal['component', 'mobile', 'overlay', 'panel']]
|
|
|
|
|
|
class UserExtensions(BaseSchema):
|
|
data: list[UserExtension]
|
|
|
|
|
|
class UserActiveExtensionPanelActive(BaseSchema):
|
|
active: Literal[True]
|
|
id: str
|
|
version: str
|
|
name: str
|
|
|
|
|
|
class UserActiveExtensionPanelInactive(BaseSchema):
|
|
active: Literal[False]
|
|
|
|
|
|
class UserActiveExtensionOverlayActive(UserActiveExtensionPanelActive):
|
|
pass
|
|
|
|
|
|
class UserActiveExtensionOverlayInactive(UserActiveExtensionPanelInactive):
|
|
pass
|
|
|
|
|
|
class UserActiveExtensionComponentActive(UserActiveExtensionPanelActive):
|
|
x: int
|
|
y: int
|
|
|
|
|
|
class UserActiveExtensionComponentInactive(UserActiveExtensionPanelInactive):
|
|
pass
|
|
|
|
|
|
class UserActiveExtension(BaseSchema):
|
|
panel: dict[
|
|
int, UserActiveExtensionPanelActive | UserActiveExtensionPanelInactive
|
|
]
|
|
overlay: dict[
|
|
int,
|
|
UserActiveExtensionOverlayActive | UserActiveExtensionOverlayInactive,
|
|
]
|
|
component: dict[
|
|
int,
|
|
UserActiveExtensionComponentActive
|
|
| UserActiveExtensionComponentInactive,
|
|
]
|
|
|
|
|
|
class UserActiveExtensions(BaseSchema):
|
|
data: list[UserActiveExtension]
|
|
|
|
|
|
class VideoMutedSegment(BaseSchema):
|
|
duration: int
|
|
offset: int
|
|
|
|
|
|
class Video(BaseSchema):
|
|
id: int
|
|
stream_id: str | None
|
|
user_id: int
|
|
user_login: str
|
|
user_name: str
|
|
title: str
|
|
description: str
|
|
created_at: datetime
|
|
published_at: datetime
|
|
url: str
|
|
thumbnail_url: str
|
|
viewable: Literal['public']
|
|
view_count: int
|
|
language: str
|
|
type: Literal['archive', 'highlight', 'upload']
|
|
duration: str
|
|
muted_segments: list[VideoMutedSegment]
|
|
|
|
|
|
class Videos(BaseSchema):
|
|
data: list[Video]
|
|
pagination: Pagination | dict[Any, Any] | None
|
|
|
|
|
|
class DeleteVideos(BaseSchema):
|
|
data: list[int]
|