How to return value from async function - python

I have an async function that I'm trying to get the return variable from but I'm not able to get it to work for some reason, I've tried a few different things from googling but theyre all returning a similar error.
I have this function:
#bot.command()
async def start(ctx):
"""starts the server"""
try:
status = server.status()
await ctx.channel.send("The server is already online!")
except:
os.chdir(".\\Minecraft")
file = subprocess.Popen("Start.bat")
await ctx.channel.send("starting the server")
starting = True
while starting == True:
time.sleep(int(delay))
with open("outfile.txt") as outfile:
for line in outfile:
if "Done" in line:
await ctx.channel.send("server has loaded")
starting = False
return file
else:
continue
and i return the variable file
But then when I try to get the variable in another function
#bot.command()
async def kill(ctx):
"""shuts down the server"""
x = start(ctx)
print(x)
x.terminate()
I get the error:
<coroutine object Command.__call__ at 0x040F7B28>
Ignoring exception in command kill:
Traceback (most recent call last):
File "C:\Users\TheRi\AppData\Local\Programs\Python\Python38-32\lib\site-packages\discord\ext\commands\core.py", line 83, in wrapped
ret = await coro(*args, **kwargs)
File "c:/Users/TheRi/OneDrive/Desktop/Python/MinecraftDiscordBot/minecraftBot.py", line 113, in kill
x.terminate()
AttributeError: 'coroutine' object has no attribute 'terminate'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\TheRi\AppData\Local\Programs\Python\Python38-32\lib\site-packages\discord\ext\commands\bot.py", line 892, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\TheRi\AppData\Local\Programs\Python\Python38-32\lib\site-packages\discord\ext\commands\core.py", line 797, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\TheRi\AppData\Local\Programs\Python\Python38-32\lib\site-packages\discord\ext\commands\core.py", line 92, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'coroutine' object has no attribute 'terminate'
C:\Users\TheRi\AppData\Local\Programs\Python\Python38-32\lib\asyncio\events.py:81: RuntimeWarning: coroutine 'Command.__call__' was never awaited
self._context.run(self._callback, *self._args)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
The first line seems to be where I've attempted to print x, to see if I could see what was going on, and the rest is the error. It doesn't seem to be returning any value but just the co routine itself?
I've tried changing the way I refrence the function, x = start(ctx),x = start(),x = start etc.
Is there something I'm doing wrong? How can I return the variable.

You need to await coroutines; i.e. x = await start(ctx)

Related

DiscordPy Extension 'cogs.economy' raised an error: TypeError: object NoneType can't be used in 'await' expression

