kicksdk

Kick (kick.com) without the I/O.

kicksdk knows Kick - which requests to make, what the answers look like, how the realtime chat feed speaks, how webhooks are signed - and never sends a request or opens a socket itself. Send the Request objects with any HTTP client and hand the status and body back to the matching parse_*. For a ready chat connection over asyncio, see kicksdk.aio.

Values come back Kick-shaped: dicts with snake_case keys, as Kick writes them.

Modules: kicksdk.events, kicksdk.content, kicksdk.realtime, kicksdk.public_api, kicksdk.website, kicksdk.webhooks.

 1"""Kick (kick.com) without the I/O.
 2
 3kicksdk knows Kick - which requests to make, what the answers look like, how
 4the realtime chat feed speaks, how webhooks are signed - and never sends a
 5request or opens a socket itself. Send the :class:`Request` objects with any
 6HTTP client and hand the status and body back to the matching ``parse_*``.
 7For a ready chat connection over asyncio, see :mod:`kicksdk.aio`.
 8
 9Values come back Kick-shaped: dicts with snake_case keys, as Kick writes them.
10
11Modules: :mod:`kicksdk.events`, :mod:`kicksdk.content`,
12:mod:`kicksdk.realtime`, :mod:`kicksdk.public_api`, :mod:`kicksdk.website`,
13:mod:`kicksdk.webhooks`.
14"""
15
16from __future__ import annotations
17
18from dataclasses import dataclass
19from typing import Any, Mapping, Optional
20
21from . import _native
22
23__all__ = ["KickError", "Request", "events", "content", "realtime", "public_api", "website", "webhooks"]
24
25
26class KickError(Exception):
27    """Kick answered with an error, or a call could not be made.
28
29    ``kind`` is ``status`` (Kick's HTTP status is in ``status``), ``shape``,
30    ``json``, ``invalid``, ``webhook`` or ``call``.
31    """
32
33    def __init__(self, kind: str, status: Optional[int], message: str) -> None:
34        super().__init__(message)
35        self.kind = kind
36        self.status = status
37        self.message = message
38
39    def __repr__(self) -> str:
40        return f"KickError({self.kind!r}, {self.status!r}, {self.message!r})"
41
42
43@dataclass(frozen=True)
44class Request:
45    """A request to send with any HTTP client."""
46
47    method: str
48    url: str
49    headers: list[tuple[str, str]]
50    body: Optional[str]
51
52    @classmethod
53    def _from(cls, v: Mapping[str, Any]) -> "Request":
54        return cls(v["method"], v["url"], [(k, val) for k, val in v["headers"]], v.get("body"))
55
56
57def _call(_fn: str, /, endpoints: Optional[Mapping[str, str]] = None, **args: Any) -> Any:
58    # Positional-only, so a function's own `name` argument (events.parse) is
59    # never taken for the function's name.
60    if endpoints:
61        args["endpoints"] = dict(endpoints)
62    try:
63        return _native.call(_fn, args)
64    except _native.NativeError as e:
65        kind, status, message = e.args
66        raise KickError(kind, status, message) from None
67
68
69def _request(_fn: str, /, **kw: Any) -> Request:
70    return Request._from(_call(_fn, **kw))
71
72
73def _requests(_fn: str, /, **kw: Any) -> list[Request]:
74    return [Request._from(r) for r in _call(_fn, **kw)]
75
76
77from . import content, events, public_api, realtime, webhooks, website  # noqa: E402
class KickError(builtins.Exception):
27class KickError(Exception):
28    """Kick answered with an error, or a call could not be made.
29
30    ``kind`` is ``status`` (Kick's HTTP status is in ``status``), ``shape``,
31    ``json``, ``invalid``, ``webhook`` or ``call``.
32    """
33
34    def __init__(self, kind: str, status: Optional[int], message: str) -> None:
35        super().__init__(message)
36        self.kind = kind
37        self.status = status
38        self.message = message
39
40    def __repr__(self) -> str:
41        return f"KickError({self.kind!r}, {self.status!r}, {self.message!r})"

Kick answered with an error, or a call could not be made.

kind is status (Kick's HTTP status is in status), shape, json, invalid, webhook or call.

KickError(kind: str, status: Optional[int], message: str)
34    def __init__(self, kind: str, status: Optional[int], message: str) -> None:
35        super().__init__(message)
36        self.kind = kind
37        self.status = status
38        self.message = message
kind
status
message
@dataclass(frozen=True)
class Request:
44@dataclass(frozen=True)
45class Request:
46    """A request to send with any HTTP client."""
47
48    method: str
49    url: str
50    headers: list[tuple[str, str]]
51    body: Optional[str]
52
53    @classmethod
54    def _from(cls, v: Mapping[str, Any]) -> "Request":
55        return cls(v["method"], v["url"], [(k, val) for k, val in v["headers"]], v.get("body"))

A request to send with any HTTP client.

Request( method: str, url: str, headers: list[tuple[str, str]], body: Optional[str])
method: str
url: str
headers: list[tuple[str, str]]
body: Optional[str]