Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Python results and events

Typed operations return results and can deliver events as work progresses. Use this reference to interpret those objects and handle failures. See the operations reference for calling conventions, or streams and mappings for their completion rules.

Events and terminal results

cp and rm return frozen dataclasses after validating the complete results stream and process exit status. A truncated stream raises even if the process exits successfully. Dry runs return the same types, with planned totals.

CpResult

Returned by cp(), or available as SyqOperationError.result after an unsuccessful copy. Read attributes directly, for example result.files_transferred. It includes the common result fields below plus:

AttributeTypeMeaning
files_transferredintRegular files transferred
files_unchangedintRegular files skipped as unchanged
files_excludedintFiles excluded from copying
directories_createdintDirectories created
symlinks_createdintSymbolic links created
specials_createdintSpecial filesystem objects created
bytes_transferredintFile-content bytes transferred, not compressed network traffic
bytes_total_knownbool | NoneFor descriptor copies, whether the source length is known; otherwise absent (None)
bytes_unchangedintBytes in unchanged files
deletions_plannedint or NoneEntries selected for pruning
deletions_completedint or NoneEntries pruned
deletions_blockedint or NonePruning deletions blocked by a safety limit
receiptReceiptSummary or NoneVerified receiver receipt details; None for ordinary copies

With dry_run=True, mutation totals describe planned changes. A failed call reports work completed before it stopped.

Ordinary copies have all three deletion fields only with prune=True; otherwise they are None. Receiver-attested results have only deletions_completed, and their unchanged/excluded totals are always zero because the receiver cannot observe source-side skips. receipt is None for ordinary copies.

RmResult

Returned by rm(), or available as SyqOperationError.result after an unsuccessful removal. It includes the common result fields below plus:

AttributeTypeMeaning
selectors_totalintExplicit source selectors supplied
selectors_resolvedintSelectors that resolved to an object
selectors_missingintSelectors already missing; this is not an error
entries_plannedintEntries a dry run would remove; zero in live runs
entries_removedintEntries removed; zero in dry runs
entries_already_absentintEntries gone by removal time; zero in dry runs
entries_failedintRemoval or inspection failures, including during dry runs
modestrAlways "rm"

Selectors identify requests; entries count individual filesystem objects. One directory selector can account for many entries. Duplicate and overlapping selectors have separate indexes.

Common result fields

Both CpResult and RmResult include:

AttributeTypeMeaning
statusOperationStatusOutcome from the table below
exit_codeintsyq process exit code
dry_runboolWhether this was a preview
errorsintCounted errors
elapsed_msintRun duration in milliseconds
protocolProtocolMetadataAutomation envelope; also present on every event

ProtocolMetadata

Frozen dataclass accessed through result.protocol or event.protocol. The SDK checks these fields; applications normally only need them when recording or diagnosing a stream.

AttributeTypeMeaning
schemastr"syq.automation"
schema_versionint2
seqintRecord sequence number, starting at zero
typestrWire record type; "result" for terminal totals

ReceiptSummary

Frozen dataclass accessed through CpResult.receipt for receiver-attested copies.

AttributeTypeMeaning
statusReceiptStatusReceiver receipt outcome
operationsintAttested operation record count
final_statesintAttested final-state record count
recordsintTotal receipt record count
provenancestr"receiver_attested"

OperationStatus

String enum: compare with syq.OperationStatus.SUCCESS, or use .value for "success".

MemberValueExit codeMeaning
SUCCESS"success"0Requested operation succeeded
PARTIAL"partial"23Per-entry failures; independent work finished
REFUSED"refused"25A safety cap refused deletions; copy only
ABORTED"aborted"1Operation aborted; copy only
FAILED"failed"1Fatal failure

Event callbacks

on_event(event) receives an AutomationEvent in stream order. Events are not stored in the result. AsyncClient accepts synchronous or awaitable callbacks; awaitable callbacks count toward the timeout.

AutomationEvent is the union of the event classes below and CpResult and RmResult. Each event is a frozen dataclass. Its fields are listed below; all events also carry protocol: ProtocolMetadata, just like results. event.protocol.type identifies the wire record type. Optional fields use None when unavailable.

See Automation results for stream semantics. Python exposes class as class_ and paths as PathValue.

