Skip to content

Add FixedKeyMapper and SegmentWindow for categorical asset-partition rollup - #67716

Merged
Lee-W merged 4 commits into
apache:mainfrom
astronomer:asset-partition-segment
Jun 10, 2026
Merged

Add FixedKeyMapper and SegmentWindow for categorical asset-partition rollup#67716
Lee-W merged 4 commits into
apache:mainfrom
astronomer:asset-partition-segment

Conversation

@Lee-W

@Lee-WLee-W commented May 29, 2026

Copy link
Copy Markdown
Member

Why

We already supports temporal asset-partition rollup by composing two primitives inside a RollupMapper: a mapper that routes upstream events to a downstream partition key (e.g. StartOfDayMapper) and a window that declares which upstream partitions must arrive before the downstream run is released (e.g. DayWindow). There was no equivalent for categorical rollup — folding a fixed set of named segments (such as us, eu, apac) into a single downstream run.

This PR adds the two primitives needed to express categorical rollup with the same composition model as the temporal family, rather than introducing a self-contained bespoke segment mapper:

RollupMapper(
upstream_mapper=FixedKeyMapper("all_regions"),
window=SegmentWindow(["us", "eu", "apac"]),
)
  • FixedKeyMapper handles forward routing: every incoming upstream segment event (us / eu / apac) is routed to one downstream partition key ("all_regions"), so all 3 accumulate into the same run.
  • SegmentWindow handles reverse gating: it declares the set of segments to wait for, and the scheduler releases the downstream run only once all of them have arrived (to_upstream + issubset).

Keeping the scheduler aware of only RollupMapper — and letting authors swap in different mapper/window pairs — means categorical and temporal rollup share one mental model instead of each shipping its own mapper.

The FixedKeyMapper downstream key is required and semantic (the example uses "all_regions") to avoid a silent default that would obscure where rolled-up events land.

SegmentWindow is also reusable as the gating side of a categorical scatter (1-to-n) when paired with the recently merged FanOutMapper.

What

Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Opus 4.8)

Generated-by: Claude Code (Opus 4.8) following the guidelines


  • 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.

@Lee-WLee-W changed the title AIP-76: Hold Dag run until all upstream partitions arriveAdd SegmentWindow and DynamicSegmentWindow for categorical asset partition rollupMay 29, 2026
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch 3 times, most recently from e7a47e8 to 943d3e1CompareMay 29, 2026 15:24
@Lee-WLee-W added this to the Airflow 3.3.0 milestone Jun 5, 2026
@Lee-WLee-W moved this to In Progress in AIP-76 Asset PartitioningJun 5, 2026
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch 7 times, most recently from ee72740 to d3bcb9fCompareJune 8, 2026 13:58
@Lee-WLee-W changed the title Add SegmentWindow and DynamicSegmentWindow for categorical asset partition rollupAdd FixedKeyMapper and SegmentWindow for categorical asset-partition rollupJun 8, 2026
@Lee-W
Lee-W marked this pull request as ready for review June 8, 2026 14:12
@Lee-W
Lee-W requested a review from ashb as a code ownerJune 8, 2026 14:12
Comment threadairflow-core/src/airflow/partition_mappers/window.py Outdated
Comment threadairflow-core/src/airflow/partition_mappers/window.py Outdated
Comment threadtask-sdk/src/airflow/sdk/definitions/partition_mappers/window.py Outdated
Comment threadtask-sdk/src/airflow/sdk/definitions/partition_mappers/fixed_key.py Outdated
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from 32010ec to 4f0edbdCompareJune 9, 2026 08:00
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from 4f0edbd to cffebd6CompareJune 9, 2026 13:53
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from cffebd6 to a2dd91fCompareJune 9, 2026 15:06
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 10, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 10, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from a2dd91f to ef80d9bCompareJune 10, 2026 00:22
Lee-W added 4 commits June 10, 2026 16:38
…entWindow
Express categorical asset-partition rollup by composing
RollupMapper(FixedKeyMapper(...), SegmentWindow(...)): FixedKeyMapper routes
every upstream segment event onto one downstream bucket, and SegmentWindow
declares the segment set the scheduler waits for. Categorical and temporal
rollups now share one composition model, and SegmentWindow also composes with
FanOutMapper for categorical scatter.
- Add FixedKeyMapper (collapse any upstream key onto a fixed downstream key)
and SegmentWindow (enumerate a fixed categorical segment set), on both the
SDK authoring side and the scheduler runtime side.
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from ef80d9b to 6f2a885CompareJune 10, 2026 08:39
@Lee-W
Lee-W merged commit f690474 into apache:mainJun 10, 2026
144 of 145 checks passed
@Lee-W
Lee-W deleted the asset-partition-segment branch June 10, 2026 10:06
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:APIAirflow's REST/HTTP APIarea:ConfigTemplatesarea:DAG-processingarea:db-migrationsPRs with DB migrationarea:dev-toolsarea:Schedulerincluding HA (high availability) schedulerarea:task-sdkarea:translationsarea:UIRelated to UI/UX. For Frontend Developers.kind:documentationtranslation:defaulttranslation:zh-TW

Projects

No open projects

Development

Successfully merging this pull request may close these issues.

Segment-based (categorical) asset partitions for static sets — rollup (n-1) and fan-out (1-n)

4 participants

@Lee-W@uranusjr@phanikumv@eladkal
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Add FixedKeyMapper and SegmentWindow for categorical asset-partition rollup by Lee-W · Pull Request #67716 · apache/airflow · GitHub
Skip to content

Add FixedKeyMapper and SegmentWindow for categorical asset-partition rollup - #67716

