Skip to content

Commit 256331b

Browse files
committed
Add pyright type-checking to examples, fix discoveries
1 parent 0401859 commit 256331b

17 files changed

Lines changed: 90 additions & 51 deletions

File tree

examples/activity_sequence.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
that calls an activity function in a sequence and prints the outputs."""
33
import logging
44
import os
5+
from collections.abc import Generator
6+
from typing import Any
57

68
from azure.identity import DefaultAzureCredential
79

@@ -17,7 +19,7 @@ def hello(ctx: task.ActivityContext, name: str) -> str:
1719
return f'Hello {name}!'
1820

1921

20-
def sequence(ctx: task.OrchestrationContext, _):
22+
def sequence(ctx: task.OrchestrationContext, _: Any) -> Generator[task.Task[Any], Any, list[str]]:
2123
"""Orchestrator function that calls the 'hello' activity function in a sequence"""
2224
# Create a replay-safe logger to avoid duplicate log messages during replay
2325
replay_logger = ctx.create_replay_safe_logger(logger)

examples/distributed-tracing/app.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616

1717
import os
1818
import time
19+
from collections.abc import Generator
1920
from datetime import timedelta
21+
from typing import Any
2022

2123
from opentelemetry import trace
2224
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
@@ -64,7 +66,7 @@ def get_weather(ctx: task.ActivityContext, city: str) -> str:
6466
return result
6567

6668

67-
def summarize(ctx: task.ActivityContext, reports: list) -> str:
69+
def summarize(ctx: task.ActivityContext, reports: list[str]) -> str:
6870
"""Combine individual weather reports into a summary string."""
6971
summary = " | ".join(reports)
7072
print(f" [Activity] summarize -> {summary}")
@@ -75,9 +77,9 @@ def summarize(ctx: task.ActivityContext, reports: list) -> str:
7577
# Sub-orchestration
7678
# ---------------------------------------------------------------------------
7779

78-
def collect_weather(ctx: task.OrchestrationContext, cities: list):
80+
def collect_weather(ctx: task.OrchestrationContext, cities: list[str]) -> Generator[task.Task[Any], Any, list[str]]:
7981
"""Sub-orchestration that collects weather for a list of cities."""
80-
results = []
82+
results: list[str] = []
8183
for city in cities:
8284
weather = yield ctx.call_activity(get_weather, input=city)
8385
results.append(f"{city}: {weather}")
@@ -88,7 +90,7 @@ def collect_weather(ctx: task.OrchestrationContext, cities: list):
8890
# Main orchestration
8991
# ---------------------------------------------------------------------------
9092

91-
def weather_report_orchestrator(ctx: task.OrchestrationContext, cities: list):
93+
def weather_report_orchestrator(ctx: task.OrchestrationContext, cities: list[str]) -> Generator[task.Task[Any], Any, str]:
9294
"""Top-level orchestration demonstrating timers, activities, and sub-orchestrations.
9395
9496
Flow:

examples/entities/class_based_entity.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"""End-to-end sample that demonstrates how to configure an orchestrator
22
that calls an activity function in a sequence and prints the outputs."""
33
import os
4+
from collections.abc import Generator
5+
from typing import Any
46

57
from azure.identity import DefaultAzureCredential
68

@@ -13,7 +15,7 @@ class Counter(entities.DurableEntity):
1315
def set(self, input: int):
1416
self.set_state(input)
1517

16-
def add(self, input: int):
18+
def add(self, input: int | None = None):
1719
current_state = self.get_state(int, 0)
1820
new_state = current_state + (1 if input is None else input)
1921
self.set_state(new_state)
@@ -23,7 +25,7 @@ def get(self):
2325
return self.get_state(int, 0)
2426

2527

26-
def counter_orchestrator(ctx: task.OrchestrationContext, _):
28+
def counter_orchestrator(ctx: task.OrchestrationContext, _: Any) -> Generator[task.Task[Any], Any, Any]:
2729
"""Orchestrator function that demonstrates the behavior of the counter entity"""
2830

2931
entity_id = task.EntityInstanceId("Counter", "myCounter")

examples/entities/class_based_entity_actions.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"""End-to-end sample that demonstrates how to configure an orchestrator
22
that calls an activity function in a sequence and prints the outputs."""
33
import os
4+
from collections.abc import Generator
5+
from typing import Any
46

57
from azure.identity import DefaultAzureCredential
68

@@ -13,7 +15,7 @@ class Counter(entities.DurableEntity):
1315
def set(self, input: int):
1416
self.set_state(input)
1517

16-
def add(self, input: int):
18+
def add(self, input: int | None = None):
1719
current_state = self.get_state(int, 0)
1820
new_state = current_state + (1 if input is None else input)
1921
self.set_state(new_state)
@@ -32,7 +34,7 @@ def get(self):
3234
return self.get_state(int, 0)
3335

