#python #multithreading #discord.py #python-asyncio #discord.py-rewrite
#python #многопоточность #python-asyncio #discord.py
Вопрос:
У меня есть discord.py
бот для доступа к API для политики и войны, и у меня есть поток, который нужно проверять каждые 20 минут, чтобы проверять наличие новых действий. Я пытался вставить эту часть on_ready
, но, похоже, это останавливает выполнение любых команд, поэтому мне пришлось создать поток. Однако, когда я пытаюсь запустить этот код, и появляется новое действие для отправки сообщения, возникает ошибка RuntimeError:
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:UsersnaturAppDataLocalProgramsPythonPython38libthreading.py", line 932, in _bootstrap_inner
self.run()
File "C:UsersnaturAppDataLocalProgramsPythonPython38libthreading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "C:/Users/natur/Desktop/Trans-Atlantic-Bot/BOT/main.py", line 100, in update
asyncio.run(update_war())
File "C:UsersnaturAppDataLocalProgramsPythonPython38libasynciorunners.py", line 44, in run
return loop.run_until_complete(main)
File "C:UsersnaturAppDataLocalProgramsPythonPython38libasynciobase_events.py", line 616, in run_until_complete
return future.result()
File "C:/Users/natur/Desktop/Trans-Atlantic-Bot/BOT/main.py", line 61, in update_war
defense_channel = await client.fetch_channel(CHANNEL_1)
File "C:UsersnaturAppDataLocalProgramsPythonPython38libsite-packagesdiscordclient.py", line 1447, in fetch_channel
data = await self.http.get_channel(channel_id)
File "C:UsersnaturAppDataLocalProgramsPythonPython38libsite-packagesdiscordhttp.py", line 185, in request
async with self.__session.request(method, url, **kwargs) as r:
File "C:UsersnaturAppDataLocalProgramsPythonPython38libsite-packagesaiohttpclient.py", line 1012, in __aenter__
self._resp = await self._coro
File "C:UsersnaturAppDataLocalProgramsPythonPython38libsite-packagesaiohttpclient.py", line 426, in _request
with timer:
File "C:UsersnaturAppDataLocalProgramsPythonPython38libsite-packagesaiohttphelpers.py", line 579, in __enter__
raise RuntimeError('Timeout context manager should be used '
RuntimeError: Timeout context manager should be used inside a task
import os
import time
import json
import difflib
import datetime
import asyncio
import threading
import requests
import discord
from discord.ext import commands
TOKEN = os.environ.get("TRANSATLANTICBOT")
KEY = os.environ.get("PNWKEY")
command_dict = {
"help": "Lists the commands and their descriptions",
"help_commands": "ALIAS: help",
"city": "Gets information about the specified city. URL and ID are both accepted.",
}
def req(loc, key_provider=None):
if key_provider is not None:
return requests.get(f"https://politicsandwar.com/api/{loc}{key_provider}key={KEY}").json()
if "=" in loc:
return requests.get(f"https://politicsandwar.com/api/{loc}amp;key={KEY}").json()
else:
return requests.get(f"https://politicsandwar.com/api/{loc}/?key={KEY}").json()
def dict_to_string(d):
newline = "n"
return f'```ymln{newline.join((f"{key}: {value}" for key, value in d.items()))}n```'
async def get_nation(ctx, n_id):
if not n_id.isdigit():
if n_id.startswith("http"):
n_id = n_id[n_id.find("=") 1].rstrip("/")
else:
pass
return n_id
# update
async def update_war():
start_time = time.time()
print("nWAR")
print(f"Update Started - 0 secs")
new = req("wars?alliance_id=7536")
print(f"Recieved Data - {time.time() - start_time} secs")
if "success" in new.keys():
lastcheck = datetime.datetime.utcnow() - datetime.timedelta(hours=0, minutes=21)
wars = new["wars"]
war_time = datetime.datetime.strptime(wars[0]["date"][:19], "%Y-%m-%dT%X")
war = 0
while war_time >= lastcheck:
current_war = wars[war]
war_time = datetime.datetime.strptime(wars[war 1]["date"][:19], "%Y-%m-%dT%X")
if current_war["attackerAA"] in ("Atlantian Council", "Atlantian Council Applicant"):
defense_channel = await client.fetch_channel(CHANNEL_1)
else:
defense_channel = await client.fetch_channel(CHANNEL_2)
spec_war = req(f"war/{current_war['warID']}", "/amp;")
emb = discord.Embed(
title="WAR REPORT",
description=dict_to_string(spec_war),
color=discord.Color(0x00ff00)
)
emb.set_footer(text=f"Pamp;W bot for ANYONE, unlike SOME OTHER BOT - Requested by The Atlantian Council")
await defense_channel.send(embed=emb)
war = 1
print(f"Update Success - {time.time() - start_time} secs")
else:
print(f"Upate Failure - {time.time() - start_time} secs")
print(f"Waiting for next update - {time.time() - start_time} secs")
async def update_nations():
start_time = time.time()
print("nNATION")
print(f"Update Started - 0 secs")
with open("all_nations.json", "w") as nations:
new = req("nations")
print(f"Recieved Data - {time.time() - start_time} secs")
if "success" in new.keys():
json.dump(new, nations)
print(f"Update Success - {time.time() - start_time} secs")
else:
print(f"Upate Failure - {time.time() - start_time} secs")
print(f"Waiting for next update - {time.time() - start_time} secs")
def update():
while True:
try:
asyncio.run(update_war())
asyncio.run(update_nations())
except Exception as e:
print("nnERROR HAPPENEDn")
print(e)
time.sleep(60 * 20)
updater = threading.Thread(target=update, daemon=True)
# run bot
client = commands.Bot(command_prefix=("^", "!", "also,n", "also, ", "tst!"))
client.remove_command("help")
@client.event
async def on_ready():
await client.change_presence(
status=discord.Status.online,
activity=discord.Game(name="Pamp;W")
)
print("BOT READY")
updater.start()
Ответ №1:
async def start():
await bot.wait_until_ready()
# Whatever function you want
bot.loop.create_task(start())