Merged
Lee-W merged 4 commits into
apache:mainfrom
astronomer:asset-partition-segment
Jun 10, 2026
Merged

Add FixedKeyMapper and SegmentWindow for categorical asset-partition rollup#67716
Lee-W merged 4 commits into
apache:mainfrom
astronomer:asset-partition-segment

Conversation

@Lee-W

@Lee-WLee-W commented May 29, 2026

Copy link
Copy Markdown
Member

Why

We already supports temporal asset-partition rollup by composing two primitives inside a RollupMapper: a mapper that routes upstream events to a downstream partition key (e.g. StartOfDayMapper) and a window that declares which upstream partitions must arrive before the downstream run is released (e.g. DayWindow). There was no equivalent for categorical rollup — folding a fixed set of named segments (such as us, eu, apac) into a single downstream run.

This PR adds the two primitives needed to express categorical rollup with the same composition model as the temporal family, rather than introducing a self-contained bespoke segment mapper:

RollupMapper(
upstream_mapper=FixedKeyMapper("all_regions"),
window=SegmentWindow(["us", "eu", "apac"]),
)
  • FixedKeyMapper handles forward routing: every incoming upstream segment event (us / eu / apac) is routed to one downstream partition key ("all_regions"), so all 3 accumulate into the same run.
  • SegmentWindow handles reverse gating: it declares the set of segments to wait for, and the scheduler releases the downstream run only once all of them have arrived (to_upstream + issubset).

Keeping the scheduler aware of only RollupMapper — and letting authors swap in different mapper/window pairs — means categorical and temporal rollup share one mental model instead of each shipping its own mapper.

The FixedKeyMapper downstream key is required and semantic (the example uses "all_regions") to avoid a silent default that would obscure where rolled-up events land.

SegmentWindow is also reusable as the gating side of a categorical scatter (1-to-n) when paired with the recently merged FanOutMapper.

What

Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Opus 4.8)

Generated-by: Claude Code (Opus 4.8) following the guidelines


  • 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.

@Lee-WLee-W changed the title AIP-76: Hold Dag run until all upstream partitions arriveAdd SegmentWindow and DynamicSegmentWindow for categorical asset partition rollupMay 29, 2026
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch 3 times, most recently from e7a47e8 to 943d3e1CompareMay 29, 2026 15:24
@Lee-WLee-W added this to the Airflow 3.3.0 milestone Jun 5, 2026
@Lee-WLee-W moved this to In Progress in AIP-76 Asset PartitioningJun 5, 2026
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch 7 times, most recently from ee72740 to d3bcb9fCompareJune 8, 2026 13:58
@Lee-WLee-W changed the title Add SegmentWindow and DynamicSegmentWindow for categorical asset partition rollupAdd FixedKeyMapper and SegmentWindow for categorical asset-partition rollupJun 8, 2026
@Lee-W
Lee-W marked this pull request as ready for review June 8, 2026 14:12
@Lee-W
Lee-W requested a review from ashb as a code ownerJune 8, 2026 14:12
Comment threadairflow-core/src/airflow/partition_mappers/window.py Outdated
Comment threadairflow-core/src/airflow/partition_mappers/window.py Outdated
Comment threadtask-sdk/src/airflow/sdk/definitions/partition_mappers/window.py Outdated
Comment threadtask-sdk/src/airflow/sdk/definitions/partition_mappers/fixed_key.py Outdated
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from 32010ec to 4f0edbdCompareJune 9, 2026 08:00
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from 4f0edbd to cffebd6CompareJune 9, 2026 13:53
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from cffebd6 to a2dd91fCompareJune 9, 2026 15:06
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 10, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 10, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from a2dd91f to ef80d9bCompareJune 10, 2026 00:22
Lee-W added 4 commits June 10, 2026 16:38
…entWindow
Express categorical asset-partition rollup by composing
RollupMapper(FixedKeyMapper(...), SegmentWindow(...)): FixedKeyMapper routes
every upstream segment event onto one downstream bucket, and SegmentWindow
declares the segment set the scheduler waits for. Categorical and temporal
rollups now share one composition model, and SegmentWindow also composes with
FanOutMapper for categorical scatter.
- Add FixedKeyMapper (collapse any upstream key onto a fixed downstream key)
and SegmentWindow (enumerate a fixed categorical segment set), on both the
SDK authoring side and the scheduler runtime side.
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from ef80d9b to 6f2a885CompareJune 10, 2026 08:39
@Lee-W
Lee-W merged commit f690474 into apache:mainJun 10, 2026
144 of 145 checks passed
@Lee-W
Lee-W deleted the asset-partition-segment branch June 10, 2026 10:06
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:APIAirflow's REST/HTTP APIarea:ConfigTemplatesarea:DAG-processingarea:db-migrationsPRs with DB migrationarea:dev-toolsarea:Schedulerincluding HA (high availability) schedulerarea:task-sdkarea:translationsarea:UIRelated to UI/UX. For Frontend Developers.kind:documentationtranslation:defaulttranslation:zh-TW

Projects

No open projects

Development

Successfully merging this pull request may close these issues.

Segment-based (categorical) asset partitions for static sets — rollup (n-1) and fan-out (1-n)

4 participants

@Lee-W@uranusjr@phanikumv@eladkal
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add FixedKeyMapper and SegmentWindow for categorical asset-partition rollup by Lee-W · Pull Request #67716 · apache/airflow · GitHub
Skip to content

Add FixedKeyMapper and SegmentWindow for categorical asset-partition rollup - #67716

Merged
Lee-W merged 4 commits into
apache:mainfrom
astronomer:asset-partition-segment
Jun 10, 2026
Merged

