Read file content: byte-exact downloads (Box answers with a redirect to dl.boxcloud.com, which Hot follows without forwarding the token), Range and chunked downloads past the response cap, Box's extracted_text representation, and read-document for one-call text reads.

Extracted text. Box makes a plain-text rendition of documents (PDF, Office, Google, iWork, ...) on request. extracted-text never waits: it returns an ExtractedText whose state is "success" (with text), "pending" (generation is running), "none" (just asked Box to generate it), "unavailable" (Box offers no text for this file type) or "error". Poll again from a later step or a Hot schedule (for example every few minutes) until is-done; small documents are usually ready within seconds, large ones can take minutes.

Limits. Every single response is capped by the runtime's http.max-response-bytes (16 MiB by default, 120 s timeout): download-file switches to Range-chunked downloads when a file is larger. The whole file is still held in memory. Box answers 202 with Retry-After while a just-uploaded file is not yet downloadable; that comes back as a retryable HttpError.

Values

ASSET_PATH_PLACEHOLDER

ASSET_PATH_PLACEHOLDER: Str "{+asset_path}"

DEFAULT_DOWNLOAD_CHUNK

DEFAULT_DOWNLOAD_CHUNK: Int 8388608

DONE_STATES

DONE_STATES: Vec [
  "success",
  "unavailable",
  "error"
]

DOWNLOAD_LOCAL_KEYS

DOWNLOAD_LOCAL_KEYS: Vec [
  "range",
  "chunk-size",
  "name",
  "mime-type",
  "boxapi"
]

READ_FIELDS

READ_FIELDS: Str "id,type,name,size,sha1,etag,sequence_id,file_version,parent,path_collection,created_at,modified_at,content_created_at,content_modified_at,trashed_at,item_status,extension,description,representations"

READ_LOCAL_KEYS

READ_LOCAL_KEYS: Vec [
  "fields",
  "download-fallback",
  "rep-hints"
]

TEXT_REP

TEXT_REP: Str "extracted_text"

TEXT_REP_HINT

TEXT_REP_HINT: Str "[extracted_text]"

Functions

content-url

fn (file-id: Str, opts: Map): Str

download-file

fn (file-id: Str): ::box/FileContent
fn (file-id: Str, opts: Map): ::box/FileContent

GET /files/{id}/content - download a file's bytes as a FileContent. When the file is larger than http.max-response-bytes, it is fetched again in Range chunks (download-file-chunked).

Options: range: {start, end} (inclusive; end null for the rest) for a partial download, version (an older file version id), chunk-size for the chunked fallback, boxapi for shared-link access, plus credentials.

pdf ::box::content/download-file("12345")
pdf.bytes       // exact bytes

download-file-chunked

fn (file-id: Str): ::box/FileContent
fn (file-id: Str, opts: Map): ::box/FileContent

Download a file in Range requests of opts.chunk-size bytes (default 8 MiB; keep it under http.max-response-bytes) and join them, so files larger than one response can be read. The whole file is still held in memory.

download-headers

fn (opts: Map): Map

The download request headers (pure): Range from opts.range ({start, end}, inclusive) and boxapi for shared-link access.

download-params

fn (opts: Map): Map

Query parameters for a download (pure): Box parameters from opts, such as version (a file version id for an older version).

download-range

fn (file-id: Str, start: Int, end: Int): ::box/FileContent
fn (file-id: Str, start: Int, end: Int, opts: Map): ::box/FileContent

Download bytes start..end (inclusive) of a file.

download-ranges

fn (size: Int, chunk-size: Int): Vec

Split size bytes into inclusive [start, end] ranges of at most chunk-size bytes (pure). download-ranges(10, 4) is [[0, 3], [4, 7], [8, 9]].

download-text

fn (file-id: Str): Str
fn (file-id: Str, opts: Map): Str

Download a file and decode it as UTF-8 text.

empty-content

fn (file: Map, format: Str?, text-state: Str?): ::box/FileContent

extracted-text

fn (file-id: Str): ExtractedText
fn (file-id: Str, opts: Map): ExtractedText

Check (and when needed request) a file's extracted_text representation, and fetch the text when it is ready. Never waits: returns an ExtractedText in whatever state Box reports. Call it again later (a later step, or a Hot schedule) until is-done.

