Skip to main content

xbot

Build Status License: MIT PyPI version

xbot (read cross-bot), is a code generation tool for translating messaging bots from one platform to another.

pip install x-bot

Abstract

Problem: I built my bot in X (e.g. Telegram) and now I want to have it also in Y (Discord) and Z (Slack). Solution: xbot takes your code for X and generates automatically code for Y and Z, afterward you can still test it and edit it as you wish. xbot does only the boilerplate part, is up to you what you do with it.

Why not having a multiplatform bot? There are some solution there around multiplatform bot, but different messaging platform offer different features, e.g. in Telegram you can have rich bot UI and in Discord you can display a "Bot is typing" message. More then that you might want to have different deployment strategies for different bot, so with we don't want to force any opinion around what you do with your code.

Usage

Decorate functions you want to translate with

@xbot.xfunction
def my_telegram_bot_function(telegram_arguments):

And then generate translated python code (statically) with

python -m xbot my_telegram_bot.py --from python-telegram-bot --to discord.py

where python-telegram-bot is the wrapper you are using to write your Telegram bot, and discord.py is the wrapper you are translating to.

You will now will have a generated code file at gen__xbot.py with the transated runnable code. You are free to do what you want with it!

Example

You can see an example of a real translation in the tests folder where we translate from an orginal_code.py (that runs in Telegram) to an translated_code__expected.py (that runs in Discord).

To view it your self you can just run the tests to assert that the generated code (inside gen__xbot.py) is identical to the expected code.

python -m pytest tests

Build Status If the button is green, it means the test above is passing.

How does it work

xbot is built around the concept that different bot APIs wrappers pretty much works the same way just with different syntax. Here is an example with python-telegram-bot(A) and discord.py(B).

# python-telegram-bot, (A)

def add(update, context):
    """Add two numbers together."""
    try:
        message = update.message.text
        _, left, right = message.split(" ")
        result = int(left) + int(right)
        update.message.reply_text(result)
    except (IndexError, ValueError):
        update.message.reply_text('Usage: /add <left> <right>')
# discord.py, (B)

@bot.command(name='add')
async def add(ctx):
    """Adds two numbers together."""
    try:
        message = ctx.message.content
        _, left, right = message.split(" ")
        result = int(left) + int(right)
        await ctx.send(result)
    except (IndexError, ValueError):
        await ctx.send('Usage: /add <left> <right>')

There is a bunch of differences with the two wrappers, but they practically do the same job.

  • (A) is sync, (B) is async
  • (A) uses plain handlers, (B) uses decorators
  • (A) sends a message with update.message.reply_text, (B) with await ctx.send

NOTE: we are not using the two wrapper in the most idiomatic way we could, but both exampls are still reasonable real-life working examples.

So how can we effectively translate from (A) to (B)? We can use a Jinja2 template to generate (B)

# discord.py, (B)
# xbot TEMPLATE

@bot.command(name='{{function_name}}')
async def {{function_name}}(ctx):
    """
    {{function_docstring}}
    """
    {{ body.replace('update.message.text', 'ctx.message.content')}}

This basic template we can easily generate the original (B) code.

Given that template we just need to parse (A) (we can use it walking the AST for example) to get the values like function name, arguments and body and then just pass them to (B).

Contributing

To add a new translation platform this is the checklist

  • add a TEMPLATE for you library at xbot/templates/WRAPPER_NAME/reply.py (to see the full lists of templates and libraries check xbot/constants.py)
  • add a DICTIONARY in xbot/parsers/WRAPPER_NAME/dictionary.py (that maps to the MetaDictionary in xbot/templates.py)
  • [optional] add a PARSER if you want to translate from your platform to another platform in xbot/parsers/WRAPPER_NAME/parser.py. You can pretty much use all the functions inside xbot/parsers/telegram/parser.py

Release files for x-bot 0.0.15

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

Source distribution (sdist)

Source distribution for x-bot 0.0.15
File Size Uploaded
x-bot-0.0.15.tar.gz 12.0 kB Details

Release files / x-bot-0.0.15.tar.gz

Download URL x-bot-0.0.15.tar.gz
Size 12.0 kB
Tags Source
SHA-256 checksum
How to use checksums
628a17f96d96a9bc15600d115cd9320a54f27a5c61a0f943992a206a116ecf36
BLAKE2b-256 checksum
How to use checksums
7fb52b8c9f8a5eb07b10245a182250925dce2e5bb47b52d18872d143b6550e21
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/46.4.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.7.1

Release history Release notifications | RSS feed

This release

0.0.15 This release

1 release file

0.0.14

1 release file

0.0.13

1 release file

0.0.8

1 release file

0.0.7

1 release file

0.0.6

1 release file

0.0.5

1 release file

0.0.4

1 release file

0.0.3

1 release file

0.0.2

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