ShuttleAI with discord.py

A lot of you won’t remember me. This is my first post in 3 months. I have officially moved to https://pebblehost.com to host my projects ( if you are wondering where I have been ).

Now, I want to show you this new AI platform i found that is safe and trusted. https://shuttleai.app/. Now I am not going to taunt you openai users, but I found shuttleai is more of a high risk high reward AI. Let me give you a short summary of what shuttleai can do. Shuttleai has more than 30 models to choose from (eg. midjourney, gpt-4,anything-v5, etc. ) . You won’t have to pay a cent for SOME of these models. You can create an account here . You should head over to the https://shuttleai.app/keys API keys section. You should copy the master key. This key on free plan will provide ( in comparison to openai’s api key limits ):

OPENAI

  • 3 requests/min
  • 200 requests/day
  • $5 budget given

ShuttleAI:

  • 5 requests/min
  • 500 requests/day
  • No budget required, which means that as long as you don’t go over the requests/min or requests/day, you can infinitely use it without a budget.

Heres an example of shuttleai in action, we shall pick the gpt-4 model. ( Synchronous )

import requests
url = "https://api.shuttleai.app/v1/chat/completions"

payload = {
    "model": "gpt-4",
    "messages": [
        {
            "role": "<string>",
            "content": "<string>"
        }
    ]
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}
response = requests.request("POST", url, json=payload, headers=headers)
response = response.json()
print(response["choices"][0]["message"]["content"])

Now that you know How to use shuttleAI to generate response prompts, lets move on to discord.py, we shall use slash commands instead of prefix commands, since im more familiar with slash commands.
lets import the necessary things and get things ready to run our bot.

import discord
from discord import app_commands
from discord.ext import commands

intents = discord.Intents.default()


bot = commands.Bot(command_prefix="!", intents=intents)


@bot.event
async def on_ready():
    print("We have logged in as {0.user}".format(bot))
    #await bot.change_presence(activity=discord.Game(name="PlaceHolder")) #set your activity prescence.
    try:
        synced = await bot.tree.sync()
        print(f"synced {len(synced)} command(s)")
    except Exception as e:
        raise e
    

try:
    token = "PlaceHolder for your real token" #replace this with your bot token, to get your bot token, go to https://discord.com/developers/applications and create a bot. Then go to the 'bot' section and generate a key.
    bot.run(token)
except discord.HTTPException as e:
    if e.status == 429:
        print("The Discord servers denied the connection for too many requests")
        print(
            "Get help from https://stackoverflow.com/questions/66724687/in-discord-py-how-to-solve-the-error-for-toomanyrequests"
        )
    else:
        raise e

now, after all this has been done, lets move on.

Lets create your first command!

Now, lets create your first command with:

import discord
from discord import app_commands
from discord.ext import commands

intents = discord.Intents.default()


bot = commands.Bot(command_prefix="!", intents=intents)


@bot.event
async def on_ready():
    print("We have logged in as {0.user}".format(bot))
    #await bot.change_presence(activity=discord.Game(name="PlaceHolder")) #set your activity prescence.
    try:
        synced = await bot.tree.sync()
        print(f"synced {len(synced)} command(s)")
    except Exception as e:
        raise e
    
@bot.tree.command(name='prompt')
async def prompt(interaction:discord.Interaction):
    pass

try:
    token = "PlaceHolder for your real token" #replace this with your bot token, to get your bot token, go to https://discord.com/developers/applications and create a bot. Then go to the 'bot' section and generate a key.
    bot.run(token)
except discord.HTTPException as e:
    if e.status == 429:
        print("The Discord servers denied the connection for too many requests")
        print(
            "Get help from https://stackoverflow.com/questions/66724687/in-discord-py-how-to-solve-the-error-for-toomanyrequests"
        )
    else:
        raise e

we shall use prompt for the purposes of this resource. Now, lets make a functioning command that lets you chat! We will require aiohttp for this.


import discord
from discord import app_commands
from discord.ext import commands

intents = discord.Intents.default()


bot = commands.Bot(command_prefix="!", intents=intents)


@bot.event
async def on_ready():
    print("We have logged in as {0.user}".format(bot))
    #await bot.change_presence(activity=discord.Game(name="PlaceHolder")) #set your activity prescence.
    try:
        synced = await bot.tree.sync()
        print(f"synced {len(synced)} command(s)")
    except Exception as e:
        raise e
    