Add FixedKeyMapper and SegmentWindow for categorical asset-partition rollup#67716
Lee-W merged 4 commits into
apache:mainfrom
astronomer:asset-partition-segment

Conversation

@Lee-W

@Lee-WLee-W commented May 29, 2026

Copy link
Copy Markdown
Member

Why

We already supports temporal asset-partition rollup by composing two primitives inside a RollupMapper: a mapper that routes upstream events to a downstream partition key (e.g. StartOfDayMapper) and a window that declares which upstream partitions must arrive before the downstream run is released (e.g. DayWindow). There was no equivalent for categorical rollup — folding a fixed set of named segments (such as us, eu, apac) into a single downstream run.

This PR adds the two primitives needed to express categorical rollup with the same composition model as the temporal family, rather than introducing a self-contained bespoke segment mapper:

RollupMapper(
upstream_mapper=FixedKeyMapper("all_regions"),
window=SegmentWindow(["us", "eu", "apac"]),
)
  • FixedKeyMapper handles forward routing: every incoming upstream segment event (us / eu / apac) is routed to one downstream partition key ("all_regions"), so all 3 accumulate into the same run.
  • SegmentWindow handles reverse gating: it declares the set of segments to wait for, and the scheduler releases the downstream run only once all of them have arrived (to_upstream + issubset).

Keeping the scheduler aware of only RollupMapper — and letting authors swap in different mapper/window pairs — means categorical and temporal rollup share one mental model instead of each shipping its own mapper.

The FixedKeyMapper downstream key is required and semantic (the example uses "all_regions") to avoid a silent default that would obscure where rolled-up events land.

SegmentWindow is also reusable as the gating side of a categorical scatter (1-to-n) when paired with the recently merged FanOutMapper.

What

Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Opus 4.8)

Generated-by: Claude Code (Opus 4.8) following the guidelines


  • 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.

@Lee-WLee-W changed the title AIP-76: Hold Dag run until all upstream partitions arriveAdd SegmentWindow and DynamicSegmentWindow for categorical asset partition rollupMay 29, 2026
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch 3 times, most recently from e7a47e8 to 943d3e1CompareMay 29, 2026 15:24
@Lee-WLee-W added this to the Airflow 3.3.0 milestone Jun 5, 2026
@Lee-WLee-W moved this to In Progress in AIP-76 Asset PartitioningJun 5, 2026
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch 7 times, most recently from ee72740 to d3bcb9fCompareJune 8, 2026 13:58
@Lee-WLee-W changed the title Add SegmentWindow and DynamicSegmentWindow for categorical asset partition rollupAdd FixedKeyMapper and SegmentWindow for categorical asset-partition rollupJun 8, 2026
@Lee-W
Lee-W marked this pull request as ready for review June 8, 2026 14:12
@Lee-W
Lee-W requested a review from ashb as a code ownerJune 8, 2026 14:12
Comment threadairflow-core/src/airflow/partition_mappers/window.py Outdated
Comment threadairflow-core/src/airflow/partition_mappers/window.py Outdated
Comment threadtask-sdk/src/airflow/sdk/definitions/partition_mappers/window.py Outdated
Comment threadtask-sdk/src/airflow/sdk/definitions/partition_mappers/fixed_key.py Outdated
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from 32010ec to 4f0edbdCompareJune 9, 2026 08:00
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from 4f0edbd to cffebd6CompareJune 9, 2026 13:53
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from cffebd6 to a2dd91fCompareJune 9, 2026 15:06
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 10, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 10, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from a2dd91f to ef80d9bCompareJune 10, 2026 00:22
Lee-W added 4 commits June 10, 2026 16:38
…entWindow
Express categorical asset-partition rollup by composing
RollupMapper(FixedKeyMapper(...), SegmentWindow(...)): FixedKeyMapper routes
every upstream segment event onto one downstream bucket, and SegmentWindow
declares the segment set the scheduler waits for. Categorical and temporal
rollups now share one composition model, and SegmentWindow also composes with
FanOutMapper for categorical scatter.
- Add FixedKeyMapper (collapse any upstream key onto a fixed downstream key)
and SegmentWindow (enumerate a fixed categorical segment set), on both the
SDK authoring side and the scheduler runtime side.
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from ef80d9b to 6f2a885CompareJune 10, 2026 08:39
@Lee-W
Lee-W merged commit f690474 into apache:mainJun 10, 2026
144 of 145 checks passed
@Lee-W
Lee-W deleted the asset-partition-segment branch June 10, 2026 10:06
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:APIAirflow's REST/HTTP APIarea:ConfigTemplatesarea:DAG-processingarea:db-migrationsPRs with DB migrationarea:dev-toolsarea:Schedulerincluding HA (high availability) schedulerarea:task-sdkarea:translationsarea:UIRelated to UI/UX. For Frontend Developers.kind:documentationtranslation:defaulttranslation:zh-TW

Projects

No open projects

Development

Successfully merging this pull request may close these issues.

Segment-based (categorical) asset partitions for static sets — rollup (n-1) and fan-out (1-n)

4 participants

@Lee-W@uranusjr@phanikumv@eladkal
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add FixedKeyMapper and SegmentWindow for categorical asset-partition rollup by Lee-W · Pull Request #67716 · apache/airflow · GitHub
Skip to content

Add FixedKeyMapper and SegmentWindow for categorical asset-partition rollup - #67716

Merged
Lee-W merged 4 commits into
apache:mainfrom
astronomer:asset-partition-segment
Jun 10, 2026
Merged

