Skip to main content

darkob

darkob

Fast, stable async Python for the Rubika & Shad platforms.
Build bots and userbots that stay up, without the boilerplate.

CI PyPI MIT Python 3.9-3.14 Tests


darkob (دارکوب, woodpecker) is a fork of maxrubika by MEHRAB Farahmand, rebuilt around foundations you can trust. Same protocol, same power, far less guesswork when something goes wrong.

from darkob import Bot

bot = Bot(token="YOUR_BOT_TOKEN")

@bot.on_command("start")
async def start(bot, event):
    await event.reply("Welcome 👋")

bot.run()

✨ Why darkob

The upstream library is feature-complete, but its foundations were never hardened. Speed and new features are only worth having on a base that does not quietly fail, so darkob starts there.

Inherited problem What darkob does instead
Contacted PyPI at startup (urlopen inside the package init) Importing darkob performs no network I/O. The update check is opt-in via darkob.check_for_updates().
TLS verification disabled on every connector Verification is on by default; opt out explicitly with verify_ssl=False.
Bare except: swallowed KeyboardInterrupt and SystemExit Narrowed to except Exception:; session-loading failures are logged rather than silently returning None.
Data used without being imported in the request path Fixed — that branch would have raised NameError at runtime.
Every update scanned all handlers, rebuilt the update name per handler, and spawned an OS thread per synchronous handler Indexed dispatch: handlers grouped by update name once; blocking handlers run in the loop's bounded executor.
Retries were endpoints × max_retries — 3 endpoints meant 9 attempts with exponential backoff Bounded budget per request, endpoint rotation, jitter, and explicit 429 / TOO_REQUESTS backoff.
A fresh ClientSession (and TLS handshake) per file download Pooled sessions per file server, reused across downloads.
No tests, no CI, no pyproject.toml 121 tests, GitHub Actions across 3.9–3.14 plus Windows, modern packaging.

🚀 Install

pip install darkob

Latest development version:

pip install git+https://github.com/ManiTheFerfri/darkob.git

📦 What's inside

  • Two surfaces, one library. Bot talks to the official Bot API; Messenger drives a real user account, including channels, groups, voice chats and stickers. Shad is the same Messenger protocol against the Shad platform.
  • Async first, sync friendly. Every method works with await or without it — darkob runs one background loop and hops onto it for you.
  • Decorator handlers. on_message, on_command, on_callback, on_edit_message, and friends, with a composable filter system (&, |, ~).
  • Routers. Split a bot into feature modules and include them in one line.
  • Finite state machines. Multi-step conversations with pluggable storage that can survive a restart.
  • Polling or webhook. bot.run() polls; bot.run(webhook_url=...) serves a webhook instead.

🔀 Routers

Handlers can live in their own modules and be registered from one place:

from darkob import Bot, Router

bot = Bot(token="YOUR_BOT_TOKEN")
admin = Router("admin")

@admin.command("ban")
async def ban(bot, event):
    await bot.ban_member(event.chat_id, event.author_id)
    await event.reply("Banned.")

bot.include_router(admin)
bot.run()

Routers nest, so a larger bot can keep one root router per feature area.

🧠 Conversations (FSM)

Track which step a user is on and remember what they told you:

from darkob import Bot, FSMContext, JsonFileStorage, StateFilter

bot = Bot(token="YOUR_BOT_TOKEN")
storage = JsonFileStorage("fsm.json")   # survives restarts

@bot.on_command("order")
async def order(bot, event):
    ctx = FSMContext(storage, key=event.chat_id)
    await ctx.set_state("address")
    await event.reply("What is your delivery address?")

@bot.on_new_message(StateFilter(storage, "address"))
async def address(bot, event):
    ctx = FSMContext(storage, key=event.chat_id)
    await ctx.update_data(address=event.text)
    await ctx.clear()
    await event.reply("Order received ✅")

Swap JsonFileStorage for MemoryStorage in tests, or implement the Storage interface to back it with Redis or SQL.

👤 Userbots

from darkob import Messenger

app = Messenger(auth="...", private_key="...")

Authentication, session strings, platforms (web, pwa, android, rubx, rubino, …) and the full method surface are covered in the documentation.

📚 Documentation

The exhaustive, method-by-method reference lives in docs/:

Area Start here
Getting started with bots bot-guide
Bot methods bot-methods
Bot filters bot-filters
Userbot guide client-guide
Userbot methods client-methods
Shad platform shad-guide

Every public method also ships a full docstring:

from darkob import Bot
import inspect

for name in dir(Bot):
    if not name.startswith("_"):
        print(f"{name}: {inspect.getdoc(getattr(Bot, name))}\n")

🗂 Project layout

darkob/
├── bot/          # Bot API surface: endpoint mixins, filters, registry, plugins
├── client/       # Messenger API: chats, groups, channels, messages, settings
├── types/        # Event and update models
├── router.py     # Composable routers
├── fsm.py        # Conversation state + pluggable storage
├── hybrid.py     # Sync/async bridge
└── data.py       # Attribute/item-accessible response wrapper

🛠 Development

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

pytest                    # 121 tests, no network required
ruff check .              # lint
pytest --cov=darkob       # coverage

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

🗺 Roadmap

  • Foundation: packaging, TLS, logging, test suite, CI
  • Performance: indexed dispatch, bounded retries, pooled sessions
  • Routers and FSM
  • Middleware chain on routers
  • Pagination helpers (async for over messages and members)
  • Redis storage backend
  • CLI (darkob new, darkob run)
  • Type-complete public API and mypy in CI

🤝 Contributing

Issues and pull requests are welcome. Please run pytest and ruff check . before opening a PR; CI runs both on every push.

📄 License & credits

MIT. darkob is derived from maxrubika, copyright MEHRAB Farahmand, and keeps the original MIT notice. See 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.2.1

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.2.1
File Size Uploaded Provenance Actions
darkob-0.2.1.tar.gz 195.4 kB With provenance Details for darkob-0.2.1.tar.gz

Built distribution (wheel)

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

Total release size: 550.9 kB

Release files / darkob-0.2.1.tar.gz

Download URL darkob-0.2.1.tar.gz
Size 195.4 kB
Tags Source
SHA-256 checksum
How to use checksums
027f88989d08e5417527a4b89f609d40f2328a150fa1a66ffb0d01c1fb009f05
BLAKE2b-256 checksum
How to use checksums
d3fe45f8f58eb8f47c8bb308e1104153b808b4333f2c584c55bffef9b64ad231
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.2.1-py3-none-any.whl

Download URL darkob-0.2.1-py3-none-any.whl
Size 355.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a6a0fdc9bae134055e89507932e671cec71a9643cdd3a3d873aa6beaa07ac0e1
BLAKE2b-256 checksum
How to use checksums
3482d7ba3ed646a0f9db118275d559b026287a280ea7b1ea1f6729c2f4193523
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.2.1

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.2.1.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