Issue
This code is for a discord bot that sends a message via a non-async function and I get the error. I understand from the error that there is no event loop, so maybe the solution is to create one. I don't know. Or maybe get_event_loop() is not necessary.
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Users\LENOVO\AppData\Local\Programs\Python\Python38\lib\threading.py", line 932, in _bootstrap_inner
self.run()
File "C:\Users\LENOVO\AppData\Local\Programs\Python\Python38\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "c:/Users/LENOVO/Documents/Ada-online/Discord bot/main copy.py", line 19, in check_time
asyncio.get_event_loop().create_task(channel.send("example message"))
File "C:\Users\LENOVO\AppData\Local\Programs\Python\Python38\lib\asyncio\events.py", line 639, in get_event_loop
raise RuntimeError('There is no current event loop in thread %r.'
RuntimeError: There is no current event loop in thread 'Thread-1'
I am not familiar with discord.py yet so I would need some help. Here's my code:
import discord
import threading
import datetime
import time
import asyncio
intents = discord.Intents.default()
intents.message_content = True
client = discord.Client(intents=intents)
my_secret = 'bot_key'
def check_time():
time.sleep(10)
channel = client.get_channel(1027207022132863036)
print('Channel:', channel)
asyncio.get_event_loop().create_task(channel.send("example message"))
while True:
ndt = datetime.datetime.now()
if ndt.strftime('%A') == 'Friday' and ndt.hour == 16 and ndt.minute == 29 and ndt.second == 5:
asyncio.get_event_loop().create_task(channel.send("example message"))
time.sleep(0.9)
@client.event
async def on_ready():
print('We have logged in as {0.user}'.format(client))
@client.event
async def on_message(msg):
print(msg.channel)
msg_words1 = msg.content.split(' ')
msg_words = []
for i in msg_words1:
msg_words.append(i.lower())
if msg.author == client.user:
return
if ('zoom' in msg_words and 'when' in msg_words) or ('zoom' in msg_words and 'when?' in msg_words) or ('zoom?' in msg_words and 'when' in msg_words):
await msg.channel.send('We have zoom every day from 16:00 to 17:30.')
t = threading.Thread(target=check_time)
t.start()
client.run(my_secret)
Thanks!
Solution
You are running the check_time function as a separate thread. The asyncio event loop is thread-specific. So if you want to do asyncio-stuff in a second thread, there must be a running event loop in that thread.
The function asyncio.get_event_loop(), if called from the main thread will create and set a new event loop. This behavior has changed slightly in Python3.10 and will change some more in Python3.11. But note what the docs say:
"If there is no current event loop set in the current OS thread, the OS thread is main, and set_event_loop() has not yet been called, asyncio will create a new event loop and set it as the current one."
But if the OS thread isn't main, a call to this function will raise an Exception, as you observe. The fix is simple enough - create and set the event loop explicitly in your secondary thread:
def check_time():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
# The rest of the code is unchanged
time.sleep(10)
channel = client.get_channel(1027207022132863036)
print('Channel:', channel)
asyncio.get_event_loop().create_task(channel.send("example message"))
while True:
ndt = datetime.datetime.now()
if ndt.strftime('%A') == 'Friday' and ndt.hour == 16 and ndt.minute == 29 and ndt.second == 5:
asyncio.get_event_loop().create_task(channel.send("example message"))
time.sleep(0.9)
However, this is probably only one of your issues. The event loop is an infinite loop, and your code also has one of those. You can't have two such loops in the same task. So you probably want to organize your program in a more task-like structure, for example:
async def tgif():
channel = client.get_channel(1027207022132863036)
print('Channel:', channel)
asyncio.create_task(channel.send("example message"))
while True:
ndt = datetime.datetime.now()
if ndt.strftime('%A') == 'Friday' and ndt.hour == 16 and ndt.minute == 29 and ndt.second == 5:
asyncio.create_task(channel.send("example message"))
await asyncio.sleep(0.9)
def check_time():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
time.sleep(10)
asyncio.run(tgif())
You need to look carefully at the documentation for time.sleep and asyncio.sleep, which are different in important ways. I changed one of your time.sleep calls to asyncio.sleep because that seemed right; I don't understand why you have put those sleeps in your program, so I won't comment on that.
Also the new function that now contains your infinite loop, which I named tgif
, needs to be declared with the async keyword, since it is a Task.
Unfortunately I don't know anything about discord, but at least this should get rid of the error.
Answered By - Paul Cornelius
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.