Translation in discord.py bot doesn't work - python

I've been trying to make my discord bot translate texts using a module called googletrans. It seems fairly simple and it should have worked without any hassle, or so I thought.
So after my import statements, I have translator = Translator().
My following cog code is:
#commands.command(aliases=["tl", "Tl", "Translate"])
async def translate(self, ctx, *, message):
language = translator.detect(message)
translation = translator.translate(message)
embed = discord.Embed(color=discord.Color.dark_theme())
embed.add_field(name=f"Language: {language} ", value=f'{translation}')
await ctx.send(embed=embed)
But it shows this error: discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'NoneType' object has no attribute 'group'.
Where am I going wrong? Any help would be much appreciated!
Edit: the full traceback:
Ignoring exception in command translate:
Traceback (most recent call last):
File "C:\Users\wave computer\PycharmProjects\pythonProject\venv\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "C:\Users\wave computer\PycharmProjects\pythonProject\cogs\translate.py", line 13, in translate
language = translator.detect(message)
File "C:\Users\wave computer\PycharmProjects\pythonProject\venv\lib\site-packages\googletrans\client.py", line 255, in detect
data = self._translate(text, 'en', 'auto', kwargs)
File "C:\Users\wave computer\PycharmProjects\pythonProject\venv\lib\site-packages\googletrans\client.py", line 78, in _translate
token = self.token_acquirer.do(text)
File "C:\Users\wave computer\PycharmProjects\pythonProject\venv\lib\site-packages\googletrans\gtoken.py", line 194, in do
self._update()
File "C:\Users\wave computer\PycharmProjects\pythonProject\venv\lib\site-packages\googletrans\gtoken.py", line 62, in _update
code = self.RE_TKK.search(r.text).group(1).replace('var ', '')
AttributeError: 'NoneType' object has no attribute 'group'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\wave computer\PycharmProjects\pythonProject\venv\lib\site-packages\discord\ext\commands\bot.py", line 902, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\wave computer\PycharmProjects\pythonProject\venv\lib\site-packages\discord\ext\commands\core.py", line 864, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\wave computer\PycharmProjects\pythonProject\venv\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: AttributeError: 'NoneType' object has no attribute 'group'

I had a same problem. Installing alpha version of google trans helped, so try doing this:
pip install googletrans==3.1.0a0
And:
from googletrans import Translator
#client.command()
async def translate(ctx, lang, *, thing):
translator = Translator()
translation = translator.translate(thing, dest=lang)
await ctx.send(translation.text)

