Skip to content

Partitioning

Partitions scope a run to a slice of time; windows span several.

PartitionConfig

PartitionConfig(*, column: str, allow_window: bool = False)

Bases: abc.ABC

How an asset is partitioned: the authority on its partition space.

Declared on an asset. Every concrete kind names itself through kind and is registered at class creation, so a catalog definition rebuilds the right one through from_definition. The check messages read as predicates of the asset, so callers prefix them with its name.

Attributes:

Name Type Description
column

The column the rows carry the partition value in.

allow_window

Whether one run may cover several partitions.

allow_window

allow_window = False

bool(x) -> bool

Returns True when the argument x is true, False otherwise. The builtins True and False are the only two instances of the class bool. The class bool is a subclass of the class int, and cannot be subclassed.

check

check(window: PartitionWindow | None) -> None

Validate the window a run was given against this partitioning.

Parameters:

Name Type Description Default
window PartitionWindow | None

The run's window, None when the run was unscoped.

required

Raises:

Type Description
PartitionError

If no window was given, if several partitions were given and windows are not allowed, or if the kind-specific check fails.

compatible

compatible(other: PartitionConfig) -> bool

Whether other accepts exactly the windows this config accepts.

Parameters:

Name Type Description Default
other PartitionConfig

The partitioning at the other end of a DAG edge.

required

Returns:

Type Description
bool

True when a run's window is valid for both.

from_definition

from_definition(
    definition: Mapping[str, Any],
) -> PartitionConfig

Rebuild a partitioning from its catalog definition.

Parameters:

Name Type Description Default
definition Mapping[str, Any]

The mapping to_definition rendered, possibly after a JSON round trip.

required

Returns:

Type Description
PartitionConfig

The partitioning, of the kind the definition names.

Raises:

Type Description
ConfigError

If the definition names no registered kind, or carries a field its kind does not declare.

partition

partition(key: str) -> Partition

Parse a persisted key into the partition it names.

Parameters:

Name Type Description Default
key str

The partition key.

required

Returns:

Type Description
Partition

The partition.

to_definition

to_definition() -> dict[str, Any]

Render the catalog definition of this partitioning.

Returns:

Type Description
dict[str, Any]

The fields, plus kind.

window

window(start_key: str, end_key: str) -> PartitionWindow

Build the window from its first and last key.

Parameters:

Name Type Description Default
start_key str

The first partition's key.

required
end_key str

The last partition's key.

required

Returns:

Type Description
PartitionWindow

The window covering both keys and everything between.

Partition

Bases: abc.ABC

The storage unit: one slice of a partitioned asset, named by its key.

Concrete kinds are frozen dataclasses carrying the partition's value (a period start for a time partition, a declared string for a list one); the base declares the contract and types that one attribute every kind carries, so context.partition.value reads without narrowing. str(partition) is the key, which is what reaches destination paths, run rows and filters.

key

key

The partition's key.

window

window

The one-partition window covering only this partition.

filter

filter(column: str) -> PartitionFilter

The rows this partition covers.

Parameters:

Name Type Description Default
column str

The partition column the rows carry.

required

Returns:

Type Description
PartitionFilter

The filter a database selects the partition's rows with.

slice

slice(data: Any, column: str) -> Any

Return this partition's slice of data.

Parameters:

Name Type Description Default
data Any

The table to slice, in any registered representation's type.

required
column str

Name of the partition column to select on.

required

Returns:

Type Description
Any

The partition's slice of the data.

PartitionWindow

PartitionWindow(start: Any, end: Any)

Bases: abc.ABC

The run scope: a contiguous, never empty range of a partition space.

Named by its first and last partition's values; the concrete kind enumerates what lies between. str(window) is the single partition's key for a window of one, and "first..last" otherwise.

Attributes:

Name Type Description
start

The first partition's value.

end

The last partition's value.

first

first

The window's first partition.

last

last

The window's last partition.

partitions

partitions

Every partition of the window, first to last.

filter

filter(column: str) -> PartitionFilter

The rows the whole window covers.

Parameters:

Name Type Description Default
column str

The partition column the rows carry.

required

Returns:

