Skip to content

feat(AIP-76): support forward fan-out via forward kwarg on Window#67475

Merged
Lee-W merged 5 commits into
apache:mainfrom
astronomer:partition-fanout-direction
Jun 10, 2026
Merged

feat(AIP-76): support forward fan-out via forward kwarg on Window#67475
Lee-W merged 5 commits into
apache:mainfrom
astronomer:partition-fanout-direction

Conversation

@Lee-W

@Lee-W Lee-W commented May 25, 2026

Copy link
Copy Markdown
Member

Why

Fan-out today always produces keys inside the upstream window — weekly W10 (Mar 4–10) → days Mar 4–10. But the seven days that follow (Mar 11–17, i.e. W11) is just as valid a pattern. #65761 asks for a way to express that direction.

What

Adds forward: bool = False on Window. Pass forward=True to fan out the next period instead:

FanOutMapper(window=WeekWindow(forward=True))
# "2024-03-04" (W10) -> ["2024-03-11" .. "2024-03-17"]  (W11, daily)

FanOutMapper is unchanged; the shift lives on the window because the math is per-window-type. Default False preserves existing behavior, and deserialize(... data.get("forward", False)) handles already-persisted Dags. For Month / Quarter / Year, the existing day-1 guard runs before the shift, so non-day-1 input with forward=True raises symmetrically with current behavior.

Test plan

  • TestForwardWindow covers all six built-in windows (Hour / Day / Week / Month / Quarter / Year): forward shift produces the next period, day-1 guard fires before shift, serialize round-trip, and back-compat when the forward key is missing.
  • test_fan_out.py integration tests: FanOutMapper(window=WeekWindow(forward=True)) produces W11 from a W10 key, default downstream mapper still resolves, serialize round-trip through FanOutMapper.

Closes #65761.


Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

  • Read the Pull Request Guidelines for more information. Note: commit author/co-author name and email in commits become permanently public when merged.
  • For fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
  • When adding dependency, check compliance with the ASF 3rd Party License Policy.
  • For significant user-facing changes create newsfragment: {pr_number}.significant.rst, in airflow-core/newsfragments. You can add this file in a follow-up commit after the PR is created so you know the PR number.

@boring-cyborg boring-cyborg Bot added area:API Airflow's REST/HTTP API area:ConfigTemplates area:DAG-processing area:db-migrations PRs with DB migration area:dev-tools area:Scheduler including HA (high availability) scheduler area:task-sdk area:UI Related to UI/UX. For Frontend Developers. backport-to-v3-2-test kind:documentation labels May 25, 2026
@Lee-W Lee-W force-pushed the partition-fanout-direction branch from 81572b9 to eeda6f0 Compare May 25, 2026 15:31
@Lee-W Lee-W changed the title feat(AIP-76): window feat(AIP-76): support forward fan-out via forward kwarg on Window May 25, 2026
@Lee-W Lee-W force-pushed the partition-fanout-direction branch 11 times, most recently from 796a9ce to 89db186 Compare May 29, 2026 14:12
Comment thread airflow-core/src/airflow/partition_mappers/window.py Outdated
@Lee-W Lee-W force-pushed the partition-fanout-direction branch from 89db186 to c2e97e1 Compare June 5, 2026 01:57
@Lee-W Lee-W added this to the Airflow 3.3.0 milestone Jun 5, 2026
@phanikumv phanikumv moved this to In Progress in AIP-76 Asset Partitioning Jun 5, 2026
@Lee-W Lee-W moved this from In Progress to In Review in AIP-76 Asset Partitioning Jun 5, 2026
@Lee-W Lee-W force-pushed the partition-fanout-direction branch from c2e97e1 to 08fb555 Compare June 6, 2026 04:42
@Lee-W Lee-W force-pushed the partition-fanout-direction branch 3 times, most recently from f389552 to 396d02c Compare June 9, 2026 01:05
Comment thread airflow-core/src/airflow/partition_mappers/window.py Outdated
Comment thread airflow-core/src/airflow/partition_mappers/window.py Outdated
Comment thread task-sdk/src/airflow/sdk/definitions/partition_mappers/window.py Outdated
Comment thread task-sdk/src/airflow/sdk/definitions/partition_mappers/window.py Outdated
@Lee-W Lee-W force-pushed the partition-fanout-direction branch from 396d02c to 2174381 Compare June 9, 2026 07:57
@Lee-W Lee-W force-pushed the partition-fanout-direction branch 4 times, most recently from ee76e57 to 00a6427 Compare June 9, 2026 12:45
@Lee-W Lee-W requested a review from uranusjr June 9, 2026 12:49
@Lee-W Lee-W force-pushed the partition-fanout-direction branch from 00a6427 to 3d5755a Compare June 9, 2026 15:07
Lee-W added 5 commits June 10, 2026 08:21
WindowDirection.FORWARD now yields the trailing period ending at the
upstream key (the half-open (anchor - period, anchor], mirror of
BACKWARD) rather than the following period. The anchor is always the
last member of the forward sequence.