I cannot add comments since I do not have enough reputation, so I will edit this post once I get more information about your code.
Could you please upload the full traceback? Also what happens if before calling the method group on the object, you ensures that it is not None ? (I don't know if this is in your code or in the library)
Have you tried debugging and checking at each step what the variables are and if they are not what you think they should be
Finally, I also think that maybe your variable message is always empty, since you catch other parameters with * right before message so this makes the message parameter a keyword-only parameter, which, to the best of my knowledge cannot be passed when using a bot command
Have you tried changing your function's signature to this :
async def translate(self, ctx, message):
?
UPDATE : From what it seems, the problem happens inside the library, however this can happen if the parameter given to the library function is ill-formed.
If you simulate the bot command (await the method in a main file with ctx=None and message="Hello my friend, how are you today ? I hope you are fine"), what happens?
As can be seen on the pypi page about googletrans on section "Language detection", most of the time the function is called with a sentence. Maybe if the sentence is short enough, the detection does not work ?
Also, I think you should indicate in your question what library you are using because there is also Google's official translate API that can be used

Related

Cannot install modules using micropip (Pyodide 0.19.0)

I am facing an error of "ImportError: cannot import name 'fetch' from 'js' (unknown location)" whenever I try to install any module in pyodide.
Initially, I tried the following lines of code :
await pyodide.loadPackage('micropip')
await pyodide.runPythonAsync(`
import micropip
await micropip.install('textblob')
from textblob import TextBlob
// ... something
`)
but it still gave the above error.
then i tried to run the code from the official documentation (https://pyodide.org/en/stable/usage/loading-packages.html)
await pyodide.loadPackage("micropip");
await pyodide.runPythonAsync(`
import micropip
micropip.install('snowballstemmer')
import snowballstemmer
stemmer = snowballstemmer.stemmer('english')
print(stemmer.stemWords('go goes going gone'.split()))
`);
but it still gave me the same error.
could someone guide me how to solve this?
i also tried to loadpackage('js') and importing it inside the runPythonAsync but it still failed.
here's the full version of the error :-
PythonError: Traceback (most recent call last):
File "/lib/python3.9/asyncio/futures.py", line 201, in result
raise self._exception
File "/lib/python3.9/asyncio/tasks.py", line 258, in __step
result = coro.throw(exc)
File "/lib/python3.9/site-packages/micropip/_micropip.py", line 185, in install
transaction = await self.gather_requirements(requirements, ctx, keep_going)
File "/lib/python3.9/site-packages/micropip/_micropip.py", line 175, in gather_requirements
await gather(*requirement_promises)
File "/lib/python3.9/asyncio/futures.py", line 284, in __await__
yield self # This tells Task to wait for completion.
File "/lib/python3.9/asyncio/tasks.py", line 328, in __wakeup
future.result()
File "/lib/python3.9/asyncio/futures.py", line 201, in result
raise self._exception
File "/lib/python3.9/asyncio/tasks.py", line 256, in __step
result = coro.send(None)
File "/lib/python3.9/site-packages/micropip/_micropip.py", line 284, in add_requirement
metadata = await _get_pypi_json(req.name)
File "/lib/python3.9/site-packages/micropip/_micropip.py", line 88, in _get_pypi_json
return json.loads(await fetch_string(url))
File "/lib/python3.9/site-packages/micropip/_micropip.py", line 60, in fetch_string
return await (await pyfetch(url, **kwargs)).string()
File "/lib/python3.9/site-packages/pyodide/http.py", line 229, in pyfetch
from js import fetch as _jsfetch, Object
ImportError: cannot import name 'fetch' from 'js' (unknown location)
guidance needed.
If you are trying to achieve this in node.js you need to install node-fetch (or any other library that provides fetch function) and make it available as global/globalThis element so that pyodide's js can also access it.
For your example from the documentation regarding snowballstemmer, I was able to run it with the following code inside a file named example.mjs and executing it as node example.mjs:
import fetch from "node-fetch";
globalThis.fetch = fetch;
let pyodide_pkg = await import("./pyodide/pyodide.js");
let pyodide = await pyodide_pkg.loadPyodide({
indexURL: "pyodide",
});
await pyodide.loadPackage("micropip");
await pyodide.runPythonAsync(`
import micropip
await micropip.install('snowballstemmer')
import snowballstemmer
stemmer = snowballstemmer.stemmer('english')
print(stemmer.stemWords('go goes going gone'.split()))
`);
This gives the expected output and the stemmed results as:
['go', 'goe', 'go', 'gone']
PS: While it is a bad practice to use global/globalThis in general but since fetch in browsers is available as a member of window (i.e. window.fetch), I guess it is okay to use it this way.

Discord.py AttributeError: module 'typing' has no attribute '_UnionGenericAlias'

I have tracked my error to this code, which is in a cog:
#cog_ext.cog_slash(name="help")
async def help_slash(self, ctx, Command_Name=None):
await helpMethod(ctx, Command_Name)
Here is the full error:
Traceback (most recent call last):
File "main.py", line 102, in <module>
class bot(commands.Cog):
File "main.py", line 110, in bot
async def help_slash(self, ctx, Command_Name=None):
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord_slash/cog_ext.py", line 63, in wrapper
opts = manage_commands.generate_options(cmd, desc, connector)
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord_slash/utils/manage_commands.py", line 313, in generate_options
SlashCommandOptionType.from_type(param.annotation) or SlashCommandOptionType.STRING
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord_slash/model.py", line 488, in from_type
and isinstance(t, typing._UnionGenericAlias) # noqa
AttributeError: module 'typing' has no attribute '_UnionGenericAlias'
My research suggests this may be an error with Python itself. If so, is there a way to circumvent the problem? I have tested helpMethod: the error comes from the declaration of the slash command.
Thanks so much for reading.
Look at Python 3.8 typing library code, you can see _UnionGenericAlias is not defined.
However, in Python 3.9, it is defined.
So the solution is you have to upgrade your Python version.

TypeError: __init__() takes 1 positional argument but 2 were given , announcement bot for discord

My bot is actually having a problem with running the command and idk why its keep giving me this error ,The bot that I am using is for a announcement purpose on discord, So this the code that I am using in the bot:
import discord
from discord.ext import commands
from discord.ext.commands import Bot
import asyncio
import time
from discord.ext.commands import has_permissions
client = commands.Bot(command_prefix = "+")
client.remove_command("help")
#client.event
async def on_ready():
print(client.user.name)
print("Online")
print("-------")
#client.command(pass_context=True)
async def announce(ctx,*,message):
embed = discord.Embed("Information",description=message,color=0x9200ea)
embed.set_footer(text="Made by Elanovic#7940")
await client.send_message(ctx.message.channel,embed=embed)
client.run("TOKEN")
And this is the error I get from the cmd:
Ignoring exception in command announce:
Traceback (most recent call last):
File "C:\Users\Hasanfox69\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "C:\Users\Hasanfox69\Desktop\PYTHON\bot.py", line 19, in announce
embed = discord.Embed("Information",description=message,color=0x9200ea)
TypeError: __init__() takes 1 positional argument but 2 were given
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\Hasanfox69\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\bot.py", line 939, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\Hasanfox69\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 863, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\Hasanfox69\AppData\Local\Programs\Python\Python39\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: __init__() takes 1 positional argument but 2 were given
As well all of this is happening in the cmd and the bot take commands from the discord channel by the command +announce
but the bot respond with the above in the cmd
The error in your code is a simple command's attribute error.
The syntax for an Embed is:
discord.Embed(Name="Embed", description='This is an EMBED', color=0xff00ff)
Where is the error in your code?
The error is in the EMBED code and it can also be seen in the Traceback.
embed = discord.Embed("Information",description=message,color=0x9200ea)
You must be trying to put the name of the embed but you didn't write it correctly.
So, I would just say that change this line to:
discord.Embed(name='Information', description=message, color=0x9200ea)
This would completely solve your issue.
In the end, just a simple piece of advice from my side. Always check the Traceback for the error. In the traceback you can see this:
1.File "C:\Users\Hasanfox69\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped
2. ret = await coro(*args, **kwargs)
3. File "C:\Users\Hasanfox69\Desktop\PYTHON\bot.py", line 19, in announce
4. embed = discord.Embed("Information",description=message,color=0x9200ea)
TypeError: __init__() takes 1 positional argument but 2 were given
The line number 4 (according to my marking) shows that the error is in the Embed code so you can simply solve it by just knowing where it is coming from.
I was glad that I could help. Please feel free to ask if you still have any problem. :)
Thank You! :D

How to manipulate an image on discord.py with Pillow?

I'm trying to create an image manipulation command for discord.py. However, this error keeps appearing whenever I run the command.
C:\Users\danie\AppData\Local\Programs\Python\Python38\lib\site-packages\PIL\Image.py:2884: RuntimeWarning: coroutine 'Asset.read' was never awaited
fp = io.BytesIO(fp.read())
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Ignoring exception in on_command_error
Traceback (most recent call last):
File "C:\Users\danie\AppData\Local\Programs\Python\Python38\lib\site-packages\PIL\Image.py", line 2882, in open
fp.seek(0)
AttributeError: 'Asset' object has no attribute 'seek'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\danie\AppData\Local\Programs\Python\Python38\lib\site-packages\discord\ext\commands\core.py", line 83, in wrapped
ret = await coro(*args, **kwargs)
File "C:\Users\danie\Documents\Scripts\Bots\DiscordBot\skybot.py.py", line 802, in push
im2 = Image.open(member.avatar_url)
File "C:\Users\danie\AppData\Local\Programs\Python\Python38\lib\site-packages\PIL\Image.py", line 2884, in open
fp = io.BytesIO(fp.read())
TypeError: a bytes-like object is required, not 'coroutine'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\danie\AppData\Local\Programs\Python\Python38\lib\site-packages\discord\client.py", line 312, in _run_event
await coro(*args, **kwargs)
File "C:\Users\danie\Documents\Scripts\Bots\DiscordBot\skybot.py.py", line 237, in on_command_error
raise error
File "C:\Users\danie\AppData\Local\Programs\Python\Python38\lib\site-packages\discord\ext\commands\bot.py", line 892, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\danie\AppData\Local\Programs\Python\Python38\lib\site-packages\discord\ext\commands\core.py", line 797, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\danie\AppData\Local\Programs\Python\Python38\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: TypeError: a bytes-like object is required, not 'coroutine'
This is my current code for the command. I dont' understand what a bytes are and I'm just really confused. Will someone help me out? Basically my push command is supposed to be a picture of the author's avatar pushing another person's avatar down a cliff. That's my idea.
#client.command()
async def push(ctx, member: discord.Member):
author = ctx.author
embed = discord.Embed(title="Push :D", description = None)
im1 = Image.open(fp=r'C:\Users\danie\Documents\Scripts\Bots\DiscordBot\Img Commands\peakcommand.jpg')
im2 = Image.open(member.avatar_url)
im3 = Image.open(author.avatar_url)
im1.paste(im2)
im1.paste(im3)
img1.save(r'C:\Users\danie\Documents\Scripts\Bots\DiscordBot\Img Commands\completedpeak.jpg')
file = discord.File(r"C:\Users\danie\Documents\Scripts\Bots\DiscordBot\Img Commands", filename = "completedpeak.jpg")
embed.set_image(url="attachment://completedpeak.jpg")
await ctx.send(file=file, embed=embed)
Your Code logic is fine I guess,The only area where the code might have gone a little out of track would be at the time where you were feeding the path in the sting from.:
here:
im1 = Image.open(fp='Users\danie\Documents\Scripts\Bots\DiscordBot\Img Commands\peakcommand.jpg')
There the string is not raw, which means that the characters after the backslash() will be collectively assumed to be an escape sequence character. so a simple solution that I would suggest you is to use (r) before your string.
Like this:
im1 = Image.open(fp=r'Users\danie\Documents\Scripts\Bots\DiscordBot\Img Commands\peakcommand.jpg')
Try this:
And if this doesnt work I have written a small program that uses PIL module to change the img of Tkinter logo, you can use it as a reference for writing proper syntax while importing an image.
from tkinter import *
from PIL import ImageTk,Image
root= Tk()
img = ImageTk.PhotoImage(Image.open(r'C:\Users\Nexus\Desktop\IMG_20200531_092328-01.jpeg'))
root.iconphoto(False,img)
root.mainloop()

Python try except block runs the except code when I don't expect a problem and just gives an error when I expect it to run the except code

I'm working on a discord bot in python that will wish people a happy birthday. I plan on having users give their birthdays to the bot via a command so that it can store it in a txt file. This is the code so far:
#bot.command(pass_context=True)
async def birthday(ctx,arg1,arg2,arg3,arg4):
try:
if (ctx.user == bot.user):
return
print(arg1 + ', ' + str(arg2) + ', ' + str(arg3) + ', ' + str(arg4))
except:
channel = bot.get_channel(channel_id)
await channel.send('Oops! I didn\'t get that. Please try again using this format:\n!birthday Garfield 19 6 1978')
Basically, it should print the info it got if it is formatted correctly, and warn the user that there's a problem if it is not. This is the error message I get:
Ignoring exception in command birthday:
Traceback (most recent call last):
File "/home/valerie/.local/lib/python3.6/site-packages/discord/ext/commands/bot.py", line 892, in invoke
await ctx.command.invoke(ctx)
File "/home/valerie/.local/lib/python3.6/site-packages/discord/ext/commands/core.py", line 790, in invoke
await self.prepare(ctx)
File "/home/valerie/.local/lib/python3.6/site-packages/discord/ext/commands/core.py", line 751, in prepare
await self._parse_arguments(ctx)
File "/home/valerie/.local/lib/python3.6/site-packages/discord/ext/commands/core.py", line 670, in _parse_arguments
transformed = await self.transform(ctx, param)
File "/home/valerie/.local/lib/python3.6/site-packages/discord/ext/commands/core.py", line 516, in transform
raise MissingRequiredArgument(param)
discord.ext.commands.errors.MissingRequiredArgument: arg4 is a required argument that is missing.
Why is it throwing an exception when everything should work fine and not even running the except code when there actually is a problem? Is there a way to fix this?
Somewhere in your code, you are calling birthday function which is expecting 5 arguments. You are not providing the required number of arguments. That's why the code is failing.
If you read through the last line of the exception, you will see the error clearly called out.
discord.ext.commands.errors.MissingRequiredArgument: arg4 is a required argument that is missing.
You need to provide arg4 which you are not providing.
This is a general comment, but a little too big to fit in the comments...
(so please ignore as you see fit)
You can group you args, and use ", ".join() to make your code a bit cleaner:
#bot.command(pass_context=True)
async def birthday(ctx, *args):
try:
if (ctx.user == bot.user):
return
print(", ".join(args))
except:
...

Categories

Resources