Python SDK
Python SDKである owncast-plugin-py を使うと、Python で Owncast プラグインを作成できます。 通常のデコレータ付きの Python コードを書きます。 ビルドステップにより、Owncast サーバー内でサンドボックス化されて実行される単一のインストール可能なプラグインに変換されます: 同じ .ocpkg フォーマットと完全な機能セットは JavaScript SDK と同じため、Python プラグインは JS プラグインのファーストクラスの同等物です。
プラグイン SDK は Owncast 0.3.0 で新しく導入されたもので、API はまだ進化中です。 バグや提案がある場合は、open an issue を開くか、chat live with the community でコミュニティに参加してください。
このページは Python 特有のレイヤーです: インストール、@plugin デコレータ、owncast-plugin-py CLI、テスト。 ハンドラ、API、権限、マニフェストは両方の SDK で同じように動作し、それぞれ参照ページがあります。
リファレンスへの対応方法
共有リファレンスでは、ハンドラと API の名前は標準の(camelCase)形式で示されています。 To read it as Python, apply one rule: decorators, host methods, and payload attribute access are snake_case. Raw wire dictionaries (msg.raw) and scenario JSON keep their camelCase wire names. Quick orientation:
| リファレンスでは | Python では |
|---|---|
| ハンドラの定義 | @plugin.* でデコレートされた関数 |
イベントのハンドラ(例: chat.message.received) | @plugin.on_chat_message |
ホスト API の呼び出し(例: owncast.chat.sendAction) | owncast.chat.send_action(text): snake_case |
ペイロードフィールド(例: msg.user.displayName) | msg.user.display_name, msg.client_id. msg.raw は元の辞書を参照します。 |
フィルタ結果(filter.pass()) | filter.pass_()(末尾の _:pass はキーワードです)。 また filter.modify(...) / filter.drop(reason) |
| Declare a plugin-owned custom hook | @plugin.on("my.event"). Owned as <your-slug>.my.event |
| プラグインをビルド / テストする | owncast-plugin-py package / owncast-plugin-py test |
前提条件
- 管理可能な Owncast サーバー、バージョン 0.3.0 以上。
- Python 3.8 以上。
インストール
slug を渡して new でプロジェクトをスキャフォールドします。 uvx は PyPI から直接スキャフォルダを実行し、何もインストールしません:
uvx owncast-plugin-py new my-plugin
cd my-plugin
ビルド、テスト、serve、package ステップのために PATH 上で owncast-plugin-py CLI を入手するには SDK をインストールしてください:
uv tool install owncast-plugin-py # or: pip install owncast-plugin-py
ビルド準備済みのディレクトリが得られます:
my-plugin/
├── plugin.manifest.json name, slug, version, permissions
├── README.md how to build, test, package, and install it
├── INSTRUCTIONS.md optional, rendered as a tab in the admin
├── AGENTS.md notes for AI coding agents
├── .agents/ a bundled skill for AI coding agents
├── src/plugin.py your code, with a sample handler
└── __tests__/*.test.json a sample scenario test
プラグインを書く
plugin、owncast、filter をインポートし、デコレータでハンドラを登録します。 各デコレータは 1 つのイベントを購読します。 SDK は、定義したハンドラからマニフェストの購読リストを生成します。
from owncast_plugin import plugin, owncast, filter
@plugin.on_chat_message
def greet(msg):
name = msg.user.display_name if msg.user else "someone"
owncast.chat.send(f"{name} said: {msg.body}")
@plugin.filter_chat_message
def block_spam(msg):
return filter.drop("spam") if "spam" in msg.body else filter.pass_()
The module exports five things:
plugin: デコレータのレジストリ。@plugin.on_chat_message,@plugin.filter_chat_message,@plugin.on_stream_started,@plugin.on_tick,@plugin.on_fediverse_followなどはランタイムのイベントを反映しており、handlers reference を参照してください。 Two take a key:@plugin.on("custom.event")declares a local custom hook that the host owns as<your-slug>.custom.event, while@plugin.on_tab_content("slug")and@plugin.on_page_content("slug")provide dynamic viewer-page HTML. For tab content, the decorator argument matches amanifest.tabsobject key. For extra page content, it matchesmanifest.extraPageContent.slug. キーを取らないものが二つあります:@plugin.on_page_stylesと@plugin.on_page_scriptsはリクエスト時にビューワーページに注入される CSS と JavaScript を返し、ui.modifyで制御されます。owncast: ホスト API の名前空間。 メソッド名はsnake_case(owncast.chat.send_action,owncast.kv.get_json)。 各呼び出しは、マニフェストで宣言した対応する権限によって制御されます。 詳細は APIs reference を参照してください。filter:filter_chat_messageハンドラから返されるフィルタ結果:filter.pass_()(末尾のアンダースコア、passは Python のキーワード)、filter.modify(...)、filter.drop(reason)。auth_check: verdict helpers for the@plugin.on_auth_checkhandler of anauth.gateplugin:auth_check.ok(),auth_check.refresh(ttl=...),auth_check.deny(reason).CommandContext: what a declared command'srun()receives:.msg,.user,.command,.invoked_as,.args, and.arg_string, plusreply(text)andreply_privately(text)helpers. Import it for type hints.
ペイロードはワイヤー上の JSON に対して snake_case のアクセサを持つ属性オブジェクトです(msg.body, msg.user.display_name, msg.client_id)。 基になる辞書には msg.raw を使用してください。 JSON オブジェクトを返すホスト呼び出しは、同様の属性オブジェクトとして返されます(owncast.server.info().name)。 リストは Python のリストとして返されます。
知っておくべき Python の慣用表現がさらに2つあり、どちらも該当ページに(Python の例付きで)完全に文書化されています:
- HTTP routing:
http.serveを持つプラグインはデコレータでルートを宣言します:@plugin.get/post/put/delete/patch(path),@plugin.route(path, methods=[...]),@plugin.on_http_request(path), および引数なしの@plugin.on_http_requestキャッチオール。 ハンドラはdict({status, body, headers})、str(→ 200)、またはNone(→ 204)を返します。 詳細は Serving HTTP を参照してください。 - Chat commands:
plugin.commands({...})はエイリアス、モデレーター制御、ユーザーごとのクールダウンを持つコマンドを宣言します。 組み込みの!helpがそれらを自動的に一覧表示します。 詳細は Chat commands を参照してください。
CLI
SDK をインストールすると owncast-plugin-py が利用できるようになります。 ビルドとパッケージングはソースをバンドルし、コンパイラを必要としません。 The test, serve, and package commands fetch the prebuilt host binaries on first use (package runs its install-time load check through the test binary):
| コマンド | 機能 |
|---|---|
owncast-plugin-py new my-plugin | 新しいプラグインプロジェクトを ./my-plugin にスキャフォールドします |
owncast-plugin-py build | src/plugin.py をビルドします(パッケージングは行いません) |
owncast-plugin-py test | ビルドしてから __tests__/ のシナリオを実行します |
owncast-plugin-py serve | ローカル開発サーバー(ポートを変更するには -p/--port、デフォルトは 8080) |
owncast-plugin-py package | ビルド + バンドル → <slug>.ocpkg: 配布するファイル |
owncast-plugin-py package # produces my-plugin.ocpkg
owncast-plugin-py test
owncast-plugin-py serve # POST /_dev/chat to drive event handlers
All four run against the current directory. The positional project argument defaults to ., so inside the project you pass nothing. From elsewhere, pass the project directory: owncast-plugin-py package my-plugin. .ocpkg は単一の配布アーティファクトです。 何が含まれるかとインストール方法については Packaging & distribution を参照してください。
知っておくべき制約
Python プラグインのビルド方法に関するいくつかの点が、プラグインの書き方に影響します。 エディタの補助やユニットテストのために owncast_plugin を通常どおりインポートします。 残りはビルドが処理します。
- Pure-Python only, and no
pip.pip installステップはなく、サードパーティのコードは(Pure-Python であれば)ソースをプロジェクトにコピーして追加します。 C 拡張を含む依存関係(numpy、pandas 等)は読み込めません。 詳細は Third-party libraries を参照してください。 外向き HTTP にはowncast.http.fetchを使用し、requestsは使用しないでください。 - 標準ライブラリ名をシャドウしないでください。 最上位に
def json(...)(または他の stdlib 名)を定義すると実際のモジュールをシャドウしてビルドが壊れる可能性があり、標準ライブラリモジュール名のファイル(src/json.py)は実際のものが優先されて無視されます。 それらはjson_responseのように名前を付けてください。 - The entry can't use relative imports. In
src/plugin.py, import your own modules absolutely (from helpers import ...), notfrom . import helpers. そこ(トップレベル)での相対インポートはビルドに失敗しますが、パッケージ内のモジュール間の相対インポートは問題ありません。 snake_casein the code you write, in contrast to the JS SDK's camelCase:send_action,get_json,msg.user.display_name,filter.pass_(). Raw wire dictionaries (msg.raw) and scenario JSON stay camelCase.
サードパーティライブラリ
pip install も requirements.txt もありません。 サードパーティライブラリは、pure Python でありそのソースを src/ にコピーする 場合にのみ動作し、そこであなたのモジュールの一つになります。
virtualenv にパッケージをインストールしても配布物には影響せず、import requests はランタイムで失敗します。 ライブラリを使用するには、その .py ソースを src/(単一モジュールまたはパッケージディレクトリ)にコピーしてインポートしてください。
- C 拡張は絶対に動作しません。 numpy、pandas、lxml、Pydantic v2、およびコンパイル済みコードを含むものは読み込めません。
- コピーしたツリー全体はあなたの管理下です。 コピーしたライブラリが他のサードパーティをインポートする場合は、それらもコピーするか、より小さいライブラリを選んでください。
- 外向き HTTP には
owncast.http.fetchを使用し、requestsを使わないでください。
標準ライブラリは利用可能です(モジュールが pure Python であれば)(json, re, datetime, base64 等)。
例えば、page-content-demo の例は Mustache テンプレートを必要とします。 テンプレートパッケージをコピーする代わりに、小さな Mustache サブセットのレンダラを独自に同梱しています。
テスト
テストは __tests__/*.test.json のシナリオファイルで、owncast-plugin-py test で実行します。 フォーマットは JS SDK と完全に同一 なので、プラグインの Python 版は JS 版のテストシナリオをそのまま再利用できます。 各シナリオはイベント/HTTP リクエストをディスパッチし、観測された副作用(chatSends, kv 書き込み, HTTP レスポンス, …)をアサートします。
[
{
"name": "echoes the message",
"events": [
{
"event": "chat.message.received",
"payload": { "user": { "id": "u1", "displayName": "alice" }, "body": "hi" }
}
],
"expect": { "chatSends": ["alice said: hi"] }
}
]
完全なシナリオデータモデル(ステップタイプ、given ステート、expect のアサーション)は Testing ページにあります。 シナリオ JSON はホストイベントを表すため、wire フィールド名(camelCase: displayName, clientId)を使っている点に注意してください。
状態
ランタイム、owncast-plugin-py CLI(scaffold、build、test、serve、package)、完全なホスト API、HTTP ルーティング、および .ocpkg パッケージングはすべて現在動作します。 すべての JS サンプルプラグインには、examples/python/ 以下に Python 対応版があります。
次に進むべき場所
- Handlers reference: 購読できるすべてのイベント(名前は
snake_caseとして読みます)。 - APIs reference: すべての
owncast.*メソッドとそれに必要な権限。 - Testing: 完全なシナリオデータモデル。
- Packaging & distribution:
.ocpkgのビルドとインストール。 - Python example plugins: 各機能ごとに1つずつ、コピーして使える完全な出発点が用意されています。
- SDK source:
owncast-plugin-pyパッケージとツールチェーン。
Improve this page
See something missing or incorrect? Edit this page and improve the documentation for everyone.
Gabe Kangas