- WeekWindow(direction=FORWARD) on a Monday fans out the seven days
ending at that Monday, not the next calendar week.
- MonthWindow forward enumerates the trailing month ending at the
anchor and is intentionally not calendar-month aligned, matching the
week behaviour.

Closes apache#65761.
Coerce the `direction` argument through `WindowDirection(...)` in
`Window.__init__` so an invalid value raises `ValueError` at construction
instead of silently behaving as FORWARD when the later `is` identity check
fails to match a stray string. Applies to both the core and task-sdk copies.
Collapse the per-class `if direction is BACKWARD: shift; forward-generate`
duplication in the temporal Window classes into a single `_directional_steps`
helper, so the trailing-period rule lives in one place. Hour/Day/Week/Quarter/
Year share it via a step callable; MonthWindow stays bespoke (variable member
count, open-closed backward interval).
… hook

Replace the manual "keep in sync" header comment on the Task SDK Window copy
with a `check-window-in-sync` prek hook that AST-compares the shared surface
(class names, WindowDirection enum, direction default, serialize/deserialize
bodies, expected_decoded_type) against the core copy and fails on drift.
Replace the top-level `WindowDirection` enum with a nested `Window.Direction`
so authors reference `Window.Direction.FORWARD` and import only `Window`.
Removes the standalone export from the SDK and core partition_mappers surfaces;
serialized values ("forward"/"backward") are unchanged. The core/SDK sync prek
hook is updated to track the nested name.
@Lee-W Lee-W force-pushed the partition-fanout-direction branch from 3d5755a to 8b9f6f7 Compare June 10, 2026 00:21
@Lee-W Lee-W merged commit a8c9910 into apache:main Jun 10, 2026
281 of 282 checks passed
@Lee-W Lee-W deleted the partition-fanout-direction branch June 10, 2026 08:26
@github-project-automation github-project-automation Bot moved this from In Review to Done in AIP-76 Asset Partitioning Jun 10, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Backport failed to create: v3-2-test. View the failure log Run details

Note: As of Merging PRs targeted for Airflow 3.X
the committer who merges the PR is responsible for backporting the PRs that are bug fixes (generally speaking) to the maintenance branches.

In matter of doubt please ask in #release-management Slack channel.

Status Branch Result
v3-2-test Commit Link

You can attempt to backport this manually by running:

cherry_picker a8c9910 v3-2-test

This should apply the commit to the v3-2-test branch and leave the commit in conflict state marking
the files that need manual conflict resolution.

After you have resolved the conflicts, you can continue the backport process by running:

cherry_picker --continue

If you don't have cherry-picker installed, see the installation guide.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:API Airflow's REST/HTTP API area:ConfigTemplates area:DAG-processing area:db-migrations PRs with DB migration area:dev-tools area:Scheduler including HA (high availability) scheduler area:task-sdk area:UI Related to UI/UX. For Frontend Developers. kind:documentation

Projects

Development

Successfully merging this pull request may close these issues.

Fan-out: backward vs. forward direction semantics

3 participants