Skip to content

Commit 6dc7c20

Browse files
committed
Add documentation
1 parent c9881ea commit 6dc7c20

13 files changed

Lines changed: 853 additions & 26 deletions

File tree

.github/workflows/docs.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Deploy Documentation
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- "docs/**"
8+
- "mkdocs.yml"
9+
- "src/kickpy/**"
10+
workflow_dispatch:
11+
12+
permissions:
13+
contents: read
14+
pages: write
15+
id-token: write
16+
17+
concurrency:
18+
group: "pages"
19+
cancel-in-progress: false
20+
21+
jobs:
22+
build:
23+
runs-on: ubuntu-latest
24+
steps:
25+
- uses: actions/checkout@v4
26+
27+
- uses: actions/setup-python@v5
28+
with:
29+
python-version: "3.13"
30+
31+
- name: Install dependencies
32+
run: pip install -e ".[docs]"
33+
34+
- name: Build documentation
35+
run: mkdocs build --strict
36+
37+
- uses: actions/upload-pages-artifact@v3
38+
with:
39+
path: site
40+
41+
deploy:
42+
needs: build
43+
runs-on: ubuntu-latest
44+
environment:
45+
name: github-pages
46+
url: ${{ steps.deployment.outputs.page_url }}
47+
steps:
48+
- id: deployment
49+
uses: actions/deploy-pages@v4

README.md

Lines changed: 175 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,211 @@
11
# kickcom.py
22

