<@ULVA73B9P> how do I get a secret block in a Jupy...
# ask-marvin
t
@Marvin how do I get a secret block in a Jupyter notebook? When trying to access it I get the following error: 'coroutine' object has no attribute 'host' I think it has to do with the secret blocks being an asynchronous.
m
thought for 8.2 seconds
Ah yes, the classic async/sync impedance mismatch. The error you're seeing occurs because Secret blocks (like many Prefect objects) are async by default, but Jupyter notebooks run in a synchronous context. Here's how to properly access a Secret block:
Copy code
python
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:
Copy code
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.
t
@Marvin When I try to use the asyncio.run() I get the following error: asyncio.run() cannot be called from a running event loop
m
thought for 7.7 seconds
Ah yes, that error is a classic Jupyter notebook quirk - Jupyter already has an event loop running. Here's how to handle it properly in a Jupyter environment:
Copy code
python
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:
Copy code
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.
t
@Marvin await worked, thanks
m
thought for 6.9 seconds
Excellent! Yes,
await
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?
t
@Marvin RuntimeWarning: coroutine 'Block.aload' was never awaited When I run I get something like this.
m
thought for 6.9 seconds
That warning typically appears when you forget to use the
await
keyword when loading a block. Here's how to fix it:
Copy code
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:
Copy code
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.