Suurte failide üleslaadimine
Faili saab saata ühe päringuga POST /v1/cards kuni paigalduse üleslaadimislimiidini
(vaikimisi 200 MB). Suurema faili või sellise võrgu korral, kus pikk päring tõenäoliselt katkeb, laadige fail üles
osadena:
- Looge üleslaadimine: teatage Sursale faili nimi, tüüp ja suurus.
- Saatke osad mis tahes järjekorras ja soovi korral paralleelselt. Ebaõnnestunud osa saadetakse eraldi uuesti.
- Lõpetage üleslaadimine kogu faili SHA-256 räsiga. Sursa paneb faili kokku ja kontrollib seda.
- Kasutage faili asemel üleslaadimise ID-d: kaardi, arhiivi või kohandatud allika dokumendi jaoks.
| Piirang | Väärtus |
|---|---|
| Faili suurus | Kuni 5 GB |
| Osa suurus | Sursa valib selle väljal part_size, 5–100 MiB; viimane osa võib olla väiksem |
| Osade arv | Kuni 1000 |
| Aeg lõpetamiseks | 24 tundi pärast üleslaadimise loomist |
| Aeg lõpetatud üleslaadimise kasutamiseks | 24 tundi |
1. Looge üleslaadimine
POST /v1/uploads võtab vastu faili nime, tüübi ja suuruse ning selle, milleks
kavatsete faili kasutada:
FILE=training-video-transcripts.zip
SIZE=$(wc -c < "$FILE" | tr -d ' ')
curl -X POST https://api.sursa.com/v1/uploads \
-H "Authorization: Bearer $SURSA_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d "{\"filename\": \"$FILE\", \"content_type\": \"application/zip\", \"size\": $SIZE, \"purpose\": \"archive\"}"{
"id": "upl_5d3c2b1a0f9e8d7c6b5a493827161504",
"status": "pending",
"part_size": 8388608,
"part_count": 23,
"expires_at": "2026-10-25T10:00:00Z"
}
purpose | Üleslaadimist kasutatakse |
|---|---|
card_file | Kaardi jaoks: POST /v1/cards. |
archive | Dokumendiarhiivi jaoks: POST /v1/cards/archive. |
import_attachment | Kohandatud allika dokumendi failina väljal upload_id või attachments. |
Võtmel peab olema selle koha ulatus, kuhu üleslaadimine läheb: card_file ja archive jaoks cards:write,
import_attachment jaoks import:write.
Sursa valib väärtuse part_size ja ütleb, mitu osa saata. Kui teate faili SHA-256 räsi ette, võite selle siin
edastada ka väljal sha256.
2. Saatke osad
Lõigake fail part_count tükiks, igaüks part_size baiti (viimane on ülejääk), ja saatke iga tükk päringuga
PUT /v1/uploads/{upload_id}/parts/{n}. Osad nummerdatakse alates 1-st. Keha
on osa toored baidid.
UPLOAD=upl_5d3c2b1a0f9e8d7c6b5a493827161504
split -b 8388608 -a 4 "$FILE" part-
n=1
for part in part-*; do
curl -X PUT "https://api.sursa.com/v1/uploads/$UPLOAD/parts/$n" \
-H "Authorization: Bearer $SURSA_API_KEY" \
-H "Content-Type: application/octet-stream" \
--data-binary "@$part" --retry 5 --fail
n=$((n + 1))
doneOsa uuesti saatmine asendab selle, seega saadetakse ebaõnnestunud või ajalõpuga osa lihtsalt uuesti. Kuni 4 paralleelset osa kasutavad kiire ühenduse tavaliselt täielikult ära.
Osade kontrollimine
Iga osa läheb läbi API: otselinke salvestusruumi ei ole. Osa vastusel on päis ETag, osa SHA-256 räsi
jutumärkides, ja sama väärtus JSON-keha väljal etag. GET /v1/uploads/{upload_id}
loetleb väljal parts seni saabunud osad, nii et pärast katkestust saadate ainult puuduvad osad.
3. Lõpetage üleslaadimine
POST /v1/uploads/{upload_id}/complete võtab vastu kogu faili SHA-256 räsi
64 kuueteistkümnendsüsteemi märgina ja soovi korral väljal parts iga osa väärtuse etag, et kontrollida ka osi:
SHA=$(shasum -a 256 "$FILE" | cut -d' ' -f1)
curl -X POST "https://api.sursa.com/v1/uploads/$UPLOAD/complete" \
-H "Authorization: Bearer $SURSA_API_KEY" \
-H "Idempotency-Key: complete-$UPLOAD" \
-H "Content-Type: application/json" \
-d "{\"sha256\": \"$SHA\"}"Sursa paneb osad kokku, võrdleb räsi ja kontrollib faili samamoodi nagu iga üleslaadimist: selle vormingut ja, kui see
on lubatud, viirusskannimisega. Vastus on 200, kui kontroll on tehtud, ja 202, kui see veel käib. Üleslaadimise
olek muutub väärtuselt processing väärtusele ready või väärtusele rejected, mille põhjus on väljal
reject_reason. Lugege olekut päringuga GET /v1/uploads/{upload_id}.
4. Kasutage üleslaadimist
Edastage upload_id seal, kus saadaksite faili. Iga üleslaadimist kasutatakse üks kord: pärast seda on selle
olek consumed.
Kaardi ja arhiivi puhul saatke upload_id vormi multipart/form-data asemel JSON-kehas. See keha võtab kogu vastu
selle nime järgi väljal collection.
# A card from the uploaded file
curl -X POST https://api.sursa.com/v1/cards \
-H "Authorization: Bearer $SURSA_API_KEY" \
-H "Idempotency-Key: card-from-$UPLOAD" \
-H "Content-Type: application/json" \
-d "{\"upload_id\": \"$UPLOAD\", \"collection\": \"support\", \"async\": true}"
# An archive of documents from the uploaded ZIP
curl -X POST https://api.sursa.com/v1/cards/archive \
-H "Authorization: Bearer $SURSA_API_KEY" \
-H "Idempotency-Key: archive-from-$UPLOAD" \
-H "Content-Type: application/json" \
-d "{\"upload_id\": \"$UPLOAD\", \"collection\": \"support\"}"Täielik üleslaadija
import { createHash } from "node:crypto";
import { createReadStream } from "node:fs";
import { open, stat } from "node:fs/promises";
import { basename } from "node:path";
const BASE = "https://api.sursa.com";
const auth = { Authorization: `Bearer ${process.env.SURSA_API_KEY}` };
async function call(method, path, body, headers = {}) {
const isJson = body !== undefined && !(body instanceof Uint8Array);
const response = await fetch(BASE + path, {
method,
headers: { ...auth, ...(isJson ? { "Content-Type": "application/json" } : {}), ...headers },
body: isJson ? JSON.stringify(body) : body,
});
if (!response.ok) throw new Error(`${method} ${path}: HTTP ${response.status} ${await response.text()}`);
return response.json();
}
export async function uploadLargeFile(file, contentType, purpose, parallel = 4) {
const { size } = await stat(file);
const upload = await call("POST", "/v1/uploads",
{ filename: basename(file), content_type: contentType, size, purpose },
{ "Idempotency-Key": crypto.randomUUID() });
const hash = createHash("sha256");
for await (const block of createReadStream(file)) hash.update(block);
const handle = await open(file);
let next = 1;
async function worker() {
for (let n = next++; n <= upload.part_count; n = next++) {
const buffer = new Uint8Array(Math.min(upload.part_size, size - (n - 1) * upload.part_size));
await handle.read(buffer, 0, buffer.length, (n - 1) * upload.part_size);
for (let attempt = 1; ; attempt++) {
try {
await call("PUT", `/v1/uploads/${upload.id}/parts/${n}`, buffer, { "Content-Type": "application/octet-stream" });
break;
} catch (error) {
if (attempt === 5) throw error;
await new Promise((resolve) => setTimeout(resolve, 1000 * 2 ** attempt));
}
}
}
}
await Promise.all(Array.from({ length: parallel }, worker));
await handle.close();
await call("POST", `/v1/uploads/${upload.id}/complete`, { sha256: hash.digest("hex") },
{ "Idempotency-Key": `complete-${upload.id}` });
for (;;) {
const state = await call("GET", `/v1/uploads/${upload.id}`);
if (state.status === "ready") return upload.id;
if (state.status === "rejected") throw new Error(`upload rejected: ${state.reject_reason}`);
await new Promise((resolve) => setTimeout(resolve, 2000));
}
}Vead
| Kood | Olek | Põhjus |
|---|---|---|
uploads.too_large | 413 | Fail on suurem kui 5 GB või suurem kui organisatsiooni paketi kogu salvestusruum. |
limits.storage | 402 | Organisatsioonil ei ole faili jaoks piisavalt vaba salvestusruumi. |
uploads.part_invalid | 400 | Osa number on vahemikust väljas või osa suurus ei ole lubatud piirides. |
uploads.checksum_mismatch | 422 | Kokkupandud faili SHA-256 ei ole see, mille saatsite. Mõni osa on rikutud või puudub: saatke osad uuesti ja lõpetage üleslaadimine uuesti. |
uploads.not_ready | 409 | Üleslaadimine ei ole veel lõpetatud ega kontrollitud. Oodake olekut ready. |
uploads.already_used | 409 | Üleslaadimist on juba kasutatud. Iga üleslaadimist kasutatakse üks kord. |
uploads.expired | 410 | Möödunud on üle 24 tunni. Looge uus üleslaadimine. |
uploads.rejected | 422 | Fail ei läbinud kontrolle, näiteks selle vorming ei vasta selle nimele. Teade ütleb, miks. |
uploads.not_found | 404 | Organisatsioonis sellist üleslaadimist ei ole. |