Type Description
PartitionFilter

The filter a database selects the window's rows with.

of

of(
    scope: Partition | PartitionWindow | None,
) -> PartitionWindow | None

The window a run argument denotes.

The entry points accept a bare partition as sugar for the window of one it names; inside the framework there is one scope, the window.

Parameters:

Name Type Description Default
scope Partition | PartitionWindow | None

A partition, a window, or None for an unscoped run.

required

Returns:

Type Description
PartitionWindow | None

The partition's one-partition window, the window as given, or None.

TimeGranularity

Bases: builtins.str, enum.Enum

The length of the period one time partition covers.

Partition keys are ISO-8601 prefixes (2026, 2026-08, 2026-08-21, 2026-08-21T13): they sort chronologically as strings, embed in paths unchanged, and each shape names its granularity, which is what TimePartition.from_key relies on.

DAY

DAY = <TimeGranularity.DAY: 'day'>

The length of the period one time partition covers.

Partition keys are ISO-8601 prefixes (2026, 2026-08, 2026-08-21, 2026-08-21T13): they sort chronologically as strings, embed in paths unchanged, and each shape names its granularity, which is what TimePartition.from_key relies on.

HOUR

HOUR = <TimeGranularity.HOUR: 'hour'>

The length of the period one time partition covers.

Partition keys are ISO-8601 prefixes (2026, 2026-08, 2026-08-21, 2026-08-21T13): they sort chronologically as strings, embed in paths unchanged, and each shape names its granularity, which is what TimePartition.from_key relies on.

MONTH

MONTH = <TimeGranularity.MONTH: 'month'>

The length of the period one time partition covers.

Partition keys are ISO-8601 prefixes (2026, 2026-08, 2026-08-21, 2026-08-21T13): they sort chronologically as strings, embed in paths unchanged, and each shape names its granularity, which is what TimePartition.from_key relies on.

YEAR

YEAR = <TimeGranularity.YEAR: 'year'>

The length of the period one time partition covers.

Partition keys are ISO-8601 prefixes (2026, 2026-08, 2026-08-21, 2026-08-21T13): they sort chronologically as strings, embed in paths unchanged, and each shape names its granularity, which is what TimePartition.from_key relies on.

format

format(value: object) -> str

Render a value as a partition key.

Parameters:

Name Type Description Default
value object

Any value inside the period the key names.

required

Returns:

Type Description
str

The canonical key of the period containing value.

TimePartitionConfig

TimePartitionConfig(*, column: str, allow_window: bool = False, granularity: TimeGranularity = <TimeGranularity.DAY: 'day'>, start: date | None = None)

Bases: interloper.partitioning.base.PartitionConfig

Partitioning by time periods of one granularity.

Attributes:

Name Type Description
granularity

The period one partition covers.

start

Optional lower bound. Windows reaching before it are rejected, and trailing windows built against this asset are clamped to it.

granularity

granularity = <TimeGranularity.DAY: 'day'>

The length of the period one time partition covers.

Partition keys are ISO-8601 prefixes (2026, 2026-08, 2026-08-21, 2026-08-21T13): they sort chronologically as strings, embed in paths unchanged, and each shape names its granularity, which is what TimePartition.from_key relies on.

kind

kind = 'time'

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'.

compatible

compatible(other: PartitionConfig) -> bool

Whether other is a time partitioning of the same granularity.

Parameters:

Name Type Description Default
other PartitionConfig

The partitioning at the other end of a DAG edge.

required

Returns:

Type Description
bool

True when both share the granularity.

partition

partition(key: str) -> TimePartition

Parse a key at this granularity.

Parameters:

Name Type Description Default
key str

The partition key.

required

Returns:

Type Description
TimePartition

The partition.

Raises:

Type Description
PartitionError

If the key is not of this granularity's shape.

TimePartition

TimePartition(value: date, granularity: TimeGranularity = <TimeGranularity.DAY: 'day'>)

Bases: interloper.partitioning.base.Partition

A single time partition, identified by the start of its period.

Attributes:

Name Type Description
value

The period's start, normalised on construction.

granularity

The period one partition covers.

bounds

bounds

The partition's (start, end_exclusive) bounds.