3436

35-
def counter_orchestrator(ctx: task.OrchestrationContext, _):
37+
def counter_orchestrator(ctx: task.OrchestrationContext, _: Any) -> Generator[task.Task[Any], Any, Any]:
3638
"""Orchestrator function that demonstrates the behavior of the counter entity"""
3739

3840
entity_id = task.EntityInstanceId("Counter", "myCounter")
@@ -51,7 +53,7 @@ def counter_orchestrator(ctx: task.OrchestrationContext, _):
5153
return (yield ctx.call_entity(parent_entity_id, "get"))
5254

5355

54-
def hello_orchestrator(ctx: task.OrchestrationContext, _):
56+
def hello_orchestrator(ctx: task.OrchestrationContext, _: Any) -> str:
5557
return "Hello world!"
5658

5759

examples/entities/entity_locking.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"""End-to-end sample that demonstrates how to configure an orchestrator
22
that calls an activity function in a sequence and prints the outputs."""
33
import os
4+
from collections.abc import Generator
5+
from typing import Any
46

57
from azure.identity import DefaultAzureCredential
68

@@ -13,7 +15,7 @@ class Counter(entities.DurableEntity):
1315
def set(self, input: int):
1416
self.set_state(input)
1517

16-
def add(self, input: int):
18+
def add(self, input: int | None = None):
1719
current_state = self.get_state(int, 0)
1820
new_state = current_state + (1 if input is None else input)
1921
self.set_state(new_state)
@@ -23,7 +25,7 @@ def get(self):
2325
return self.get_state(int, 0)
2426

2527

26-
def counter_orchestrator(ctx: task.OrchestrationContext, _):
28+
def counter_orchestrator(ctx: task.OrchestrationContext, _: Any) -> Generator[task.Task[Any], Any, Any]:
2729
"""Orchestrator function that demonstrates the behavior of the counter entity"""
2830

2931
entity_id = entities.EntityInstanceId("Counter", "myCounter")

examples/entities/function_based_entity.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"""End-to-end sample that demonstrates how to configure an orchestrator
22
that calls an activity function in a sequence and prints the outputs."""
33
import os
4+
from collections.abc import Generator
5+
from typing import Any
46

57
from azure.identity import DefaultAzureCredential
68

@@ -9,7 +11,7 @@
911
from durabletask.azuremanaged.worker import DurableTaskSchedulerWorker
1012

1113

12-
def counter(ctx: entities.EntityContext, input: int) -> int | None:
14+
def counter(ctx: entities.EntityContext, input: int | None = None) -> int | None:
1315
if ctx.operation == "set":
1416
ctx.set_state(input)
1517
elif ctx.operation == "add":
@@ -23,7 +25,7 @@ def counter(ctx: entities.EntityContext, input: int) -> int | None:
2325
raise ValueError(f"Unknown operation '{ctx.operation}'")
2426

2527

26-
def counter_orchestrator(ctx: task.OrchestrationContext, _):
28+
def counter_orchestrator(ctx: task.OrchestrationContext, _: Any) -> Generator[task.Task[Any], Any, Any]:
2729
"""Orchestrator function that demonstrates the behavior of the counter entity"""
2830

2931
entity_id = entities.EntityInstanceId("counter", "myCounter")

examples/entities/function_based_entity_actions.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"""End-to-end sample that demonstrates how to configure an orchestrator
22
that calls an activity function in a sequence and prints the outputs."""
33
import os
4+
from collections.abc import Generator
5+
from typing import Any
46

57
from azure.identity import DefaultAzureCredential
68

@@ -9,7 +11,7 @@
911
from durabletask.azuremanaged.worker import DurableTaskSchedulerWorker
1012

1113

12-
def counter(ctx: entities.EntityContext, input: int) -> int | None:
14+
def counter(ctx: entities.EntityContext, input: int | None = None) -> int | None:
1315
if ctx.operation == "set":
1416
ctx.set_state(input)
1517
elif ctx.operation == "add":
@@ -30,7 +32,7 @@ def counter(ctx: entities.EntityContext, input: int) -> int | None:
3032
raise ValueError(f"Unknown operation '{ctx.operation}'")
3133

3234

33-
def counter_orchestrator(ctx: task.OrchestrationContext, _):
35+
def counter_orchestrator(ctx: task.OrchestrationContext, _: Any) -> Generator[task.Task[Any], Any, Any]:
3436
"""Orchestrator function that demonstrates the behavior of the counter entity"""
3537

3638
entity_id = task.EntityInstanceId("counter", "myCounter")
@@ -49,7 +51,7 @@ def counter_orchestrator(ctx: task.OrchestrationContext, _):
4951
return (yield ctx.call_entity(parent_entity_id, "get"))
5052

