You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This means that practically, you need to ship your class definition to your runtime somehow, like packaging it into an internal library that you pip install in your image or otherwise make available in your python environment. This is a bit cumbersome if you only wanted to access the values from your saved block instance.
Today, it is possible to load the BlockDocument from the server without the class present, which looks like:
but this is not a first-class experience (nor is using the private method Block._get_block_document) as:
it requires a bespoke client method
a user needs to know the shape of a "non-public" class BlockDocument to fetch their data
there is no typing information associated with the values of the block
Below we'll go through some proposals to address some of the above.
Proposed enhancements
Important
No proposed solution will involve recovering methods on the block subclass, since we would strictly need the actual Block subclass to access/use these (as methods are not serializable / not stored on the server etc)
A more first-class experience might look like:
# say we saved some class earlier# class CustomBlock(Block):# some_value: Any# and later, we want to load a view of this blockfromprefect.blocks.coreimportBlockViewblock_view_A: BlockView=BlockView.from_block_name("custom-block-type/my-block-name")
print(block_view.some_value) # we could have attribute access here via `extra="allow"`# or perhaps instead the view is just the raw contents of the block documentfromprefect.blocks.coreimportget_block_viewblock_view_B: dict=get_block_view("custom-block-type/my-block-name")
print(block_view.get("some_value"))
preserves some semblance of intuitive attribute / dot access of fields
con
it gets tricky when you have nested blocks or basemodels on the original class, since recreating a faithful model where attribute access is preserved all the way down would require us to inspect the original schema and make an extra="allow" model for each such field we find
not a straightforward way to get strong type hinting on the extra fields
simpler to implement and reason about, not pretending to be a "real" Block
con
no attribute access, just a dict
still no typing, as its just a dict
Important
On Schema to Model Conversion: It would be simple to create the view (i.e. "data portion") of the Block subclass without the original if we could reliably convert an OpenAPI schema into a real pydantic model, but the only reasonable way I'm familiar with to do this is using datamodel-code-generator, which is not something we want to hastily adopt just for this case.
Questions to discuss
Do you find it cumbersome to get custom block types to your runtime? i.e. does this proposal sound useful?
What level of type safety and familiar features (e.g. attribute access) would you expect from a BlockView-like solution?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Background
this discussion is inspired by this issue #14899
Currently, to load and use an existing custom Prefect block, we need to:
0. have a custom block type created and registered, and an instance of that block saved
how to create and register a block type, then save an instance of that block
1. have the block's class definition available when you want to
load
the blockThis means that practically, you need to ship your class definition to your runtime somehow, like packaging it into an internal library that you
pip install
in your image or otherwise make available in your python environment. This is a bit cumbersome if you only wanted to access the values from your saved block instance.Today, it is possible to load the
BlockDocument
from the server without the class present, which looks like:but this is not a first-class experience (nor is using the private method
Block._get_block_document
) as:BlockDocument
to fetch theirdata
Below we'll go through some proposals to address some of the above.
Proposed enhancements
Important
No proposed solution will involve recovering methods on the block subclass, since we would strictly need the actual
Block
subclass to access/use these (as methods are not serializable / not stored on the server etc)A more first-class experience might look like:
Comments on tradeoffs between these two options
version A
could look something like this
pro
con
extra="allow"
model for each such field we findextra
fieldsversion B
could look like this
pro
Block
con
dict
dict
Important
On Schema to Model Conversion: It would be simple to create the view (i.e. "data portion") of the
Block
subclass without the original if we could reliably convert an OpenAPI schema into a real pydantic model, but the only reasonable way I'm familiar with to do this is using datamodel-code-generator, which is not something we want to hastily adopt just for this case.Questions to discuss
Do you find it cumbersome to get custom block types to your runtime? i.e. does this proposal sound useful?
What level of type safety and familiar features (e.g. attribute access) would you expect from a
BlockView
-like solution?Beta Was this translation helpful? Give feedback.
All reactions