whentmp
whentmp

Reputation: 3

Discord Python Multithread Bot

I take user input from users on discord and use it for my function check. Though, the check function can take 30-50 seconds to complete each because it has to wait for websites to load etc. I am using requests.get. How can I make this multi threaded?

My current code:

import json
import discord
import os
import bs4
from dotenv import load_dotenv
from discord.ext import commands
from datetime import datetime
import requests
import threading
import time
import re
from string import digits, ascii_letters

load_dotenv()
DISCORD_TOKEN = os.getenv("DISCORD_TOKEN")
bot = commands.Bot(command_prefix="$")
bot.remove_command('help')
now = datetime.now()
dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
url = 'hidden'
url2 = 'hidden'
url3 = 'hidden'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36'}

whitelist = set(digits + ascii_letters + "#_[] -")
blacklist = set("")


@bot.event
async def on_ready():
    print("It's ready")


@bot.command()
async def check(ctx, *args):
    #my very advanced code start
    response = ""
    start_time = time.time()
    for arg in args:
        response = response + " " + arg
    #go on website and scrape with username 
    # my very advanced code end


bot.run(DISCORD_TOKEN)

I am hiding most of my information in my function check.

Upvotes: 0

Views: 627

Answers (1)

Łukasz Kwieciński
Łukasz Kwieciński

Reputation: 15689

requests and urllib are blocking. Do not use this libraries within your asynchronous code. Use aiohttp instead.

Here an example of code using aiohttp and discord.py

import aiohttp

@bot.command()
async def foo(ctx):
    async with aiohttp.ClientSession() as session:
        async with session.get('https://httpbin.org/json') as r:
            res = await r.json()

Don't create a session per request. Most likely you need a session per application which performs all requests altogether.

Here's how to keep one session that you can access from cogs/extensions/functions

@bot.event
async def on_ready():
    await bot.wait_until_ready()
    bot.session = aiohttp.ClientSession()


@bot.command()
async def bar(ctx):
    async with bot.session.get('https://httpbin.org/json') as r:
        res = await r.json()

But if you really want to use requests:

def fetch():
    x = requests.get('https://httpsbin.org/json')
    return x.json()


# in your asynchronous code
response = await bot.loop.run_in_executor(None, fetch)

aiohttp

Upvotes: 1

Related Questions