Add FixedKeyMapper and SegmentWindow for categorical asset-partition rollup#67716
Lee-W merged 4 commits into
apache:mainfrom
astronomer:asset-partition-segment

Conversation

@Lee-W

@Lee-WLee-W commented May 29, 2026

Copy link
Copy Markdown
Member

Why

We already supports temporal asset-partition rollup by composing two primitives inside a RollupMapper: a mapper that routes upstream events to a downstream partition key (e.g. StartOfDayMapper) and a window that declares which upstream partitions must arrive before the downstream run is released (e.g. DayWindow). There was no equivalent for categorical rollup — folding a fixed set of named segments (such as us, eu, apac) into a single downstream run.

This PR adds the two primitives needed to express categorical rollup with the same composition model as the temporal family, rather than introducing a self-contained bespoke segment mapper:

RollupMapper(
upstream_mapper=FixedKeyMapper("all_regions"),
window=SegmentWindow(["us", "eu", "apac"]),
)
  • FixedKeyMapper handles forward routing: every incoming upstream segment event (us / eu / apac) is routed to one downstream partition key ("all_regions"), so all 3 accumulate into the same run.
  • SegmentWindow handles reverse gating: it declares the set of segments to wait for, and the scheduler releases the downstream run only once all of them have arrived (to_upstream + issubset).

Keeping the scheduler aware of only RollupMapper — and letting authors swap in different mapper/window pairs — means categorical and temporal rollup share one mental model instead of each shipping its own mapper.

The FixedKeyMapper downstream key is required and semantic (the example uses "all_regions") to avoid a silent default that would obscure where rolled-up events land.

SegmentWindow is also reusable as the gating side of a categorical scatter (1-to-n) when paired with the recently merged FanOutMapper.

What

Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Opus 4.8)

Generated-by: Claude Code (Opus 4.8) following the guidelines


  • 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.

@Lee-WLee-W changed the title AIP-76: Hold Dag run until all upstream partitions arriveAdd SegmentWindow and DynamicSegmentWindow for categorical asset partition rollupMay 29, 2026
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch 3 times, most recently from e7a47e8 to 943d3e1CompareMay 29, 2026 15:24
@Lee-WLee-W added this to the Airflow 3.3.0 milestone Jun 5, 2026
@Lee-WLee-W moved this to In Progress in AIP-76 Asset PartitioningJun 5, 2026
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch 7 times, most recently from ee72740 to d3bcb9fCompareJune 8, 2026 13:58
@Lee-WLee-W changed the title Add SegmentWindow and DynamicSegmentWindow for categorical asset partition rollupAdd FixedKeyMapper and SegmentWindow for categorical asset-partition rollupJun 8, 2026
@Lee-W
Lee-W marked this pull request as ready for review June 8, 2026 14:12
@Lee-W
Lee-W requested a review from ashb as a code ownerJune 8, 2026 14:12
Comment threadairflow-core/src/airflow/partition_mappers/window.py Outdated
Comment threadairflow-core/src/airflow/partition_mappers/window.py Outdated
Comment threadtask-sdk/src/airflow/sdk/definitions/partition_mappers/window.py Outdated
Comment threadtask-sdk/src/airflow/sdk/definitions/partition_mappers/fixed_key.py Outdated
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from 32010ec to 4f0edbdCompareJune 9, 2026 08:00
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from 4f0edbd to cffebd6CompareJune 9, 2026 13:53
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from cffebd6 to a2dd91fCompareJune 9, 2026 15:06
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 10, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 10, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from a2dd91f to ef80d9bCompareJune 10, 2026 00:22
Lee-W added 4 commits June 10, 2026 16:38
…entWindow
Express categorical asset-partition rollup by composing
RollupMapper(FixedKeyMapper(...), SegmentWindow(...)): FixedKeyMapper routes
every upstream segment event onto one downstream bucket, and SegmentWindow
declares the segment set the scheduler waits for. Categorical and temporal
rollups now share one composition model, and SegmentWindow also composes with
FanOutMapper for categorical scatter.
- Add FixedKeyMapper (collapse any upstream key onto a fixed downstream key)
and SegmentWindow (enumerate a fixed categorical segment set), on both the
SDK authoring side and the scheduler runtime side.
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from ef80d9b to 6f2a885CompareJune 10, 2026 08:39
@Lee-W
Lee-W merged commit f690474 into apache:mainJun 10, 2026
144 of 145 checks passed
@Lee-W
Lee-W deleted the asset-partition-segment branch June 10, 2026 10:06
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:APIAirflow's REST/HTTP APIarea:ConfigTemplatesarea:DAG-processingarea:db-migrationsPRs with DB migrationarea:dev-toolsarea:Schedulerincluding HA (high availability) schedulerarea:task-sdkarea:translationsarea:UIRelated to UI/UX. For Frontend Developers.kind:documentationtranslation:defaulttranslation:zh-TW

Projects

No open projects

Development

Successfully merging this pull request may close these issues.

Segment-based (categorical) asset partitions for static sets — rollup (n-1) and fan-out (1-n)

4 participants

@Lee-W@uranusjr@phanikumv@eladkal
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Add FixedKeyMapper and SegmentWindow for categorical asset-partition rollup by Lee-W · Pull Request #67716 · apache/airflow · GitHub
Skip to content

Add FixedKeyMapper and SegmentWindow for categorical asset-partition rollup - #67716

Merged
Lee-W merged 4 commits into
apache:mainfrom
astronomer:asset-partition-segment
Jun 10, 2026
Merged

Add FixedKeyMapper and SegmentWindow for categorical asset-partition rollup#67716
Lee-W merged 4 commits into
apache:mainfrom
astronomer:asset-partition-segment