results= accepts a binary file-like object with write(bytes) returning a positive byte count for nonempty writes, and optional flush(). The client copies validated NDJSON records, flushes after completion, and leaves it open. It withholds the terminal record if stream validation, process completion, or a callback fails. Sink failures raise and abort the operation.

OperationResult.is_retryable identifies retryable failures; retry_entry() preserves expected_hash and metadata and returns a MappingEntry when a complete mapping identity is available, otherwise None. Only use collected entries after the call returns a validated success or partial result. A terminal callback alone does not establish completion. The client does not retry automatically.

Event types

RunEvent

Invocation details. started_at is Unix seconds; mode is "cp" or "rm". prune and mapping are None for removal.

protocol.type = "run". Fields in addition to the common envelope:

run_id: str
started_at: int
syq_version: str
mode: str
prune: bool | None
mapping: bool | None
dry_run: bool
endpoints: tuple[Endpoint, ...]

ProgressEvent

Sampled progress for displays; use the terminal result for final totals. Byte fields measure file content, scanned counts scanned entries, and elapsed_ms is milliseconds. Optional activity contains diagnostic measurements when the producer collects them; otherwise it is None. Optional rate_bytes_per_second and eta_ms provide rate and remaining-time estimates; use final byte counts and elapsed time for completed-run measurements.

protocol.type = "progress". Fields in addition to the common envelope:

bytes_done: int
bytes_total: int
bytes_unchanged: int
files_done: int
files_total: int
files_unchanged: int
files_excluded: int
scanned: int
scan_done: bool
elapsed_ms: int
activity: dict[str, Any] | None
rate_bytes_per_second: int | None
eta_ms: int | None

TraceEvent

One planned copy change. dst is relative to the destination container; src is the mapping source when available. bytes is the planned file size, and reason describes why the change is needed.

protocol.type = "trace". Fields in addition to the common envelope:

action: OperationAction
dst: PathValue
src: PathValue | None
kind: EntryKind
bytes: int | None
reason: TraceReason

OperationResult

One copy outcome. dst is destination-relative, or relative to the signed destination scope for a receiver receipt. src is present for mapping entries when available. bytes and attempts give transfer information. Error details are present when known; message is display text. provenance, scope, and code apply to receiver-attested outcomes.

protocol.type = "operation_result". Fields in addition to the common envelope:

action: OperationAction
dst: PathValue
src: PathValue | None
kind: EntryKind | None
disposition: Disposition
bytes: int | None
attempts: int | None
retryable: Retryability | None
class_: ErrorClass | None
os_kind: OsKind | None
message: str | None
expected_hash: Hash | None
metadata: DestinationMetadata | None
provenance: str | None
scope: int | None
code: ReceiptCode | None

SelectionResult

One removal selector, indexed from zero. path is the original selector; status says whether it resolved. kind is None for a missing selector.

protocol.type = "selection_result". Fields in addition to the common envelope:

selector: int
path: PathValue
status: SelectionStatus
kind: EntryKind | None

RemovalTrace

One entry a preview would remove. selector identifies its source selector; path identifies the entry. disposition is always WOULD_REMOVE.

protocol.type = "removal_trace". Fields in addition to the common envelope:

selector: int
path: PathValue
kind: EntryKind
disposition: RemovalDisposition
s3_version_id: str | None
s3_delete_marker: bool | None

RemovalResult

One removal outcome or preview inspection failure. selector identifies its source selector; path identifies the entry. attempts counts attempts; retryable, class_, os_kind, and message describe failures when available.

protocol.type = "removal_result". Fields in addition to the common envelope:

selector: int
path: PathValue
kind: EntryKind | None
disposition: RemovalDisposition
attempts: int
retryable: Retryability | None
class_: ErrorClass | None
os_kind: OsKind | None
message: str | None
s3_version_id: str | None
s3_delete_marker: bool | None

ErrorEvent

One counted error. message is display text; class_ and os_kind classify it when known. Receiver errors can also carry provenance and code.

protocol.type = "error". Fields in addition to the common envelope:

message: str
class_: ErrorClass | None
os_kind: OsKind | None
provenance: str | None
code: ReceiptCode | None

FinalStateEvent

Receiver-attested destination state. dst is relative to the signed scope. provenance is "receiver_attested". Present objects have kind and byte size; metadata, hash, and symlink_target are present where available. observation_error describes a partial observation. Absent objects have no object details; failed observations have code and optional message.