status ::box::content/extracted-text("12345")
cond {
  ::box::content/is-ready(status) => { index-text(status.text) }
  ::box::content/is-done(status) => { println(`box: no text for this file (${status.state})`) }
  => { println("box: text is still being generated; try again later") }
}

extracted-text-from

fn (file-id: Str, file: Map, text: Str?): ExtractedText

Build an ExtractedText from file information that carries representations (pure; no text fetched).

fetch-ranges

fn (full-url: Str, ranges: Vec, index: Int, acc: Bytes, opts: Map): Bytes

fetch-representation-text

fn (url: Str, opts: Map): Any

find-representation

fn (file: Map, rep: Str): Map?

The entry of file.representations.entries whose representation is rep (e.g. "extracted_text"), or null (pure).

get-representations

fn (file-id: Str, hints: Str): Map
fn (file-id: Str, hints: Str, opts: Map): Map

GET /files/{id}?fields=representations with an x-rep-hints header (e.g. "[extracted_text]", "[pdf][jpg?dimensions=320x320]"). Returns the file information with representations.entries.

is-done

fn (status: Map): Bool

True when polling an ExtractedText again would not change it: state is "success", "unavailable" or "error".

is-ready

fn (status: Map): Bool

True when an ExtractedText carries the text.

is-size-limit-error

fn (result: Result): Bool

True when a request failed because the response exceeded http.max-response-bytes.

range-header

fn (start: Int, end: Int?): Str

An HTTP Range value for bytes start..end inclusive (end null for "to the end"): range-header(0, 1023) is "bytes=0-1023".

read-document

fn (file-id: Str): ::box/FileContent
fn (file-id: Str, format: Str?): ::box/FileContent
fn (file-id: Str, format: Str?, opts: Map): ::box/FileContent

Read any file as a FileContent with its DocFile attached, in one metadata call plus one content call.

  • format "auto" (default) or "text": textual files (txt, md, csv, json, ...) are downloaded as is; other documents use Box's extracted_text when it is ready (source: "extracted-text"). When it is not ready, generation is requested and the original is downloaded instead (text is then null for binary files); text-state says what Box reported, so read again later for the text. {download-fallback: false} skips that download (empty bytes).
  • "original" (or "download", "raw"): download the stored bytes.
doc ::box::content/read-document("12345", "text")
doc.text            // ready for chunking and embedding, or null
doc.text-state      // "success", "pending", "unavailable", ...
doc.file.sha1       // for incremental re-indexing

read-document-text

fn (file-id: Str): Str
fn (file-id: Str, format: Str?): Str
fn (file-id: Str, format: Str?, opts: Map): Str

read-document, returning just the text; an Err when there is no text yet (the message says whether Box is still generating it, so a schedule can try again).

read-with-file

fn (file-id: Str, file: Map, fmt: Str, original: Bool, opts: Map): ::box/FileContent

representation-state

fn (entry: Map?): Str

The status.state of a representation entry (pure), or "unavailable" for a null entry.

representation-url

fn (template: Str, asset-path: Str): Str

Fill a representation url_template (pure): {+asset_path} becomes asset-path ("" for unpaged representations such as extracted_text, "1.png" for page 1 of a paged one).

resolve-text

fn (status: ExtractedText, opts: Map): ExtractedText

to-content

fn (file-id: Str, response: Map, source: Str, opts: Map): ::box/FileContent

trigger-generation

fn (info-url: Str?, opts: Map): Any

wants-original

fn (format: Str?): Bool

True when a read-document format asks for the stored bytes ("original", "download", "raw", "bytes"), not text (pure).

with-file

fn (content: Result, file: Map, format: Str?, text-state: Str?): ::box/FileContent

Types

ExtractedText

ExtractedText type {
    file-id: Str,
    state: Str,
    text: Str?,
    ready: Bool,
    info-url: Str?,
    content-url: Str?,
    file: Map?
}

The state of a file's extracted_text representation.

Fields

  • file-id
  • state - "success", "pending", "none" (generation was just requested), "unavailable" (Box offers no text rendition for this file) or "error"
  • text - the text when state is "success", else null
  • ready - true when text is set
  • info-url - the representation info URL (GET it to check or trigger generation)
  • content-url - the URL the text is fetched from
  • file - the file information returned with the representation