Conversation

@Lee-W

@Lee-WLee-W commented May 29, 2026

Copy link
Copy Markdown
Member

Why

We already supports temporal asset-partition rollup by composing two primitives inside a RollupMapper: a mapper that routes upstream events to a downstream partition key (e.g. StartOfDayMapper) and a window that declares which upstream partitions must arrive before the downstream run is released (e.g. DayWindow). There was no equivalent for categorical rollup — folding a fixed set of named segments (such as us, eu, apac) into a single downstream run.

This PR adds the two primitives needed to express categorical rollup with the same composition model as the temporal family, rather than introducing a self-contained bespoke segment mapper:

RollupMapper(
upstream_mapper=FixedKeyMapper("all_regions"),
window=SegmentWindow(["us", "eu", "apac"]),
)
  • FixedKeyMapper handles forward routing: every incoming upstream segment event (us / eu / apac) is routed to one downstream partition key ("all_regions"), so all 3 accumulate into the same run.
  • SegmentWindow handles reverse gating: it declares the set of segments to wait for, and the scheduler releases the downstream run only once all of them have arrived (to_upstream + issubset).

Keeping the scheduler aware of only RollupMapper — and letting authors swap in different mapper/window pairs — means categorical and temporal rollup share one mental model instead of each shipping its own mapper.

The FixedKeyMapper downstream key is required and semantic (the example uses "all_regions") to avoid a silent default that would obscure where rolled-up events land.

SegmentWindow is also reusable as the gating side of a categorical scatter (1-to-n) when paired with the recently merged FanOutMapper.

What

Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Opus 4.8)

Generated-by: Claude Code (Opus 4.8) following the guidelines


  • 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.

@Lee-WLee-W changed the title AIP-76: Hold Dag run until all upstream partitions arriveAdd SegmentWindow and DynamicSegmentWindow for categorical asset partition rollupMay 29, 2026
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch 3 times, most recently from e7a47e8 to 943d3e1CompareMay 29, 2026 15:24
@Lee-WLee-W added this to the Airflow 3.3.0 milestone Jun 5, 2026
@Lee-WLee-W moved this to In Progress in AIP-76 Asset PartitioningJun 5, 2026
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch 7 times, most recently from ee72740 to d3bcb9fCompareJune 8, 2026 13:58
@Lee-WLee-W changed the title Add SegmentWindow and DynamicSegmentWindow for categorical asset partition rollupAdd FixedKeyMapper and SegmentWindow for categorical asset-partition rollupJun 8, 2026
@Lee-W
Lee-W marked this pull request as ready for review June 8, 2026 14:12
@Lee-W
Lee-W requested a review from ashb as a code ownerJune 8, 2026 14:12
Comment threadairflow-core/src/airflow/partition_mappers/window.py Outdated
Comment threadairflow-core/src/airflow/partition_mappers/window.py Outdated
Comment threadtask-sdk/src/airflow/sdk/definitions/partition_mappers/window.py Outdated
Comment threadtask-sdk/src/airflow/sdk/definitions/partition_mappers/fixed_key.py Outdated
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from 32010ec to 4f0edbdCompareJune 9, 2026 08:00
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from 4f0edbd to cffebd6CompareJune 9, 2026 13:53
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from cffebd6 to a2dd91fCompareJune 9, 2026 15:06
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 10, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 10, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from a2dd91f to ef80d9bCompareJune 10, 2026 00:22
Lee-W added 4 commits June 10, 2026 16:38
…entWindow
Express categorical asset-partition rollup by composing
RollupMapper(FixedKeyMapper(...), SegmentWindow(...)): FixedKeyMapper routes
every upstream segment event onto one downstream bucket, and SegmentWindow
declares the segment set the scheduler waits for. Categorical and temporal
rollups now share one composition model, and SegmentWindow also composes with
FanOutMapper for categorical scatter.
- Add FixedKeyMapper (collapse any upstream key onto a fixed downstream key)
and SegmentWindow (enumerate a fixed categorical segment set), on both the
SDK authoring side and the scheduler runtime side.
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from ef80d9b to 6f2a885CompareJune 10, 2026 08:39
@Lee-W
Lee-W merged commit f690474 into apache:mainJun 10, 2026
144 of 145 checks passed
@Lee-W
Lee-W deleted the asset-partition-segment branch June 10, 2026 10:06
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:APIAirflow's REST/HTTP APIarea:ConfigTemplatesarea:DAG-processingarea:db-migrationsPRs with DB migrationarea:dev-toolsarea:Schedulerincluding HA (high availability) schedulerarea:task-sdkarea:translationsarea:UIRelated to UI/UX. For Frontend Developers.kind:documentationtranslation:defaulttranslation:zh-TW

Projects

No open projects

Development

Successfully merging this pull request may close these issues.

Segment-based (categorical) asset partitions for static sets — rollup (n-1) and fan-out (1-n)

4 participants

@Lee-W@uranusjr@phanikumv@eladkal
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add FixedKeyMapper and SegmentWindow for categorical asset-partition rollup by Lee-W · Pull Request #67716 · apache/airflow · GitHub
Skip to content

Add FixedKeyMapper and SegmentWindow for categorical asset-partition rollup - #67716

Merged
Lee-W merged 4 commits into
apache:mainfrom
astronomer:asset-partition-segment
Jun 10, 2026
Merged

Add FixedKeyMapper and SegmentWindow for categorical asset-partition rollup#67716
Lee-W merged 4 commits into
apache:mainfrom
astronomer:asset-partition-segment

Conversation

@Lee-W

@Lee-WLee-W commented May 29, 2026

