document_stream()

Reads a byte range from a document file via std.GetDocumentStream. The server reads length bytes starting at offset from the page-th file of the document and returns them as the contents of a single response file, which is converted to bytes and returned to the caller.

This method is well suited to streaming large files in chunks without having to download a full copy via files().

1. Signature

  • Sync

  • Async

ecm.dms.document_stream(
    model: ECMDocumentModel | int,
    object_type_id: int | None = None,
    *,
    offset: int = 0,
    length: int,
    page: int = 1,
) -> bytes
await ecm.dms.document_stream(
    model: ECMDocumentModel | int,
    object_type_id: int | None = None,
    *,
    offset: int = 0,
    length: int,
    page: int = 1,
) -> bytes

2. Parameters

Parameter Type Default Description

model

ECMDocumentModel | int

The document: either an ECMDocumentModel instance (its system.id is used) or a plain integer object ID.

object_type_id

int | None

None

Numeric object type ID. Resolved automatically when None — taken from the model when available, or fetched via get_object_type_by_id() for plain IDs.

offset

int

0

Zero-based byte offset at which to start reading. Must be less than the file size; otherwise the server returns ERR_WRONGPARAM.

length

int

Number of bytes to read. The server may return fewer bytes if the requested range extends past the end of the file.

page

int

1

One-based page index of the document file to read from (default 1).

3. Return value

The requested byte range as a single bytes object. May be shorter than length if the file ends earlier. Returns an empty bytes object when the server produces no file.

4. Possible server error codes

The server may raise these errors (as ECMException):

  • ERR_WRONGPARAM — offset is greater than the file size.

  • ERR_GETOBJECTDEFPARAM — unknown object type.

  • ERR_GETPARAMETER — not enough (valid) parameters supplied.

  • ERR_SQLSELECT — DB query error.

  • ERR_NOTDEFINED_YET — object lives on a remote server.

  • ERR_INSOURCE — source file cannot be found or opened.

  • ERR_INDESTINATION — destination file cannot be created.

5. Examples

5.1. Read the first 50 bytes

  • Sync

  • Async

header = ecm.dms.document_stream(doc, offset=0, length=50)
print(header[:4])  # e.g. file-magic check
header = await ecm.dms.document_stream(doc, offset=0, length=50)

5.2. Stream a file in chunks

  • Sync

  • Async

chunks = []
pos = 0
chunk_size = 64 * 1024  # 64 KiB
while True:
    chunk = ecm.dms.document_stream(doc, offset=pos, length=chunk_size)
    if not chunk:
        break
    chunks.append(chunk)
    pos += len(chunk)
    if len(chunk) < chunk_size:
        break  # End-of-file reached
full_content = b"".join(chunks)
chunks = []
pos = 0
chunk_size = 64 * 1024
while True:
    chunk = await ecm.dms.document_stream(doc, offset=pos, length=chunk_size)
    if not chunk:
        break
    chunks.append(chunk)
    pos += len(chunk)
    if len(chunk) < chunk_size:
        break
full_content = b"".join(chunks)

5.3. By plain integer ID without type resolution

When the object type ID is already known, pass it explicitly to skip the extra get_object_type_by_id() round trip:

obj_type = ecm.dms.get_object_type_by_id(doc_id)
chunk = ecm.dms.document_stream(doc_id, obj_type, offset=0, length=1024)

6. Comparison with files()

Aspect files() document_stream()

Result type

List of JobResponseFile

bytes

Transfer

Whole file(s) at once

Configurable byte range

Multiple files

Yes (one per page)

No — single page per call

Streaming friendly

Limited

Excellent — enables chunking

Server job

std.StoreInCacheById

std.GetDocumentStream

7. See also

  • files() — Download the full files of a document

  • digest() — Retrieve the hash of a document