darkob
Fast, stable async Python for the Rubika & Shad platforms.
Build bots and userbots that stay up, without the boilerplate.
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.
Bottalks to the official Bot API;Messengerdrives a real user account, including channels, groups, voice chats and stickers.Shadis the same Messenger protocol against the Shad platform. - Async first, sync friendly. Every method works with
awaitor 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 forover messages and members) - Redis storage backend
- CLI (
darkob new,darkob run) - Type-complete public API and
mypyin 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)
| 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)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| 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 logRelease 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 logSecurity 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.
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 logA 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.