5153

52-
def hello_orchestrator(ctx: task.OrchestrationContext, _):
54+
def hello_orchestrator(ctx: task.OrchestrationContext, _: Any) -> str:
5355
return "Hello world!"
5456

5557

examples/fanout_fanin.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import os
55
import random
66
import time
7+
from collections.abc import Generator
8+
from typing import Any
79

810
from azure.identity import DefaultAzureCredential
911

@@ -12,7 +14,7 @@
1214
from durabletask.azuremanaged.worker import DurableTaskSchedulerWorker
1315

1416

15-
def get_work_items(ctx: task.ActivityContext, _) -> list[str]:
17+
def get_work_items(ctx: task.ActivityContext, _: Any) -> list[str]:
1618
"""Activity function that returns a list of work items"""
1719
# return a random number of work items
1820
count = random.randint(2, 10)
@@ -31,15 +33,15 @@ def process_work_item(ctx: task.ActivityContext, item: str) -> int:
3133
return random.randint(0, 10)
3234

3335

34-
def orchestrator(ctx: task.OrchestrationContext, _):
36+
def orchestrator(ctx: task.OrchestrationContext, _: Any) -> Generator[task.Task[Any], Any, dict[str, Any]]:
3537
"""Orchestrator function that calls the 'get_work_items' and 'process_work_item'
3638
activity functions in parallel, waits for them all to complete, and prints
3739
an aggregate summary of the outputs"""
3840

3941
work_items: list[str] = yield ctx.call_activity(get_work_items)
4042

4143
# execute the work-items in parallel and wait for them all to return
42-
tasks = [ctx.call_activity(process_work_item, input=item) for item in work_items]
44+
tasks: list[task.Task[int]] = [ctx.call_activity(process_work_item, input=item) for item in work_items]
4345
results: list[int] = yield task.when_all(tasks)
4446

4547
# return an aggregate summary of the results

examples/history_export/app.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919

2020
import os
2121
import time
22+
from collections.abc import Generator
2223
from datetime import datetime, timedelta, timezone
24+
from typing import Any
2325

2426
from durabletask import client, task, worker
2527
from durabletask.extensions.history_export import (
@@ -50,7 +52,7 @@ def square(_: task.ActivityContext, n: int) -> int:
5052
return n * n
5153

5254

53-
def sample_orchestrator(ctx: task.OrchestrationContext, n: int):
55+
def sample_orchestrator(ctx: task.OrchestrationContext, n: int) -> Generator[task.Task[Any], Any, int]:
5456
result = yield ctx.call_activity(square, input=n)
5557
return result
5658

examples/human_interaction.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
import os
77
import threading
88
import time
9-
from collections import namedtuple
9+
from collections.abc import Generator
1010
from dataclasses import dataclass
1111
from datetime import timedelta
12+
from typing import Any, NamedTuple
1213

1314
from azure.identity import DefaultAzureCredential
1415

@@ -17,6 +18,11 @@
1718
from durabletask.azuremanaged.worker import DurableTaskSchedulerWorker
1819

1920

21+
class Approval(NamedTuple):
22+
"""Represents an approval event payload"""
23+
approver: str
24+
25+
2026
@dataclass
2127
class Order:
2228
"""Represents a purchase order"""
@@ -39,7 +45,7 @@ def place_order(_: task.ActivityContext, order: Order) -> None:
3945
print(f'*** Placing order: {order}')
4046

4147

42-
def purchase_order_workflow(ctx: task.OrchestrationContext, order: Order):
48+
def purchase_order_workflow(ctx: task.OrchestrationContext, order: Order) -> Generator[task.Task[Any], Any, str]:
4349
"""Orchestrator function that represents a purchase order workflow"""
4450
# Orders under $1000 are auto-approved
4551
if order.Cost < 1000:
@@ -87,7 +93,7 @@ def purchase_order_workflow(ctx: task.OrchestrationContext, order: Order):
8793

8894
def prompt_for_approval():
8995
input("Press [ENTER] to approve the order...\n")
90-
approval_event = namedtuple("Approval", ["approver"])(args.approver)
96+
approval_event = Approval(args.approver)
9197
c.raise_orchestration_event(instance_id, "approval_received", data=approval_event)
9298

9399
# Prompt the user for approval on a background thread
@@ -133,7 +139,7 @@ def prompt_for_approval():
133139

134140
def prompt_for_approval():
135141
input("Press [ENTER] to approve the order...\n")
136-
approval_event = namedtuple("Approval", ["approver"])(args.approver)
142+
approval_event = Approval(args.approver)
137143
c.raise_orchestration_event(instance_id, "approval_received", data=approval_event)
138144

139145
# Prompt the user for approval on a background thread

0 commit comments

Comments
 (0)