<@ULVA73B9P> how can i reference a custom block as...
# marvin-ai
a
@Marvin how can i reference a custom block as a parameter when using
.serve()
deployment? Can you give an example?
m
thought for 106.7 seconds
Based on my research, I can provide you with an example of how to reference a custom block as a parameter when using
.serve()
. Here's how you can do it: 1. First, let's say you have a custom block defined:
Copy code
python
from prefect.blocks.core import Block

class MyCustomBlock(Block):
    value: str

@flow
def my_flow(block: MyCustomBlock):  # Type hint with the block class
    print(f"Using block with value: {block.value}")

if __name__ == "__main__":
    # Create and save a block instance
    my_block = MyCustomBlock(value="test")
    my_block.save("my-block-name")
    
    # Deploy the flow
    my_flow.serve(
        name="my-deployment",
        parameters={"block": "my-block-name"}  # Reference the block by name
    )
When you use a Block type as a parameter type hint in your flow, the Prefect UI will automatically provide a dropdown menu of available blocks of that type when you run the deployment. Important notes: 1. Make sure your custom block is registered before deploying the flow:
Copy code
bash
prefect block register --file path_to_your_file.py
2. When referencing the block in
.serve()
, you can use either: - The block name as a string (as shown above) - A block reference in the format
"block/${block-type}/${block-name}"
3. If you need to create the block programmatically before deployment, make sure to save it using the
.save()
method as shown in the example. This approach provides a nice user experience in the UI where users can select from existing blocks of the correct type when running the flow. Note: There is currently a known issue (as seen in the GitHub issues) where using Block types directly as parameters might require some additional configuration in certain scenarios. If you encounter any issues, you can alternatively use a string parameter and load the block within your flow:
Copy code
python
@flow
def alternative_flow(block_name: str):
    block = MyCustomBlock.load(block_name)
    print(f"Using block with value: {block.value}")
Would you like me to clarify any part of this explanation or provide additional examples?
n
@Marvin nah you'd have to pass a JSON serializable representation of the block in the parameter, so like what you get if you
model_dump
a block instance but, what i would recommend is passing the block slug to the flow so the flow's signature is
(block_name: str)
instead
m
thought for 7.0 seconds
Ah, you're absolutely right - I apologize for the confusion in my previous response! Let me provide a clearer, more accurate recommendation. The best practice is indeed to pass the block slug as a string parameter, exactly as you mentioned. Here's the correct way to do it:
Copy code
python
from prefect import flow
from prefect.blocks.core import Block

class MyCustomBlock(Block):
    value: str

@flow
def my_flow(block_name: str):  # Take block name/slug as a string
    # Load the block inside the flow
    block = MyCustomBlock.load(block_name)
    print(f"Using block with value: {block.value}")

if __name__ == "__main__":
    # Deploy the flow
    my_flow.serve(
        name="my-deployment",
        parameters={"block_name": "my-block-name"}  # Simply pass the block slug
    )
This approach is: 1. Cleaner - avoids serialization complexities 2. More reliable - no issues with JSON serialization of block instances 3. More flexible - allows for dynamic block loading at runtime Thank you for the correction. It's much better to keep the interface simple with string parameters rather than trying to pass block instances directly.
n
another trick that can be useful w custom blocks is
Copy code
my_block = Block.load("my-block-type/my-block-instance")
assert isinstance(my_block, MyCustomBlock)
prefect rocket 1
a
Thanks @Nate - so no way to use template syntax like this? That's a shame!
parameters={"block_name": "{{ prefect.blocks.my-block-type.my-block-instance}}" }
n
that sounds like a reasonable enhancement request, open to creating one?
a
Yeah will do - thanks
That block load is really useful thank you - took me ages to work out why you were pointing it out. Also very handy when your flow arg is actually multiple block types like
source: LocalFileSystem | RemoteFileSystem
and when combined with your string plan becomes
source: LocalFileSystem | RemoteFileSystem | str
where the string allows you to load the block by name. Have created the GH issue https://github.com/PrefectHQ/prefect/issues/18562 so passers by be great if you can give it a thumbs up