link: DESIGN.md of online-judge-tools organization
oj-api
コマンドは、競技プログラミングのためのツールを作成するための API 基盤を提供する。
特にこれを jmerle/competitive-companion と共通の JSON 形式で提供する。
- ジャッジサーバとの通信機能を個別のツールから削除し、メンテコストを共通化し低減すること
- ジャッジサーバとの通信機能を標準化し、ひとつの API ライブラリのメンテが止まっても依存ツールの開発が止まらないようにすること
- ツール開発者の体験を向上させること
- エンドユーザの体験を直接向上させること
- エンドユーザにとって使いやすいものとツール開発者にとって使いやすいものは異なる
競技プログラミング用のツールのメンテコストの中心となるのはスクレイピング関連であるという背景がある。 競技プログラミング用の (レートを上げることを目的とした) ツールを作成するにあたっては「問題を指定してそのサンプルケースを取得する」「問題とコードを指定して提出を行う」などのサーバとの基本的な通信機能を実装することになるのがたいていである。 しかしほとんどのオンラインジャッジはツールからのアクセスを想定していない。 オンラインジャッジのサービスごとに個別にスクレイピング処理を書く必要がでてくる。 スクレイピングは一般にあまり歓迎されずかつ不安定な処理であり、適切に書かなければ誤動作が多くなり、たとえ適切に書いたとしてもサーバ側の仕様変更により容易に壊れてしまう。 これらの修正や対応は面倒であり、しかも継続的に行ない続けなければならない。
スクレイピングをする。
- API は JSON で提供する。Python ライブラリとしての提供は避ける。
- Python ライブラリは互換性を壊さないために未だ提供されているができれば消していきたい。規模が異なるのでそれほど酷くはないが、構造は「悪い方が良い」原則と僕の体験談|Rui Ueyama|note と似ている。
- API の出力は禁欲的に留める。ログ出力に色を付けたりはしない。開発者にとって使いやすく、かつエンドユーザにとっては避けるべきものにするためである。
- ログイン関連は難しすぎるので諦める。ログイン関連はセキュリティに直結する都合により頻繁に仕様変更がある。また Gmail GitHub Twitter Facebook などの各種サービスを経由してのログインなどを個別にすべてカバーするのは現実的ではない。スクレイピングによる対応は重要度の高いサービスだけにして、残りは WebDriver による対応とする。
- 内部はできる限り状態を持たない。状態はすべて HTTP 通信ライブラリのセッションオブジェクトに持たせ、独自に定義するクラスは「正規化されていてかつ便利なメソッドが生えている URL」でしかないという状況を保つ。
TODO: もうすこし詳しく書く
コンテスト中のページの閲覧やコードの提出にはログインが必要である。 この際、ユーザのパスワードあるいはセッション情報が必要となる。 パスワードを平文で保存するのでなく、クッキーとして保持されるセッション情報のみを保存するようにする。 セッション情報のみでも悪用は可能だが、これは一般のブラウザを用いてログインした場合も同様であるため、許容できるだろう。
特になし。
難しい。
End-to-end tests を中心とし、schedule 機能を用いて定期実行する。 外部の web サービスをスクレイピングして利用するという形態上、本体コードに変化がなくても定期的にツールは動かなくなる。