Blocks
A Block is a collection of options defined as a class.
Blocks are useful for grouping related options, as they can then be passed to the Engin in one go helping manage complex applications.
Blocks are preferred over other data structures such as a list of options as they integrate with other functionality in the rest of the framework.
Defining an empty Block
A Block is just a class that inherits from Block:
Adding options to the Block
Blocks have a class attribute named options which can be used to include existing
options.
import asyncio
from engin import Engin, Block, Invoke, Provide, Supply
def print_string(string: str) -> None:
print(string)
class ExampleBlock(Block):
options = [
Supply("hello"),
Invoke(print_string)
]
# register it as a provider with the Engin
engin = Engin(ExampleBlock())
asyncio.run(engin.run()) # prints 'hello'
Tip
Blocks are themselves valid options, so Blocks can include other Blocks as options. This compositional approach can help you build and manage larger applications.
Defining Providers, Modifiers & Invocations in the Block
Engin ships three decorators: @provide, @modify & @invoke that can be used to define
providers, modifiers and invocations within a Block as methods. These decorators mirror the
signature of their respective classes Provide, Modify & Invoke.
from engin import Engin, Block, provide, modify, invoke
# this block is equivalent to the one in the example above
class ExampleBlock(Block):
@provide
def string_factory(self) -> str:
return "hello"
@modify
def add_prefix(self, value: str) -> str:
return f"[INFO] {value}"
@invoke
def print_string(self, string: str) -> None:
print(string)
Note
The self parameter in these methods is replaced with an empty object at runtime so
should not be used. Blocks do not need to be instantiated to be passed to Engin as an
option.