🔖

PythonのMisskeyライブラリの進捗

2023/12/09に公開

はじめに

この記事では私が開発しているMisskey API WrapperのMiPACとBot frameworkであるMiPAを紹介しつつ、その過程でMisskeyに貢献した物などをご紹介します。最初に軽くMiPA / MiPACそれぞれについてサンプルを交えつつ紹介していきます。

MiPACについて

https://github.com/yupix/MiPAC

MiPACはMisskey Pthon API Coreの略で、Python上でMisskeyのAPIを操作するために作成しているライブラリとなります。特徴としてはAPIの戻り値がモデル化されており、モデルから直接そのモデルに対して操作を行える点となっています。

実際に簡単な操作を行うコードを書いてみます。
お題としては招待コードの作成・削除です。これはMisskeyで招待に関するロールを持ってないと動かないので予めそこは注意してください。

async def main():
    async with Client("https://example.com", "token") as client:
    api = client.api

    created_invite = await api.invite.action.create()  # 招待を作成
    await created_invite.api.action.delete()  # 作成した招待コードを削除

このように async with を用いて簡単にセッション管理ができます。実際に何かに組み込むとして例を挙げるとすれば、Discord側でスラッシュコマンドを打ちMiPACを用いて自分のサーバーの招待コードを発行しそれをDiscord側に返すといった感じの使い方が出来ます。