Copy link
Copy Markdown
Member

Why

We already supports temporal asset-partition rollup by composing two primitives inside a RollupMapper: a mapper that routes upstream events to a downstream partition key (e.g. StartOfDayMapper) and a window that declares which upstream partitions must arrive before the downstream run is released (e.g. DayWindow). There was no equivalent for categorical rollup — folding a fixed set of named segments (such as us, eu, apac) into a single downstream run.

This PR adds the two primitives needed to express categorical rollup with the same composition model as the temporal family, rather than introducing a self-contained bespoke segment mapper:

RollupMapper(
upstream_mapper=FixedKeyMapper("all_regions"),
window=SegmentWindow(["us", "eu", "apac"]),
)
  • FixedKeyMapper handles forward routing: every incoming upstream segment event (us / eu / apac) is routed to one downstream partition key ("all_regions"), so all 3 accumulate into the same run.
  • SegmentWindow handles reverse gating: it declares the set of segments to wait for, and the scheduler releases the downstream run only once all of them have arrived (to_upstream + issubset).

Keeping the scheduler aware of only RollupMapper — and letting authors swap in different mapper/window pairs — means categorical and temporal rollup share one mental model instead of each shipping its own mapper.

The FixedKeyMapper downstream key is required and semantic (the example uses "all_regions") to avoid a silent default that would obscure where rolled-up events land.

SegmentWindow is also reusable as the gating side of a categorical scatter (1-to-n) when paired with the recently merged FanOutMapper.

What

Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Opus 4.8)

Generated-by: Claude Code (Opus 4.8) following the guidelines


  • 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.

@Lee-WLee-W changed the title AIP-76: Hold Dag run until all upstream partitions arriveAdd SegmentWindow and DynamicSegmentWindow for categorical asset partition rollupMay 29, 2026
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch 3 times, most recently from e7a47e8 to 943d3e1CompareMay 29, 2026 15:24
@Lee-WLee-W added this to the Airflow 3.3.0 milestone Jun 5, 2026
@Lee-WLee-W moved this to In Progress in AIP-76 Asset PartitioningJun 5, 2026
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch 7 times, most recently from ee72740 to d3bcb9fCompareJune 8, 2026 13:58
@Lee-WLee-W changed the title Add SegmentWindow and DynamicSegmentWindow for categorical asset partition rollupAdd FixedKeyMapper and SegmentWindow for categorical asset-partition rollupJun 8, 2026
@Lee-W
Lee-W marked this pull request as ready for review June 8, 2026 14:12
@Lee-W
Lee-W requested a review from ashb as a code ownerJune 8, 2026 14:12
Comment threadairflow-core/src/airflow/partition_mappers/window.py Outdated
Comment threadairflow-core/src/airflow/partition_mappers/window.py Outdated
Comment threadtask-sdk/src/airflow/sdk/definitions/partition_mappers/window.py Outdated
Comment threadtask-sdk/src/airflow/sdk/definitions/partition_mappers/fixed_key.py Outdated
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from 32010ec to 4f0edbdCompareJune 9, 2026 08:00
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from 4f0edbd to cffebd6CompareJune 9, 2026 13:53
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from cffebd6 to a2dd91fCompareJune 9, 2026 15:06
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 10, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 10, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from a2dd91f to ef80d9bCompareJune 10, 2026 00:22
Lee-W added 4 commits June 10, 2026 16:38
…entWindow
Express categorical asset-partition rollup by composing
RollupMapper(FixedKeyMapper(...), SegmentWindow(...)): FixedKeyMapper routes
every upstream segment event onto one downstream bucket, and SegmentWindow
declares the segment set the scheduler waits for. Categorical and temporal
rollups now share one composition model, and SegmentWindow also composes with
FanOutMapper for categorical scatter.
- Add FixedKeyMapper (collapse any upstream key onto a fixed downstream key)
and SegmentWindow (enumerate a fixed categorical segment set), on both the
SDK authoring side and the scheduler runtime side.
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from ef80d9b to 6f2a885CompareJune 10, 2026 08:39
@Lee-W
Lee-W merged commit f690474 into apache:mainJun 10, 2026
144 of 145 checks passed
@Lee-W
Lee-W deleted the asset-partition-segment branch June 10, 2026 10:06
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:APIAirflow's REST/HTTP APIarea:ConfigTemplatesarea:DAG-processingarea:db-migrationsPRs with DB migrationarea:dev-toolsarea:Schedulerincluding HA (high availability) schedulerarea:task-sdkarea:translationsarea:UIRelated to UI/UX. For Frontend Developers.kind:documentationtranslation:defaulttranslation:zh-TW

Projects

No open projects

Development

Successfully merging this pull request may close these issues.

Segment-based (categorical) asset partitions for static sets — rollup (n-1) and fan-out (1-n)

4 participants

@Lee-W@uranusjr@phanikumv@eladkal
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add FixedKeyMapper and SegmentWindow for categorical asset-partition rollup by Lee-W · Pull Request #67716 · apache/airflow · GitHub
Skip to content

Add FixedKeyMapper and SegmentWindow for categorical asset-partition rollup - #67716

Merged
Lee-W merged 4 commits into
apache:mainfrom
astronomer:asset-partition-segment
Jun 10, 2026
Merged

Add FixedKeyMapper and SegmentWindow for categorical asset-partition rollup#67716
Lee-W merged 4 commits into
apache:mainfrom
astronomer:asset-partition-segment

Conversation

@Lee-W

@Lee-WLee-W commented May 29, 2026

Copy link
Copy Markdown
Member

Why