@bot.tree.command(name='prompt')
async def prompt(
    interaction:discord.Interaction,
    prompt: str
                 ):
    url = "https://api.shuttleai.app/v1/chat/completions"
    payload = {
                "messages": [
                    {
                        "content": f"""
    """,
                        "role": "user",
                    }
                ],
                "model": "shuttle-2-turbo", # can be another model.
            }
    headers = {
        "Authorization": f"Bearer shuttle-xxxxxxxxxxxxxxxxxxx",
        "Content-Type": "application/json",
    }
    #Requests wont work in asynchronous, lets use aiohttp.
    async with aiohttp.ClientSession() as session:
        async with session.post(url, json=payload, headers=headers) as response:
            if response.status == 200:
                response_data = await response.json()
                generated_response = response_data["choices"][0]["message"][
                    "content"
                ]
            else:
                # Handle errors

                error_message = await response.text()
                await interaction.followup.send(
                    f"Error with API: {error_message}"
                )
                return
    await interaction.response.send_message(f'Your response: {generated_response}')
    return

try:
    token = "PlaceHolder for your real token" #replace this with your bot token, to get your bot token, go to https://discord.com/developers/applications and create a bot. Then go to the 'bot' section and generate a key.
    bot.run(token)
except discord.HTTPException as e:
    if e.status == 429:
        print("The Discord servers denied the connection for too many requests")
        print(
            "Get help from https://stackoverflow.com/questions/66724687/in-discord-py-how-to-solve-the-error-for-toomanyrequests"
        )
    else:
        raise e

extra: Now if you notice slow responses, it’s because you are using a lot of resources during that aiohttp session, lets try and reduce that by using a singleton aiohttp session, then closing it to minimize resources wasted.

#imports here...


class SingletonAiohttpSession:
    _session = None

    @classmethod
    async def get_session(cls):
        if cls._session is None:
            cls._session = aiohttp.ClientSession()
        return cls._session

    @classmethod
    async def close_session(cls):
        if cls._session is not None:
            await cls._session.close()
            cls._session = None


#rest of your code here

now, lets define a function that uses this singleton aiohttp session and implement it into our code, we shall also use orjson because .json is SUPER SUPER SUPER slow.

import discord
from discord import app_commands
from discord.ext import commands
import orjson
import aiohttp

class SingletonAiohttpSession:
    _session = None

    @classmethod
    async def get_session(cls):
        if cls._session is None:
            cls._session = aiohttp.ClientSession()
        return cls._session

    @classmethod
    async def close_session(cls):
        if cls._session is not None:
            await cls._session.close()
            cls._session = None
async def make_post_request(url, payload, headers):
    session = await SingletonAiohttpSession.get_session()
    async with session.post(url, json=payload, headers=headers) as response:
        if response.status == 200:
            response_data = await response.read()
            response_data = orjson.loads(response_data)
            generated_response = response_data["choices"][0]["message"]["content"]
            return generated_response
        else:

            error_message = await response.text()
            return

intents = discord.Intents.default()


bot = commands.Bot(command_prefix="!", intents=intents)


@bot.event
async def on_ready():
    print("We have logged in as {0.user}".format(bot))
    #await bot.change_presence(activity=discord.Game(name="PlaceHolder")) #set your activity prescence.
    try:
        synced = await bot.tree.sync()
        print(f"synced {len(synced)} command(s)")
    except Exception as e:
        raise e
    
@bot.tree.command(name='prompt')
async def prompt(
    interaction:discord.Interaction,
    prompt: str
                 ):
    url = "https://api.shuttleai.app/v1/chat/completions"
    payload = {
                "messages": [
                    {
                        "content": f"""
    """,
                        "role": "user",
                    }
                ],
                "model": "shuttle-2-turbo", # can be another model.
            }
    headers = {
        "Authorization": f"Bearer shuttle-xxxxxxxxxxxxxxxxxxx",
        "Content-Type": "application/json",
    }
    #Requests wont work in asynchronous, lets use aiohttp.
    generated_response = await make_post_request(url, payload, headers)
    await SingletonAiohttpSession.close_session()
    await interaction.response.send_message(f'Your response: {generated_response}')
    return

try:
    token = "PlaceHolder for your real token" #replace this with your bot token, to get your bot token, go to https://discord.com/developers/applications and create a bot. Then go to the 'bot' section and generate a key.
    bot.run(token)
except discord.HTTPException as e:
    if e.status == 429:
        print("The Discord servers denied the connection for too many requests")
        print(
            "Get help from https://stackoverflow.com/questions/66724687/in-discord-py-how-to-solve-the-error-for-toomanyrequests"
        )
    else:
        raise e

and now you have finished, enjoy. to check out shuttle, please go to https://shuttleai.app/

1 Like

If you want the discord server, lmk.

Hi @Idkwhttph , welcome back!
Nice to see you back, hope you’ve been fine!
Can this be ran on Replit?

In what way?

Shuttle offers a TON and I mean a TON of AI models, ranging from chat completion models to text to speech models. So sometimes some AI models may tend go have some kind of downtime, while openai has almost 100% uptime.

And yes you can run this on replit, it just needs some pip installing of orjson, aiohttp, etc if needed and done.

1 Like