protocol.type = "final_state". Fields in addition to the common envelope:

provenance: str
scope: int
dst: PathValue
state: FinalObjectState
kind: FinalObjectKind | None
size: int | None
metadata: ObjectMetadata | None
hash: AttestedHash | None
symlink_target: PathValue | None
observation_error: str | None
code: ReceiptCode | None
message: str | None

Endpoint, ObjectMetadata, and AttestedHash

Nested frozen dataclasses used by events:

TypeFieldsMeaning
Endpointrole: EndpointRole, kind: EndpointKind, host: str | None, user: str | NoneSource/destination and local/SSH/S3 identity; host and user are optional
ObjectMetadatamode: int, uid: int, gid: int, mtime: int, mtime_nsec: int, rdev: intUnix mode, owner/group IDs, modification time (seconds plus nanoseconds), and device ID
AttestedHashalgorithm: str, value: str"blake3" and its 64 lowercase hexadecimal hash characters

Enums

All enums are string enums exported by syq. Members use uppercase names; values use lowercase, for example EntryKind.FILE.value == "file". OperationStatus is defined with the result types above.

TypeMembers
EntryKindFILE, DIR, SYMLINK, SPECIAL
EndpointKindLOCAL, SSH, S3
EndpointRoleSOURCE, DESTINATION
OperationActionTRANSFER_FILE, CREATE_DIRECTORY, CREATE_SYMLINK, CREATE_SPECIAL, DELETE, SET_METADATA, OBSERVE_HASH
DispositionSUCCEEDED, FAILED, BLOCKED, INCOMPLETE, OBSERVED
ReceiptCodeNONE, EXECUTION_FAILED, AUTHORIZATION_REFUSED, FILE_LIFECYCLE_INCOMPLETE, OBSERVATION_FAILED
FinalObjectStatePRESENT, ABSENT, OBSERVATION_FAILED
FinalObjectKindDIR, FILE, SYMLINK, FIFO, SOCKET, CHARACTER_DEVICE, BLOCK_DEVICE, OTHER
ReceiptStatusCLEAN, FAILED, INCOMPLETE
RetryabilityYES, NO, UNKNOWN
ErrorClassIO, TRANSPORT, CONFLICT, INTEGRITY, SAFETY_LIMIT, USAGE, INTERNAL
OsKindNOT_FOUND, PERMISSION_DENIED, ALREADY_EXISTS, INVALID_INPUT, NO_SPACE, QUOTA_EXCEEDED, READ_ONLY, OTHER
TraceReasonDESTINATION_MISSING, TYPE_DIFFERS, CONTENT_DIFFERS, METADATA_DIFFERS, DESTINATION_ONLY
SelectionStatusRESOLVED, MISSING
RemovalDispositionWOULD_REMOVE, REMOVED, ALREADY_ABSENT, FAILED

ReceiptStatus.CLEAN means a clean receipt, FAILED reports receiver failures, and INCOMPLETE reports an incomplete lifecycle. Retryability.YES, NO, and UNKNOWN state whether a failed entry can be retried.

Failure model

SyqError is the base class for every SDK-defined exception below. Specific subclasses retain their details so callers can distinguish an unsuccessful operation from a broken results stream.

ExceptionMeaning / useful attributes
SyqInstallErrorBundled executable is missing, or managed installation or verification failed
SyqInvocationErrorInvalid Python arguments
SyqOperationErrorTyped operation was unsuccessful; .result and .stderr (last 8 KiB)
SyqProtocolErrorInvalid, unsupported, inconsistent, or incomplete results; .returncode, .stderr
SyqProcessErrorRaw run exited nonzero; .result contains complete output
SyqOutputErrorA helper such as version() received unexpected output

For cp and rm, check=False returns unsuccessful typed results; for run, it returns nonzero process results. It does not suppress other errors. Spawn failures, timeouts, and ordinary Python type/value errors use standard Python exceptions. Exceptions from application callbacks or mapping iterators are re-raised unchanged. Async cancellation remains asyncio.CancelledError. These exceptions are not wrapped in SyqError.

Timeout, cancellation, early mapping exit, and streaming failures stop the local process group, including SSH children. Filesystem changes already completed are not rolled back.