Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Mistral Custom Actions ~ With Base Classes (Usage)
import base
class MyCustomAction(base.Action):
def run(self):
return "I ran"
class MyAsyncAction(base.AsyncAction):
def run(self):
return "I have the is_sync method: %s" % hasattr(self, "is_sync")
class MyContextAction(base.ContextAction):
def run(self, context):
return "I have a context: %s" % context
# extensibiltiy scenario: an asynchronous action that requires a context
# using the base class scenario requires you to redefine is_sync
class AsyncContextAction(base.ContextAction):
def is_sync(self):
"""Returns False if the action is asynchronous, otherwise True."""
return False
# basic custom action
a = MyCustomAction()
a.run()
# Async
b = MyAsyncAction()
# current test in mistral for is_sync tests for is_sync.
# The new example remains backwards compatible.
is_sync = b.is_sync()
# alternate tests for the AsyncAction
# 1) class inheritance. (Is-A)
# The following wouldn't require the presence of the is_sync method and could
# be tested against all actions, regardless of base type
is_sync = not isinstance(b, "AsyncAction")
# 2) function existence
# this line tests for presence of the method and is likely considered more "pythonic"
# this would also make more sense if the method on the AsyncAction was named "is_async"
is_sync = callable(getattr(b, 'is_sync', None))
# run to stay complete with the other examples
b.run()
context = {"name": "someval"}
c = MyContextAction()
# Current actions in Mistral would be unharmed and backwards compatible
# we would simply add the following block in the default_executor to ensure
# new actions would get the context as needed
if isinstance(c, "ContextAction"):
c.run(context)
else:
c.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment