Skip to main content

slimbots

Shared plumbing for slim-m bot templates in this repo.

This is not a typed model of slim-m's API. There is no Channel class, no Message object, no cache, no event hierarchy - the kind of thing a discord.js-shaped SDK would give you for a few hundred endpoints. slim-m's entire bot surface is: log in with a token, call REST, hold one websocket, track a per-scope seq. That is what this package covers:

  • authentication (Authorization: Bearer, a real User-Agent, GET /me)
  • a REST helper, Client.call, for any route a template needs, including a raw (non-JSON) body and extra headers for an attachment upload
  • an idempotent send that keeps the message id fixed across a retry, retries only a genuinely uncertain failure - a network error, a 5xx, or a 429 - never a rejected 4xx, and can carry attachment_ids
  • the websocket connect and hello handshake (Connection)
  • the reconnect loop with exponential backoff, and treating a 401 as terminal rather than retryable (run_forever)
  • a seq cursor in sqlite and the /sync catch-up call (cursor)
  • refusing to carry a token over plain ws:// to anything but a loopback address (socket_url)

It deliberately does not give you a typed route client, a cache, or an event-object hierarchy. See docs/bots/building-bots.md in slim-m for the protocol this wraps, and bot-ping/ in this repo for the same protocol written out with nothing hidden - it stays free of this package on purpose, so there is always one template that shows the whole thing in one file.

Testing a bot built on this

slimbots.testing.FakeClient is a Client that never touches the network, for unit-testing a bot's command handlers - the thing every template but this package's own tests had no way to do without a live deployment. It records every call in .calls, auto-answers a message send and records it separately in .sent (the one route every template calls on every command), and raises immediately on anything else the bot under test calls that was not stubbed with respond(method, path, response), so a forgotten stub fails the test loudly instead of hanging.

from slimbots.testing import FakeClient

client = FakeClient(me_id="bot-1")
handle_message(client, conn, "bot-1", "chan-1", {"author_id": "u1", "content": "!ping", "id": "m1"})
assert client.sent[0]["content"] == "pong"

It is not imported by slimbots/__init__.py, so it costs nothing for a template that never writes a test. bot-reminders/test_bot.py is a worked example against a real template's handlers. It is not a mock of slim-m's API - concurrency and money-safety still need a real sqlite connection and real threads racing it, the way bot-casino/test_concurrency.py does.

Hand-written, not generated

slim-m's wire contract is schema/openapi.yaml, and crates/slimm-server/tests/openapi_contract.rs already fails CI on drift, so a generated client would stay honest automatically. This package is hand-written anyway. What it wraps is not route-shaped: auth, a socket, and a retry policy, not a set of typed request/response pairs. A generator produces that badly, and slim-m already prefers hand-written DTOs and models on both the server and the client for the same reason. If somebody wants a fully typed route client later, generating one from openapi.yaml is a reasonable project - it just is not this one.

Installing

The distribution is named slim-m on PyPI; the import stays slimbots.

pip install slim-m

To run against unreleased changes, install from git instead:

pip install "slim-m @ git+https://github.com/NC1107/slim-bots.git@main#subdirectory=slimbots"

Each template's requirements.txt pins one of those two lines.

Releasing

.github/workflows/publish.yml builds and uploads on a published GitHub release, using PyPI trusted publishing - it exchanges the workflow's own OIDC identity for an upload token, so there is no API token stored in this repo. The publisher on PyPI must name this repository, publish.yml, and the pypi environment, or the exchange is refused.

Bump version in pyproject.toml, then publish a release.

Tests

pip install -e ".[dev]"
pytest

Covers the retry policy (which errors retry, which do not, and that the message id and content never change across a retry), the reconnect loop's backoff and its terminal handling of a 401, and socket_url's loopback-only refusal of plaintext ws://.

Release files for slim-m 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for slim-m 0.2.0
File Size Uploaded
slim_m-0.2.0.tar.gz 13.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for slim-m 0.2.0
File Interpreter ABI Platform
slim_m-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 26.0 kB

Release files / slim_m-0.2.0.tar.gz

Download URL slim_m-0.2.0.tar.gz
Size 13.9 kB
Tags Source
SHA-256 checksum
How to use checksums
80aef72e98ce35cc1a6df65e37d75de74c31fd5a4017d74ebd4eee4ca0ae170c
BLAKE2b-256 checksum
How to use checksums
33196210ad9f9d156083f52b70e4f4bc7460eabce7e0b252e01e48ef82e120cc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / slim_m-0.2.0-py3-none-any.whl

Download URL slim_m-0.2.0-py3-none-any.whl
Size 12.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
16de509aa3896f1484627b5bad3fb77bd6a83756eeee6649a9d6aa786ad3595f
BLAKE2b-256 checksum
How to use checksums
62de24a6d9498ff7269647aefbf13823bc66f9cea199fd84fb3f72cef7da2a64
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release history Release notifications | RSS feed

0.4.0

2 release files

0.3.0

2 release files

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page