I get the following error when i run my bot.
discord.ext.commands.errors.ExtensionFailed: Extension 'cogs.economy' raised an error: TypeError: object NoneType can't be used in 'await' expression
I have the extension economy.py in the folder cogs. economy.py:
from discord.ext import commands
class Economy(commands.Cog):
def __init__(self, client):
self.client = client
#commands.Cog.listener()
async def on_message(self, message):
if message.author != self.client.user:
await message.channel.send("hello")
#commands.command()
async def ping(self, ctx):
await ctx.send("pong")
def setup(client):
client.add_cog(Economy(client))
and my client.py has:
import discord
from discord.ext import commands
intents = discord.Intents.all()
intents.message_content = True
prefix = "?"
client = commands.Bot(command_prefix=prefix, intents=intents)
#client.event
async def on_ready():
await client.load_extension('hello')
await client.load_extension('cogs.economy')
print("Bot is ready")
client.run(token=token)
I have tried async-await for the setup but i still cant around this. This is my first time coding a bot. The 'hello' has just a command in it, and it works just fine. I have no idea how there is a NoneType object here.
Thanks.
Edit: Full Error
Traceback (most recent call last):
File "D:\Documents\PythonProjects\DiscordBot\venv\lib\site-packages\discord\ext\commands\bot.py", line 946, in _load_from_module_spec
await setup(self)
TypeError: object NoneType can't be used in 'await' expression
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "D:\Documents\PythonProjects\DiscordBot\venv\lib\site-packages\discord\client.py", line 409, in _run_event
await coro(*args, **kwargs)
File "D:\Documents\PythonProjects\DiscordBot\exp_bot.py", line 51, in on_ready
await client.load_extension('cogs.economy')
File "D:\Documents\PythonProjects\DiscordBot\venv\lib\site-packages\discord\ext\commands\bot.py", line 1012, in load_extension
await self._load_from_module_spec(spec, name)
File "D:\Documents\PythonProjects\DiscordBot\venv\lib\site-packages\discord\ext\commands\bot.py", line 951, in _load_from_module_spec
raise errors.ExtensionFailed(key, e) from e
discord.ext.commands.errors.ExtensionFailed: Extension 'cogs.economy' raised an error: TypeError: object NoneType can't be used in 'await' expression
You didn't show FULL error message but it shows problem with await setup(self)
Traceback (most recent call last):
File "/usr/local/lib/python3.10/dist-packages/discord/ext/commands/bot.py", line 946, in _load_from_module_spec
await setup(self)
TypeError: object NoneType can't be used in 'await' expression
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/local/lib/python3.10/dist-packages/discord/client.py", line 409, in _run_event
await coro(*args, **kwargs)
File "/home/furas/main.py", line 18, in on_ready
await client.load_extension('cogs.economy')
File "/usr/local/lib/python3.10/dist-packages/discord/ext/commands/bot.py", line 1012, in load_extension
await self._load_from_module_spec(spec, name)
File "/usr/local/lib/python3.10/dist-packages/discord/ext/commands/bot.py", line 951, in _load_from_module_spec
raise errors.ExtensionFailed(key, e) from e
discord.ext.commands.errors.ExtensionFailed: Extension 'cogs.economy' raised an error: TypeError: object NoneType can't be used in 'await' expression
and it may suggest that setup() has to use async.
When I use async def setup(client) then I gets different error
/home/furas/cogs/economy.py:19: RuntimeWarning: coroutine 'BotBase.add_cog' was never awaited
client.add_cog(Economy(client))
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
which may suggest that add_cog() has to use await
Code works for me when I add async and await.
async def setup(client):
await client.add_cog(Economy(client))
BTW:
Documentation for load_extension also shows async def setup()

Dictionary "Command' Object is not subscriptable

