feat(workflow): align history propagation API with go-sdk#1047
feat(workflow): align history propagation API with go-sdk#1047nelson-parente wants to merge 2 commits into
Conversation
Cassie (durabletask-go author) flagged divergence between python-sdk dapr#1025 and the freshly-renamed go-sdk helpers in durabletask-go dapr#105 (merged 2026-05-19, after dapr#1025 landed). This brings python-sdk's surface back in line for cross-SDK parity before 1.18 ships. Read API renames (mirror durabletask-go GetLast*ByName): - PropagatedHistory.get_workflow_by_name -> get_last_workflow_by_name - WorkflowResult.get_activity_by_name -> get_last_activity_by_name - WorkflowResult.get_child_workflow_by_name -> get_last_child_workflow_by_name Plural variants (get_workflows_by_name, get_activities_by_name, get_child_workflows_by_name) and the chain-level helpers are unchanged. Scheduling helpers (mirror go-sdk workflow.PropagateLineage / workflow.PropagateOwnHistory): - propagate_lineage() -> PropagationScope.LINEAGE - propagate_own_history() -> PropagationScope.OWN_HISTORY PropagationScope enum is kept as the underlying value, so both `propagation=propagate_lineage()` and `propagation=PropagationScope.LINEAGE` work. Example, README snippet, and tests updated to use the renamed/new surface. No runtime/proto changes. Refs: dapr#1001, dapr/durabletask-go#105, dapr/go-sdk#823 Signed-off-by: Nelson Parente <nelson_parente@live.com.pt>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1047 +/- ##
==========================================
- Coverage 86.63% 82.46% -4.17%
==========================================
Files 84 146 +62
Lines 4473 14501 +10028
==========================================
+ Hits 3875 11958 +8083
- Misses 598 2543 +1945 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
seherv
left a comment
There was a problem hiding this comment.
Thanks for opening the PR! Left you one comment
PD: I agree with keeping it as propagation=
| - `propagation=propagate_own_history()` on a child workflow call — | ||
| forwards the caller's events only. | ||
| - `propagation=PropagationScope.LINEAGE` on an activity call — forwards the | ||
| - `propagation=propagate_lineage()` on an activity call — forwards the | ||
| caller's events *plus* anything the caller itself received from its parent. |
There was a problem hiding this comment.
The way this is implemented would work fine, but IMO this is not idiomatic Python.
It also obscures things a bit (and might even mess with type checkers) because the return type of these functions only tells us that propagation=OwnHistory|Lineage, while the plain enum value tells us exactly what the value is without a doubt.
If I understand correctly, this is the way Go makes up for a lack of enums and is not a pattern we should apply in Python.
There was a problem hiding this comment.
ty! Let me work around this feedback!
…ories Per review feedback, Go-style factory helpers are not idiomatic Python: they obscure the actual enum value at the call site and confuse static type checkers (return annotation only shows PropagationScope, not the specific member). Use PropagationScope.LINEAGE / PropagationScope.OWN_HISTORY directly instead. Signed-off-by: Nelson Parente <nelson_parente@live.com.pt>
Cassie (durabletask-go author) flagged the .NET surface for cross-SDK divergence post-merge of dotnet-sdk#1802 / #1818. This rewrites the public history-propagation API to match the go-sdk shape — same one the python-sdk just adopted (python-sdk#1047). Issue dotnet-sdk#1801 was closed before her review; this PR delivers what the issue originally described. Three concrete gaps closed: 1. Activity-level opt-in (was missing entirely) - PropagationScope moved from ChildWorkflowTaskOptions to base WorkflowTaskOptions; ChildWorkflowTaskOptions inherits it. - WithHistoryPropagation() extension method added on the base record. - scheduleTaskAction.HistoryPropagationScope is now wired in WorkflowOrchestrationContext.CallActivityInternalAsync so activities can opt into propagation, matching CallChildWorkflowInternalAsync. - Without this, the Go SDK's reference example (SettlePayment activity using PropagateOwnHistory) literally cannot be ported to .NET. 2. Read API rewritten as high-level resolvers (was lossy FilterBy* + a PropagatedHistoryEvent record that dropped input/output/failure payloads) - PropagatedHistory.FilterByAppId/InstanceId/WorkflowName removed. - PropagatedHistory now exposes GetWorkflows(), GetWorkflowsByName(), GetLastWorkflowByName(), GetAppIds(), GetWorkflowsByAppId(), GetWorkflowsByInstanceId(). - New WorkflowResult class with InstanceId/AppId/Name plus GetActivitiesByName(), GetLastActivityByName(), GetChildWorkflowsByName(), GetLastChildWorkflowByName() — mirrors durabletask-go's GetLastWorkflowByName / GetLastActivityByName / GetLastChildWorkflowByName renames from durabletask-go#105. - New ActivityResult record carries Name, Started, Completed, Failed, Input, Output, FailureDetails — matching the Go/Python equivalents so chain-of-custody patterns line up. - New ChildWorkflowResult record with the equivalent shape. 3. Event payload preserved internally (was discarded by ConvertChunk) - ConvertChunk in WorkflowOrchestrationContext now parses raw events, walks them to resolve TaskScheduled <-> TaskCompleted/Failed and ChildWorkflowInstanceCreated <-> ChildWorkflowInstanceCompleted/ Failed by scheduleId, and produces fully-populated ActivityResult / ChildWorkflowResult instances. SDK retries reuse TaskExecutionId so matching is on scheduleId (matching Go/Python semantics). - Public API does not leak the proto HistoryEvent type — resolution happens at construction time inside Dapr.Workflow. Additional surface additions: - PropagationNotFoundException for missing-name lookups (mirrors Python's PropagationNotFoundError / Go's error returns). - Static WorkflowHistory.PropagateLineage() / PropagateOwnHistory() factory helpers for go-sdk call-site parity. Removed (clean break — 1.18 unreleased): PropagatedHistoryEntry, PropagatedHistoryEvent, HistoryEventKind, FilterByAppId, FilterByInstanceId, FilterByWorkflowName. Tests: - WorkflowHistoryPropagationTests.cs rewritten end-to-end to cover the new resolvers, query helpers, factory helpers, activity-level scope wiring, and child-workflow-level scope wiring. - HistoryPropagationWorkflowTests.cs (integration) updated to use GetWorkflows().Count in place of Entries.Count. Refs: #1801, dapr/durabletask-go#105, dapr/go-sdk#823, dapr/python-sdk#1047 Signed-off-by: Nelson Parente <nelson_parente@live.com.pt> Co-authored-by: nelson-parente <20144601+nelson-parente@users.noreply.github.com>
Summary
Aligns the workflow history propagation surface added in #1025 with the freshly-renamed go-sdk helpers (durabletask-go#105, merged 2026-05-19). That rename landed four days after #1025 merged, so this is drift, not a defect — Cassie flagged it post-merge while building the cross-SDK quickstarts.
This brings python-sdk back in line for cross-SDK parity before 1.18 ships.
Read API renames
Mirror durabletask-go's
GetLast*ByNameform to make it obvious these return the most-recent occurrence (with pluralget_*s_by_namesiblings for the full list):PropagatedHistory.get_workflow_by_nameget_last_workflow_by_nameWorkflowResult.get_activity_by_nameget_last_activity_by_nameWorkflowResult.get_child_workflow_by_nameget_last_child_workflow_by_namePlural variants (
get_workflows_by_name,get_activities_by_name,get_child_workflows_by_name) and chain-level helpers (get_app_ids,get_events_by_*) are unchanged.Scheduling — use the enum directly
The propagation scope is passed via the existing
propagation=kwarg, usingPropagationScopemembers:Non-goals
propagation=). Renaming towith_history_propagation=would mirror go-sdk'sWithHistoryPropagation()more literally but isn't idiomatic Python.Test plan
uv run ruff check --fix && uv run ruff format— cleanuv run pytest ext/dapr-ext-workflow/tests/durabletask/test_propagation.py ext/dapr-ext-workflow/tests/durabletask/test_propagation_wiring.py— 29 passeduv run python -m unittest discover -v ./ext/dapr-ext-workflow/tests— 133 passeduv run pytest tests/examples/test_workflow.py::test_history_propagationagainst a 1.18-RC sidecar (output-based test; print statements unchanged, should still pass)References
cc @cicoyle @acroca