Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get stream destination info #19

Merged
merged 3 commits into from
Nov 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion kick/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from .http import HTTPClient
from .livestream import PartialLivestream
from .message import Message
from .users import ClientUser, PartialUser, User
from .users import ClientUser, PartialUser, User, DestinationInfo
from .utils import MISSING, decorator, setup_logging

if TYPE_CHECKING:
Expand Down Expand Up @@ -213,6 +213,28 @@ async def fetch_user(self, name: str, /) -> User:
user = User(data=data, http=self.http)
return user

async def fetch_stream_url_and_key(self) -> DestinationInfo:
"""
|coro|

Fetches your stream URL and stream key from the API.
You must be authenticated to use this endpoint.

Raises
-----------
HTTPException
Fetching Failed
Forbidden
You are not authenticated

Returns
-----------
DestinationInfo
"""

data = await self.http.fetch_stream_destination_url_and_key()
return DestinationInfo(data=data)

def dispatch(self, event_name: str, *args, **kwargs) -> None:
event_name = f"on_{event_name}"

Expand Down
25 changes: 17 additions & 8 deletions kick/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@
ReplyOriginalSender,
V1MessageSentPayload,
)
from .types.user import ChatterPayload, ClientUserPayload, UserPayload
from .types.user import (
ChatterPayload,
ClientUserPayload,
UserPayload,
DestinationInfoPayload,
)
from .types.videos import GetVideosPayload

T = TypeVar("T")
Expand All @@ -60,10 +65,9 @@
async def json_or_text(response: ClientResponse, /) -> Union[dict[str, Any], str]:
text = await response.text()
try:
try:
return json.loads(text)
except json.JSONDecodeError:
pass
return json.loads(text)
except json.JSONDecodeError:
pass
except KeyError:
pass

Expand Down Expand Up @@ -238,9 +242,11 @@ async def request(self, route: Route, **kwargs) -> Any:
try:
res = await self.__session.request(
route.method,
url
if self.whitelisted is True
else f"{self.bypass_host}:{self.bypass_port}/request?url={url}",
(
url
if self.whitelisted is True
else f"{self.bypass_host}:{self.bypass_port}/request?url={url}"
),
headers=headers,
cookies=cookies,
**kwargs,
Expand Down Expand Up @@ -488,6 +494,9 @@ def reply_to_message(
def get_me(self) -> Response[ClientUserPayload]:
return self.request(Route.root("GET", "/api/v1/user"))

def fetch_stream_destination_url_and_key(self) -> Response[DestinationInfoPayload]:
return self.request(Route.root("GET", "/stream/publish_token"))

async def get_asset(self, url: str) -> bytes:
if self.__session is MISSING:
self.__session = ClientSession()
Expand Down
5 changes: 5 additions & 0 deletions kick/types/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,8 @@ class ClientUserPayload(TypedDict):
streamer_channel: ClientUserStreamerChannelsPayload
roles: list # Unknown
profilepic: str | None


class DestinationInfoPayload(TypedDict):
rtmp_publish_path: str
rtmp_stream_token: str
28 changes: 26 additions & 2 deletions kick/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,33 @@
if TYPE_CHECKING:
from .chatroom import Chatroom
from .http import HTTPClient
from .types.user import ClientUserPayload, InnerUser, UserPayload
from .types.user import (ClientUserPayload, InnerUser, UserPayload,
DestinationInfoPayload)

__all__ = ("User", "Socials", "PartialUser", "ClientUser")
__all__ = ("DestinationInfo", "Socials", "PartialUser", "User", "ClientUser")


class DestinationInfo(BaseDataclass["DestinationInfoPayload"]):
"""
Information about a user's stream destination

Attributes
-----------
stream_url: str
The URL for streaming
stream_key: str
The stream key
"""

@property
def stream_url(self) -> str:
"""The URL for streaming"""
return self._data["rtmp_publish_path"]

@property
def stream_key(self) -> str:
"""The stream key"""
return self._data["rtmp_stream_token"]


class Socials(BaseDataclass["InnerUser | ClientUserPayload"]):
Expand Down
Loading