制作も終盤、スケジュールはタイト。新しいマシンに重要なパイプラインツールを導入する必要があります。撮影(ショット)のステータスを同期したり、プレイブラストを公開したり、あるいは Kitsu のワークフローを自動化 したりするためのものです。ツール自体は大したことはありません。Python です。あなたはすでに書いています。
問題は、その周りのすべて。
導入先のマシンには Python が入っていません。あるいは、間違ったバージョンです。スタジオの Linux サーバーはロックダウンされています。フリーランサーの Windows 環境では依存関係をコンパイルできません。誰かが「pip が必要なのか、仮想環境が必要なのか、それとも Gazu SDK なのか」と聞いてきます。すると、あっという間に「シンプルなスクリプト」はドキュメント、トラブルシューティング、そして失われる時間へと変わってしまうのです。
パイプラインツールを作る代わりに、環境の管理をしている状態になります。
これは誰も楽しくない工程です。Python をインストールし、バージョンを固定し、足りないライブラリを追いかけて、OS の更新で何も壊れないことを祈ること。さらに、ツールをアーティストのワークステーション、レンダーノード、CI サーバーで動かす必要があるとき、その脆さは本当の制作上のリスクになります。
本当に欲しいのはシンプルです。1 つのツール、1 つのコマンド。あとはただ実行されること。
この記事では、Kitsu Python SDK(Gazu)を Command Line Interface(CLI)で包み込み、さらに単一のバイナリ実行ファイルにコンパイルすることで、Kitsu ワークフローをどのようにパッケージするかを学びます。 Python のインストールは不要。依存関係の管理も不要。すぐにどんなマシンでも使える、信頼できる実行ファイルだけです。
なぜ CLI が必要なのか
GUI は創造的な作業に最適です。しかし パイプライン管理を扱う段階になると、Web UI はすぐに負担になります。Kitsu の適切なタスクを CLI に移すことで、より速く、より拡張性があり、そして自動化しやすい形で作業できるようになります。
5 つのショットのアニメーションを仕上げて、ステータスを更新し、プレビューをアップロードする必要があるとします。ブラウザだとコンテキスト切り替えが発生します。Alt-Tab、Chrome を開く、Kitsu に移動、プロジェクトに入る、エピソードを探す、ショットをクリック、ステータス変更、動画のアップロード。そして同じ作業を、すべてのショット分繰り返すのです。CLI なら、その場に留まれます。kitsu publish --status Review と入力して Enter。あとは次へ。キーボードから離れることはなく、集中が途切れず、メニューをクリックすることで発生する認知的コストも支払わずに済みます。
CLI は自然に「引数」「リスト」「自動化」の発想へと導き、そこで一気に積み上がっていきます。1 つのショットを更新できるなら、同じコマンドで 10 も 100 も更新できます。 シーケンスをループしたり、ショット名をパイプで渡したり、DCC やレンダー出力から直接操作したりできます。Web UI で 1 時間かかる反復クリック作業が、スクリプト化された数秒に変わるのです。そして一貫していて、繰り返せて、バージョン管理もしやすい。
最後に、すべてのパイプライン処理が、モニター付きのワークステーション上で動くわけではありません。 レンダーファームのノード、ビルドサーバー、あるいはディスク上のファイルに反応するバックグラウンドプロセスで実行する必要があることもあります。そうした環境では、ブラウザもなく、ボタンをクリックするユーザーもいません。CLI はシェルがある場所ならどこでも動きます。パブリッシュ、自動化によるステータス変更、バリデーション、同期処理まで行え、Kitsu はより深いレベルでパイプラインに組み込まれていきます。
このガイドで紹介している例の統合について、完全なソースコードは GitHub で確認できます。
🔗 https://github.com/cgwire/blog-tutorials/tree/main/kitsu-cli
1. CLI インターフェースの設計
Kitsu API に触れる前に、まずツールの骨組みが必要です。Python にはコマンドライン引数を解析する方法がいくつかありますが、プロ向けのパイプラインツールなら、Click や Typer といったライブラリの利用を強くおすすめします。
このウォークスルーでは、kitsu-cli というツールを想像してみましょう。
ツールを木(ツリー)だと思ってください。 主幹(幹)がメインの実行ファイルで、枝があなたのコマンドとサブコマンドです。
kitsu-cli (root)
└── production (production に関するコマンド)
└── list (すべての productions を一覧表示)
次は、Click を使ってこのロジックを Python で構成する方法です。この構造は、ツールを拡張可能にするために重要です。今日あなたが production を管理しているとしても、明日には asset やプレイリストを管理しているかもしれません。
import click@click.group() def cli(): """My Studio Kitsu Tool""" pass
@cli.group() def production(): """productions を管理するためのコマンド""" pass
@production.command() @click.option('--name', help='名前でフィルタ') def list(name): """productions を一覧表示""" click.echo(f"productions を一覧表示中: {name}")
if name == 'main': cli()
このスニペットだけでも、ヘルプメニューが自動で手に入ります。ユーザーが kit-cli --help と入力すれば、ドキュメントが表示されます。これは開発者の思いやりであり、ユーザーに使い方を教えるツールを作ることです。
CLI を実行するには、通常の Python プログラムと同じように同じコマンドを使うだけです。
python3 cli.py production list
2. Gazu の機能を追加する
骨組みができたので、次は筋肉が必要です。Kitsu には Gazu という素晴らしい Python クライアントが用意されています。
もし Gazu を使ったことがないなら、Gazu はあなたのスクリプトと Kitsu サーバーの間をつなぐブリッジだと考えてください。
どのパイプラインツールでも最初のハードルは 認証 です。アーティストに、パスワードをスクリプトへ直書きさせたくはありません。堅牢な CLI は、すでにセッションが存在するかどうかを確認します。なければ、ユーザーに 1 回ログインしてもらい、トークンをローカルに保存します。簡単のため、認証ロジックは次のように固定しておきます。
import gazu
gazu.set_host("http://localhost/api") user = gazu.log_in("admin@example.com", "mysecretpassword")
認証が済んだら、先ほど書いた list コマンドを具体化できます。productions を一覧表示するには次のようにします。
@production.command()
@click.option('--name', help='名前でフィルタ')
def list(name):
"""productions を一覧表示"""
click.echo(f"productions を一覧表示中: {name}")
ブラウザを開いて Vue アプリの読み込みを待ったり、ビューをフィルタしたりする必要はありません。このスクリプトは生データを即座に返します。
3. インタラクティブなインターフェース
--name test のようなコマンドフラグも便利ですが、production をインタラクティブな一覧から選べるようにする方が、はるかに良い体験になります。
シーケンスの正確な名前をユーザーに入力させる代わりに(必ずスペルミスが起きます)、プロンプトを追加することで CLI を賢くできます。もしユーザーが引数を渡し忘れたら、その場で聞けばいいのです。
questionary のようなライブラリは、ターミナルに自己説明型のインタラクティブな選択リストを追加できるので最適です。
import questionary@production.command() def select(): """利用可能な productions を一覧表示""" productions = gazu.project.all_projects()
selected_project = questionary.select( "どのプロジェクトで作業していますか?", choices=productions ).ask() click.echo(f"{selected_project} を選択しました。assets を読み込み中...")
この小さな追加によって、ユーザー体験は「怖いハッカー向けツール」から「頼りになるアシスタント」へと変わります。ユーザーが Kitsu から取得した有効な選択肢しか選べないため、エラー率はほぼゼロにまで下がります。
4. 単一の実行可能バイナリ
最後にもう一つ、「自分のラップトップでは動かない」問題を解決する必要があります。依存関係を含む Python スクリプトがあります:gazu、click、questionary など。
フリーランサーのマシンで動かすには、本来は Python をインストールしたり、仮想環境を作って pip install で要件を入れたりする必要があります。これらの手順をすべてなくすために PyInstaller を使います。
python3 -m pip install pyinstaller
PyInstaller はあなたの Python スクリプトを解析し、インポートされているすべてのライブラリを見つけ、Python インタプリタ自体もバンドルし、すべてを 1 つの .exe ファイル(Windows)またはターゲットのバイナリ(Linux/Mac)に包み込みます。
ターミナルでスクリプトのフォルダに移動して、次を実行します。
python3 -m PyInstaller --onefile --name kitsu-cli cli.py
--onefile: このフラグは、バラバラの依存関係が入ったフォルダではなく、すべてを 1 つのファイルとしてバンドルするよう PyInstaller に指示します。--name: 最終的なバイナリファイルの名前。
処理が終わったら dist/ フォルダを確認します。kitsu-cli(または kitsu-cli.exe)というファイルが見つかるはずです。
これをそのまま使って、USB ドライブに入れたり、メールで送ったり、ネットワークドライブに置いたりできます。アーティストはデスクトップにドラッグして、同じ OS のアーキテクチャ(macOS、Windows など)でコンパイルされていればすぐに実行できます。Python をインストールする必要はありません。Gazu を手動でインストールする必要もありません。つまり、ただ動くだけです。
./kitsu-cli production list
とはいえ、私の言葉を信じるだけではなく、GitHub リポジトリをクローンして自分で試してみてください。

