確定の 201 は、文書の行があり処理がキューに入ったことです。インデックス済みではありません。

ワークスペースへファイルを入れる Add Data 画面
Add Data はファイルを入れる画面です。下の HTTP は署名付きアップロードであり、別製品ではありません。

ファイルをアップロードする

架空のテキストを保存型コレクションに入れ、状態を読み戻します。手を動かす時間は約 20 分です。確定の後の待ちは別で、数分かかることがあります。

目的

urllib でアップロードを繰り返し、各状態を説明できます。レベルは HTTP を呼べる人です。ロールは document:upload です。モードは保存型です。ワークスペースは 作業の場所 のものを使います。アップロード自体にプロバイダ鍵は要りません。

サンプル

harbor-note.txt を作り、次の一行だけを入れます。Harbor Sample delivery window is 14 days. 形式は txt です。本物の契約や、ダウンロードしたコーパスは使わないでください。終わったらローカルのファイルを消します。コレクションの行は、コレクション管理ができる人が消すまで残ります。

手順

  1. 下の JSON で POST /api/collections/{collectionId}/documents/upload-url を送ります。documentId、storageKey、uploadUrl、expiresIn、headers が返ります。
  2. バイトを uploadUrl へ PUT します。送るのは headers の Content-Type だけです。Bundata のセッションや bearer トークンをその URL に付けないでください。uploadUrl を表示しないでください。
  3. 同じ documentId、storageKey、名前、形式、バイト数で POST /api/collections/{collectionId}/documents/confirm を送ります。新しい行は 201 で、status は processing です。
  4. GET /api/collections/{collectionId}/documents でその documentId を見つけます。移るまで processing のままにします。専用の状態 URL はありません。

フィールド

フィールド型規則
filenamestring1–500 文字。ストレージキーの材料です。
formatenumpdf、docx、txt、image、csv、xlsx。
sizeBytesintegerupload-url では任意。confirm では必須。0 から 500 MiB。upload-url で送るときは正の数。
contentTypestring任意、最大 200。PUT が送るのは応答の headers です。
relativePathstring任意、最大 2048。探索用のフォルダ相対パスです。メタデータ編集ではありません。
documentIduuidupload-url が返します。自分では作りません。
storageKeystringupload-url が返します。confirm のときもそのコレクションと一致している必要があります。

例

ブラウザ以外は POST /auth/login の bearer トークンを使います。環境変数から読み、表示しないでください。ブラウザはセッションクッキーを使い、両方は送りません。

curl -sS -X POST "$BUNDATA_ORIGIN/api/collections/$COLLECTION_ID/documents/upload-url" \
  -H "Authorization: Bearer $BUNDATA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"filename":"harbor-note.txt","format":"txt","sizeBytes":42,"contentType":"text/plain"}'
import json, os, urllib.request
origin = os.environ["BUNDATA_ORIGIN"].rstrip("/")
token = os.environ["BUNDATA_TOKEN"]
collection = os.environ["BUNDATA_COLLECTION_ID"]
body = json.dumps({"filename": "harbor-note.txt", "format": "txt", "sizeBytes": 42, "contentType": "text/plain"}).encode()
req = urllib.request.Request(origin + "/api/collections/" + collection + "/documents/upload-url", data=body, method="POST")
req.add_header("Authorization", "Bearer " + token)
req.add_header("Content-Type", "application/json")
with urllib.request.urlopen(req) as res:
    issued = json.load(res)
payload = b"Harbor Sample delivery window is 14 days.\n"
put = urllib.request.Request(issued["uploadUrl"], data=payload, method="PUT")
put.add_header("Content-Type", issued["headers"]["Content-Type"])
urllib.request.urlopen(put).close()
confirm = json.dumps({
    "documentId": issued["documentId"], "storageKey": issued["storageKey"],
    "name": "harbor-note.txt", "format": "txt", "sizeBytes": len(payload),
}).encode()
creq = urllib.request.Request(origin + "/api/collections/" + collection + "/documents/confirm", data=confirm, method="POST")
creq.add_header("Authorization", "Bearer " + token)
creq.add_header("Content-Type", "application/json")
with urllib.request.urlopen(creq) as res:
    row = json.load(res)
assert res.status == 201
assert row["status"] == "processing"

依存は標準ライブラリだけです。BUNDATA_TOKEN、BUNDATA_ORIGIN、BUNDATA_COLLECTION_ID は環境変数に置く仮の値です。

回復

結果すること
201 かつ processingGET /api/collections/{id}/documents を見ます。二通目を上げないでください。
同じ内容でもう一度 confirm200 と既存の行です。安全な再試行です。
同じ documentId で名前、サイズ、キーが違う409 です。突き合わせてください。衝突を隠すために新しい ID は作りません。
S3_NOT_CONFIGURED または S3_PRESIGN_UNAVAILABLEその環境ではアップロードできません。止めてください。
DOCUMENT_PROCESSING_QUEUE_UNAVAILABLE行は error のことがあります。同じ confirm を再試行します。
403ロールに document:upload がありません。
upload-directゲート付きの代替です。ゲートがオフのとき、その経路は見つかりません。本番の契約ではありません。

エラーは { "error": { "code", "message", "statusCode" } } です。署名付き URL は期限が切れます。死んだ PUT を繰り返さず、upload-url を取り直してください。

制限

画像は保存できても、探索の対象にはなりません。.meta.json の取り込みも、任意のファイルメタデータを書く API もありません。relativePath はパスであり、タグではありません。

確認

成功: 文書一覧の harbor-note.txt が processing から、本文が使える ready へ進みます。失敗: 閲覧者のトークンは 403 で、一覧は変わりません。