Skip to content

Actions

An action is a Python function the dashboard calls from a button. A widget lists its actions by name, and each one shows as a button on its card.

import dachshund
from dachshund.widgets import Number


@dachshund.action("block_user", label="Block", confirm=True)
def block_user(ctx, user_id: str) -> None: ...


with dachshund.row():
    dachshund.add(
        Number(
            "last_signup",
            actions=["block_user"],
            action_args={"block_user": {"user_id": "42"}},
        )
    )

An action used by a Page's widgets is registered on the page, and goes on the dashboard with it:

@overview_page.action("flush", label="Flush cache")
def flush(ctx) -> None:
    ctx["cache"].clear()

Arguments

A handler receives the arguments it declares after ctx, by name. Extra ones are ignored, and a missing required one fails the call before the handler runs.

  • On a card, arguments come from the widget's action_args.
  • On a Table row, they come from the row's fields merged over action_args.

A handler can be sync or async. A sync handler runs in a thread, so it can block.

Context

ctx is the context given to dachshund.init(). Put whatever a handler needs from your application in it.

dachshund.init("My service", context={"db": db})


@dachshund.action("deactivate")
async def deactivate(ctx, user_id: str) -> None:
    await ctx["db"].deactivate_user(int(user_id))

ctx defaults to {}. Calling init() again merges the new context into it.

Event loop

When init() is called from a running event loop, async handlers run on that loop. A client bound to your application's loop, such as a database pool, can then be awaited from a handler. Called from sync code, handlers run on dachshund's own loop.

Result

Whatever a handler returns is sent back as result in the response of POST /_actions/{name}. Buttons only show whether the call succeeded.