I am trying to make a bot that does a very simple task, it adds points to a member in the channel for the time the bot is live, in a temporary context. Trying to accomplish this without databases, because I don't need a permanent record of these points. I seem to have come very close to a solution combining a lot of references I've found over the internet. In essence, I create a dictionary based on the member ID and add 1 that key value pair whenever I use the give command, however, I keep getting the error listed below, I appreciate your time and please if someone can explain to me WHY this sub scriptable error happens with my code, Thank you and have a great day.
Adding my code below:
import discord
from discord.ext.commands import Bot
from collections import defaultdict
TOKEN = '#code would go here.'
bot = Bot('!')
points = defaultdict(int)
#bot.event
async def on_ready():
print('We have logged in as {0.user}'.format(bot))
#bot.event
async def on_message(message):
username = str(message.author).split('#')[0]
user_message = str(message.content)
channel = str(message.channel.name)
print(f'{username}: {user_message} ({channel})')
if message.content == "hello":
# SENDS A MESSAGE TO THE CHANNEL.
await message.channel.send("FIX CONTEXT")
# INCLUDES THE COMMANDS FOR THE BOT. WITHOUT THIS LINE, YOU CANNOT TRIGGER YOUR COMMANDS.
await bot.process_commands(message)
#bot.command(pass_context=True)
async def give(ctx, member: discord.Member):
points[member.id] += 1
ctx.send("{} now has {} radiation".format(member.mention, points[member.id]))
#bot.command(pass_context=True)
async def points(ctx, member: discord.Member):
ctx.send("{} has {} radiation".format(member.mention, points[member.id]))
bot.run(TOKEN)
The main thing I don't understand about my code is the line Command raised an exception: TypeError: 'Command' object is not subscriptable
We have logged in as RadiationTracker#7562
AdamKostandy: !!give AdamKostandy#9900 (ffg-game-chat)
Ignoring exception in command None:
discord.ext.commands.errors.CommandNotFound: Command "!give" is not found
AdamKostandy: !give AdamKostandy#9900 (ffg-game-chat)
Ignoring exception in command give:
Traceback (most recent call last):
File "C:\Users\Adam\anaconda3\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "C:/Users/Adam/Documents/GitHub/Discord-Bot/main.py", line 34, in give
points[member.id] += 1
TypeError: 'Command' object is not subscriptable
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\Adam\anaconda3\lib\site-packages\discord\ext\commands\bot.py", line 939, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\Adam\anaconda3\lib\site-packages\discord\ext\commands\core.py", line 863, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\Adam\anaconda3\lib\site-packages\discord\ext\commands\core.py", line 94, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: 'Command' object is not subscriptable
AdamKostandy: !points AdamKostandy#9900 (ffg-game-chat)
Ignoring exception in command points:
Traceback (most recent call last):
File "C:\Users\Adam\anaconda3\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "C:/Users/Adam/Documents/GitHub/Discord-Bot/main.py", line 39, in points
ctx.send("{} has {} radiation".format(member.mention, points[member.id]))
TypeError: 'Command' object is not subscriptable
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\Adam\anaconda3\lib\site-packages\discord\ext\commands\bot.py", line 939, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\Adam\anaconda3\lib\site-packages\discord\ext\commands\core.py", line 863, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\Adam\anaconda3\lib\site-packages\discord\ext\commands\core.py", line 94, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: 'Command' object is not subscriptable

Command raised an exception: TypeError: index 'wallet' cannot be applied to Cursor instances. Discord.py?

