-
Notifications
You must be signed in to change notification settings - Fork 40
/
hooks.rst
69 lines (52 loc) · 2.83 KB
/
hooks.rst
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
=====
Hooks
=====
.. _hooks:
.. note::
Hooks allow you to customize every aspect of Burr's execution, plugging in whatever tooling,
observability framework, or debugging tool you need.
Burr has a system of lifecycle adapters (adapted from the similar `Hamilton <https://github.com/dagworks-inc/hamilton>`_ concept), which allow you to run tooling before and after
various places in a node's execution. For instance, you could:
1. Log every step as a trace in datadog
2. Add a time-delay to your steps to allow for rendering
3. Add a print statement to every step to see what happened (E.G. implement the printline in cowsay above)
4. Synchronize state/updates to an external database
5. Put results on a queue to feed to some monitoring system
Note some of the above are yet to be implemented.
To implement hooks, you subclass any number of the :ref:`available lifecycle hooks <hooksref>`.
These have synchronous and asynchronous versions, and your hook can subclass as many as you want
(as long as it doesn't do both the synchronous and asynchronous versions of the same hook).
To use them, you pass them into the :py:class:`ApplicationBuilder <burr.core.application.ApplicationBuilder>` as a ``*args`` list of hooks. For instance,
a hook that prints out the nodes name during execution looks like this.
We implement the pre/post run step hooks.
.. code-block:: python
class PrintLnHook(PostRunStepHook, PreRunStepHook):
def pre_run_step(self, *, state: "State", action: "Action", **future_kwargs: Any):
print(f"Starting action: {action.node.name}")
def post_run_step(
self,
*,
state: "State",
action: "Action",
result: Optional[dict],
sequence_id: int,
exception: Exception,
**future_kwargs: Any,
):
print(f"Finishing action: {action.node.name}")
To include this in the application, you pass it into the :py:meth:`with_hooks <burr.core.application.ApplicationBuilder.with_hooks>` method.
.. code-block:: python
app = (
ApplicationBuilder()
.with_hooks(PrintLnHook())
...
.build())
.. note::
There are synchronous and asynchronous hooks. Synchronous hooks will be called with both synchronous and asynchronous run methods
(all of ``step``, ``astep``, ``iterate``, ``aiterate``, ``run``, and ``arun``), whereas synchronous hooks will only be called with
the asynchronous methods (``astep``, ``aiterate``, ``arun``).
.. warning::
Hook order is currently undefined -- they happen to be called now in the order in which they are defined. We will likely
alter them to be called in the order they are defined (for `pre...`) hooks and in reverse order for `post...` hooks,
but this is not yet implemented.
Read more about the hook API in the :ref:`hooks section <hooksref>`.