Skip to main content

darkob

darkob

Fast, stable async Python for the Rubika & Shad platforms.
Bots and userbots that stay up — with an API verified against the real server.

PyPI Python 3.9-3.14 CI License Stars

Docs · AI context · PyPI · Roadmap


pip install darkob
from darkob import Bot, Keyboard

bot = Bot(token="YOUR_BOT_TOKEN")

@bot.on_command("start")
async def start(bot, event):
    await event.reply(
        "Welcome 👋",
        inline_keypad=Keyboard().row("Docs", "Support"),
    )

bot.run()

Why darkob

A fork of maxrubika, rebuilt so failures are visible, the fast paths are actually fast, and the API surface matches the server.

Inherited problem What darkob does
Contacted PyPI at import time Importing performs no network I/O
TLS verification disabled everywhere Verification on by default, opt-out explicit
Bare except: swallowed KeyboardInterrupt Narrowed to Exception, and logged
Background handler crashes vanished at GC Logged the moment they happen
Every event scanned all handlers Indexed dispatch, built once
Retries were endpoints × max_retries Bounded budget with jitter and 429 handling
A new TLS handshake per download Pooled sessions everywhere, including files
Saved sessions opened but never read Credentials restored; sessions survive restarts
A corrupt session file was deleted Quarantined, never destroyed
Keypad editing called a non-existent endpoint Fixed by live testing, pinned by a regression test

What's inside

Two surfaces, one library

Bot for the official Bot API. Messenger for real user accounts — channels, groups, voice chats, settings. Shad is the same protocol against Shad's hosts.

Async first, sync friendly

Every method works with await or without it. One background loop, no per-call threads.

Handlers, filters, routers

Decorators, 42 filters composing with &, |, ~, middleware, nested routers, and a global on_error handler.

Conversations

FSMContext with four storage backends: memory, TTL memory, JSON file, and SQLite (WAL, concurrent-safe).

Keyboards for every button type

Keyboard().row(...) builders for all 19 documented button types — selection, calendar, number/string pickers, location, textbox, barcode, camera and gallery variants.

Message helpers

MessageBuilder for text + keypad + reply target, bold() / link() / code() formatting, and event.reply(...) shortcuts.

Iterators, not pagination loops

bot.iter_updates() and client.iter_messages() own the cursor and stop when it stops advancing.

Testing toolkit

darkob.testing ships FakeBot, FakeEvent and make_message, so a handler test needs no token and no network.

Reliability

Six primitives that most bot libraries leave to the user:

Primitive What it buys you
Retry(attempts=, backoff=, jitter=) A policy you can reason about, honoured by both surfaces
RateLimiter(rate=, per_chat_rate=) Token buckets globally and per chat, applied to every attempt
CircuitBreaker A dead data centre stops burning your retry budget
SendQueue(path=) Messages survive a dropped connection and flush on reconnect
ProtocolTracker Reports when Rubika reshuffles its endpoints
Resumable downloads Byte-range resume that survives an interrupted file
from darkob import Bot, RateLimiter, Retry, SendQueue

bot = Bot(
    token="...",
    retry=Retry(attempts=4, backoff=0.5),
    rate_limiter=RateLimiter(rate=20, per_chat_rate=3),
)

outbox = SendQueue(bot, path="outbox.json")
outbox.start()

Verified against the real API

The Bot API documents 19 endpoints. All are implemented, and 18 were exercised against a live server — including the full file round-trip (requestSendFile → uploadFile → getFile → sendFile → download) and byte-range resume.

That testing caught three things static reading could not:

  1. editInlineKeypad — the docs' own cURL — answers INVALID_INPUT: Invalid Method. The working endpoint is editMessageKeypad.
  2. A bare Payment button is rejected; Button.payment() now demands its fields instead of failing at send time.
  3. Bot.download_file was opening its own HTTP session, paying a fresh TLS handshake per file.

The remaining two gaps are documented rather than guessed: getChatMember needs a group chat to verify, and setCommands has no read-back, so testing it would destroy your command list.

Documentation

Full site: manitheferfri.github.io/darkob

Quickstart Install to running bot in five minutes
Handlers · Filters Every decorator and all 42 constraints
Routers Split a bot into modules, with scoped middleware
Conversations State, storage backends, StateFilter
Keyboards All button types and formatting
Composing messages MessageBuilder and formatting together
Errors Retries, breaker, rate limiting, queue
Bot API · Messenger API Generated from the package

Built for AI-assisted development

Most darkob bots are written by an assistant, so the docs are built to be read by a model.

https://manitheferfri.github.io/darkob/llms-full.txt

One file, one fetch: hard rules, every guide, and the complete API with full docstrings for all 688 methods.

  • llms.txt — curated map
  • api.json — every method as JSON
  • Every page is also served as raw Markdown: append .md to any URL
  • The API reference is generated from the installed package, so it cannot drift

Development

git clone https://github.com/ManiTheFerfri/darkob.git
cd darkob
pip install -e ".[dev]"

pytest --cov=darkob     # 463 tests, no network required
ruff check .            # lint
mypy darkob/router.py darkob/retry.py darkob/builders.py \
     darkob/keyboards.py darkob/formatting.py darkob/testing.py

The suite never opens a socket: HTTP goes through fake transports, and a subprocess test asserts that importing darkob cannot reach the network.

Two extra tools live in scripts/:

  • benchmark.py — micro-benchmarks for the hot paths, no network.
  • conformance.py — exercises every Bot API method against a real token, cleans up after itself, and exits non-zero on failure.

Roadmap

See docs/roadmap.md — milestones 1–3 and P0–P2 are closed. It records what is proven, what is impossible, and why.

License

MIT. Derived from maxrubika, copyright MEHRAB Farahmand; the original MIT notice is preserved in LICENSE.

Maintained by Mani Keikhosravi.

Not affiliated with Rubika or Shad. Use responsibly and in line with the platforms' terms of service.

Metadata

Release files for darkob 0.11.2

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

Source distribution (sdist)

Source distribution for darkob 0.11.2
File Size Uploaded Provenance Actions
darkob-0.11.2.tar.gz 236.1 kB With provenance Details for darkob-0.11.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for darkob 0.11.2
File Interpreter ABI Platform Actions
darkob-0.11.2-py3-none-any.whl Python 3 none any Details for darkob-0.11.2-py3-none-any.whl

Total release size: 617.8 kB

Release files / darkob-0.11.2.tar.gz

Download URL darkob-0.11.2.tar.gz
Size 236.1 kB
Tags Source
SHA-256 checksum
How to use checksums
234e3c44ee8e89e01d114405cd0eb840654e22e0e3f602f6240816d18452bb71
BLAKE2b-256 checksum
How to use checksums
58ce129d1c054767dfc7cd97783d7f0e10f3563c424d211e89e2344b8c875ef3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 5, 2026.

Transparency log

Release files / darkob-0.11.2-py3-none-any.whl

Download URL darkob-0.11.2-py3-none-any.whl
Size 381.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
284c0cb00c49980c977554e4d17447482149a985741681a2933a9f46fd290d16
BLAKE2b-256 checksum
How to use checksums
179090c7c4f0099ef2ec5c471ad56573ed9f31ecae319671f2b096e622095e47
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 5, 2026.

Transparency log

Security for darkob 0.11.2

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for darkob-0.11.2.tar.gz

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 Nov 5, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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