openapi: 3.1.0 info: description: "" version: "2.0.0" title: "yukicoder API" termsOfService: "https://yukicoder.me/" license: name: "Apache 2.0" url: "http://www.apache.org/licenses/LICENSE-2.0.html" servers: - url: "https://yukicoder.me/api" # ここに並べた順で Swagger UI のグループが表示される。 # ここに無いタグを operation に付けると末尾に回るので、タグを足したらここにも足す # (app/controllers/swagger_render_test.go の TestSwaggerTagsDeclared が見ている)。 tags: - name: "user" description: "ユーザー情報。" - name: "problems" description: "問題の取得・提出・編集。" - name: "submissions" description: "提出の取得。" - name: "編集トークン対応" description: > 問題の管理画面で発行した編集トークン(ypt_...)で叩ける API。 Authorization: Bearer ypt_... を付けます。 トークンは発行元の問題にしか効きません(別の問題を指すと 401)。 同じ API はアカウントの APIキー でも使えます。その場合は対象がその問題に限られず、 自分が作者・テスターの問題(管理者なら全問題)が対象になります。 ここに出ている operation は、本来のグループにも重複して載っています。 - name: "language" description: "言語・ジャッジ環境の情報。" - name: "ranking" description: "ランキング。" - name: "ranking (非推奨)" description: "旧ランキング。v2 を使ってください。" - name: "contest" description: "コンテスト。" - name: "statistics" description: "統計情報。" paths: /v1/authUser: get: operationId: getAuthUser tags: - "user" summary: "get login user" description: "現在ログインされているユーザー情報を取得します。" security: - BearerAuth: [ ] responses: 200: description: "OK" content: application/json: schema: $ref: "#/components/schemas/AuthUser" 403: description: "ログインしていない。本文は HTML" content: text/html: schema: type: "string" 404: description: "ログイン中のユーザーの情報が引けない" content: application/json: schema: type: "object" example: Message: "指定したユーザーは存在しません" /v1/user/{param}/{user}: get: operationId: getUser tags: - "user" summary: "Get user info" description: "ユーザー情報を取得します。" security: [ ] parameters: - in: "path" name: "param" description: "id or name or twitter" required: true schema: type: "string" enum: [ id,name,twitter ] - in: "path" name: "user" description: "idのときはuserId(数値), nameのときはユーザー名,twitterのときは@以降" required: true schema: type: "string" responses: 200: description: "OK" content: application/json: schema: $ref: "#/components/schemas/User" 404: description: "Not Found" content: application/json: schema: type: "object" example: Message: "指定したユーザーは存在しません" /v1/solved/{param}/{user}: get: operationId: getSolvedProblems tags: - "user" summary: "Get user latest solved problems" description: "ユーザーの最新のACした問題一覧とその問題情報を取得します。名前だと同じアカウントがいると意図したデータが取れないかも知れないので、/user/{param}/{user}で確認するか、idで指定したほうが確実です。" security: [ ] parameters: - in: "path" name: "param" description: "id or name or twitter" required: true schema: type: "string" enum: [ id,name,twitter ] - in: "path" name: "user" description: "idのときはuserId(数値), nameのときはユーザー名,twitterのときは@以降" required: true schema: type: "string" responses: 200: description: "OK" content: application/json: schema: $ref: "#/components/schemas/Problems" 404: description: "Not Found" content: application/json: schema: type: "object" example: Message: "指定したユーザーは存在しません" /v1/solved/{param}/{user}/{first}: get: operationId: getFirstSolvedProblems tags: - "user" summary: "Get user first solved problems" description: "ユーザーが最初に(リジャッジ前に)ACした問題一覧とその問題情報を取得します。名前だと同じアカウントがいると意図したデータが取れないかも知れないので、/user/{param}/{user}で確認するか、idで指定したほうが確実です。" security: [ ] parameters: - in: "path" name: "param" description: "id or name or twitter" required: true schema: type: "string" enum: [ id,name,twitter ] - in: "path" name: "user" description: "idのときはuserId(数値), nameのときはユーザー名,twitterのときは@以降" required: true schema: type: "string" - in: "path" name: "first" required: true description: "最初にACをした情報を取りたい場合はfirstを指定する。" schema: type: "string" enum: [ first ] responses: 200: description: "OK" content: application/json: schema: $ref: "#/components/schemas/Problems" 404: description: "Not Found" content: application/json: schema: type: "object" example: Message: "指定したユーザーは存在しません" /v1/problems/{ProblemId}: get: operationId: getProblem tags: - "problems" summary: "Get problem by ProblemId" description: "ProblemIdを指定して問題を取得します。APIキーを使うとログイン情報に依存する問題も取得できます。/problems/{ProblemId}はすべて、/problems/no/{ProblemNo}と置き換えることが可能です" security: - {} # 認証なしでも呼べる - BearerAuth: [ ] parameters: - in: "path" name: "ProblemId" required: true description: "問題ID" schema: type: "integer" responses: 200: description: "OK" content: application/json: schema: $ref: "#/components/schemas/ProblemWithStatics" 404: description: "Not Found" content: application/json: schema: type: "object" example: Message: "指定した問題は存在しません" /v1/problems/{ProblemId}/favorite_status: get: operationId: getProblemFavoriteStatus tags: - "problems" summary: "問題のお気に入り状態を取得" description: "指定された問題IDに対して、現在のユーザーのお気に入り状態と総お気に入り数を返します。" security: - {} # ログインしていなくても総数は取得可能 - BearerAuth: [] # APIキーでも認証可能 parameters: - $ref: "#/components/parameters/ProblemIdPath" responses: "200": description: "成功" content: application/json: schema: $ref: "#/components/schemas/ProblemFavoriteStatus" "404": description: "問題が見つかりません" content: application/json: schema: $ref: "#/components/schemas/Error" "500": description: "サーバーエラー" content: application/json: schema: $ref: "#/components/schemas/Error" /v1/problems/{ProblemId}/submit: post: operationId: submitProblem tags: - "problems" - "編集トークン対応" summary: "Submit problem by ProblemId" description: "langは必須ですが、sourceかfileのどちらかを指定してください。Bearer にはアカウントの APIキー のほか、問題の編集トークン(ypt_...)も使えます。編集トークンの場合は発行者としての提出になります(想定解のACをトークンだけで用意できます)。" security: - BearerAuth: [ ] parameters: - in: "path" name: "ProblemId" required: true description: "問題ID" schema: type: "integer" requestBody: content: multipart/form-data: schema: type: object required: - lang properties: lang: type: string source: type: string file: type: string format: binary responses: 200: description: "OK" content: application/octet-stream: schema: type: string format: binary 404: description: "Not Found" content: application/json: schema: type: "object" example: Message: "指定した問題は存在しません" /v1/problems/{ProblemId}/file/{Which}: get: operationId: getTestCaseFiles tags: - "problems" - "編集トークン対応" summary: "Get TestCaseFiles by ProblemId" description: "問題IDに対応するテストケースリストを取得します。detail=1 を付けると、名前に加えてサイズと内容の SHA-256 を返します。付けなければ従来どおり名前の配列です。並び順はどちらも自然順です。" security: - BearerAuth: [ ] parameters: - in: "path" name: "ProblemId" required: true description: "問題ID" schema: type: "integer" - in: "path" name: "Which" required: true description: "入力ケース or 出力ケース" schema: type: "string" enum: [ "in","out" ] - in: "query" name: "detail" required: false description: "1 を指定すると [{name, size, sha256}] を返す。sha256 は GET /v1/problems/{ProblemId}/file/{Which}/{FileName} が返すバイト列、つまりサーバに保存されている内容に対する値なので、そのまま差分判定に使える" schema: type: "string" enum: [ "1" ] responses: 200: description: "OK" content: application/json: schema: type: "array" items: type: "string" description: "ファイル名のリスト" 404: description: "Not Found" content: application/json: schema: type: "object" example: Message: "指定した問題は存在しません" post: operationId: uploadTestCaseFiles tags: - "problems" - "編集トークン対応" summary: "Post TestCaseFiles by ProblemId" description: "複数のファイルをアップします。フォーム名は newfiles で、複数指定できます。ファイル名はアップするファイル名になります(パスでは指定しません)。制限はHTTPヘッダーなども含め30MiBです。 / 保存時にファイルの内容が正規化されることがあります(主に改行と空白の扱い)。取得すると正規化後の内容が返るため、送った内容とバイト単位で一致しない場合があります。差分を取るときは保存後の内容を基準にしてください。 / ファイル名は A-Za-z0-9._ 以外の文字が取り除かれます(例: case-01.txt は case01.txt になる)。実際に保存された名前はレスポンスの FileNames を見てください。 / リクエストボディに Content-Encoding: gzip を付けると展開してから処理します。multipart 全体を gzip する形で使え、JSON を送る PUT でも同じように使えます。 / Swagger の Web UI からは multipart の複数ファイルがうまく送れません(https://github.com/OAI/OpenAPI-Specification/issues/254)。その場合は curl などから叩いてください。" security: - BearerAuth: [ ] parameters: - in: "path" name: "ProblemId" required: true description: "問題ID" schema: type: "integer" - in: "path" name: "Which" required: true description: "入力ケース or 出力ケース" schema: type: "string" enum: [ "in","out" ] requestBody: content: multipart/form-data: schema: type: object properties: newfiles: type: array items: type: string format: binary responses: 200: description: "FileNamesにはサニタイズ後のファイル名が返ります" 404: description: "Not Found" content: application/json: schema: type: "object" example: Message: "指定した問題は存在しません" delete: operationId: deleteAllTestCaseFiles tags: - "problems" - "編集トークン対応" summary: "Delete All TestCaseFiles by ProblemId" description: "" security: - BearerAuth: [ ] parameters: - in: "path" name: "ProblemId" required: true description: "問題ID" schema: type: "integer" - in: "path" name: "Which" required: true description: "入力ケース or 出力ケース" schema: type: "string" enum: [ "in","out" ] responses: 200: description: "OK" 404: description: "Not Found" content: application/json: schema: type: "object" example: Message: "指定した問題は存在しません" /v1/problems/{ProblemId}/file/{Which}/{FileName}: get: operationId: getTestCaseFile tags: - "problems" - "編集トークン対応" summary: "Get TestCaseFile by ProblemId" description: "" security: - BearerAuth: [ ] parameters: - in: "path" name: "ProblemId" required: true description: "問題ID" schema: type: "integer" - in: "path" name: "Which" required: true description: "入力ケース or 出力ケース" schema: type: "string" enum: [ "in","out" ] - in: "path" name: "FileName" required: true description: "ファイル名" schema: type: "string" responses: 200: description: "OK" content: application/json: schema: $ref: "#/components/schemas/ProblemSubmitted" 404: description: "Not Found" content: application/json: schema: type: "object" example: Message: "指定した問題は存在しません" delete: operationId: deleteTestCaseFile tags: - "problems" - "編集トークン対応" summary: "Delete TestCaseFile by ProblemId" description: "テストケースを削除します" security: - BearerAuth: [ ] parameters: - in: "path" name: "ProblemId" required: true description: "問題ID" schema: type: "integer" - in: "path" name: "Which" required: true description: "入力ケース or 出力ケース" schema: type: "string" enum: [ "in","out" ] - in: "path" name: "FileName" required: true description: "ファイル名" schema: type: "string" responses: 200: description: "OK" 404: description: "Not Found" content: application/json: schema: type: "object" example: Message: "指定した問題は存在しません" /v1/problems/{ProblemId}/file/{Which}/{FileName}/{NewFileName}: patch: operationId: renameTestCaseFile tags: - "problems" - "編集トークン対応" summary: "Rename TestCaseFile" description: "テストケース名のリネームをします" security: - BearerAuth: [ ] parameters: - in: "path" name: "ProblemId" required: true description: "問題ID" schema: type: "integer" - in: "path" name: "Which" required: true description: "入力ケース or 出力ケース" schema: type: "string" enum: [ "in","out" ] - in: "path" name: "FileName" required: true description: "ファイル名" schema: type: "string" - in: "path" name: "NewFileName" required: true description: "新しいファイル名" schema: type: "string" responses: 200: description: "OK" 404: description: "Not Found" content: application/json: schema: type: "object" example: Message: "指定した問題は存在しません" /v1/problems: get: operationId: getProblems tags: - "problems" summary: "Get all problems" description: "公開されているテスト以外のすべての問題を取得します" security: [ ] responses: 200: description: "OK" content: application/json: schema: $ref: "#/components/schemas/Problems" /v1/problems/{ProblemId}/edit: get: operationId: getProblemForEdit tags: - "problems" - "編集トークン対応" summary: "問題の現在の内容を取得(編集用)" description: "問題文の生ソースを含む編集用の情報を返します。Bearer にはアカウントの APIキー(作者・テスター・管理者のみ) か、問題の管理画面で発行した編集トークン(ypt_...) を入れます。編集トークンは紐づく問題にしか使えません。Cookie セッションでは使えません。" security: - BearerAuth: [ ] parameters: - in: "path" name: "ProblemId" required: true description: "問題ID" schema: type: "integer" responses: 200: description: "OK。キーは POST が受け付ける名前と同じで、値を書き換えてそのまま POST できる(showable / problemId / content / isMarkdown は読み取り専用)" content: application/json: schema: $ref: "#/components/schemas/ProblemEditContent" 401: description: "認証情報が無い・不正・失効・別の問題のトークン" content: application/json: schema: type: "object" example: error: "トークンが正しくありません" 403: description: "APIキーのユーザーにこの問題の編集権限がない" 404: description: "Not Found" put: operationId: replaceProblem tags: - "problems" - "編集トークン対応" summary: "問題を更新(全置換)" description: "画面の編集フォームと同じ処理を API で実行します。公開・削除・作者の変更はできません。認証は GET と同じ(アカウントの APIキー か 編集トークン、または Cookie セッション + X-CSRFToken)。全置換なので、GET で取得した JSON の値を書き換えてそのまま送るのが基本です。省略した boolean は false になります。一部のキーだけ変えたいときは PATCH を使ってください。GET だけにある読み取り専用キー(problemId, content, isMarkdown, showable)は混ざっていても無視されます。問題文の変更は content ではなく html / markdown で送ります(どちらも空だと問題文が空で上書きされるので、必ずどちらか一方に中身を入れること)。latestModNanoTime を省略すると競合検出なしで常に上書きします(last-write-wins)。未知のフィールドはエラーになります。" security: - BearerAuth: [ ] parameters: - in: "path" name: "ProblemId" required: true description: "問題ID" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/ProblemEditRequest" responses: 200: description: "保存された。許可されていない HTML が削除された場合は Message に警告が付く" content: application/json: schema: type: "object" properties: Message: type: "string" example: "保存されました。" LatestModNanoTime: type: "string" description: "保存後のファイル更新時刻(画面の編集フォーム用。API では使わない)" Ignored: type: "array" items: type: "string" description: | 送られたが読み取り専用として無視したキー(problemId, content, isMarkdown, showable)。 無視したものが無ければこのキー自体が出ません。 問題文を content で送ると 200 が返るのに何も保存されないので、 書いたつもりが反映されていないときはここを見てください。 example: [ "content" ] 401: description: "認証情報が無い・不正・失効・別の問題のトークン" 403: description: "編集権限がない、入力の検証エラー、または latestModNanoTime を渡していて値が古い(編集競合)。本文はエラーメッセージのテキスト" content: text/plain: schema: type: "string" 404: description: "Not Found" patch: operationId: patchProblem tags: - "problems" - "編集トークン対応" summary: "問題を部分更新" description: "送ったキーだけを変えます。省略したキーは現在の値のままです。PUT と違って、boolean を省略しても false にならず、html / markdown を省略しても問題文は消えません。認証・受け付けるキー・エラーの扱いは PUT と同じです。読み取り専用キー(problemId, content, isMarkdown, showable)は無視されます。問題文を変えるときは content ではなく html / markdown で送ります。latestModNanoTime を省略すると競合検出なしで上書きします。未知のフィールドはエラーになります。" security: - BearerAuth: [ ] parameters: - in: "path" name: "ProblemId" required: true description: "問題ID" schema: type: "integer" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/ProblemPatchRequest" responses: 200: description: "保存された。許可されていない HTML が削除された場合は Message に警告が付く" content: application/json: schema: type: "object" properties: Message: type: "string" example: "保存されました。" LatestModNanoTime: type: "string" description: "保存後のファイル更新時刻(画面の編集フォーム用。API では使わない)" Ignored: type: "array" items: type: "string" description: | 送られたが読み取り専用として無視したキー(problemId, content, isMarkdown, showable)。 無視したものが無ければこのキー自体が出ません。 問題文を content で送ると 200 が返るのに何も保存されないので、 書いたつもりが反映されていないときはここを見てください。 example: [ "content" ] 401: description: "認証情報が無い・不正・失効・別の問題のトークン" 403: description: "編集権限がない、入力の検証エラー、または latestModNanoTime を渡していて値が古い(編集競合)。本文はエラーメッセージのテキスト" content: text/plain: schema: type: "string" 404: description: "Not Found" /v1/problems/{ProblemId}/code: get: operationId: getJudgeCode tags: - "problems" - "編集トークン対応" summary: "ジャッジコードを取得" description: "スペシャルジャッジのコードと、そのコンパイル状態を返します。未登録なら langId / status / source とも空です。認証は問題編集 API と同じ(アカウントの APIキー か 編集トークン、または Cookie セッション + X-CSRFToken)。作者・テスター・管理者のみ。" security: - BearerAuth: [ ] parameters: - in: "path" name: "ProblemId" required: true description: "問題ID" schema: type: "integer" responses: 200: description: "OK" content: application/json: schema: type: "object" properties: langId: type: "string" source: type: "string" status: $ref: "#/components/schemas/JudgeStatusOrEmpty" description: | コンパイル状態。WJ(待ち) → Judge(実行中) → AC(成功) / CE(失敗) と遷移します。 未登録なら空です。結果を待つなら AC か CE になるまで見てください (Judge は途中の状態)。 各値の意味は GET /v1/statuses で取れます。 compileMessage: type: "string" description: | コンパイラまたはシステムからのメッセージ。 エラーだけでなく**警告も入る**ので、成功していても空とは限りません。 まだコンパイルしていない・未登録なら空です。 **先頭 2000 バイトまで**です。長い出力は途中で切れます。 401: description: "認証情報が無い・不正・失効・別の問題のトークン" 403: description: "編集権限がない" 404: description: "Not Found" put: operationId: putJudgeCode tags: - "problems" - "編集トークン対応" summary: "ジャッジコードを保存" description: "スペシャルジャッジのコードを保存し、コンパイルを開始します。source が空文字列なら削除します(ジェネレータと同じ)。保存のたびに既存のソースは消してから書き直すので、言語を変えても古いソースは残りません。ジャッジタイプが標準のままだと保存はできますが使われず、その旨が Message に入ります。" security: - BearerAuth: [ ] parameters: - in: "path" name: "ProblemId" required: true description: "問題ID" schema: type: "integer" requestBody: required: true content: application/json: schema: type: "object" properties: langId: type: "string" description: "言語ID。source が空のときは見ません" source: type: "string" description: "ジャッジコード。空文字列で削除" responses: 200: description: "保存または削除された" content: application/json: schema: type: "object" properties: Message: type: "string" status: type: "string" description: "保存したときは WJ(コンパイル待ち)。削除したときは空。結果はここでは分からないので、GET で待つこと" enum: [ "WJ", "" ] 400: description: "無効な言語" 401: description: "認証情報が無い・不正・失効・別の問題のトークン" 403: description: "編集権限がない" 404: description: "Not Found" /v1/submissions/{SubmissionId}: get: operationId: getSubmission tags: - "submissions" - "編集トークン対応" summary: "提出の状態を取得" description: | 提出したあと、結果が出るまで待つのに使います。ソースコードは含みません。 **Authorization: Bearer で、サイトサポーター限定です。** サポーターでない場合は 403 になります。 アカウントの API キーと、問題の編集トークン(ypt_...)の両方が使えます。 提出 API が編集トークンを受けるので、トークンで提出して結果を待つ、という流れがそのまま通ります。 ただし編集トークンは**その問題への提出しか読めません**(別の問題の提出を指すと 401)。 誰の提出を見られるかは画面と同じ判定です。自分の提出、自分が作問者/テスターの 問題への提出、詳細が公開されている問題への提出が見えます。サポーターであることは この判定を緩めません。 結果を待つときは status を見てください。judging 分類の間はまだ出ていません (分類は GET /v1/statuses)。 security: - BearerAuth: [ ] parameters: - in: "path" name: "SubmissionId" required: true description: "提出ID" schema: type: "integer" responses: 200: description: "OK" content: application/json: schema: type: "object" properties: submissionId: type: "integer" problemId: type: "integer" submitterId: type: "integer" langId: type: "string" status: $ref: "#/components/schemas/JudgeStatus" description: "今の判定。各値の意味は GET /v1/statuses" firstStatus: $ref: "#/components/schemas/JudgeStatus" description: "最初の判定。リジャッジで status が変わったかを見るのに使う" runTimeMs: type: "integer" description: "最大実行時間(ミリ秒)" length: type: "integer" description: "コード長(バイト)" score: type: "integer" description: "得点。スコア問題以外は 0。サブタスク問題では割合(0-100)が入る" date: type: "string" format: "date-time" description: "提出日時" 401: description: "認証情報が無い・不正。編集トークンが別の問題のものだった場合もここ" 403: description: "サイトサポーターでない、またはこの提出を見る権限がない" 404: description: "提出が見つからない" /v1/problems/{ProblemId}/rejudge: post: operationId: rejudgeProblem tags: - "problems" - "編集トークン対応" summary: "問題の提出をリジャッジする" description: | テストケースや想定解を直したあとに、その問題の提出を判定し直します。 **Authorization: Bearer で叩く場合はサイトサポーター限定です。** サポーターでない場合は 403 になります。画面のリジャッジボタンは今までどおり 作問者なら誰でも使えます(Cookie セッション + X-CSRFToken で叩いた場合も制限しません)。 非同期です。登録した件数を返すので、結果は提出一覧で確認してください。 security: - BearerAuth: [ ] parameters: - in: "path" name: "ProblemId" required: true description: "問題ID" schema: type: "integer" requestBody: required: false content: application/json: schema: type: "object" properties: target: type: "string" description: | どの提出を対象にするか。省略すると all。画面のボタンと同じ区分です。 * `all` — その問題の全提出 * `firstAC` — 最初の判定が AC だったもの * `onlyAC` — 今の判定が AC のもの * `noOut` — 今の判定が NoOut のもの enum: [ "all", "firstAC", "onlyAC", "noOut" ] default: "all" responses: 200: description: "登録した(対象が0件でも200)" content: application/json: schema: type: "object" properties: Message: type: "string" target: type: "string" count: type: "integer" description: "リジャッジに送った提出の件数。0 なら対象が無かった" 400: description: "target が不正" 401: description: "認証情報が無い・不正・失効・別の問題のトークン" 403: description: "編集権限がない、または Bearer なのにサイトサポーターでない" 404: description: "Not Found" /v1/problems/{ProblemId}/validator: get: operationId: getValidator tags: - "problems" - "編集トークン対応" summary: "テストケースのバリデータを取得" description: "テストケース(入力)の検証コードと、その検証状態を返します。未登録なら langId / source / status が空、latestCheck / testCaseLatest が 0 です。認証はジャッジコードと同じ(アカウントの APIキー か 編集トークン、または Cookie セッション + X-CSRFToken)。作者・テスター・管理者のみ。" security: - BearerAuth: [ ] parameters: - in: "path" name: "ProblemId" required: true description: "問題ID" schema: type: "integer" responses: 200: description: "OK" content: application/json: schema: type: "object" properties: langId: type: "string" source: type: "string" status: $ref: "#/components/schemas/JudgeStatusOrEmpty" description: | 検証状態。Pending(テストケース変更後の待ち) → WJ(検証待ち) → Judge(実行中) → 結果 と遷移します。この3つ以外が結果で、**成功は AC のみ**です。 WA はテストケースが検証を通らなかった、RE / TLE / MLE / OLE はバリデータの 実行時エラー、CE はコンパイルエラーです。未登録なら空です。 各値の意味は GET /v1/statuses で取れます。 latestCheck: type: "integer" format: "int64" description: "最後に検証した時刻(unix ナノ秒)。未登録なら 0。DB の型が秒精度なので下9桁は常に 0" testCaseLatest: type: "integer" format: "int64" description: "テストケースを最後に変更した時刻(unix ナノ秒)。一度も変更していなければ 0。latestCheck > testCaseLatest なら、今の結果は最新のテストケースに対するもの。秒精度なので厳密比較(>)を使うこと。等号だと同一秒の変更を取りこぼす" compileMessage: type: "string" description: | コンパイラまたはシステムからのメッセージ。 エラーだけでなく**警告も入る**ので、成功していても空とは限りません。 まだ検証していない・未登録なら空です。 **先頭 2000 バイトまで**です。長い出力は途中で切れます。 cases: type: "array" description: | ケースごとの検証結果。検証が終わっていなければ空。 status が AC 以外のケースが、バリデータを通らなかったテストケースです。 実行時のエラー出力(stderr)は含みません。ケース数だけ膨らむためで、 必要なら GET /problems/{ProblemId}/validation/print/err/{name} で取れます (画面用のエンドポイントで、Cookie セッションが要ります)。 items: type: "object" properties: name: type: "string" description: "テストケースのファイル名" status: $ref: "#/components/schemas/JudgeStatus" description: | そのケースの結果。AC 以外がバリデータを通らなかったケースです。 各値の意味は GET /v1/statuses で取れます。 401: description: "認証情報が無い・不正・失効・別の問題のトークン" 403: description: "編集権限がない" 404: description: "Not Found" put: operationId: putValidator tags: - "problems" - "編集トークン対応" summary: "テストケースのバリデータを保存" description: "検証コードを保存し、検証を開始します。source が空文字列なら削除します(ジャッジコードと同じ)。削除するとソースと前回の結果も消えます。 / テストケースを更新すると、最後の更新から10秒後に検証が自動で走ります(連続変更のたびに走らないためのデバウンス)。その待ち時間の間は status が Pending になります。テストケースを送ってから結果を待つときは、status が Pending / WJ / Judge のいずれでもなくなり、かつ latestCheck > testCaseLatest になるまで見てください。 / バリデータが未登録の問題では、テストケースを更新しても何も走りません。" security: - BearerAuth: [ ] parameters: - in: "path" name: "ProblemId" required: true description: "問題ID" schema: type: "integer" requestBody: required: true content: application/json: schema: type: "object" properties: langId: type: "string" description: "言語ID。source が空のときは見ません" source: type: "string" description: "バリデータのソース。空文字列で削除" responses: 200: description: "保存または削除された" content: application/json: schema: type: "object" properties: Message: type: "string" status: type: "string" description: "保存したときは WJ(検証待ち)。削除したときは空。結果はここでは分からないので、GET で待つこと" enum: [ "WJ", "" ] 400: description: "無効な言語" 401: description: "認証情報が無い・不正・失効・別の問題のトークン" 403: description: "編集権限がない" 404: description: "Not Found" /v1/problems/{ProblemId}/generator: get: operationId: getGenerator tags: - "problems" - "編集トークン対応" summary: "ジェネレータのソースと設定を取得" description: "認証は /v1/problems/{ProblemId}/edit と同じ(アカウントの APIキー か 問題の編集トークン。作者・テスター・管理者のみ)。" security: - BearerAuth: [ ] parameters: - in: "path" name: "ProblemId" required: true description: "問題ID" schema: type: "integer" responses: 200: description: "OK。未登録なら langId と source は空" content: application/json: schema: type: "object" properties: langId: type: "string" source: type: "string" enable: type: "boolean" description: "生成の有効フラグ(管理者が承認すると true)" testCaseNum: type: "integer" description: "生成ケース数" 401: description: "認証情報が無い・不正" 403: description: "編集権限がない" 404: description: "Not Found" put: operationId: putGenerator tags: - "problems" - "編集トークン対応" summary: "ジェネレータを保存" description: "認証は GET と同じ。source を空にすると削除します。generate を true にすると保存後にケース生成を起動します(1〜50ケース。結果はメッセージで通知)。未知のフィールドはエラーになります。" security: - BearerAuth: [ ] parameters: - in: "path" name: "ProblemId" required: true description: "問題ID" schema: type: "integer" requestBody: required: true content: application/json: schema: type: "object" required: - langId - source - testCaseNum properties: langId: type: "string" source: type: "string" description: "ジェネレータのソース。空文字列で削除" testCaseNum: type: "integer" description: "生成ケース数" generate: type: "boolean" description: "true なら保存後にケース生成を起動(1〜50ケース)" prefix: type: "string" description: "生成するケース名の接頭辞" enable: type: "boolean" description: "管理者のみ。生成の有効フラグ" responses: 200: description: "OK" content: application/json: schema: type: "object" properties: Message: type: "string" example: "保存されました。" 400: description: "入力の検証エラー、または生成を開始できなかった(保存は済んでいる)" 401: description: "認証情報が無い・不正" 403: description: "編集権限がない" 404: description: "Not Found" /v1/problems/{ProblemId}/testcase.zip: get: operationId: getTestCaseZip tags: - "problems" - "編集トークン対応" summary: "テストケースを zip で一括取得" description: >- test_in/ と test_out/ をまとめた zip を返します。 認証は /v1/problems/{ProblemId}/edit と同じ(アカウントの APIキー か 問題の編集トークン)。 アカウントで叩く場合は、テストケースを見られる問題であること(作者・テスター・管理者、 または AC 済みなど問題の設定によります)。 1ケースずつ /file/{Which}/{FileName} で取るより軽いので、まとめて要るときはこちらを使ってください (認証と問題の読み込みが1回で済みます)。差分だけ取りたいときは GET /file/{Which}?detail=1 のサイズとハッシュで判断できます。 旧パス /problems/{ProblemId}/testcase.zip も同じものを返します(oj などが使っています)。 security: - BearerAuth: [ ] parameters: - in: "path" name: "ProblemId" required: true description: "問題ID" schema: type: "integer" responses: 200: description: "zip。中身は test_in/<ファイル名> と test_out/<ファイル名>" content: application/zip: schema: type: "string" format: "binary" 401: description: "認証情報が無い・不正" 403: description: "テストケースを見る権限がない" 404: description: "問題が無い、またはテストケースが1つも無い" /v1/problems/{ProblemId}/subtask: get: operationId: getSubtask tags: - "problems" - "編集トークン対応" summary: "部分点(サブタスク)の設定を取得" description: "認証は /v1/problems/{ProblemId}/edit と同じ(アカウントの APIキー か 問題の編集トークン。作者・テスター・管理者のみ)。未設定でも subtasks は空配列で返ります。レスポンス本文は PUT の本文と同じ形なので、そのまま PUT に渡せます(未設定のまま渡せば設定を消すことになります)。問題IDは URL にあるので本文には入れません。" security: - BearerAuth: [ ] parameters: - in: "path" name: "ProblemId" required: true description: "問題ID" schema: type: "integer" responses: 200: description: "OK" content: application/json: schema: type: "object" properties: subtasks: type: "array" description: "サブタスクの一覧。未設定なら空配列(null にはならない)" items: $ref: "#/components/schemas/Subtask" 401: description: "認証情報が無い・不正" 403: description: "編集権限がない" 404: description: "Not Found" put: operationId: putSubtask tags: - "problems" - "編集トークン対応" summary: "部分点(サブタスク)を設定" description: >- 画面の部分点設定と同じ処理を API で実行します。認証は GET と同じ。 score の合計は 100 にしてください(合計が違うと 400)。 prefixes が空のサブタスクがあると 400 になります。 subtasks を空配列にする(または省略する)と部分点の設定を消します。 prefixes に一致するテストケースが無いサブタスクがあると、保存はできたうえで Warning を返します(そのサブタスクは常に0点になるため)。 未知のフィールドはエラーになります。 security: - BearerAuth: [ ] parameters: - in: "path" name: "ProblemId" required: true description: "問題ID" schema: type: "integer" requestBody: required: true content: application/json: schema: type: "object" properties: subtasks: type: "array" description: "サブタスクの一覧。空配列にすると部分点の設定を消す" items: $ref: "#/components/schemas/Subtask" examples: two: summary: "2つのサブタスクに分ける" value: subtasks: - name: "サブタスク1" prefixes: [ "01" ] score: 30 - name: "サブタスク2" prefixes: [ "02", "03" ] score: 70 clear: summary: "部分点の設定を消す" value: subtasks: [ ] responses: 200: description: "保存された" content: application/json: schema: type: "object" properties: Message: type: "string" description: >- 「保存しました」。subtasks を空にして設定を消したときは 「部分点の設定を削除しました」 Warning: type: "string" description: >- 保存はできたが注意がある場合だけ入る。今のところ、 prefixes に一致するテストケースが1つも無いサブタスクがあるとき (そのサブタスクは誰が解いても0点で固定される)。 テストケースが1件も登録されていない問題では出さない 400: description: "配点の合計が100でない、prefixes が空、または JSON が不正(未知のフィールドを含む)" content: application/json: schema: type: "object" properties: Message: type: "string" 401: description: "認証情報が無い・不正" 403: description: "編集権限がない" 404: description: "Not Found" /v1/problems/{ProblemId}/editorial: get: operationId: getEditorial tags: - "problems" - "編集トークン対応" summary: "解説の生ソースを取得(編集用)" description: "認証は /v1/problems/{ProblemId}/edit と同じ(アカウントの APIキー か 問題の編集トークン。作者・テスター・管理者のみ)。まだ書かれていなければテンプレートの内容が返ります。" security: - BearerAuth: [ ] parameters: - in: "path" name: "ProblemId" required: true description: "問題ID" schema: type: "integer" responses: 200: description: "OK" content: application/json: schema: type: "object" properties: content: type: "string" description: "解説の生テキスト(isMarkdown が true なら Markdown、false なら HTML)" isMarkdown: type: "boolean" urlTable: type: "string" description: "外部URLの一覧。「userId,URL」の行形式" 401: description: "認証情報が無い・不正" 403: description: "編集権限がない" 404: description: "Not Found" put: operationId: putEditorial tags: - "problems" - "編集トークン対応" summary: "解説を更新" description: "画面の解説編集と同じ処理を API で実行します。認証は GET と同じ。latestModNanoTime を省略すると競合検出なしで上書きします。未知のフィールドはエラーになります。" security: - BearerAuth: [ ] parameters: - in: "path" name: "ProblemId" required: true description: "問題ID" schema: type: "integer" requestBody: required: true content: application/json: schema: type: "object" required: - html properties: html: type: "string" description: "解説(HTML)。markdown を渡すときは空文字列にすること。非空だとこちらが優先され markdown は変換されない" markdown: type: "string" description: "解説(Markdown)。html が空のときだけサーバが HTML に変換して保存する" urlTable: type: "string" description: "外部URLの追加。「userId,URL」の行形式(既存分に追記)" latestModNanoTime: type: "string" description: "API では指定不要(省略すると競合検出なしで上書き)。WebUI の編集フォームだけが編集競合の検出に使う。ナノ秒の値は 2^53 を超えるため文字列で指定する(数値はエラー)" responses: 200: description: "保存された" content: application/json: schema: type: "object" properties: Message: type: "string" LatestModNanoTime: type: "string" description: "保存後のファイル更新時刻(画面用。API では使わない)" 401: description: "認証情報が無い・不正" 403: description: "編集権限がない、入力の検証エラー、または latestModNanoTime を渡していて値が古い(編集競合)。本文はエラーメッセージのテキスト" content: text/plain: schema: type: "string" 404: description: "Not Found" /v1/submissions/{SubmissionId}/solution: put: operationId: putSubmissionSolution tags: - "problems" - "編集トークン対応" summary: "提出を想定解として登録/削除" description: "AC した提出を解説ページの「想定解」一覧に載せます。認証は /v1/problems/{ProblemId}/edit と同じ(アカウントの APIキー か 問題の編集トークン。作者・テスター・管理者のみ)。編集トークンの場合、その提出が属する問題と一致している必要があります。delete: true で登録を消します。未知のフィールドはエラーになります。" security: - BearerAuth: [ ] parameters: - in: "path" name: "SubmissionId" required: true description: "提出ID" schema: type: "integer" requestBody: required: true content: application/json: schema: type: "object" properties: summary: type: "string" description: "想定解の説明(解説ページに出る)。delete のときは無視される" delete: type: "boolean" description: "true なら想定解の登録を消す" responses: 200: description: "OK" content: application/json: schema: type: "object" properties: Message: type: "string" 400: description: "JSON が不正、または未知のフィールド" 401: description: "認証情報が無い・不正" 403: description: "この問題の編集権限がない" 404: description: "提出が見つからない" /v1/languages: get: operationId: getLanguages tags: - language summary: "Get available language" description: "利用できる言語を取得します。何度も呼び出すような想定ではありません" security: [ ] responses: 200: description: "OK" content: application/json: schema: $ref: "#/components/schemas/Languages" /v1/testcase_name_rule: get: operationId: getTestCaseNameRule tags: - "problems" summary: "Get testcase name rule" description: "テストケース名に使える文字の規則を取得します。何度も呼び出すような想定ではありません。 / アップロードするとき、サーバはファイル名から使えない文字を取り除きます(例: case-01.txt は case01.txt になる)。送る前に名前が変わるかを知りたいときは、この規則で判定してください。規則を自分で持つと、サーバ側で変わったときにずれます。" security: [ ] responses: 200: description: "OK" content: application/json: schema: type: "object" properties: allowedChars: type: "string" description: | ファイル名に使える文字を並べたもの。ここに無い文字は取り除かれて保存されます。 並び順に意味はありません。 取り除いた結果が空になる名前はアップロードできません。 example: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz._0123456789" /v1/statuses: get: operationId: getStatuses tags: - "language" summary: "Get judge statuses" description: "ジャッジステータスの一覧を取得します。何度も呼び出すような想定ではありません。 / 結果を待つクライアントは category を見てください。judging の間はまだジャッジ中なのでポーリングを続けます。ジャッジ中のステータスを自分で列挙すると、サーバ側で値が増えたときに新しいものを「終わった」と誤判定します。 / 提出には出ない内部用の値(-- / judge_err / NoCheck)も含みます。" security: [ ] responses: 200: description: "OK" content: application/json: schema: type: "array" items: type: "object" properties: id: type: "string" description: | ステータスの値。提出やバリデーションの status に入るもの。 * `WJ` (judging) — Waiting for Judge : ジャッジ待ちです。しばらくお待ちください。 * `Pending` (judging) — 実行待ち : 実行することは決まっていますが、まだ開始されていません。 * `Judge` (judging) — Judge : ジャッジ中です。しばらくお待ちください。(並列ジャッジで片方のサーバーが異常(TLE等)になると再判定され、該当サーバーの進捗が最初に戻ることがあります) * `WJ_PURE` (judging) — 純コード判定待ち : 正解ですが、純コード判定が完了していません。 * `AC` (success) — Accepted : 正解です! * `NOT_PURE` (wrong) — 純コードではありません : 正解ですが、純コードと判定されませんでした。 * `WA` (wrong) — Wrong Answer : 残念ながら不正解です! * `TLE` (wrong) — Time Limit Exceeded : 実行時間オーバーです。効率的なアルゴリズムを考えてみましょう。 * `MLE` (wrong) — Memory Limit Exceeded : 実行メモリーオーバーです。効率的なアルゴリズムを考えてみましょう。 * `OLE` (wrong) — Output Limit Exceeded : 出力ファイル制限です。出力を少なくしてください。 * `QLE` (wrong) — Query Limit Exceeded : 出力するクエリが想定より多いです。 * `RE` (wrong) — Runtime Error : ランタイムエラーです。 * `CE` (wrong) — Compile Error : コンパイルエラーです。手元でご確認などをお願いします。 * `--` (wrong) — 撃墜 : 以降のケースを実行せずに打ち切りました。 * `J_TLE` (writer) — ジャッジ側の時間切れです。ジャッジ調整ミスか特殊な問題です。 * `NoOut` (writer) — NO_OUT : 大変申し訳ございません。出力ケースがありません。作問設定ミスです。 * `NoCheck` (writer) — テストケースが存在しません。 * `judge_err` (writer) — Judge Program Error : おそらくスペシャルジャッジなのにジャッジコードがありません * `J_ERR` (danger) — 想定解エラー : システムテストで、想定解が RE / MLE / OLE になり期待出力を作れませんでした。 * `IE` (danger) — Internal Error : 大変申し訳ございません。 システムのエラーです。 enum: - "WJ" - "Pending" - "Judge" - "WJ_PURE" - "AC" - "NOT_PURE" - "WA" - "TLE" - "MLE" - "OLE" - "QLE" - "RE" - "CE" - "--" - "J_TLE" - "NoOut" - "NoCheck" - "judge_err" - "J_ERR" - "IE" example: "AC" category: type: "string" description: | 分類。 * `judging` — 実行中・実行待ち。**この間はポーリングを続けてください** * `success` — 正解 * `wrong` — 不正解・実行失敗 * `writer` — 作問側の対応待ち。提出したコードの問題ではありません * `danger` — ジャッジ側の異常 judging 以外になっても「結果が確定した」わけではありません。 リジャッジや、IE などの異常終了がサーバ再起動で投げ直されることで、 後から変わることがあります。 enum: [ "success", "wrong", "judging", "writer", "danger" ] description: type: "string" description: "日本語の説明" /v2/ranking/golfer: get: operationId: getGolfersV2 tags: - "ranking" summary: "Get golfers" description: "各問題のショートコードを取得します。コード長非表示の問題の場合はlengthがnullになります。" security: [ ] responses: 200: description: OK content: application/json: schema: $ref: '#/components/schemas/RankingProblems' /v2/ranking/golfer/pure: get: operationId: getPureGolfersV2 tags: - "ranking" summary: "Get pure golfers" description: "各提出の純ショートコードを取得します。コード長非表示の問題の場合はlengthがnullになります。" security: [ ] responses: 200: description: OK content: application/json: schema: $ref: '#/components/schemas/RankingProblems' /v2/ranking/golfer/pure/{langId}: get: operationId: getPureGolfersByLangV2 tags: - "ranking" summary: "Get pure golfers" description: "各提出の言語別純ショートコードを取得します。言語IDは/languagesで取得できるもの。コード長非表示の問題の場合はlengthがnullになります" security: [ ] parameters: - in: "path" name: "langId" description: "言語ID" required: true schema: type: "string" responses: 200: description: OK content: application/json: schema: $ref: '#/components/schemas/RankingProblems' /v2/ranking/speeder: get: operationId: getSpeedersV2 tags: - "ranking" summary: "Get speeder" description: "各問題の最速実行時間コードを取得します。コード長非表示の問題の場合はlengthがnullになります" security: [ ] responses: 200: description: OK content: application/json: schema: $ref: '#/components/schemas/RankingProblems' /v1/ranking/golfer: get: operationId: getGolfersV1 tags: - "ranking (非推奨)" summary: "Get golfers" description: "各問題のショートコードを取得します。コード長非表示の問題は取得されません。" security: [ ] responses: 200: description: OK content: application/json: schema: $ref: '#/components/schemas/RankingProblems' /v1/ranking/golfer/pure: get: operationId: getPureGolfersV1 tags: - "ranking (非推奨)" summary: "Get pure golfers" description: "各提出の純ショートコードを取得します。コード長非表示の問題は取得されません。" security: [ ] responses: 200: description: OK content: application/json: schema: $ref: '#/components/schemas/RankingProblems' /v1/ranking/golfer/pure/{langId}: get: operationId: getPureGolfersByLangV1 tags: - "ranking (非推奨)" summary: "Get pure golfers" description: "各提出の言語別純ショートコードを取得します。言語IDは/languagesで取得できるもの。コード長非表示の問題は取得されません。" security: [ ] parameters: - in: "path" name: "langId" description: "言語ID" required: true schema: type: "string" responses: 200: description: OK content: application/json: schema: $ref: '#/components/schemas/RankingProblems' /v1/ranking/speeder: get: operationId: getSpeedersV1 tags: - "ranking (非推奨)" summary: "Get speeder" description: "各問題の最速実行時間コードを取得します。コード長非表示の問題は取得されません。" security: [ ] responses: 200: description: OK content: application/json: schema: $ref: '#/components/schemas/RankingProblems' /v1/contest/id/{ContestId}: get: operationId: getContestById tags: - "contest" summary: "Get contest by ContestId" description: "コンテストIDからコンテスト情報を取得します。" security: [ ] parameters: - in: "path" name: "ContestId" required: true description: "コンテストID" schema: type: "integer" responses: 200: description: OK content: application/json: schema: $ref: '#/components/schemas/Contest' 404: description: "コンテストが見つからない(日付未設定のコンテストを含む)" content: application/json: schema: type: "object" example: Message: "指定したコンテストは存在しません" /v1/contest/future: get: operationId: getFutureContests tags: - "contest" summary: "Get future contests" description: "開催予定のコンテスト情報を取得します。" security: [ ] responses: 200: description: OK content: application/json: schema: $ref: '#/components/schemas/Contests' /v1/contest/current: get: operationId: getCurrentContests tags: - "contest" summary: "Get current contests" description: "現在開催中のコンテスト情報を取得します。" security: [ ] responses: 200: description: OK content: application/json: schema: $ref: '#/components/schemas/Contests' /v1/contest/past: get: operationId: getPastContests tags: - "contest" summary: "Get past contests" description: "開催終了のコンテスト情報を取得します。" security: [ ] responses: 200: description: OK content: application/json: schema: $ref: '#/components/schemas/Contests' /v1/statistics/tags: get: operationId: getProblemTags tags: - "statistics" summary: "Get all tags for problems" description: "問題につけられたタグ一覧を取得します" security: [ ] responses: 200: description: OK content: application/json: schema: $ref: '#/components/schemas/Tags' components: securitySchemes: BearerAuth: type: http scheme: bearer parameters: # Add a global parameters section if not already present for ProblemIdPath ProblemIdPath: name: ProblemId # パステンプレート {ProblemId} と一致させる必要がある in: path required: true description: 問題ID schema: type: integer schemas: # ジャッジステータスの語彙。サーバの定義から生成しているので、 # 値が増えればここも増える。各値の意味は GET /v1/statuses。 # 部分点(サブタスク)1つ分。DB では ProblemSetting.SubtaskJson に # まとめて JSON 文字列で入っている。 Subtask: type: "object" required: - prefixes - score properties: name: type: "string" description: "サブタスク名(例: サブタスク1)" prefixes: type: "array" description: >- このサブタスクに含めるテストケースの目印。ファイル名の 最後の _ より前を _ で分割したトークンのいずれかと一致すれば含まれる (例: 01_sample_01.txt はトークン 01 と sample になる)。空にはできない items: type: "string" score: type: "integer" description: "配点(%)。サブタスク内が全部 AC のときだけ入る。全サブタスクの合計を100にする" description: type: "string" description: "問題文に出す補足(省略可)" JudgeStatus: type: "string" enum: - "WJ" - "Pending" - "Judge" - "WJ_PURE" - "AC" - "NOT_PURE" - "WA" - "TLE" - "MLE" - "OLE" - "QLE" - "RE" - "CE" - "--" - "J_TLE" - "NoOut" - "NoCheck" - "judge_err" - "J_ERR" - "IE" # JudgeStatus に「空」を足したもの。まだ登録されていない・まだ実行して # いないことを空文字列で表す項目で使う。 JudgeStatusOrEmpty: type: "string" enum: - "WJ" - "Pending" - "Judge" - "WJ_PURE" - "AC" - "NOT_PURE" - "WA" - "TLE" - "MLE" - "OLE" - "QLE" - "RE" - "CE" - "--" - "J_TLE" - "NoOut" - "NoCheck" - "judge_err" - "J_ERR" - "IE" - "" Error: # Define a generic error schema if not already present type: object properties: Message: type: string ProblemEditRequest: type: object required: - title - level - timeLimitMs - memoryLimit - epsMode - eps - wip - recruitingTester - problemType - judgeType - html properties: title: type: string tags: type: string description: "スペース区切り" level: type: number timeLimitMs: type: integer description: "ミリ秒" memoryLimit: type: integer description: "MB" epsMode: type: string enum: [ "-", "abs", "rel", "all" ] eps: type: string example: "0.0" description: "許容誤差。文字列で指定する。取得も常に文字列。書いた形のまま保存するので、0 と 0.0 は別の値として残る" wip: type: boolean aiReviewModels: type: array maxItems: 20 items: type: string minLength: 1 maxLength: 200 description: "ユーザーが手元のAIでこの問題をテスト・レビューした際に使用したモデル名の記録。複数指定可。空配列で記録を削除。PATCHで省略すると維持。" recruitingTester: type: boolean problemType: type: integer description: "0:通常 1:教育的 2:スコア 3:ネタ 4:未証明 5:数学要素が高い 6:ショートコード" judgeType: type: integer description: "0:通常 1:スペシャル 2:リアクティブ" showAns: type: boolean description: "テスト後解答表示。省略すると false" enablePureJudge: type: boolean description: "省略すると false" forceSingleServerJudge: type: boolean description: "省略すると false" html: type: string description: "問題文(HTML)。markdown を渡すときは空文字列にすること。非空だとこちらが優先され markdown は変換されない" markdown: type: string description: "問題文(Markdown)。html が空のときだけサーバが HTML に変換して保存する" allowedLangs: type: array items: type: string description: "許可言語。省略で全言語" latestModNanoTime: type: string description: "API では指定不要(省略すると競合検出なしで上書き)。WebUI の編集フォームだけが編集競合の検出に使う。渡す場合、値が古いと 403 で保存されない。ナノ秒の値は 2^53 を超えるため文字列で指定する(数値はエラー)" example: "1773624774196132600" ProblemPatchRequest: # PUT と同じプロパティだが required は無い。送ったキーだけが変わる。 type: object properties: title: type: string tags: type: string description: "スペース区切り" level: type: number timeLimitMs: type: integer description: "ミリ秒" memoryLimit: type: integer description: "MB" epsMode: type: string enum: [ "-", "abs", "rel", "all" ] eps: type: string example: "0.0" description: "許容誤差。文字列で指定する。取得も常に文字列。書いた形のまま保存するので、0 と 0.0 は別の値として残る" wip: type: boolean aiReviewModels: type: array maxItems: 20 items: type: string minLength: 1 maxLength: 200 description: "ユーザーが手元のAIでこの問題をテスト・レビューした際に使用したモデル名の記録。複数指定可。空配列で記録を削除。PATCHで省略すると維持。" recruitingTester: type: boolean problemType: type: integer description: "0:通常 1:教育的 2:スコア 3:ネタ 4:未証明 5:数学要素が高い 6:ショートコード" judgeType: type: integer description: "0:通常 1:スペシャル 2:リアクティブ" showAns: type: boolean description: "テスト後解答表示。省略すると false" enablePureJudge: type: boolean description: "省略すると false" forceSingleServerJudge: type: boolean description: "省略すると false" html: type: string description: "問題文(HTML)。markdown を渡すときは空文字列にすること。非空だとこちらが優先され markdown は変換されない" markdown: type: string description: "問題文(Markdown)。html が空のときだけサーバが HTML に変換して保存する" allowedLangs: type: array items: type: string description: "許可言語。省略で全言語" latestModNanoTime: type: string description: "API では指定不要(省略すると競合検出なしで上書き)。WebUI の編集フォームだけが編集競合の検出に使う。渡す場合、値が古いと 403 で保存されない。ナノ秒の値は 2^53 を超えるため文字列で指定する(数値はエラー)" example: "1773624774196132600" ProblemEditContent: description: "GET /v1/problems/{ProblemId}/edit のレスポンス。編集可能なキーは POST のリクエストと同名。POST するときは読み取り専用キー(problemId, content, isMarkdown, showable)を取り除き、問題文は html / markdown で送る" type: object properties: problemId: type: integer description: "読み取り専用" title: type: string tags: type: string description: "スペース区切り" level: type: number timeLimitMs: type: integer description: "ミリ秒" memoryLimit: type: integer description: "MB" epsMode: type: string enum: [ "-", "abs", "rel", "all" ] eps: type: string description: "許容誤差。常に文字列。保存した形のまま返す" wip: type: boolean aiReviewModels: type: array maxItems: 20 items: type: string minLength: 1 maxLength: 200 description: "ユーザーが手元のAIでこの問題をテスト・レビューした際に使用したモデル名の記録。複数指定可。空配列で記録を削除。PATCHで省略すると維持。" recruitingTester: type: boolean problemType: type: integer judgeType: type: integer showAns: type: boolean enablePureJudge: type: boolean forceSingleServerJudge: type: boolean allowedLangs: type: array items: type: string description: "許可言語。空配列で全言語" content: type: string description: "問題文の生テキスト(isMarkdown が true なら Markdown、false なら HTML)。読み取り専用。書き換えるときは html / markdown で送る" isMarkdown: type: boolean description: "読み取り専用" showable: type: boolean description: "公開済みか。読み取り専用(API からは変更できない)" ProblemFavoriteStatus: type: object properties: problemId: type: integer description: 問題ID isFavorited: type: boolean description: 現在のユーザーがお気に入り登録しているか totalFavorites: type: integer description: 総お気に入り数 example: problemId: 123 isFavorited: true totalFavorites: 42 User: type: "object" properties: Id: type: "integer" description: "ユーザーID" Name: type: "string" description: "ユーザー名" Solved: type: "integer" description: "解いている問題数" Level: type: "integer" description: "ユーザーLevel" LevelFloat: type: "number" description: "ユーザーLevel(小数)" Rank: type: "integer" description: "解いている問題数内でのランキング" Score: type: "integer" description: "スコア" Points: type: "integer" description: "ゆるふわポイント" AtCoderId: type: "string" description: "AtCoderId" CodeforcesId: type: "string" description: "CodeforcesId" Notice: type: "string" description: "注意事項など" example: Id: 10 Name: yuki2006 Solved: 313 Level: 30 LevelFloat: 30.50 Rank: 69 Score: 57950 Points: 8125 AtCoderId: hoge CodeforcesId: hoge Notice: 特になし AuthUser: allOf: - $ref: "#/components/schemas/User" - type: object properties: langId: type: string Problems: type: "array" items: $ref: "#/components/schemas/Problem" Problem: type: "object" properties: No: type: [ "integer", "null" ] description: "問題No" ProblemId: type: "integer" description: "問題Id" Title: type: "string" description: "問題名" AuthorId: type: "integer" description: "作問者のユーザーId" TesterIds: type: "string" description: "テスターのユーザーIdをカンマ区切りした文字列" Level: type: "number" format: "float" description: "問題レベル小数あり" ProblemType: type: "integer" description: "問題タイプ 0は通常問題,1は教育的問題,2はスコア形式問題 3はネタ問題,4は未証明問題" enum: [ 0,1,2,3 ] Tags: type: "string" description: "問題のタグ カンマ区切り" Date: type: [ "string", "null" ] format: "date-time" description: "問題の出題時間(RFC 3339)" example: No: 1 ProblemId: 17 Title: "道のショートカット" AuthorId: 10 TesterIds: "1,2" Level: 2.5 ProblemType: 0 Tags: "動的計画法,ダイクストラ法" Date: "2016-10-20T01:09:07+09:00" ProblemWithStatics: type: "object" properties: No: type: [ "integer", "null" ] description: "問題No" ProblemId: type: "integer" description: "問題Id" Title: type: "string" description: "問題名" AuthorId: type: "integer" description: "作問者のユーザーId" TesterIds: type: "string" description: "テスターのユーザーIdをカンマ区切りした文字列" Level: type: "number" format: "float" description: "問題レベル小数あり" ProblemType: type: "integer" description: "問題タイプ 0:通常問題 1:教育的問題 2:スコア問題 3:ネタ問題 4:未証明問題 5:数学要素が高い問題 6:ショートコード" enum: [ 0,1,2,3,4,5,6 ] Tags: type: "string" description: "問題のタグ カンマ区切り" Date: type: [ "string", "null" ] format: "date-time" description: "問題の出題時間(RFC 3339)" EpsMode: type: "string" enum: [ "-", "abs", "rel", "all" ] description: "誤差許容の種類。-:なし abs:絶対誤差 rel:相対誤差 all:両方" Eps: type: "string" description: "許容誤差。EpsMode が - のときは意味を持たない" EnablePureJudge: type: "boolean" description: "純コード判定が有効か" WIP: type: "boolean" description: "任意項目。WIP(作問中)のときだけ true で現れる。WIP の問題が見えるのは作者・テスター・管理者のみ" AllowedLangs: type: "array" items: type: "string" description: "許可言語。空配列なら全言語" Statistics: $ref: "#/components/schemas/Statistics" example: No: 1 ProblemId: 17 Title: "道のショートカット" AuthorId: 10 TesterIds: "1,2" Level: 2.5 ProblemType: 0 Tags: "動的計画法,ダイクストラ法" Date: "2016-10-20T01:09:07+09:00" Statistics: "Total": 716 "Solved": 707 "FirstAcceptedTimeSecond": 698393 "FirstACSubmissionId": 139 "ShortCodeSubmissionId": 633867 "PureShortCodeSubmissionId": 265348 "FastSubmissionId": 29557 Statistics: type: "object" properties: Total: type: "integer" description: "提出者数" Solved: type: "integer" description: "AC数" FirstAcceptedTimeSecond: type: "number" description: "ACまでの秒数" FirstACSubmissionId: type: "integer" description: "FirstACの提出ID" ShortCodeSubmissionId: type: "integer" description: "ショートコードの提出ID" PureShortCodeSubmissionId: type: "integer" description: "純ショートコードの提出ID" FastSubmissionId: type: "integer" description: "最速の提出ID" ProblemSubmitted: type: "object" properties: SubmissionId: type: "integer" description: "提出ID" example: "SubmissionId": 266299 RankingProblem: type: "object" properties: ProblemId: type: "integer" description: "問題ID" SubmissionId: type: "integer" description: "提出ID" TimeStamp: type: "string" format: "date-time" description: "提出時間(RFC 3339)" No: type: "integer" description: "問題No" Title: type: "string" description: "問題名" SubmitterId: type: "integer" description: "提出者ID" UserName: type: "string" description: "提出者名" Length: type: [ "integer", "null" ] description: "ソースコード長" LangId: type: "string" description: "言語ID" example: "ProblemId": 100 "SubmissionId": 266299 "TimeStamp": "2018-06-16T02:45:23+09:00" "No": 704 "Title": "ゴミ拾い Medium" "SubmitterId": 1206 "UserName": "ikd" "Length": 1403 "LangId": "cpp" RankingProblems: type: "array" items: $ref: '#/components/schemas/RankingProblem' ContestProblemInfo: type: "object" properties: ProblemId: type: "integer" description: "問題ID" No: type: [ "integer", "null" ] description: "問題番号(未設定の場合はnull)" Title: type: "string" description: "問題タイトル" Solved: type: "boolean" description: "ログインユーザーがこの問題を正解済みかどうか" Submitted: type: "boolean" description: "ログインユーザーがこの問題に提出済みかどうか" example: ProblemId: 17 No: 1 Title: "道のショートカット" Solved: true Submitted: true Contest: type: "object" properties: Id: type: "integer" description: "一意な値 コンテストID" Name: type: "string" description: "コンテスト名" Date: type: "string" format: "date-time" description: "コンテスト開始日時(RFC 3339)" EndDate: type: "string" format: "date-time" description: "コンテスト終了日時(RFC 3339)" ProblemIdList: type: "array" items: type: "integer" description: "問題IDのリスト" Problems: type: "array" items: $ref: '#/components/schemas/ContestProblemInfo' description: "問題情報のリスト(問題番号とタイトルを含む)" example: "Id": 203 "Name": "yukicoder contest 196" "Date": "2018-07-27T22:20:00+09:00" "EndDate": "2018-07-28T00:20:00+09:00" "ProblemIdList": [ 1,2,3 ] "Problems": - ProblemId: 1 No: 100 Title: "問題A" - ProblemId: 2 No: 101 Title: "問題B" - ProblemId: 3 No: 102 Title: "問題C" Contests: type: "array" items: $ref: '#/components/schemas/Contest' Languages: type: "array" items: type: "object" properties: Id: type: "string" description: "言語ID (一意な文字列)" Name: type: "string" description: "言語名" Ver: type: "string" description: "コンパイラバージョン" example: "Id": "cpp" "Name": "C++11" "Ver": "gcc 4.8.5" Tags: type: "array" items: type: "object" properties: Key: type: "string" description: "タグ名" Count: type: "integer" description: "問題数" example: "Key": "動的計画法" "Count": 100 security: - {} # 認証なしでも呼べる - BearerAuth: [ ]