Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions docs/v3/advanced/results.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,35 @@ def my_flow():
other_storage_task()
```

<Info>
**Using result storage with decorators**

When specifying `result_storage` in `@flow` or `@task` decorators, you have two options:

- **Block instances**: The block instance must be saved server-side or loaded from a saved block instance before it is provided to the `@task` or `@flow` decorator.
- **String references**: Use the format `"block-type-slug/block-name"` for deferred resolution at runtime

For testing scenarios, string references are recommended since they don't require server connectivity at import time.

```python
from prefect import flow
from prefect.filesystems import LocalFileSystem

# Option 1: Save block first (requires server connection at import time)
storage = LocalFileSystem(basepath="/tmp/results")
storage.save("my-storage", overwrite=True)

@flow(result_storage=storage) # Works because block is saved
def my_flow():
return "result"

# Option 2: Use string reference (recommended for testing)
@flow(result_storage="local-file-system/my-storage") # Resolved at runtime
def my_flow():
return "result"
```
</Info>

#### Specifying a default filesystem

Alternatively, you can specify a different filesystem through the `PREFECT_DEFAULT_RESULT_STORAGE_BLOCK` setting.
Expand Down
23 changes: 16 additions & 7 deletions src/prefect/flows.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,13 @@ class Flow(Generic[P, R]):
that Prefect should choose whether the result should be persisted depending on
the features being used.
result_storage: An optional block to use to persist the result of this flow.
This value will be used as the default for any tasks in this flow.
If not provided, the local file system will be used unless called as
a subflow, at which point the default will be loaded from the parent flow.
This can be either a saved block instance or a string reference (e.g.,
"local-file-system/my-storage"). Block instances must have `.save()` called
first since decorators execute at import time. String references are resolved
at runtime and recommended for testing scenarios. This value will be used as
the default for any tasks in this flow. If not provided, the local file system
will be used unless called as a subflow, at which point the default will be
loaded from the parent flow.
result_serializer: An optional serializer to use to serialize the result of this
flow for persistence. This value will be used as the default for any tasks
in this flow. If not provided, the value of `PREFECT_RESULTS_DEFAULT_SERIALIZER`
Expand Down Expand Up @@ -376,7 +380,8 @@ def __init__(
if getattr(result_storage, "_block_document_id", None) is None:
raise TypeError(
"Result storage configuration must be persisted server-side."
" Please call `.save()` on your block before passing it in."
" Please call `.save()` on your block before passing it in,"
" or use a string reference like 'local-file-system/my-storage' instead."
)
self.result_storage = result_storage
self.result_serializer = result_serializer
Expand Down Expand Up @@ -1889,9 +1894,13 @@ def __call__(
that Prefect should choose whether the result should be persisted depending on
the features being used.
result_storage: An optional block to use to persist the result of this flow.
This value will be used as the default for any tasks in this flow.
If not provided, the local file system will be used unless called as
a subflow, at which point the default will be loaded from the parent flow.
This can be either a saved block instance or a string reference (e.g.,
"local-file-system/my-storage"). Block instances must have `.save()` called
first since decorators execute at import time. String references are resolved
at runtime and recommended for testing scenarios. This value will be used as
the default for any tasks in this flow. If not provided, the local file system
will be used unless called as a subflow, at which point the default will be
loaded from the parent flow.
result_serializer: An optional serializer to use to serialize the result of this
flow for persistence. This value will be used as the default for any tasks
in this flow. If not provided, the value of `PREFECT_RESULTS_DEFAULT_SERIALIZER`
Expand Down
15 changes: 12 additions & 3 deletions src/prefect/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,11 @@ class Task(Generic[P, R]):
indicates that the global default should be used (which is `True` by
default).
result_storage: An optional block to use to persist the result of this task.
Defaults to the value set in the flow the task is called in.
This can be either a saved block instance or a string reference (e.g.,
"local-file-system/my-storage"). Block instances must have `.save()` called
first since decorators execute at import time. String references are resolved
at runtime and recommended for testing scenarios. Defaults to the value set
in the flow the task is called in.
result_storage_key: An optional key to store the result in storage at when persisted.
Defaults to a unique identifier.
result_serializer: An optional serializer to use to serialize the result of this
Expand Down Expand Up @@ -576,7 +580,8 @@ def __init__(
if getattr(result_storage, "_block_document_id", None) is None:
raise TypeError(
"Result storage configuration must be persisted server-side."
" Please call `.save()` on your block before passing it in."
" Please call `.save()` on your block before passing it in,"
" or use a string reference like 'local-file-system/my-storage' instead."
)

self.result_storage = result_storage
Expand Down Expand Up @@ -1992,7 +1997,11 @@ def task(
indicates that the global default should be used (which is `True` by
default).
result_storage: An optional block to use to persist the result of this task.
Defaults to the value set in the flow the task is called in.
This can be either a saved block instance or a string reference (e.g.,
"local-file-system/my-storage"). Block instances must have `.save()` called
first since decorators execute at import time. String references are resolved
at runtime and recommended for testing scenarios. Defaults to the value set
in the flow the task is called in.
result_storage_key: An optional key to store the result in storage at when persisted.
Defaults to a unique identifier.
result_serializer: An optional serializer to use to serialize the result of this
Expand Down