CLI を別の OS ターゲットへクロスコンパイルする必要がある場合は、Github Actions を使えます。
CLI の例:「Render Fetcher」
よりパイプライン中心のシナリオに切り替えてみましょう。
複数のマシンにわたって 分散レンダリングを管理 するワークフローを思い浮かべてください。それぞれのレンダーノードは、Kitsu から定期的に新しい作業を取得する必要があります。レンダリング待ち(TODO)としてマークされたショットと、その対応するプレビュー .blend ファイルです。これらのマシンはヘッドレスで、ロックダウンされ、意図的にミニマム構成になっています。Python のインストールはなし。仮想環境もなし。依存関係のやりくりもなし。
そこで欲しいのは、どんなサーバーにも置いて、cron ジョブやサービスとして実行できる「単一の実行ファイル」です。
./kitsu-cli pull MechaFight /home/user/flamenco/jobs
対応するコードは次のようになります。
import osimport click import gazu import questionary
gazu.set_host("http://localhost/api") user = gazu.log_in("admin@example.com", "mysecretpassword")
@click.group() def cli(): """My Studio Kitsu Tool""" pass
@cli.command() @click.argument("project_name", required=True) @click.argument("output_path", required=True) def pull(project_name, output_path): click.echo(f"Fetching TODO render tasks for project: {project_name}")
project = gazu.project.get_project_by_name(project_name) tasks = gazu.task.all_tasks_for_project(project) rendering = gazu.task.get_task_type_by_name("Rendering") todo = gazu.task.get_task_status_by_name("todo") render_tasks = [ t for t in tasks if t["task_type_id"] == rendering["id"] and t["task_status_id"] == todo["id"] ] for task in render_tasks: files = gazu.files.get_all_preview_files_for_task(task) size = len(files) if size > 0: latest = files[size - 1] if latest["extension"] == "blend": target_path = os.path.join( output_path, latest["name"] + "." + latest["extension"] ) gazu.files.download_preview_file(latest, target_path)
if name == "main": cli()
- Kitsu を照会する - CLI は Kitsu(Gazu 経由)に接続し、指定したプロジェクトに対して TODO ステータスのレンダリングタスクをすべて取得します。
- タスクをフィルタする -
todoとマークされ、かつ対応するプレビュー ファイルが関連付いているタスクを抽出します(この場合は.blendファイルです)。 - アセットをダウンロードする - 各タスクごとに、CLI は対応するプレビュー
.blendファイルを、指定された出力パスへディスクへダウンロードします。 - レンダリング - ダウンロードが完了すると、ファイルは Blender が取得できる状態になり、手動または Flamenco のような自動レンダーオーケストレータ経由でレンダリングできます。
この CLI を単一のバイナリにコンパイルしてしまえば、デプロイは簡単になります。Linux のレンダーノードにそのまま置いて、Python や依存関係をインストールせずに cron や systemd から起動できます。すべてのサーバーで同じ方法で作業を取得します。フォルダ構成は一貫します。タスクの状態はそのまま Kitsu から取得されます。そしてレンダーファームはレンダリングに集中できます。
繰り返しになりますが、対応する Github リポジトリで実際に確認してください。
まとめ
自分で Kitsu CLI を作ることは、必ずしも複雑である必要はありません。Gazu ライブラリを使いやすい CLI に包み、PyInstaller で固定化することで、パイプラインをスケールさせられます。環境管理に伴う技術的な摩擦を取り除き、アーティストが最も得意なこと、つまり美しいアニメーションを作ることに集中できるようになります。
ブログを購読して、Kitsu と Blender のスクリプトを組み合わせる方法も学んでください!


