Skip to content

Commit 3847fdb

Browse files
authored
fix(python): updated python examples to show correct usage of pass through for activities (#4131)
1 parent 96475d5 commit 3847fdb

4 files changed

Lines changed: 35 additions & 18 deletions

File tree

docs/develop/python/core-application.mdx

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ To return a value of the Workflow, use `return` to return an object.
119119

120120
To return the results of a Workflow Execution, use either `start_workflow()` or `execute_workflow()` asynchronous methods.
121121

122+
For performance and behavior reasons, users should pass through all modules, including Activities, Nexus services, and third-party plugins, whose calls will be deterministic using [`imports_passed_through`](https://python.temporal.io/temporalio.workflow.unsafe.html#imports_passed_through) or at Worker creation time by customizing the runner's restrictions with [`with_passthrough_modules`](https://python.temporal.io/temporalio.worker.workflow_sandbox.SandboxRestrictions.html#with_passthrough_modules).
123+
122124
<div className="copycode-notice-container">
123125
<a href="https://github.com/temporalio/documentation/blob/main/sample-apps/python/your_app/your_workflows_dacx.py">
124126
View the source code
@@ -128,7 +130,10 @@ To return the results of a Workflow Execution, use either `start_workflow()` or
128130

129131
```python
130132
from temporalio import workflow
131-
# ...
133+
134+
with workflow.unsafe.imports_passed_through():
135+
from your_activities_dacx import your_activity
136+
from your_dataobject_dacx import YourParams
132137
# ...
133138
@workflow.defn(name="YourWorkflow")
134139
class YourWorkflow:
@@ -160,7 +165,10 @@ You can customize the Workflow name with a custom name in the decorator argument
160165

161166
```python
162167
from temporalio import workflow
163-
# ...
168+
169+
with workflow.unsafe.imports_passed_through():
170+
from your_activities_dacx import your_activity
171+
from your_dataobject_dacx import YourParams
164172
# ...
165173
@workflow.defn(name="YourWorkflow")
166174
class YourWorkflow:
@@ -365,7 +373,10 @@ A single argument to the Activity is positional. Multiple arguments are not supp
365373

366374
```python
367375
from temporalio import workflow
368-
# ...
376+
377+
with workflow.unsafe.imports_passed_through():
378+
from your_activities_dacx import your_activity
379+
from your_dataobject_dacx import YourParams
369380
# ...
370381
@workflow.defn(name="YourWorkflow")
371382
class YourWorkflow:
@@ -435,7 +446,10 @@ You must provide either `schedule_to_close_timeout` or `start_to_close_timeout`.
435446

436447
```python
437448
from temporalio import workflow
438-
# ...
449+
450+
with workflow.unsafe.imports_passed_through():
451+
from your_activities_dacx import your_activity
452+
from your_dataobject_dacx import YourParams
439453
# ...
440454
@workflow.defn(name="YourWorkflow")
441455
class YourWorkflow:

docs/develop/python/failure-detection.mdx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,12 @@ You could do this in response to an Activity Failure, if the failure of that Act
112112

113113
```python
114114
try:
115-
credit_card_confirmation = await workflow.execute_activity_method()
115+
credit_card_confirmation = await workflow.execute_activity_method()
116116
except ActivityError as e:
117-
workflow.logger.error(f"Unable to process credit card {e.message}")
118-
raise ApplicationError(
119-
"Unable to process credit card", "CreditCardProcessingError"
120-
)
117+
workflow.logger.error(f"Unable to process credit card {e.message}")
118+
raise ApplicationError(
119+
"Unable to process credit card", "CreditCardProcessingError"
120+
)
121121
```
122122

123123
This works differently in a Workflow than raising exceptions from Activities.

docs/develop/python/python-sdk-sandbox.mdx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Temporal's Python SDK uses a sandbox environment for Workflow runs to make devel
3636
If a Workflow Execution performs a non-deterministic event, an exception is thrown, which results in failing the Task Worker.
3737
The Workflow will not progress until the code is fixed.
3838

39-
The Temporal Python sandbox offers a mechanism to _pass through modules_ from outside the sandbox. By default, this includes all standard library modules and Temporal modules. For performance and behavior reasons, users are encouraged to pass through all third-party modules whose calls will be deterministic. For more information, see [Passthrough modules](#passthrough-modules).
39+
The Temporal Python sandbox offers a mechanism to _pass through modules_ from outside the sandbox. By default, this includes all standard library modules and Temporal modules. For performance and behavior reasons, users should pass through all models, Activities, Nexus services, or other modules that are in separate files whose calls will be deterministic. For more information, see [Passthrough modules](#passthrough-modules).
4040

4141
## How it works
4242

@@ -108,14 +108,13 @@ The [`SandboxRestrictions`](https://python.temporal.io/temporalio.worker.workflo
108108

109109
### Passthrough modules
110110

111-
By default, the sandbox completely reloads non-standard-library and non-Temporal modules for every workflow run. Passing through a module means that the module will not be reloaded every time the Workflow runs. Instead, the module will be imported from outside the sandbox and used directly in the Workflow. This can improve performance because importing a module can be a time-consuming process, and passing through a module can avoid this overhead.
112-
:::note
111+
By default, the sandbox completely reloads non-standard-library and non-Temporal modules for every Workflow run. Passing through a module means that the module will not be reloaded every time the Workflow runs. Instead, the module will be imported from outside the sandbox and used directly in the Workflow. This can improve performance because importing a module can be a time-consuming process, and passing through a module can avoid this overhead.
113112

113+
:::note
114114
It is important to note that you should only import _known-side-effect-free_ third-party modules: meaning they don't have any unintended consequences when imported and used multiple times. This is because passing through a module means that it will be used multiple times in a workflow without being reloaded, so any side effects it has will be repeated. For this reason, it's recommended to only pass through modules that are known to be deterministic, meaning they will always produce the same output given the same input.
115-
116115
:::
117116

118-
One way to pass through a module is at import time in the workflow file using the [`imports_passed_through`](https://python.temporal.io/temporalio.workflow.unsafe.html#imports_passed_through) context manager.
117+
One way to pass through a module is at import time in the Workflow file using the [`imports_passed_through`](https://python.temporal.io/temporalio.workflow.unsafe.html#imports_passed_through) context manager.
119118

120119
```python
121120
# my_workflow_file.py
@@ -130,7 +129,7 @@ class MyWorkflow:
130129
# ...
131130
```
132131

133-
Alternatively, this can be done at worker creation time by customizing the runner's restrictions.
132+
Alternatively, this can be done at Worker creation time by customizing the runner's restrictions.
134133

135134
```python
136135
# my_worker_file.py

docs/develop/python/set-up.mdx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,9 @@ Create a Workflow file (workflows.py):
183183
```python
184184
from datetime import timedelta
185185
from temporalio import workflow
186-
from activities import greet
186+
187+
with workflow.unsafe.imports_passed_through():
188+
from activities import greet
187189

188190
@workflow.defn
189191
class SayHelloWorkflow:
@@ -208,8 +210,10 @@ Create a Worker file (worker.py):
208210
import asyncio
209211
from temporalio.client import Client
210212
from temporalio.worker import Worker
211-
from workflows import SayHelloWorkflow
212-
from activities import greet
213+
214+
with workflow.unsafe.imports_passed_through():
215+
from workflows import SayHelloWorkflow
216+
from activities import greet
213217

214218
async def main():
215219
client = await Client.connect("localhost:7233")

0 commit comments

Comments
 (0)