granularity

granularity = <TimeGranularity.DAY: 'day'>

The length of the period one time partition covers.

Partition keys are ISO-8601 prefixes (2026, 2026-08, 2026-08-21, 2026-08-21T13): they sort chronologically as strings, embed in paths unchanged, and each shape names its granularity, which is what TimePartition.from_key relies on.

key

key

The partition's canonical key (see TimeGranularity.format).

window

window

The one-partition window covering only this period.

filter

filter(column: str) -> PartitionFilter

The rows inside this period.

Rows may carry values anywhere inside the period (a monthly partition whose rows hold daily dates), so the filter is the half-open bounds, never the key.

Parameters:

Name Type Description Default
column str

The partition column the rows carry.

required

Returns:

Type Description
PartitionFilter

A bounds filter on the period.

from_key

from_key(key: str) -> TimePartition

Parse a partition key, inferring its granularity from the shape.

The key shapes are mutually unambiguous, so the key alone carries the granularity: storage and transport need one string, not a pair.

Parameters:

Name Type Description Default
key str

A partition key in any granularity's format.

required

Returns:

Type Description
TimePartition

The partition the key names.

Raises:

Type Description
PartitionError

If key matches no known key shape.

slice

slice(data: Any, column: str) -> Any

Return this partition's slice of data, selecting by its half-open bounds.

Parameters:

Name Type Description Default
data Any

The table to slice, in any registered representation's type.

required
column str

Name of the partition column to select on.

required

Returns:

Type Description
Any

The partition's slice of the data.

TimePartitionWindow

TimePartitionWindow(start: date, end: date, granularity: TimeGranularity = <TimeGranularity.DAY: 'day'>)

Bases: interloper.partitioning.base.PartitionWindow

A contiguous range of time partitions, inclusive of both bounds.

Attributes:

Name Type Description
start

The first period's start.

end

The last period's start.

granularity

The period one partition covers.

bounds

bounds

The window's (start, end_exclusive) bounds: the first period's start to the last's end.

first

first

The window's first partition.

granularity

granularity = <TimeGranularity.DAY: 'day'>

The length of the period one time partition covers.

Partition keys are ISO-8601 prefixes (2026, 2026-08, 2026-08-21, 2026-08-21T13): they sort chronologically as strings, embed in paths unchanged, and each shape names its granularity, which is what TimePartition.from_key relies on.

last

last

The window's last partition.

partitions

partitions

Every period from start to end inclusive, oldest first.

filter

filter(column: str) -> PartitionFilter

The rows inside the whole window.

Parameters:

Name Type Description Default
column str

The partition column the rows carry.

required

Returns:

Type Description
PartitionFilter

A bounds filter spanning every period of the window.

lookback

lookback(now: date, lookback: int, offset: int = 1, granularity: TimeGranularity = <TimeGranularity.DAY: 'day'>, start: date | None = None) -> TimePartitionWindow | None

Build the trailing window a scheduled workload should cover.

The window is counted in partitions, never in days: offset is how many partitions back from the current one the window ends, and lookback is how many it spans. At daily granularity, offset=1, lookback=1 is "yesterday only" and offset=0 includes the current (still incomplete) partition.

The caller's timezone reaches the window through now: passing an aware datetime localized to a zone makes DAY, MONTH and YEAR windows follow that zone's calendar. HOUR windows are the deliberate exception: an aware now is normalized back to UTC (see coerce_to_datetime), because hour partition keys are naive-UTC labels and zones on a fractional offset do not align to UTC hour boundaries at all.

Parameters:

Name Type Description Default
now date

The reference instant, in whatever timezone the caller labels partitions with.

required
lookback int

How many partitions the window spans (at least 1).

required
offset int

How many partitions back from the current one the window ends.

1
granularity TimeGranularity

The period one partition covers.

<TimeGranularity.DAY: 'day'>
start date | None

Optional lower bound (an asset's earliest partition) to clamp the window to.

None

Returns:

Type Description
TimePartitionWindow | None

The window, or None if clamping to start leaves it empty.

Raises:

Type Description
ValueError

If lookback is below 1, or offset is negative.