Skip to main content

Add your description here

Project description

🤖 Async Zulip Bot SDK

Async, type-safe Zulip bot development framework

Python 3.12+ License

English | 中文


📦 Installation

  1. Clone the repository
git clone https://github.com/Open-LLM-VTuber/async-zulip-bot-sdk.git
cd async-zulip-bot-sdk
  1. Install in a virtual environment (recommended)
# Using uv (recommended)
uv venv
uv pip install -e .

# Or using venv + pip
python -m venv venv
venv\Scripts\activate  # Windows
source venv/bin/activate  # macOS/Linux
pip install -e .

🚀 Quick Start

1. Configure Zulip Credentials

Download your zuliprc file:

You can create or regenerate your API Key in Settings - Personal - Account & privacy, enter your password, and select Download zuliprc. Place each bot's file under its own folder, e.g. bots/echo_bot/zuliprc.

2. Configure bots.yaml

Create a bots.yaml file at the root of project, you can refer to bots.yaml.example for details. Define which bots to launch and where to find them:

bots:
  - name: echo_bot
    module: bots.echo_bot
    class_name: BOT_CLASS
    enabled: true
    # Optional override; defaults to bots/<name>/zuliprc
    # zuliprc: bots/echo_bot/zuliprc
    config: {}  # optional per-bot config passed to factory (second arg)

3. Create Your First Bot

import asyncio

from bot_sdk import (
    BaseBot,
    BotRunner,
    Message,
    CommandSpec,
    CommandArgument,
    setup_logging
)

class MyBot(BaseBot):
    command_prefixes = ("!", "/")  # Command prefixes
    
    def __init__(self, client):
        super().__init__(client)
        # Register commands
        self.command_parser.register_spec(
            CommandSpec(
                name="echo",
                description="Echo back the provided text",
                args=[CommandArgument("text", str, required=True, multiple=True)],
                handler=self.handle_echo,
            )
        )
    
    async def on_start(self):
        """Called when bot starts"""
        print(f"Bot started! User ID: {self._user_id}")
    
    async def handle_echo(self, invocation, message, bot):
        """Handle echo command"""
        text = " ".join(invocation.args.get("text", []))
        await self.send_reply(message, f"Echo: {text}")
    
    async def on_message(self, message: Message):
        """Handle non-command messages"""
        await self.send_reply(message, "Try !help to see available commands!")

BOT_CLASS = MyBot

Remember to save this code in a __init__.py file under the directory your configured in bots.yaml. In this example, you would save it as bots/echo_bot/__init__.py.

4. Run Your Bots

python main.py

📚 Core Concepts

AsyncClient

Fully async Zulip API client mirroring the official zulip.Client interface:

from bot_sdk import AsyncClient

async with AsyncClient(config_file="zuliprc") as client:
    # Get user profile
    profile = await client.get_profile()
    
    # Send messages
    await client.send_message({
        "type": "stream",
        "to": "general",
        "topic": "Hello",
        "content": "Hello, world!"
    })
    
    # Get subscriptions
    subs = await client.get_subscriptions()

Command System

Type-safe command definitions with automatic validation:

from bot_sdk import CommandSpec, CommandArgument

# Define commands with arguments
self.command_parser.register_spec(
    CommandSpec(
        name="greet",
        description="Greet a user",
        args=[
            CommandArgument("name", str, required=True),
            CommandArgument("times", int, required=False),
        ],
        handler=self.handle_greet,
    )
)

async def handle_greet(self, invocation, message, bot):
    name = invocation.args["name"]
    times = invocation.args.get("times", 1)
    greeting = f"Hello, {name}! " * times
    await self.send_reply(message, greeting)

Auto-generated help:

Use !help or !? to automatically show all registered commands and arguments.

Lifecycle Hooks

class MyBot(BaseBot):
    async def on_start(self):
        """Called when bot starts"""
        pass
    
    async def on_stop(self):
        """Called when bot stops"""
        pass
    
    async def on_message(self, message: Message):
        """Called for non-command messages"""
        pass

🔧 Advanced Usage

Custom Command Prefixes and Mention Detection

class MyBot(BaseBot):
    command_prefixes = ("!", "/", ".")
    enable_mention_commands = True  # Enable @bot to trigger commands

Typed Message Models

from bot_sdk import Message, StreamMessageRequest

async def on_message(self, message: Message):
    # Full type hints
    sender = message.sender_full_name
    content = message.content
    
    # Send typed messages
    await self.client.send_message(
        StreamMessageRequest(
            to=message.stream_id,
            topic="Reply",
            content="Typed reply!"
        )
    )

📚 Documentation

Comprehensive API documentation is available:

Documentation includes:

  • 📖 Quick Start Guide
  • 🔧 API Reference (AsyncClient, BaseBot, BotRunner)
  • 💬 Command System
  • 📊 Data Models
  • ⚙️ Configuration Management
  • 📝 Logging

🤝 Contributing

Contributions are welcome! Feel free to submit Pull Requests.

Contributing Documentation: We welcome documentation contributions in both Chinese and English.

🙏 Credits & Notices

📄 License

MIT License - see LICENSE file for details


Made with ❤️ for the Open-LLM-VTuber Zulip team

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

async_zulip_bot_sdk-0.2.0.tar.gz (28.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

async_zulip_bot_sdk-0.2.0-py3-none-any.whl (32.5 kB view details)

Uploaded Python 3

File details

Details for the file async_zulip_bot_sdk-0.2.0.tar.gz.

File metadata

  • Download URL: async_zulip_bot_sdk-0.2.0.tar.gz
  • Upload date:
  • Size: 28.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for async_zulip_bot_sdk-0.2.0.tar.gz
Algorithm Hash digest
SHA256 0a7eccf2fb457ea3ca3d9493a85609da3d5e1db3ad016a511901e3d0e4776da6
MD5 d15749b2a4f714a6291203d2d369fd37
BLAKE2b-256 4afeeba20a294dfe2e9b2ec626efd2a6bb8702c7e9fb628db7c08329a14ab39e

See more details on using hashes here.

Provenance

The following attestation bundles were made for async_zulip_bot_sdk-0.2.0.tar.gz:

Publisher: python-publish.yml on Open-LLM-VTuber/async-zulip-bot-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file async_zulip_bot_sdk-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for async_zulip_bot_sdk-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a3a29cee5e6f2b35b47ccac1aeca8b8b1c31f23aadcd38290e7e273afbf2c3da
MD5 7d1c296e6f283408679cd90c2d9a9753
BLAKE2b-256 4449b1dad69f866d7d9a277efd0b4988a53f3bf9c79ae00f1dd353c14faf4a02

See more details on using hashes here.

Provenance

The following attestation bundles were made for async_zulip_bot_sdk-0.2.0-py3-none-any.whl:

Publisher: python-publish.yml on Open-LLM-VTuber/async-zulip-bot-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page