また、対応しているエンドポイントのモデルはすべて型付きで datetime 等にも自動で変換するように設計しています。そのため、以下のようにプロパティで簡単にアクセスが可能です。VSCodeやPyCharmを使用している場合がかなり快適にコーディングが可能だと思います。(Vimはどうなるのか分かりませんが

async def main():
    async with Client("https://example.com", "token") as client:
    api = client.api

    result_note = await api.note.action.get("id")
    print(f"{result_note.user.username}: {result_note.id}")

実際にVisual Studio Codeでノートの投稿・削除を行ったりする際の挙動はこんな感じになります


MiPAについて

https://github.com/yupix/MiPA

MiPAはMiPACを内部に内蔵したMisskey Bot frameworkとなっています。実際どういうことかというと、MiPACがAPIとモデルを提供。MiPAはWebsocketの接続やその過程で発生するイベントの処理などを行います。

MiPAはDiscord.py ライクな書き方が出来ることを目的として作成しているため、Discord.pyを過去に使用したことがある方は結構すんなりと理解できるかもしれません。

では実際にログイン・起動後にメッセージを投稿するBotを作ってみます。

import asyncio

from aiohttp import ClientWebSocketResponse
from mipac.models.notification import NotificationNote
from mipa.ext import commands

class MyBot(commands.Bot):
    def __init__(self):
        super().__init__()

    async def _connect_channel(self):
        await self.router.connect_channel(['main', 'global'])  # タイムラインに接続

    async def on_ready(self, ws: ClientWebSocketResponse):
        print(f'connected: {self.user.username}')
        await self.client.note.action.send('Hello, world!')  # ノートを投稿
        await self._connect_channel()

    async def on_reconnect(self, ws: ClientWebSocketResponse):
        print('Disconnected from server. Will try to reconnect.')
        await self._connect_channel()


if __name__ == '__main__':
    bot = MyBot()
    asyncio.run(bot.start('instance url', 'your token'))

本題とは関係ありませんが、 on_reconnect はサーバーとの接続が切れた際に発火し、 _connect_channel で再度タイムラインに接続しなおす役割を持っています。

とまあ、このようにMiPACの client.api に当たるものが self.client にて使用できます。あとはMiPACと同じようにAPIにアクセスできます。

また、メンションコマンドという仕組みもあり、以下の画像のような感じのコマンドを簡単に実装できます。あくまで今回は紹介なので、詳細が気になる方は下の記事をご覧ください。

https://zenn.dev/yupix/articles/c8afde0ef26b77

2023年で出来たこと

MiPAC

  • エンドポイントのサポートを増やした
  • キャッシュの速度向上

MiPA

  • tasks.loopself が受け取れない問題の修正
  • 新しいチャンネルへの接続方式を追加
  • 新しいMisskeyのイベント(Websocket上の)を追加

正直あんまりパッとした物は無いです。理由としてはv11, v12, v13のすべてをサポートしていたため一つのエンドポイントをサポートするためにそれぞれのドキュメントを確認し、念のため実際の動作などを確認したうえで実装を行っていたため、1つのエンドポイントに対するサポートコストが非常に高かったためです。来年はそれを改善するためにいくつかの大幅なアップデートをしようと思っていて、そちらを次のセクションで紹介します。

今後の開発予定

今のPyPIに上がっているMiPAやMiPACはv11, v12, v13とすべてのバージョンに対応できるようにall in one みたいな感じで作っていましたが、MiPAC v0.6.0ではブランチごとにサポートするバージョンを分けてより正確なモデルやAPIへのアクセスを可能にするための作業を行っています。

今している作業のpull requestがあるのでそれを一応貼っておきます。
https://github.com/yupix/MiPAC/pull/110
https://github.com/yupix/MiPAC/pull/109

今まで通りのすべてのバージョンをサポートしたMiPACやMiPAが使いたい型は shared ブランチを使うことで今まで通りの物が使えます。

v0.6.0では多くの破壊的変更が行われる予定です。(モデル名の変更からメソッドの削除など)既にMiPAやMiPACを利用されている方にはご迷惑をおかけしますが、現状のMiPACはあまり保守に向いておらず、またv13では既に削除されてるメソッドが残っていることによるデメリットの方が大きいと判断しての決断です。ご迷惑をおかけしますが、何卒ご理解いただけると幸いです。

また、MiPACはとても作業量が多く私一人で出来る時間にも限りがあるので一緒に作ってくれる人を募集してたりします。Pythonに興味があってMisskeyやってる人とかで興味あるよ!って人がいたら是非 https://nr.akarinext.org/@yupix に連絡くれると喜びます!

最後に

なんやかんやMisskeyを始めて今年で4年になると考えると考え深いものがあります。2,3個ほどインスタンス(サーバー)を爆散させたことがありますが、それもまたいい思い出です。他にもMiPACを作ってて初めて知らない方からプルリクエストを貰ったり意見を貰ってとてもいい経験をさせていただきました。今後も頑張って作成していくので GitHubでスターを付けたりしてくださると励みになります。

それでは長くなりましたが、ここで本題のMiPAとMiPACについては終わりとなります。ここまで読んでくださりありがとうございました。

残りの部分は私がMiPACを作ってる過程で行ったMisskeyへの貢献とかを自分の意見を載せつつだらだら書いているだけなので、気になる方はそのまま見てくださると嬉しいです。

MiPACを作ってる過程で行ったMisskeyへの貢献

実はたまにMisskeyにプルリクエストを送っています。大体はAPIの型の修正とかが多いですが、経緯とかを添えつつ振り返っていこうと思います。

開発者モードを追加した

開発者モードを追加して、コンテキストメニューに 〇〇のIDをコピー系の選択しを追加した物になります。MiPAC作ってるとどうしてもノートのIDだったりファイルのIDが必要になることが多くて、そのたびにURLからコピーしたり、ブラウザの開発者ツールでコピーしていてとてもめんどくさかったので追加したという感じです。

この画像の「ユーザーIDをコピー」とかがこのプルリクで成し遂げたかったものになります。

https://github.com/misskey-dev/misskey/pull/10847

クラシックモードでテーマが自動変更された際元に戻すように

果たしてクラシックモードを使っている方がどの程度いるのか存じませんが、私が元々Misskeyに参入したときは今年で4年前ぐらいになりますが、その当時はMisskeyのv11にあたるものを知人とforkして共同で開発しつつ作っていました。

クラシックテーマはv11のデフォルトUIで私としては現在のUIより好きなのですが、ウィンドウのサイズが一定以下になった際クラシックモードから自動的にデフォルトのモードに変更される仕様があり、元のサイズに戻った後もクラシックモードには戻らずデフォルトのままとなってしまい大変不便だったので実装した感じです。(デフォルトのUIも十分素敵ですが、単純に中央に寄ってる方が使いやすいので...)

あと、幾分マシにはなりましたが未だにたまに発生するので直しきれてないかなってのも少し思ってます

https://github.com/misskey-dev/misskey/pull/9669

ユーザーをcontextmenuからアンテナに追加できるようになど

これは単純にIssueで要望を見かけて実装できそう~って思ったので実装した物です。 tamainaさんが結構手直ししてくださり、より良いものになったと思います。(tamainaさんありがとうございます!)

https://github.com/misskey-dev/misskey/pull/11206

スキーマの修正だったりAPIの戻り値の改善系

MiPACを作る関係上APIを何度もたたいたり、ドキュメントを見たりするわけですが、所々キーが抜けてたり、 enum のところに enum が設定されてなかったりと少し不便なところなどを解消するための物です。ライブラリを作りつつMisskeyにも貢献出来て一石二鳥ですね!

最近は enum を設定しようと思ったらテーブル側は varchar でめちゃくちゃエラー出てしまって、Issue見てたら enum 辞めたいみたいなのもあって心臓がキュッってなりました

https://github.com/misskey-dev/misskey/pull/12572
https://github.com/misskey-dev/misskey/pull/12568

シン・終わり

これで終わりとなります。
ここまで読んでくれた方には感謝です!本当にありがとうございました。
またどこかで!

Discussion