We already supports temporal asset-partition rollup by composing two primitives inside a RollupMapper: a mapper that routes upstream events to a downstream partition key (e.g. StartOfDayMapper) and a window that declares which upstream partitions must arrive before the downstream run is released (e.g. DayWindow). There was no equivalent for categorical rollup — folding a fixed set of named segments (such as us, eu, apac) into a single downstream run.

This PR adds the two primitives needed to express categorical rollup with the same composition model as the temporal family, rather than introducing a self-contained bespoke segment mapper:

RollupMapper(
upstream_mapper=FixedKeyMapper("all_regions"),
window=SegmentWindow(["us", "eu", "apac"]),
)
  • FixedKeyMapper handles forward routing: every incoming upstream segment event (us / eu / apac) is routed to one downstream partition key ("all_regions"), so all 3 accumulate into the same run.
  • SegmentWindow handles reverse gating: it declares the set of segments to wait for, and the scheduler releases the downstream run only once all of them have arrived (to_upstream + issubset).

Keeping the scheduler aware of only RollupMapper — and letting authors swap in different mapper/window pairs — means categorical and temporal rollup share one mental model instead of each shipping its own mapper.

The FixedKeyMapper downstream key is required and semantic (the example uses "all_regions") to avoid a silent default that would obscure where rolled-up events land.

SegmentWindow is also reusable as the gating side of a categorical scatter (1-to-n) when paired with the recently merged FanOutMapper.

What

Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Opus 4.8)

Generated-by: Claude Code (Opus 4.8) following the guidelines


  • 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.

@Lee-WLee-W changed the title AIP-76: Hold Dag run until all upstream partitions arriveAdd SegmentWindow and DynamicSegmentWindow for categorical asset partition rollupMay 29, 2026
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch 3 times, most recently from e7a47e8 to 943d3e1CompareMay 29, 2026 15:24
@Lee-WLee-W added this to the Airflow 3.3.0 milestone Jun 5, 2026
@Lee-WLee-W moved this to In Progress in AIP-76 Asset PartitioningJun 5, 2026
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch 7 times, most recently from ee72740 to d3bcb9fCompareJune 8, 2026 13:58
@Lee-WLee-W changed the title Add SegmentWindow and DynamicSegmentWindow for categorical asset partition rollupAdd FixedKeyMapper and SegmentWindow for categorical asset-partition rollupJun 8, 2026
@Lee-W
Lee-W marked this pull request as ready for review June 8, 2026 14:12
@Lee-W
Lee-W requested a review from ashb as a code ownerJune 8, 2026 14:12
Comment threadairflow-core/src/airflow/partition_mappers/window.py Outdated
Comment threadairflow-core/src/airflow/partition_mappers/window.py Outdated
Comment threadtask-sdk/src/airflow/sdk/definitions/partition_mappers/window.py Outdated
Comment threadtask-sdk/src/airflow/sdk/definitions/partition_mappers/fixed_key.py Outdated
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from 32010ec to 4f0edbdCompareJune 9, 2026 08:00
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from 4f0edbd to cffebd6CompareJune 9, 2026 13:53
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from cffebd6 to a2dd91fCompareJune 9, 2026 15:06
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 10, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 10, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from a2dd91f to ef80d9bCompareJune 10, 2026 00:22
Lee-W added 4 commits June 10, 2026 16:38
…entWindow
Express categorical asset-partition rollup by composing
RollupMapper(FixedKeyMapper(...), SegmentWindow(...)): FixedKeyMapper routes
every upstream segment event onto one downstream bucket, and SegmentWindow
declares the segment set the scheduler waits for. Categorical and temporal
rollups now share one composition model, and SegmentWindow also composes with
FanOutMapper for categorical scatter.
- Add FixedKeyMapper (collapse any upstream key onto a fixed downstream key)
and SegmentWindow (enumerate a fixed categorical segment set), on both the
SDK authoring side and the scheduler runtime side.
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from ef80d9b to 6f2a885CompareJune 10, 2026 08:39
@Lee-W
Lee-W merged commit f690474 into apache:mainJun 10, 2026
144 of 145 checks passed
@Lee-W
Lee-W deleted the asset-partition-segment branch June 10, 2026 10:06
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:APIAirflow's REST/HTTP APIarea:ConfigTemplatesarea:DAG-processingarea:db-migrationsPRs with DB migrationarea:dev-toolsarea:Schedulerincluding HA (high availability) schedulerarea:task-sdkarea:translationsarea:UIRelated to UI/UX. For Frontend Developers.kind:documentationtranslation:defaulttranslation:zh-TW

Projects

No open projects

Development

Successfully merging this pull request may close these issues.

Segment-based (categorical) asset partitions for static sets — rollup (n-1) and fan-out (1-n)

4 participants

@Lee-W@uranusjr@phanikumv@eladkal
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Add FixedKeyMapper and SegmentWindow for categorical asset-partition rollup by Lee-W · Pull Request #67716 · apache/airflow · GitHub
Skip to content

Add FixedKeyMapper and SegmentWindow for categorical asset-partition rollup - #67716

Merged
Lee-W merged 4 commits into
apache:mainfrom
astronomer:asset-partition-segment
Jun 10, 2026
Merged

Add FixedKeyMapper and SegmentWindow for categorical asset-partition rollup#67716
Lee-W merged 4 commits into
apache:mainfrom
astronomer:asset-partition-segment

Conversation

@Lee-W

@Lee-WLee-W commented May 29, 2026

Copy link
Copy Markdown
Member

Why

