apache_beam.io.unbounded_source module
Experimental UnboundedSource support for the Python SDK.
UnboundedSource support is currently experimental in the Python SDK; the
API may change in backwards-incompatible ways.
An unbounded source reads an effectively infinite stream of records (message queues, change-data-capture feeds, and similar) with checkpoint-based pause/resume, watermark reporting, and bundle finalization.
To define a source, implement UnboundedSource, an
UnboundedReader, and (when the reader has a resumable position) a
CheckpointMark:
import apache_beam as beam
from apache_beam.io.unbounded_source import (
CheckpointMark, UnboundedReader, UnboundedSource)
from apache_beam.utils.timestamp import MAX_TIMESTAMP
class MyCheckpointMark(CheckpointMark):
def __init__(self, position):
self.position = position
def finalize_checkpoint(self):
# Commit/acknowledge records up to ``position`` upstream, e.g. ack the
# consumed messages on a queue.
...
class MyReader(UnboundedReader):
def start(self):
# Position at the first record; return whether one is available.
...
def advance(self):
# Move to the next record; ``False`` means no data is available now.
...
def get_current(self):
...
def get_current_timestamp(self):
... # event time of the current record
def get_watermark(self):
# Lower bound on the timestamps of future records. Return
# ``MAX_TIMESTAMP`` to signal the reader has permanently finished.
...
def get_checkpoint_mark(self):
return MyCheckpointMark(...)
class MySource(UnboundedSource):
def split(self, desired_num_splits, options=None):
# Return independent sub-sources, or ``[self]`` when not splittable.
return [self]
def create_reader(self, options, checkpoint_mark):
# Build a reader; resume after ``checkpoint_mark`` when it is not None.
return MyReader(...)
def get_checkpoint_mark_coder(self):
return ... # a Coder for MyCheckpointMark
Read the source in a pipeline with apache_beam.io.Read:
with beam.Pipeline() as p:
p | beam.io.Read(MySource()) | beam.Map(print)
- class apache_beam.io.unbounded_source.CheckpointMark[source]
Bases:
objectA durable, serializable position in an
UnboundedSource.Produced by
UnboundedReader.get_checkpoint_mark(), encoded withUnboundedSource.get_checkpoint_mark_coder(), and used to resume a reader (seeUnboundedSource.create_reader()).- finalize_checkpoint() None[source]
Called once the runner has durably committed work up to this mark.
Override to acknowledge/commit upstream (for example, ack the consumed messages on a queue). The default is a no-op.
The runner calls this at most once for a committed checkpoint mark. Finalization is best effort; a mark may never be finalized. An exception raised here is logged. On bundle retry an uncommitted mark may be re-cut over an overlapping span, so this method must be idempotent (acknowledge by absolute position).
- class apache_beam.io.unbounded_source.UnboundedReader[source]
Bases:
objectReads records from an
UnboundedSource.Lifecycle: exactly one
start(), then any number ofadvance()calls; whenever one returnsTruethe current record is available viaget_current()/get_current_timestamp(). AFalsereturn means “no data available right now”, which is distinct from end-of-stream: a reader signals a permanent end by reporting a watermark ofMAX_TIMESTAMP.- advance() bool[source]
Advances to the next record.
Falsemeans no data is available now.Should not block. The wrapper enforces the per-bundle record and time caps only between records, so a blocking
start/advancecan overrun the time cap and stall the bundle. ReturnFalsewhen no data is currently available instead of waiting.
- get_watermark() Timestamp[source]
An approximate lower bound on timestamps of future records.
Treated as monotonic by the wrapper. Return
MAX_TIMESTAMPto signal that this reader has permanently finished.
- get_checkpoint_mark() CheckpointMark[source]
Returns a durable mark to resume from. Call only at a bundle boundary.
- class apache_beam.io.unbounded_source.UnboundedSource[source]
Bases:
SourceBaseA source producing an unbounded stream of records with checkpointing.
Read it in a pipeline with
apache_beam.io.Read:p | beam.io.Read(MyUnboundedSource())
- split(desired_num_splits: int, options: Any | None = None) Iterable[UnboundedSource][source]
Splits into at most
desired_num_splitsindependent sub-sources.Each returned sub-source must be independent and must not share mutable state with siblings (the runner may execute them concurrently across workers). Return
[self]if the source cannot be split. Splitting is performed once, before any checkpoint exists; once a reader has checkpointed, the restriction is kept intact.
- create_reader(options: Any | None, checkpoint_mark: CheckpointMark | None) UnboundedReader[source]
Creates a reader, optionally resuming from
checkpoint_mark.- Contract:
When
checkpoint_markisNone, the returned reader’sstart()produces the very first record of the source (or returnsFalseif none yet).When
checkpoint_markis notNone, the returned reader’sstart()produces the first record strictly after the position encoded bycheckpoint_mark. The reader must not re-deliver records already covered by the prior bundle.
- get_checkpoint_mark_coder() Coder[source]
Returns the coder for this source’s
CheckpointMarkinstances.The SDK may call this while encoding or decoding source restrictions. Implementations should be deterministic, side-effect free, and should not perform I/O.
- class apache_beam.io.unbounded_source.ReadFromUnboundedSource(source: UnboundedSource, poll_interval: float = 1.0, max_records_per_bundle: int = 10000, max_read_time_seconds: float = 10.0)[source]
Bases:
PTransformReads an
UnboundedSource.Most users should prefer
apache_beam.io.Read, which dispatches anUnboundedSourcehere automatically:p | beam.io.Read(MyUnboundedSource())
- Parameters:
source – the
UnboundedSourceto read.poll_interval – resume delay in seconds applied when the reader has no data, which bounds how often an idle source is polled. Must be >= 0.
max_records_per_bundle – a busy reader self-checkpoints after emitting this many records in one bundle. Must be >= 1. Defaults to 10000.
max_read_time_seconds – a busy reader self-checkpoints after this many seconds in one bundle. Must be > 0. Defaults to 10.0. The deadline is checked between records, so a reader that blocks inside
advance()may overrun it;max_records_per_bundleis the hard backstop.
The bundle self-checkpoints as soon as either cap is reached.