Tejas Shah
07/03/2025, 7:53 AMMarvin
07/03/2025, 7:53 AMMarvin
07/03/2025, 7:53 AMpython
from prefect.blocks.system import Secret
import asyncio
# Method 1: Using asyncio.run()
secret_block = asyncio.run(Secret.load("YOUR-BLOCK-NAME"))
my_secret = secret_block.get() # This is synchronous and works directly
# Method 2: Using await in an async function
async def get_secret():
secret_block = await Secret.load("YOUR-BLOCK-NAME")
return secret_block.get()
# Then run it with:
my_secret = asyncio.run(get_secret())
A few important notes:
1. The .get()
method on Secret blocks is actually synchronous, but the .load()
method is async
2. If you're in a Jupyter notebook and want to use async/await directly, you can use the %%jupyter
magic command:
python
%%jupyter
async def main():
secret_block = await Secret.load("YOUR-BLOCK-NAME")
return secret_block.get()
await main()
This is a common point of confusion because while most block operations in Prefect are async, some methods (like get()
on Secret blocks) are intentionally synchronous for convenience.
If you're working with other types of blocks that have async methods, you'll need to use similar patterns to access their attributes or methods asynchronously.Tejas Shah
07/03/2025, 8:49 AMMarvin
07/03/2025, 8:49 AMMarvin
07/03/2025, 8:49 AMpython
from prefect.blocks.system import Secret
import asyncio
# Method 1: Using asyncio.get_event_loop()
loop = asyncio.get_event_loop()
secret_block = loop.run_until_complete(Secret.load("YOUR-BLOCK-NAME"))
my_secret = secret_block.get()
# Method 2: Using IPython's built-in async support (preferred)
# This requires no extra imports and is cleaner
secret_block = await Secret.load("YOUR-BLOCK-NAME")
my_secret = secret_block.get()
The second method using await
directly is the preferred approach in Jupyter notebooks because it's cleaner and works with IPython's built-in async support. Just make sure your cell starts with the code you want to run - no need for wrapper functions.
If you're getting errors with either approach, you might need to restart your Jupyter kernel to clear any stuck event loops.
Also, if you're working with multiple async operations, you can chain them like this:
python
# Multiple async operations
secret_block1 = await Secret.load("FIRST-SECRET")
secret_block2 = await Secret.load("SECOND-SECRET")
value1 = secret_block1.get()
value2 = secret_block2.get()
Remember that while the .load()
operation is async, the .get()
method is synchronous, so you don't need to await it.Tejas Shah
07/03/2025, 8:51 AMMarvin
07/03/2025, 8:51 AMMarvin
07/03/2025, 8:51 AMawait
is typically the cleanest solution in Jupyter notebooks since IPython (which powers Jupyter) has built-in async support. Much less ceremonial than dealing with event loops directly.
Is there anything else you'd like to know about working with blocks or async operations in Prefect?Tejas Shah
07/03/2025, 8:54 AMMarvin
07/03/2025, 8:54 AMMarvin
07/03/2025, 8:54 AMawait
keyword when loading a block. Here's how to fix it:
python
# Wrong way - causes the warning:
secret_block = Secret.load("YOUR-BLOCK-NAME") # Missing await!
# Correct way:
secret_block = await Secret.load("YOUR-BLOCK-NAME")
# Also correct - using the newer aload method:
secret_block = await Secret.aload("YOUR-BLOCK-NAME")
The warning occurs because .load()
and .aload()
return a coroutine (basically a promise of future work) that needs to be awaited. Without the await
, Python just creates the coroutine but never actually executes it.
If you're seeing this warning in your code, scan for any block loading operations and make sure they all have await
in front of them. This applies to any async Prefect operation, not just Secret blocks.
A common pattern you might use:
python
# Loading multiple blocks
s3_block = await Secret.load("S3-CREDENTIALS")
slack_block = await Secret.load("SLACK-TOKEN")
# Now you can use them
s3_secret = s3_block.get()
slack_secret = slack_block.get()
Remember: Any method that returns a coroutine (usually indicated by being defined with async def
in the source code) needs to be awaited.