Skip to content

risa.client

The client that routes clicks to views, and the functions that make one.

Client

Client(
    rest: RESTClient,
    *,
    use_global: bool = False,
    di: DependencyInjectionManager | None = None,
    register_app_dependencies: bool = True,
    auto_defer: AutoDefer = OFF,
    auto_defer_delay: float = AUTO_DEFER_DELAY,
    store: Store | None = None,
    stores: Mapping[str, Store] | None = None,
    key_prefix: str | None = None,
)

Bases: ABC

Routes clicks on registered views to their handlers.

Make one with client_from_app or client_from_lightbulb, add views with add_view, and send a view with build. A client answers only custom_ids risa wrote, so it can share a bot with other component handlers.

Parameters:

  • rest (RESTClient) –

    The REST client risa answers interactions through.

  • use_global (bool, default: False ) –

    Also route views registered with @risa.register but never added to this client.

  • di (DependencyInjectionManager | None, default: None ) –

    The linkd manager handlers are injected from; a new one by default.

  • register_app_dependencies (bool, default: True ) –

    Register the app, its REST client, and its event manager or interaction server for injection.

  • auto_defer (AutoDefer, default: OFF ) –

    The AutoDefer of views and handlers that set none, OFF by default.

  • auto_defer_delay (float, default: AUTO_DEFER_DELAY ) –

    Seconds after which auto-defer answers a click in its handler's place.

  • store (Store | None, default: None ) –

    The store InStore views use unless they name another.

  • stores (Mapping[str, Store] | None, default: None ) –

    Further stores, by the name InStore(store=...) refers to them by.

  • key_prefix (str | None, default: None ) –

    The prefix of every store key, risa:{application id} by default. Set it to fit a Redis ACL pattern, or to separate bots that share one store.

Raises:

  • ValueError –

    If key_prefix is blank, or the default store is given both as store and in stores.

app abstractmethod property

app: RESTAware

The hikari app the client receives interactions from.

di property

The dependency manager handlers are injected from.

rest property

rest: RESTClient

The REST client risa answers interactions through.

add_view

add_view(cls: type[T]) -> type[T]

Route clicks on the components of cls through this client.

Parameters:

  • cls (type[T]) –

    The view class, already registered with @risa.register.

Returns:

  • type[T] –

    The class, so that this also works as a decorator above @risa.register.

Raises:

build async

build(view: View) -> Rendered

Render view into the components of a new message, ready to send.

await ctx.respond(**await client.build(Poll(question="Ship it?")))

It runs the view's load, renders it, and writes an InStore view's first record. The result spreads into any hikari or lightbulb call that takes components=. If that send fails, the record stays behind until its TTL reaps it, or for good under InStore(ttl=None).

Parameters:

  • view (View) –

    The view to render, an instance of a registered class.

Returns:

  • Rendered –

    The components, as a mapping that spreads into a send.

Raises:

error_handler

error_handler(func: T, /, *, priority: int = 0) -> T
error_handler(*, priority: int = 0) -> _ErrorHandlerDecorator

Register a function that answers clicks that failed.

@client.error_handler
async def on_error(failure: risa.ClickFailure) -> bool:
    if isinstance(failure.error, risa.StoreUnavailableError):
        await failure.ctx.respond("Try again in a moment.", ephemeral=True)
        return True
    return False

It runs when a handler, load, View.on_outdated or View.on_state_missing raises, or when the view's state cannot be reached before them; ClickFailure.stage says which. It returns True once it has dealt with the failure, and risa then logs nothing. Otherwise the next one runs, and if none returns True, risa logs the failure as it would without them. One that raises is logged and counts as False. Its parameters after the first are injected, as a handler's are. It runs without auto-defer, and Discord's three seconds count from the click, so a failure that comes late, such as a lock timeout, may leave it no time unless auto-defer answered first.

Parameters:

  • func (ErrorHandler | None, default: None ) –

    The function to register. Left out, the call takes priority and returns the decorator.

  • priority (int, default: 0 ) –

    Higher runs first; functions of one priority run in the order they were registered.

Returns:

  • ErrorHandler | _ErrorHandlerDecorator –

    The function, unchanged, or the decorator that registers one.

GatewayClientAppT

Bases: EventManagerAware, RESTAware, Protocol

A gateway app, with an event manager and a REST client, such as hikari.GatewayBot.

GatewayEnabledClient

GatewayEnabledClient(
    app: GatewayClientAppT,
    *,
    register_app_dependencies: bool = True,
    **options: Unpack[_ClientOptions],
)

Bases: Client

A client that receives clicks as gateway events. client_from_app or client_from_lightbulb makes one.

app property

The gateway app the client receives interactions from.

LightbulbClient

Bases: Protocol

The part of a lightbulb client risa uses.

app property

app: RESTAware

The hikari app the lightbulb client runs on.

di property

The lightbulb client's dependency manager.

RestClientAppT

Bases: InteractionServerAware, RESTAware, Protocol

A REST app, with an interaction server and a REST client, such as hikari.RESTBot.

RestEnabledClient

RestEnabledClient(
    app: RestClientAppT,
    *,
    register_app_dependencies: bool = True,
    warn_shared_listener: bool = True,
    **options: Unpack[_ClientOptions],
)

Bases: Client

A client that receives clicks from hikari's interaction server.

The interaction server has a single component listener. The client takes it over and passes every interaction it does not handle on to the listener it replaced, and it logs a warning naming that listener unless warn_shared_listener=False. client_from_app or client_from_lightbulb makes one.

app property

The REST app the client receives interactions from.

client_from_app

client_from_app(
    app: GatewayClientAppT, **options: Unpack[_ClientOptions]
) -> GatewayEnabledClient
client_from_app(
    app: RestClientAppT,
    *,
    warn_shared_listener: bool = True,
    **options: Unpack[_ClientOptions],
) -> RestEnabledClient

Make a client for a hikari app, gateway or REST.

bot = hikari.GatewayBot(TOKEN)
client = risa.client_from_app(bot, store=risa.MemoryStore())

Parameters:

  • app (GatewayClientAppT | RestClientAppT) –

    The app to receive interactions from.

  • warn_shared_listener (bool, default: True ) –

    REST only: warn when the client takes over a component listener another library set.

  • **options (Unpack[_ClientOptions], default: {} ) –

    The options of Client.

Returns:

  • Client –

    A GatewayEnabledClient or a RestEnabledClient, depending on the app.

client_from_lightbulb

client_from_lightbulb(
    lightbulb_client: LightbulbClient,
    *,
    warn_shared_listener: bool = True,
    **options: Unpack[_LightbulbOptions],
) -> Client

Make a client that shares a lightbulb client's app and dependency manager.

Handlers can then be injected with anything registered with lightbulb. The app's own dependencies are left to lightbulb, which registers them already.

Parameters:

  • lightbulb_client (LightbulbClient) –

    The lightbulb client to share.

  • warn_shared_listener (bool, default: True ) –

    REST only: warn when the client takes over lightbulb's component listener.

  • **options (Unpack[_LightbulbOptions], default: {} ) –

    The options of Client, apart from di.

Returns:

  • Client –

    A GatewayEnabledClient or a RestEnabledClient, depending on the app.

Raises:

  • TypeError –

    If the lightbulb client's app is neither a gateway nor a REST app.