Skip to content

Commit 1bf8160

Browse files
committed
💥 Update activity and workflow config objects. Change execute_child_workflow summary argument to static_summary (#1019)
* Update api configs and add tests * Consolidate to static_summary and static_details on child workflows * Cleanup * Import cleanup * Fix ordering
1 parent 174de10 commit 1bf8160

File tree

2 files changed

+127
-7
lines changed

2 files changed

+127
-7
lines changed

temporalio/workflow.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2027,6 +2027,8 @@ class ActivityConfig(TypedDict, total=False):
20272027
cancellation_type: ActivityCancellationType
20282028
activity_id: Optional[str]
20292029
versioning_intent: Optional[VersioningIntent]
2030+
summary: Optional[str]
2031+
priority: temporalio.common.Priority
20302032

20312033

20322034
# Overload for async no-param activity
@@ -2043,6 +2045,7 @@ def start_activity(
20432045
cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL,
20442046
activity_id: Optional[str] = None,
20452047
versioning_intent: Optional[VersioningIntent] = None,
2048+
summary: Optional[str] = None,
20462049
priority: temporalio.common.Priority = temporalio.common.Priority.default,
20472050
) -> ActivityHandle[ReturnType]: ...
20482051

@@ -2061,6 +2064,7 @@ def start_activity(
20612064
cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL,
20622065
activity_id: Optional[str] = None,
20632066
versioning_intent: Optional[VersioningIntent] = None,
2067+
summary: Optional[str] = None,
20642068
priority: temporalio.common.Priority = temporalio.common.Priority.default,
20652069
) -> ActivityHandle[ReturnType]: ...
20662070

@@ -2080,6 +2084,7 @@ def start_activity(
20802084
cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL,
20812085
activity_id: Optional[str] = None,
20822086
versioning_intent: Optional[VersioningIntent] = None,
2087+
summary: Optional[str] = None,
20832088
priority: temporalio.common.Priority = temporalio.common.Priority.default,
20842089
) -> ActivityHandle[ReturnType]: ...
20852090

@@ -2099,6 +2104,7 @@ def start_activity(
20992104
cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL,
21002105
activity_id: Optional[str] = None,
21012106
versioning_intent: Optional[VersioningIntent] = None,
2107+
summary: Optional[str] = None,
21022108
priority: temporalio.common.Priority = temporalio.common.Priority.default,
21032109
) -> ActivityHandle[ReturnType]: ...
21042110

@@ -2118,6 +2124,7 @@ def start_activity(
21182124
cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL,
21192125
activity_id: Optional[str] = None,
21202126
versioning_intent: Optional[VersioningIntent] = None,
2127+
summary: Optional[str] = None,
21212128
priority: temporalio.common.Priority = temporalio.common.Priority.default,
21222129
) -> ActivityHandle[ReturnType]: ...
21232130

@@ -2137,6 +2144,7 @@ def start_activity(
21372144
cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL,
21382145
activity_id: Optional[str] = None,
21392146
versioning_intent: Optional[VersioningIntent] = None,
2147+
summary: Optional[str] = None,
21402148
priority: temporalio.common.Priority = temporalio.common.Priority.default,
21412149
) -> ActivityHandle[ReturnType]: ...
21422150

@@ -2158,6 +2166,7 @@ def start_activity(
21582166
cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL,
21592167
activity_id: Optional[str] = None,
21602168
versioning_intent: Optional[VersioningIntent] = None,
2169+
summary: Optional[str] = None,
21612170
priority: temporalio.common.Priority = temporalio.common.Priority.default,
21622171
) -> ActivityHandle[Any]: ...
21632172

@@ -2234,6 +2243,7 @@ def start_activity(
22342243
activity_id=activity_id,
22352244
versioning_intent=versioning_intent,
22362245
summary=summary,
2246+
priority=priority,
22372247
)
22382248

22392249

@@ -4006,6 +4016,10 @@ class ChildWorkflowConfig(TypedDict, total=False):
40064016
temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes
40074017
]
40084018
]
4019+
versioning_intent: Optional[VersioningIntent]
4020+
static_summary: Optional[str]
4021+
static_details: Optional[str]
4022+
priority: temporalio.common.Priority
40094023

40104024

40114025
# Overload for no-param workflow
@@ -4238,7 +4252,8 @@ async def execute_child_workflow(
42384252
]
42394253
] = None,
42404254
versioning_intent: Optional[VersioningIntent] = None,
4241-
summary: Optional[str] = None,
4255+
static_summary: Optional[str] = None,
4256+
static_details: Optional[str] = None,
42424257
priority: temporalio.common.Priority = temporalio.common.Priority.default,
42434258
) -> ReturnType: ...
42444259

@@ -4266,7 +4281,8 @@ async def execute_child_workflow(
42664281
]
42674282
] = None,
42684283
versioning_intent: Optional[VersioningIntent] = None,
4269-
summary: Optional[str] = None,
4284+
static_summary: Optional[str] = None,
4285+
static_details: Optional[str] = None,
42704286
priority: temporalio.common.Priority = temporalio.common.Priority.default,
42714287
) -> ReturnType: ...
42724288

@@ -4294,7 +4310,8 @@ async def execute_child_workflow(
42944310
]
42954311
] = None,
42964312
versioning_intent: Optional[VersioningIntent] = None,
4297-
summary: Optional[str] = None,
4313+
static_summary: Optional[str] = None,
4314+
static_details: Optional[str] = None,
42984315
priority: temporalio.common.Priority = temporalio.common.Priority.default,
42994316
) -> ReturnType: ...
43004317

@@ -4324,7 +4341,8 @@ async def execute_child_workflow(
43244341
]
43254342
] = None,
43264343
versioning_intent: Optional[VersioningIntent] = None,
4327-
summary: Optional[str] = None,
4344+
static_summary: Optional[str] = None,
4345+
static_details: Optional[str] = None,
43284346
priority: temporalio.common.Priority = temporalio.common.Priority.default,
43294347
) -> Any: ...
43304348

@@ -4352,7 +4370,8 @@ async def execute_child_workflow(
43524370
]
43534371
] = None,
43544372
versioning_intent: Optional[VersioningIntent] = None,
4355-
summary: Optional[str] = None,
4373+
static_summary: Optional[str] = None,
4374+
static_details: Optional[str] = None,
43564375
priority: temporalio.common.Priority = temporalio.common.Priority.default,
43574376
) -> Any:
43584377
"""Start a child workflow and wait for completion.
@@ -4379,7 +4398,8 @@ async def execute_child_workflow(
43794398
memo=memo,
43804399
search_attributes=search_attributes,
43814400
versioning_intent=versioning_intent,
4382-
static_summary=summary,
4401+
static_summary=static_summary,
4402+
static_details=static_details,
43834403
priority=priority,
43844404
)
43854405
return await handle

tests/test_workflow.py

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import inspect
22
import itertools
3-
from typing import Sequence
3+
from typing import Any, Callable, Sequence, Set, Type, get_type_hints
44

55
from temporalio import workflow
66
from temporalio.common import RawValue, VersioningBehavior
@@ -469,3 +469,103 @@ def test_workflow_update_validator_not_update():
469469
"Update validator method my_validator parameters do not match update method my_update parameters"
470470
in str(err.value)
471471
)
472+
473+
474+
def _assert_config_function_parity(
475+
function_obj: Callable[..., Any],
476+
config_class: Type[Any],
477+
excluded_params: Set[str],
478+
) -> None:
479+
function_name = function_obj.__name__
480+
config_name = config_class.__name__
481+
482+
# Get the signature and type hints
483+
function_sig = inspect.signature(function_obj)
484+
config_hints = get_type_hints(config_class)
485+
486+
# Get parameter names from function (excluding excluded ones and applying mappings)
487+
expected_config_params = set(
488+
[name for name in function_sig.parameters.keys() if name not in excluded_params]
489+
)
490+
491+
# Get parameter names from config
492+
actual_config_params = set(
493+
[name for name in config_hints.keys() if name not in excluded_params]
494+
)
495+
496+
# Check for missing and extra parameters
497+
missing_in_config = expected_config_params - actual_config_params
498+
extra_in_config = actual_config_params - expected_config_params
499+
500+
# Build detailed error message if there are mismatches
501+
if missing_in_config or extra_in_config:
502+
error_parts = []
503+
if missing_in_config:
504+
error_parts.append(
505+
f"{config_name} is missing parameters: {sorted(missing_in_config)}"
506+
)
507+
if extra_in_config:
508+
error_parts.append(
509+
f"{config_name} has extra parameters: {sorted(extra_in_config)}"
510+
)
511+
512+
error_message = "; ".join(error_parts)
513+
error_message += f"\nExpected: {sorted(expected_config_params)}\nActual: {sorted(actual_config_params)}"
514+
assert False, error_message
515+
516+
517+
async def test_activity_config_parity_with_execute_activity():
518+
"""Test that ActivityConfig has all the same parameters as execute_activity."""
519+
_assert_config_function_parity(
520+
workflow.execute_activity,
521+
workflow.ActivityConfig,
522+
excluded_params={"activity", "arg", "args", "result_type"},
523+
)
524+
525+
with pytest.raises(workflow._NotInWorkflowEventLoopError):
526+
await workflow.execute_activity("activity", **workflow.ActivityConfig())
527+
528+
529+
def test_activity_config_parity_with_start_activity():
530+
"""Test that ActivityConfig has all the same parameters as start_activity."""
531+
_assert_config_function_parity(
532+
workflow.start_activity,
533+
workflow.ActivityConfig,
534+
excluded_params={"activity", "arg", "args", "result_type"},
535+
)
536+
537+
with pytest.raises(workflow._NotInWorkflowEventLoopError):
538+
workflow.start_activity("workflow", **workflow.ActivityConfig())
539+
540+
541+
async def test_child_workflow_config_parity_with_execute_child_workflow():
542+
"""Test that ChildWorkflowConfig has all the same parameters as execute_child_workflow."""
543+
_assert_config_function_parity(
544+
workflow.execute_child_workflow,
545+
workflow.ChildWorkflowConfig,
546+
excluded_params={"workflow", "arg", "args", "result_type"},
547+
)
548+
549+
with pytest.raises(workflow._NotInWorkflowEventLoopError):
550+
await workflow.execute_child_workflow(
551+
"workflow", **workflow.ChildWorkflowConfig()
552+
)
553+
554+
555+
async def test_child_workflow_config_parity_with_start_child_workflow():
556+
"""Test that ChildWorkflowConfig has all the same parameters as start_child_workflow."""
557+
_assert_config_function_parity(
558+
workflow.start_child_workflow,
559+
workflow.ChildWorkflowConfig,
560+
excluded_params={
561+
"workflow",
562+
"arg",
563+
"args",
564+
"result_type",
565+
},
566+
)
567+
568+
with pytest.raises(workflow._NotInWorkflowEventLoopError):
569+
await workflow.start_child_workflow(
570+
"workflow", **workflow.ChildWorkflowConfig()
571+
)

0 commit comments

Comments
 (0)