Hello Codex: an OpenAI Telegram Bot

pythonperfection

Eli Ostreicher

Posted on March 6, 2022

Hello Codex: an OpenAI Telegram Bot

Python for Ukraine

Tired of waiting for a Github Copilot invite, I decided to take matters into my own hands 🙈

OpenAI’s Codex is a a GPT-3 powerhouse that converts plain english into runnable code. It can also do many other tasks related to Code, like translate code from one language to another, generate docstrings and explain already written code in plain english.

Codex

Here are the steps to creating your very own personal Codex Telegram bot.

Prerequisite: For Codex API access you need to get an invite from OpenAI. This is free and I got approved after around one week. Join the waitlist here.

If you haven’t already done so, download Telegram, they also offer a great desktop app.

Request a Bot
For this, you talk to BotFather. He is your go-to for all things bot, from creation to settings etc.
Botfather

Type /newbot to begin.

The BotFather will ask you to pick a bot name (which must be universally unique) and a username, it then generates an authentication token for your new bot.


Codex Key
Next, go ahead and grab your API key from OpenAI.

Codex API key

Take note of the 2 keys you just got, we’re going to need them soon.

💡 Dealing with secrets across environments can be a hassle. The folks at Doppler offer a great (and free) product to handle it all.


Python Code
Fire up your favorite editor (VS Code in my case) and lets have some fun!


To start, we pip install the following two libraries:

pip install openai
pip install pyTelegramBotAPI
Enter fullscreen mode Exit fullscreen mode

Begin like so:

import logging
from os import environ as env
from dotenv import load_dotenv # if you dont have dotenv yet: pip install python-dotenv

import telebot
import openai

logger = telebot.logger
telebot.logger.setLevel(logging.DEBUG)

load_dotenv()
bot = telebot.TeleBot(env["BOT_API_KEY"])
openai.api_key = env["OPENAI_API_KEY"]
Enter fullscreen mode Exit fullscreen mode

Enabling logging is always a great idea when working with API’s. Eventually we’ll want to host this somewhere and so the more we log, the less in the dark we are.

Notice how I’m importing environ from os. Using env[‘BOT_API_KEY’] is just prettier/neater than os.environ 🤷‍♂️

Now, let’s establish the communiqué between our shiny new bot and Codex.

@bot.message_handler(func=lambda message: True)
def get_codex(message):
    response = openai.Completion.create(
        engine="code-davinci-001",
        prompt='"""\n{}\n"""'.format(message.text),
        temperature=0,
        max_tokens=1200,
        top_p=1,
        frequency_penalty=0,
        presence_penalty=0,
        stop=['"""'])

    bot.send_message(message.chat.id,
    f'```python\n{response["choices"][0]["text"]}\n```',
    parse_mode="Markdown")

bot.infinity_polling()
Enter fullscreen mode Exit fullscreen mode

Above, we first establish the bot’s decorator to pass on our message to the function below it.

We set max_tokens to 1200 this is because while Codex allows for a max of 4,096 tokens (including your prompt) per call, Telegram bots are capped at 4,096 UTF-8 characters per message. One token is equivalent to roughly 4 characters.

Learn more about the various openai.Completion.create parameters here, their docs are awesome.

In bot.send_message we take advantage of the fact that Telegram offers great Markdown support so the code displays nicely and also allows for tap-to-copy.

Finally, bot.infinity_polling() keeps a constant open ear for incoming messages.

There are lots of other cool things a Telegram bot can do and pyTelegramBotAPI breaks it all down in much detail.


Before running the script, create a .env file in your current directory like so:

BOT_API_KEY = bot-key-here
OPENAI_API_KEY = openai-key-here
Enter fullscreen mode Exit fullscreen mode

Here is what your full script should look like:

    import logging
    from os import environ as env
    from dotenv import load_dotenv # if you dont have dotenv yet: pip install python-dotenv

    import telebot
    import openai


    logger = telebot.logger
    telebot.logger.setLevel(logging.DEBUG)

    load_dotenv()
    bot = telebot.TeleBot(env["BOT_API_KEY"])
    openai.api_key = env["OPENAI_API_KEY"]

    @bot.message_handler(func=lambda message: True)
    def get_codex(message):
    response = openai.Completion.create(
        engine="code-davinci-001",
        prompt='"""\n{}\n"""'.format(message.text),
        temperature=0,
        max_tokens=1200,
        top_p=1,
        frequency_penalty=0,
        presence_penalty=0,
        stop=['"""'])

    bot.send_message(message.chat.id,
    f'```python\n{response["choices"][0]["text"]}\n```',
    parse_mode="Markdown")

    bot.infinity_polling()
Enter fullscreen mode Exit fullscreen mode

Congrats! You now have your very own Codex always at your fingertips.

For your bot to be always accessible you’ll want to host it in the cloud. Whether AWS or Heroku, go with your favorite; bear in mind though that bot.infinity_polling() will need a server setup (i.e. Flask) to run correctly.

To avoid constant compute minutes we can set a webhook instead of polling. In the next article I’ll show you how I did this as an Azure Function app.

💖 💪 🙅 🚩
pythonperfection
Eli Ostreicher

Posted on March 6, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related