33
[![PyPI](https://img.shields.io/pypi/v/kickcom.py)](https://pypi.org/project/kickcom.py)
4+
[![Documentation](https://img.shields.io/badge/docs-GitHub%20Pages-blue)](https://predaaa.github.io/kickcom.py)
45

56
Async library for Kick.com API and webhooks
67

7-
> [!NOTE]
8-
> This is in alpha stage, it currently only supports app access tokens. PRs to improve are very welcome!
9-
10-
Find the kick.com [API documentation here](https://docs.kick.com/)
8+
[Documentation](https://predaaa.github.io/kickcom.py) | [Kick API Reference](https://docs.kick.com/)
119

1210
## Installation
1311

1412
```bash
1513
pip install kickcom.py
1614
```
1715

18-
## Client
16+
Optional speed extras:
17+
18+
```bash
19+
pip install kickcom.py[speed]
20+
```
1921

20-
All endpoints available for app access tokens are available.
22+
## Quick Start
23+
24+
### App Access Token (Bot / Server-side)
2125

2226
```python
23-
from kickpy.client import Client
27+
import asyncio
28+
from kickpy import KickClient
29+
30+
async def main():
31+
client = KickClient("KICK_CLIENT_ID", "KICK_CLIENT_SECRET")
2432

25-
kick_client = Client("KICK_CLIENT_ID", "KICK_CLIENT_SECRET")
33+
user = await client.fetch_user(4377088)
34+
print(user.name)
2635

27-
user = await kick_client.fetch_user(4377088)
28-
# Returns:
29-
# User(user_id=4377088, name='KickBot', email='', profile_picture='https://files.kick.com/images/user/4377088/profile_image/conversion/8dde6c21-7008-43d1-b6ac-7d9c34b7d9cc-fullsize.webp')
36+
channel = await client.fetch_channel(slug="kickbot")
37+
print(channel.stream_title)
3038

31-
channel = await kick_client.fetch_channel(4377088)
32-
# Returns:
33-
# Channel(broadcaster_user_id=4377088, slug='kickbot', channel_description='Official bot of https://kickbot.app, the #1 tool for Kick streamers. | VOD Downloader | !clip command | Custom Commands | Timed Messages | Customizable overlays | Stream Deck Plugin |\n\nContact: contact@kickbot.app', banner_picture='https://files.kick.com/images/channel/4295080/banner_image/b0d66fa3-3a4e-45d5-94ea-84d0590990d7', stream=Stream(url='', key='', is_live=False, is_mature=False, language='', start_time='0001-01-01T00:00:00Z', viewer_count=0), stream_title='', category=Category(id=0, name='', thumbnail=''))
39+
await client.close()
40+
41+
asyncio.run(main())
3442
```
3543

36-
## Webhook server
44+
### User Access Token (OAuth 2.1 + PKCE)
45+
46+
Some endpoints require a user token. The library handles the full OAuth flow with a built-in local callback server:
47+
48+
```python
49+
import asyncio
50+
from kickpy import KickClient, Scope
51+
52+
async def main():
53+
client = KickClient("KICK_CLIENT_ID", "KICK_CLIENT_SECRET")
54+
55+
# Opens browser, captures callback on localhost, exchanges code for tokens
56+
await client.authenticate(
57+
scopes=[Scope.CHAT_WRITE, Scope.MODERATION_BAN],
58+
port=3000, # redirect URI must be http://127.0.0.1:3000/callback in your Kick app settings
59+
)
60+
61+
# User token endpoints are now available
62+
await client.send_chat_message("Hello from kickcom.py!", broadcaster_user_id=4377088)
3763

38-
Support for receiving webhooks events from Kick is also available.
64+
await client.close()
65+
66+
asyncio.run(main())
67+
```
68+
69+
If you handle OAuth externally, you can inject tokens directly:
3970

4071
```python
41-
from kickpy.client import Client
72+
client.set_user_token(
73+
access_token="...",
74+
refresh_token="...",
75+
expires_in=3600,
76+
scope="chat:write moderation:ban",
77+
)
78+
```
79+
80+
## API Reference
81+
82+
### Users
83+
84+
| Method | Description | Token |
85+
|--------|-------------|-------|
86+
| `fetch_user(user_id)` | Get a user by ID | App |
87+
88+
### Channels
89+
90+
| Method | Description | Token |
91+
|--------|-------------|-------|
92+
| `fetch_channel(user_id?, slug?)` | Get a channel by broadcaster ID or slug | App |
93+
| `update_channel(category_id?, stream_title?, custom_tags?)` | Update channel metadata | User (`channel:write`) |
94+
95+
### Livestreams
96+
97+
| Method | Description | Token |
98+
|--------|-------------|-------|
99+
| `fetch_livestream(broadcaster_user_id)` | Get a single livestream | App |
100+
| `fetch_livestreams(broadcaster_user_id?, category_id?, language?, limit?, sort?)` | Get multiple livestreams | App |
101+
| `fetch_livestream_stats()` | Get global livestream stats | App |
102+
103+
### Categories
104+
105+
| Method | Description | Token |
106+
|--------|-------------|-------|
107+
| `fetch_categories(query?, name?, tag?, category_id?, cursor?, limit?)` | Search categories (v2) | App |
108+
109+
### Chat
110+
111+
| Method | Description | Token |
112+
|--------|-------------|-------|
113+
| `send_chat_message(content, message_type?, broadcaster_user_id?, reply_to_message_id?)` | Send a chat message | User (`chat:write`) |
114+
| `delete_chat_message(message_id)` | Delete a chat message | User (`moderation:chat_message:manage`) |
115+
116+
### Moderation
117+
118+
| Method | Description | Token |
119+
|--------|-------------|-------|
120+
| `ban_user(broadcaster_user_id, user_id, duration?, reason?)` | Ban or timeout a user | User (`moderation:ban`) |
121+
| `unban_user(broadcaster_user_id, user_id)` | Unban a user | User (`moderation:ban`) |
122+
123+
### Channel Rewards
124+
125+
| Method | Description | Token |
126+
|--------|-------------|-------|
127+
| `fetch_channel_rewards()` | List channel point rewards | User (`channel:rewards:read`) |
128+
| `create_channel_reward(cost, title, ...)` | Create a reward | User (`channel:rewards:write`) |
129+
| `update_channel_reward(reward_id, ...)` | Update a reward | User (`channel:rewards:write`) |
130+
| `delete_channel_reward(reward_id)` | Delete a reward | User (`channel:rewards:write`) |
131+
| `fetch_reward_redemptions(reward_id?, status?, ids?, cursor?)` | Get redemptions | User (`channel:rewards:read`) |
132+
| `accept_reward_redemptions(ids)` | Accept pending redemptions | User (`channel:rewards:write`) |
133+
| `reject_reward_redemptions(ids)` | Reject pending redemptions | User (`channel:rewards:write`) |
134+
135+
### KICKs
136+
137+
| Method | Description | Token |
138+
|--------|-------------|-------|
139+
| `fetch_kicks_leaderboard(top?)` | Get KICKs leaderboard | User (`kicks:read`) |
140+
141+
### Events / Subscriptions
142+
143+
| Method | Description | Token |
144+
|--------|-------------|-------|
145+
| `fetch_events_subscriptions()` | List event subscriptions | App |
146+
| `subscribe_to_event(event_type, user_id)` | Subscribe to a webhook event | App |
147+
| `unsubscribe_from_event(subscription_id)` | Unsubscribe from an event | App |
148+
149+
### Other
150+
151+
| Method | Description | Token |
152+
|--------|-------------|-------|
153+
| `fetch_public_key()` | Get the Kick public key for webhook verification | App |
154+
155+
## OAuth Scopes
156+
157+
```python
158+
from kickpy import Scope
159+
160+
Scope.USER_READ # user:read
161+
Scope.CHANNEL_READ # channel:read
162+
Scope.CHANNEL_WRITE # channel:write
163+
Scope.CHANNEL_REWARDS_READ # channel:rewards:read
164+
Scope.CHANNEL_REWARDS_WRITE # channel:rewards:write
165+
Scope.CHAT_WRITE # chat:write
166+
Scope.STREAMKEY_READ # streamkey:read
167+
Scope.EVENTS_SUBSCRIBE # events:subscribe
168+
Scope.MODERATION_BAN # moderation:ban
169+
Scope.MODERATION_CHAT_MESSAGE_MANAGE # moderation:chat_message:manage
170+
Scope.KICKS_READ # kicks:read
171+
```
172+
173+
## Webhook Server
174+
175+
Receive and process webhook events from Kick:
176+
177+
```python
178+
import asyncio
179+
from kickpy import KickClient, WebhookEvent, WebhookServer
42180
from kickpy.models.webhooks.chat_message import ChatMessage
43-
from kickpy.webhooks.enums import WebhookEvent
44-
from kickpy.webhooks.server import WebhookServer
45181

46182
def on_chat_message(payload: ChatMessage):
47-
print(payload)
48-
183+
print(f"{payload.sender.username}: {payload.content}")
49184

50185
async def main():
51-
kick_client = Client("KICK_CLIENT_ID", "KICK_CLIENT_SECRET")
52-
webhook_server = WebhookServer(kick_client, callback_route="KICK_CALLBACK_ROUTE")
53-
webhook_server.dispatcher.listen(WebhookEvent.CHAT_MESSAGE_SENT, on_chat_message)
54-
55-
await webhook_server.listen(host="localhost", port=3000, access_log=None)
186+
client = KickClient("KICK_CLIENT_ID", "KICK_CLIENT_SECRET")
187+
server = WebhookServer(client, callback_route="/webhooks/kick")
188+
server.dispatcher.listen(WebhookEvent.CHAT_MESSAGE_SENT, on_chat_message)
56189

190+
await server.listen(host="localhost", port=3000, access_log=None)
57191

58192
loop = asyncio.new_event_loop()
59193
asyncio.set_event_loop(loop)
60194
loop.run_until_complete(main())
61195
loop.run_forever()
62196
```
197+
198+
### Webhook Events
199+
200+
| Event | Enum |
201+
|-------|------|
202+
| `chat.message.sent` | `WebhookEvent.CHAT_MESSAGE_SENT` |
203+
| `channel.followed` | `WebhookEvent.CHANNEL_FOLLOWED` |
204+
| `channel.subscription.new` | `WebhookEvent.CHANNEL_SUB_NEW` |
205+
| `channel.subscription.gifts` | `WebhookEvent.CHANNEL_SUB_GIFTS` |
206+
| `channel.subscription.renewal` | `WebhookEvent.CHANNEL_SUB_RENEWAL` |
207+
| `livestream.status.updated` | `WebhookEvent.LIVESTREAM_STATUS_UPDATED` |
208+
| `livestream.metadata.updated` | `WebhookEvent.LIVESTREAM_METADATA_UPDATED` |
209+
| `channel.moderation.user_banned` | `WebhookEvent.MODERATION_USER_BANNED` |
210+
| `kicks.gifted` | `WebhookEvent.KICKS_GIFTED` |
211+
| `channel.reward.redemption.updated` | `WebhookEvent.CHANNEL_REWARD_REDEMPTION_UPDATED` |

docs/api/client.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# KickClient
2+
3+
The main client class for interacting with the Kick API.
4+
5+
::: kickpy.client.KickClient
6+
options:
7+
members:
8+
- authenticate
9+
- set_user_token
10+
- close
11+
- fetch_public_key
12+
- fetch_user
13+
- fetch_channel
14+
- update_channel
15+
- fetch_livestream
16+
- fetch_livestreams
17+
- fetch_livestream_stats
18+
- fetch_categories
19+
- send_chat_message
20+
- delete_chat_message
21+
- ban_user
22+
- unban_user
23+
- fetch_channel_rewards
24+
- create_channel_reward
25+
- update_channel_reward
26+
- delete_channel_reward
27+
- fetch_reward_redemptions
28+
- accept_reward_redemptions
29+
- reject_reward_redemptions
30+
- fetch_kicks_leaderboard
31+
- fetch_events_subscriptions
32+
- subscribe_to_event
33+
- unsubscribe_from_event

docs/api/enums.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Enums
2+
3+
## Scope
4+
5+
OAuth scopes used with [`authenticate()`](client.md).
6+
7+
::: kickpy.enums.Scope
8+
9+
## WebhookEvent
10+
11+
Event types for the [webhook server](../webhooks/setup.md).
12+
13+
::: kickpy.webhooks.enums.WebhookEvent

docs/api/errors.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Errors
2+
3+
All exceptions raised by the library.
4+
5+
## Base Exception
6+
7+
::: kickpy.errors.KickpyException
8+
9+
## Argument Errors
10+
11+
::: kickpy.errors.MissingArgument
12+
13+
::: kickpy.errors.NoClientId
14+
15+
::: kickpy.errors.NoClientSecret
16+
17+
## HTTP Errors
18+
19+
::: kickpy.errors.HTTPException
20+
21+
::: kickpy.errors.BadRequest
22+
23+
::: kickpy.errors.Unauthorized
24+
25+
::: kickpy.errors.Forbidden
26+
27+
::: kickpy.errors.NotFound
28+
29+
::: kickpy.errors.Ratelimited
30+
31+
::: kickpy.errors.InternalServerError

0 commit comments

Comments
 (0)