We already supports temporal asset-partition rollup by composing two primitives inside a RollupMapper: a mapper that routes upstream events to a downstream partition key (e.g. StartOfDayMapper) and a window that declares which upstream partitions must arrive before the downstream run is released (e.g. DayWindow). There was no equivalent for categorical rollup — folding a fixed set of named segments (such as us, eu, apac) into a single downstream run.

This PR adds the two primitives needed to express categorical rollup with the same composition model as the temporal family, rather than introducing a self-contained bespoke segment mapper:

RollupMapper(
upstream_mapper=FixedKeyMapper("all_regions"),
window=SegmentWindow(["us", "eu", "apac"]),
)
  • FixedKeyMapper handles forward routing: every incoming upstream segment event (us / eu / apac) is routed to one downstream partition key ("all_regions"), so all 3 accumulate into the same run.
  • SegmentWindow handles reverse gating: it declares the set of segments to wait for, and the scheduler releases the downstream run only once all of them have arrived (to_upstream + issubset).

Keeping the scheduler aware of only RollupMapper — and letting authors swap in different mapper/window pairs — means categorical and temporal rollup share one mental model instead of each shipping its own mapper.

The FixedKeyMapper downstream key is required and semantic (the example uses "all_regions") to avoid a silent default that would obscure where rolled-up events land.

SegmentWindow is also reusable as the gating side of a categorical scatter (1-to-n) when paired with the recently merged FanOutMapper.

What

Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Opus 4.8)

Generated-by: Claude Code (Opus 4.8) following the guidelines


  • 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.

@Lee-WLee-W changed the title AIP-76: Hold Dag run until all upstream partitions arriveAdd SegmentWindow and DynamicSegmentWindow for categorical asset partition rollupMay 29, 2026
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch 3 times, most recently from e7a47e8 to 943d3e1CompareMay 29, 2026 15:24
@Lee-WLee-W added this to the Airflow 3.3.0 milestone Jun 5, 2026
@Lee-WLee-W moved this to In Progress in AIP-76 Asset PartitioningJun 5, 2026
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch 7 times, most recently from ee72740 to d3bcb9fCompareJune 8, 2026 13:58
@Lee-WLee-W changed the title Add SegmentWindow and DynamicSegmentWindow for categorical asset partition rollupAdd FixedKeyMapper and SegmentWindow for categorical asset-partition rollupJun 8, 2026
@Lee-W
Lee-W marked this pull request as ready for review June 8, 2026 14:12
@Lee-W
Lee-W requested a review from ashb as a code ownerJune 8, 2026 14:12
Comment threadairflow-core/src/airflow/partition_mappers/window.py Outdated
Comment threadairflow-core/src/airflow/partition_mappers/window.py Outdated
Comment threadtask-sdk/src/airflow/sdk/definitions/partition_mappers/window.py Outdated
Comment threadtask-sdk/src/airflow/sdk/definitions/partition_mappers/fixed_key.py Outdated
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from 32010ec to 4f0edbdCompareJune 9, 2026 08:00
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from 4f0edbd to cffebd6CompareJune 9, 2026 13:53
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 9, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from cffebd6 to a2dd91fCompareJune 9, 2026 15:06
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 10, 2026
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
Lee-W added a commit to astronomer/airflow that referenced this pull request Jun 10, 2026
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from a2dd91f to ef80d9bCompareJune 10, 2026 00:22
Lee-W added 4 commits June 10, 2026 16:38
…entWindow
Express categorical asset-partition rollup by composing
RollupMapper(FixedKeyMapper(...), SegmentWindow(...)): FixedKeyMapper routes
every upstream segment event onto one downstream bucket, and SegmentWindow
declares the segment set the scheduler waits for. Categorical and temporal
rollups now share one composition model, and SegmentWindow also composes with
FanOutMapper for categorical scatter.
- Add FixedKeyMapper (collapse any upstream key onto a fixed downstream key)
and SegmentWindow (enumerate a fixed categorical segment set), on both the
SDK authoring side and the scheduler runtime side.
…edundant copy
- to_upstream returns the stored frozenset directly instead of re-wrapping it
- validate segments through a generator into frozenset, checking emptiness after the cast
- reword empty-segment error to 'must be non-empty'
Addresses review on PR apache#67716; SDK-side parity tracked in the follow-up commit.
… attrs and guard core↔SDK message drift
- core and SDK SegmentWindow/FixedKeyMapper now use @attrs.define with custom validators, preserving the same error messages and the _segments/downstream_key attribute names serialization relies on
- align the SDK empty-segment error wording with core ("must be non-empty")
- extend check-partition-mapper-defaults-in-sync to compare each class's field names and raise-message templates across core and SDK (following attrs converter functions), so validation drift fails CI
Addresses review on PR apache#67716.
@Lee-W
Lee-Wforce-pushed the asset-partition-segment branch from ef80d9b to 6f2a885CompareJune 10, 2026 08:39
@Lee-W
Lee-W merged commit f690474 into apache:mainJun 10, 2026
144 of 145 checks passed
@Lee-W
Lee-W deleted the asset-partition-segment branch June 10, 2026 10:06
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:APIAirflow's REST/HTTP APIarea:ConfigTemplatesarea:DAG-processingarea:db-migrationsPRs with DB migrationarea:dev-toolsarea:Schedulerincluding HA (high availability) schedulerarea:task-sdkarea:translationsarea:UIRelated to UI/UX. For Frontend Developers.kind:documentationtranslation:defaulttranslation:zh-TW

Projects

No open projects

Development

Successfully merging this pull request may close these issues.

Segment-based (categorical) asset partitions for static sets — rollup (n-1) and fan-out (1-n)

4 participants

@Lee-W@uranusjr@phanikumv@eladkal