I am making a search command for my discord bot with mongodb. This command was not showed anywhere so im testing it around.This is what i made so far but i get the error shown in the title. I dont know how to fix it so if you know please tell me. It would really help it all. Here is my code
async def search(self, ctx):
apple = [
'Shoe',
'Sink',
'Car'
]
await ctx.send(f'What would you like to search? \n``{apple}``')
await open_account(self, ctx.author)
document = collection.find({"userid":ctx.author.id})
wallet_amt = document['wallet']
def check(msg):
return msg.author== ctx.message.author and message.channel==ctx.message.channel and str(msg.content) in ['Shoe','Sink','Car']
msg = await self.bot.wait_for("message", check=check)
if str(msg.content) == 'Sink':
earnings = random.randint(50,200)
await ctx.send(f'You chose to search the ``Sink`` You found <:Coin:842441305242206228> **{earnings}**! Why did you even look there?')
collection.update_one({"userid":ctx.author.id}, {"inc":{"wallet":earnings}})
else:
await ctx.send('XD')
Ignoring exception in command search:
Traceback (most recent call last):
File "/home/container/.local/lib/python3.8/site-packages/discord/ext/commands/core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "/home/container/cogs/economy.py", line 51, in search
wallet_amt = document['wallet']
File "/home/container/.local/lib/python3.8/site-packages/pymongo/cursor.py", line 650, in __getitem__
raise TypeError("index %r cannot be applied to Cursor "
TypeError: index 'wallet' cannot be applied to Cursor instances
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/container/.local/lib/python3.8/site-packages/discord/ext/commands/bot.py", line 939, in invoke
await ctx.command.invoke(ctx)
File "/home/container/.local/lib/python3.8/site-packages/discord/ext/commands/core.py", line 863, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "/home/container/.local/lib/python3.8/site-packages/discord/ext/commands/core.py", line 94, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: index 'wallet' cannot be applied to Cursor instances
find() returns a cursor; you likely want find_one() which returns a dictionary.
document = collection.find_one({"userid":ctx.author.id})

how can I display in the #channel, members with a certain role? (with discord.py)

I'm trying to write a command in my (first) bot that prints in the discord channel all members
in a certain #role (in this it's called "Serf")
this is my command/function
#client.command()
async def snap(ctx):
target = discord.Role.members("Serf")
for person in target:
await ctx.send(person)
but nothing happens and I get this error in the terminal
Ignoring exception in command snap:
Traceback (most recent call last):
File "/home/thonkpad/.local/lib/python3.7/site-packages/discord/ext/commands/core.py", line 83, in wrapped
ret = await coro(*args, **kwargs)
File "Python/thanosBot/bot.py", line 28, in snap
target = discord.Role.members("Serf")
TypeError: 'property' object is not callable
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/thonkpad/.local/lib/python3.7/site-packages/discord/ext/commands/bot.py", line 892, in invoke
await ctx.command.invoke(ctx)
File "/home/thonkpad/.local/lib/python3.7/site-packages/discord/ext/commands/core.py", line 797, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "/home/thonkpad/.local/lib/python3.7/site-packages/discord/ext/commands/core.py", line 92, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: 'property' object is not callable
The problem is you're calling the actual discord.Role object itself and not finding the Role object of the specific role you want. You could do something like this:
#client.command()
async def snap(ctx):
role = discord.utils.get(ctx.message.guild.roles, name="Serf")
target = role.members
for person in target:
await ctx.send(person.name)
target will be a list of discord.Member objects

Disconnect command not working in discord bot, error when running

So I'm trying to code a discord bot, but whenever I try to get it to disconnect, the following error comes up:
Ignoring exception in command leave
Traceback (most recent call last):
File "D:\Python36\lib\site-packages\discord\ext\commands\core.py", line 50, in wrapped
ret = yield from coro(*args, **kwargs)
File "D:\new\main.py", line 31, in leave
await voice_client.disconnect()
File "D:\Python36\lib\site-packages\discord\voice_client.py", line 297, in disconnect
yield from self.ws.close()
File "D:\Python36\lib\site-packages\websockets\protocol.py", line 419, in close
yield from asyncio.shield(self.close_connection_task)
File "D:\Python36\lib\site-packages\discord\gateway.py", line 686, in close_connection
yield from super().close_connection(force=force)
TypeError: close_connection() got an unexpected keyword argument 'force'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "D:\Python36\lib\site-packages\discord\ext\commands\bot.py", line 846, in process_commands
yield from command.invoke(ctx)
File "D:\Python36\lib\site-packages\discord\ext\commands\core.py", line 374, in invoke
yield from injected(*ctx.args, **ctx.kwargs)
File "D:\Python36\lib\site-packages\discord\ext\commands\core.py", line 54, in wrapped
raise CommandInvokeError(e) from e
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: close_connection() got an unexpected keyword argument 'force'
I've tried changing around how I get the bot to disconnect, but it just doesn't seem to want to go through with this line:
await voice_client.disconnect()
Here's the code that's not working.
import discord
from discord.ext import commands
BOT_PREFIX = ('!')
client = commands.Bot(command_prefix=BOT_PREFIX)
#client.command(pass_context = True)
async def leave(ctx):
server = ctx.message.server
voice_client = client.voice_client_in(server)
if voice_client:
await voice_client.disconnect()
await client.say('Disconnected')
else:
await client.say('I am not in a voice channel')
I would recommend you alter your code such as:
voice_client = client.voice_client_in(server)
print(voice_client)
print(dir(voice_client)) # show available methods/attributes of the object
In order to double check that the voice_client object is what you expect it to be. From documentation I see no .voice_client_in(). However there is a VoiceClient.is_connected() method which returns a boolean. More in line with your code though is Client.voice_clients which returns a list of ALL voice chats that are connected. So in your case this return value would look like:
if list_of_chats_connected:
await list_of_chats_connected.disconnect()
which wouldn't make sense, since the list would need to be indexed to be able to call a method of the object inside it like disconnect()

Categories