Skip to Content
SDKsdisnake (Python)

disnake SDK

pip install mochi-analytics mochi-analytics-disnake

Requires Python 3.10+.

Quick start

import os import disnake from mochi_analytics import MochiClient from mochi_analytics_disnake import attach_mochi mochi = MochiClient( url="https://mochi.example.com", # your Mochi instance api_key=os.environ["MOCHI_API_KEY"], # from the bot's settings page ) intents = disnake.Intents.default() client = disnake.Client(intents=intents) attach_mochi(client, mochi) client.run(os.environ["DISCORD_TOKEN"])

That’s it. Mochi now records slash/context-menu command usage, guild joins and leaves, and an hourly server-count snapshot.

attach_mochi works with disnake.Client, disnake.AutoShardedClient, and disnake.ext.commands.Bot / InteractionBot. An AutoShardedClient sends one snapshot per shard, each carrying that shard’s own guild count.

Options

attach_mochi( client, mochi, include_guild_names=True, # put guild names in join/leave metadata ignore_commands=["ping"], # skip noisy commands snapshot_interval=30 * 60, # seconds; default 1 hour auto_track_commands=False, # see "accurate timings" below )

Accurate duration & success

Auto-tracking records commands the moment the interaction arrives — it can’t see whether your handler succeeded or how long it took. For that, disable auto-tracking and wrap your handlers:

from disnake.ext import commands from mochi_analytics_disnake import wrap_command bot = commands.InteractionBot() attach_mochi(bot, mochi, auto_track_commands=False) @bot.slash_command() @wrap_command(mochi) async def play(inter: disnake.ApplicationCommandInteraction): ... # duration and raised exceptions are recorded

Command names

disnake exposes qualified_name only on prefix commands, so the adapter rebuilds the full application-command name — for example config channel set — by walking the option tree the gateway sent. Value options never extend the name.

Custom events

from mochi_analytics import MochiEvent mochi.track(MochiEvent( type="custom", name="premium_purchased", user_id=str(inter.author.id), guild_id=str(inter.guild_id) if inter.guild_id else None, meta={"tier": "gold"}, ))

Design guarantees

  • Events are batched (flushed every 5 s or 100 events) and sent in the background — track() never blocks or raises.
  • Transient failures retry with backoff; the queue is bounded (oldest dropped first), so a dead Mochi instance can never leak memory or crash the bot.
  • Raw user ids are hashed server-side with a per-bot salt and never stored.

Everything above is a thin wrapper over two HTTP endpoints — see the Ingest API to integrate from any other framework.

Last updated on