pincer-org / pincer Goto Github PK
View Code? Open in Web Editor NEWπ The snappy asynchronous Discord API wrapper written with aiohttp
Home Page: https://pypi.org/project/pincer
License: MIT License
π The snappy asynchronous Discord API wrapper written with aiohttp
Home Page: https://pypi.org/project/pincer
License: MIT License
Implementing channel.send
to allow more customization within command and future tasks.
You may also want to add a optional parameter channel
to Message
& Embed
object.
@task.loop(minutes=30)
async def very_useful_task(self):
channel = await Channel.from_id(123456789)
# Todo: implement this:
await channel.send("Spam eggs!")
Also (optional):
@command()
async def useful_command():
return Message(
"Hello, world!",
channel=await Channel.from_id(123456789)
)
Is your feature request related to a problem? Please describe.
Pincer sends pillow images as PNGs by default. Bot developers with image heavy bots would benefit from being able to change the default image type and parameters to whatever they want.
Describe the solution you'd like
I think a config object in pincer/utils/_config.py
is the best option right now. Im open to other suggestions ofc.
The Config "thing" will have to handle all of the options for image.save(). Theres a lot of stuff
and none of it is guaranteed to be used besides format. Have fun :) Luckily we only need to handle the ones that the discord docs mention.
Also make sure the system can be expanded if we need other configuration ofc.
class InfoCog:
@command(guild=GUILD_ID)
async def about_command(self) -> Embed:
return Embed(
...
)
future: <Task finished name='Task-9' coro=<Client.event_handler() done, defined at D:\Pincer-Bot\venv\lib\site-packages\pincer\client.py:514> exception=AttributeError("'AppCommand' object has no attribute 'app'")>
Traceback (most recent call last):
File "D:\Pincer-Bot\venv\lib\site-packages\pincer\client.py", line 527, in event_handler
await self.process_event(payload.event_name.lower(), payload)
File "D:\Pincer-Bot\venv\lib\site-packages\pincer\client.py", line 512, in process_event
await self.execute_error(e)
File "D:\Pincer-Bot\venv\lib\site-packages\pincer\client.py", line 490, in execute_error
raise error
File "D:\Pincer-Bot\venv\lib\site-packages\pincer\client.py", line 506, in process_event
key, args, kwargs = await self.handle_middleware(payload, name)
File "D:\Pincer-Bot\venv\lib\site-packages\pincer\client.py", line 443, in handle_middleware
extractable = await ware(self, payload, *args, **kwargs)
File "D:\Pincer-Bot\venv\lib\site-packages\pincer\client.py", line 129, in wrapper
return await (
File "D:\Pincer-Bot\venv\lib\site-packages\pincer\middleware\ready.py", line 37, in on_ready_middleware
await ChatCommandHandler(self).initialize()
File "D:\Pincer-Bot\venv\lib\site-packages\pincer\commands.py", line 462, in initialize
await self.__add_commands()
File "D:\Pincer-Bot\venv\lib\site-packages\pincer\commands.py", line 455, in __add_commands
await self.add_commands(commands_to_add)
File "D:\Pincer-Bot\venv\lib\site-packages\pincer\commands.py", line 339, in add_commands
await gather(*list(map(
File "D:\Pincer-Bot\venv\lib\site-packages\pincer\commands.py", line 328, in add_command
add_endpoint = self.__add_guild.format(command=cmd)
AttributeError: 'AppCommand' object has no attribute 'app'
Is your feature request related to a problem? Please describe.
When I was editing the mCoding bot to only use a global aiohttp session, I stumbled upon an error when trying to run this code:
async def main():
async with aiohttp.ClientSession() as session:
bot.run()
asyncio.run(main())
Error: RuntimeError: This event loop is already running
Describe the solution you'd like
An (asynchronous) method that allows this behaviour.
Like this:
async def main():
async with aiohttp.ClientSession() as session:
await bot.start()
asyncio.run(main())
Describe alternatives you've considered
Use a method that always checks if the session exists, if not create one, else return the existing one.
Describe the bug
Python 3.7 does not support typing.Protocol
.
To Reproduce
Steps to reproduce the behavior:
ImportError: cannot import name 'Protocol' from 'typing' (/usr/lib/python3.7/typing.py)
Create autocomplete type. Should function abt the same as choices.
https://discord.com/developers/docs/interactions/application-commands#autocomplete
As of right now, there is only 2, or more like a single test for the whole library.
Implement new pytests to validate the behavior of objects, utils and core components of the library.
All missing tests on current should be passed.
Implement all AppCommandOptionType
s
This means for example that a user can be an argument, and also means that a user object gets provided to the command call.
Describe the bug
A clear and concise description of what the bug is.
To Reproduce
Try to create this object
Message(
content="1234",
components=[
MessageComponent(
type=1,
components=[
MessageComponent(
type=2,
label="click me!",
style=2,
custom_id="1234"
)
]
)
]
)
Theres 2 errors.
options
should be optional. A few other APINullable properties are not correctly marked as missing.Seems like commands missing a other arg
payload received
DEBUG:pincer.core:Received response for applications/901944968002801665/commands | [{"id": "901949693456678924", "application_id": "901944968002801665", "name": "panel", "description": "Description not set", "version": "901949693456678925", "default_permission": true, "default_member_permissions": null, "type": 1, "dm_permission": null}]
Traceback (most recent call last):
File "D:\Sigmou-Bot\venv\lib\site-packages\pincer\client.py", line 523, in event_handler
await self.process_event(payload.event_name.lower(), payload)
File "D:\Sigmou-Bot\venv\lib\site-packages\pincer\client.py", line 508, in process_event
await self.execute_error(e)
File "D:\Sigmou-Bot\venv\lib\site-packages\pincer\client.py", line 486, in execute_error
raise error
File "D:\Sigmou-Bot\venv\lib\site-packages\pincer\client.py", line 502, in process_event
key, args, kwargs = await self.handle_middleware(payload, name)
File "D:\Sigmou-Bot\venv\lib\site-packages\pincer\client.py", line 439, in handle_middleware
extractable = await ware(self, payload, *args, **kwargs)
File "D:\Sigmou-Bot\venv\lib\site-packages\pincer\client.py", line 111, in wrapper
return await (
File "D:\Sigmou-Bot\venv\lib\site-packages\pincer\middleware\ready.py", line 37, in on_ready_middleware
await ChatCommandHandler(self).initialize()
File "D:\Sigmou-Bot\venv\lib\site-packages\pincer\commands.py", line 486, in initialize
await self.__init_existing_commands()
File "D:\Sigmou-Bot\venv\lib\site-packages\pincer\commands.py", line 364, in __init_existing_commands
self._api_commands = await self.get_commands()
File "D:\Sigmou-Bot\venv\lib\site-packages\pincer\commands.py", line 300, in get_commands
return list(map(
File "D:\Sigmou-Bot\venv\lib\site-packages\pincer\utils\api_object.py", line 105, in from_dict
return cls(
TypeError: __init__() got an unexpected keyword argument 'default_member_permissions'
Bot structure
- app
- cogs
- __init__.py
- info.py
- __init__.py
- bot.py
- run.py
DEBUG:pincer.core:New event received, checking if handler exists for opcode: 0
DEBUG:pincer.core:Event handler found, ensuring async future in current loop.
DEBUG:pincer.core:Waiting for new event.
DEBUG:pincer:`ready` middleware has been invoked
DEBUG:root:0 commands registered.
DEBUG:pincer.core:GET applications/881583379504582727/commands | null
DEBUG:pincer:`payload` middleware has been invoked
DEBUG:pincer.core:Received response for applications/881583379504582727/commands | []
DEBUG:pincer.core:Request has been sent successfully. Returning json response.
ERROR:asyncio:Task exception was never retrieved
[crash]
future: <Task finished name='Task-9' coro=<Client.event_handler() done, defined at D:\Pincer-Bot\venv\lib\site-packages\pincer\client.py:514> exception=KeyError('app.bot')>
Traceback (most recent call last):
File "D:\Pincer-Bot\venv\lib\site-packages\pincer\client.py", line 527, in event_handler
await self.process_event(payload.event_name.lower(), payload)
File "D:\Pincer-Bot\venv\lib\site-packages\pincer\client.py", line 512, in process_event
await self.execute_error(e)
File "D:\Pincer-Bot\venv\lib\site-packages\pincer\client.py", line 490, in execute_error
raise error
File "D:\Pincer-Bot\venv\lib\site-packages\pincer\client.py", line 509, in process_event
self.execute_event(call, *args, **kwargs)
File "D:\Pincer-Bot\venv\lib\site-packages\pincer\client.py", line 400, in execute_event
args = (ChatCommandHandler.managers[call.__module__], *args)
KeyError: 'app.bot'
Traceback (most recent call last):
File "/home/container/mcoding_bot/tasks/update_channels.py", line 91, in update_channels
await self.get_guild(self.config.mcoding_server)
File "/home/container/venv/lib/python3.8/site-packages/pincer/client.py", line 561, in get_guild
return await Guild.from_id(self, guild_id)
File "/home/container/venv/lib/python3.8/site-packages/pincer/objects/guild/guild.py", line 480, in from_id
return Guild.from_dict(construct_client_dict(client, data))
File "/home/container/venv/lib/python3.8/site-packages/pincer/objects/guild/guild.py", line 535, in from_dict
return super().from_dict(data)
File "/home/container/venv/lib/python3.8/site-packages/pincer/utils/api_object.py", line 236, in from_dict
return cls(**dict(map(
File "<string>", line 64, in __init__
File "/home/container/venv/lib/python3.8/site-packages/pincer/utils/api_object.py", line 207, in __post_init__
attr_value = self.__attr_convert(attr, specific_tp)
File "/home/container/venv/lib/python3.8/site-packages/pincer/utils/api_object.py", line 168, in __attr_convert
return convert(
File "/home/container/venv/lib/python3.8/site-packages/pincer/utils/conversion.py", line 57, in convert
return MISSING if value is MISSING else handle_factory()
File "/home/container/venv/lib/python3.8/site-packages/pincer/utils/conversion.py", line 54, in handle_factory
else fin_fac(value)
File "/home/container/venv/lib/python3.8/site-packages/pincer/utils/conversion.py", line 49, in fin_fac
return factory(v)
File "/usr/local/lib/python3.8/enum.py", line 339, in __call__
return cls.__new__(cls, value)
File "/usr/local/lib/python3.8/enum.py", line 662, in __new__
raise ve_exc
ValueError: 8 is not a valid SystemChannelFlags
Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
Describe the solution you'd like
A clear and concise description of what you want to happen.
Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
Additional context
Add any other context or screenshots about the feature request here.
Implement subcommands. So that eg the following data gets sent to discord:
{
"name": "permissions",
"description": "Get or edit permissions for a user or a role",
"options": [
{
"name": "user",
"description": "Get or edit permissions for a user",
"type": 2, // 2 is type SUB_COMMAND_GROUP
"options": [
{
"name": "get",
"description": "Get permissions for a user",
"type": 1, // 1 is type SUB_COMMAND
"options": [
{
"name": "user",
"description": "The user to get",
"type": 6, // 6 is type USER
"required": true
},
{
"name": "channel",
"description": "The channel permissions to get. If omitted, the guild permissions will be returned",
"type": 7, // 7 is type CHANNEL
"required": false
}
]
},
{
"name": "edit",
"description": "Edit permissions for a user",
"type": 1,
"options": [
{
"name": "user",
"description": "The user to edit",
"type": 6,
"required": true
},
{
"name": "channel",
"description": "The channel permissions to edit. If omitted, the guild permissions will be edited",
"type": 7,
"required": false
}
]
}
]
},
{
"name": "role",
"description": "Get or edit permissions for a role",
"type": 2,
"options": [
{
"name": "get",
"description": "Get permissions for a role",
"type": 1,
"options": [
{
"name": "role",
"description": "The role to get",
"type": 8, // 8 is type ROLE
"required": true
},
{
"name": "channel",
"description": "The channel permissions to get. If omitted, the guild permissions will be returned",
"type": 7,
"required": false
}
]
},
{
"name": "edit",
"description": "Edit permissions for a role",
"type": 1,
"options": [
{
"name": "role",
"description": "The role to edit",
"type": 8,
"required": true
},
{
"name": "channel",
"description": "The channel permissions to edit. If omitted, the guild permissions will be edited",
"type": 7,
"required": false
}
]
}
]
}
]
}
Open for discussion, please post suggestions on how you'd like to use this in the lib.
Most middleware still has to be implemented.
Some files are already present in pincer.middleware
.
Find the events here
Describe the bug
Flake8 warns about both line break before and after a binary operator (W503 and W504).
Therefore you always have warnings no matter what code style you use.
Expected behavior
Flake8 should not warn about W503 errors since Pincer is already using W504's code style.
Potential fix
Add W503
to the ignore list in the file .flake8
.
e.g.
ignore =
...
H501,
# W503: line break before binary operator
W503
Describe the solution you'd like
I want to add speech recognizer code that can identify words that we spoke and this can be used for further improvement of any customized work.
Implement argument descriptions.
eg.
@command()
async def foo(argument: (type, "Description here")):
...
Implement argument options, maybe through the typing.Literal
?
Open for suggestions
Only import type hints when TYPE_CHECKING
is true.
Must be present:
from __future__ import annotations
from typing import TYPE_CHECKING
from __future__ import annotations
from typing import TYPE_CHECKING
from dataclasses import dataclass
if TYPE_CHECKING:
from typing import List
@dataclass
class Foo:
bar: List[int] = None
*Describe the solution you'd like
I want to add speech recognizer code that can identify words that we spoke and this can be used for further improvement of any customized work.
Basically what the title says. I think the method would be a bit more readable if you didn't need an argument for interactions without flags.
Describe the bug
An unsupported |
operation causing a crash within the middlewares.
future: <Task finished name='Task-10' coro=<Client.event_handler() done, defined at /home/container/pincer/client.py:340> exception=TypeError("unsupported operand type(s) for |: 'dict' and 'dict'")>
Traceback (most recent call last):
File "/home/container/pincer/client.py", line 353, in event_handler
await self.process_event(payload.event_name.lower(), payload)
File "/home/container/pincer/client.py", line 330, in process_event
key, args, kwargs = await self.handle_middleware(payload, event_name)
File "/home/container/pincer/client.py", line 295, in handle_middleware
extractable = await ware(self, payload, *args, **kwargs)
File "/home/container/pincer/client.py", line 119, in wrapper
return await (
File "/home/container/pincer/middleware/ready.py", line 26, in on_ready_middleware
{"_client": self, "_http": self.http} | payload.data.get("user")
TypeError: unsupported operand type(s) for |: 'dict' and 'dict'
DEBUG:pincer:`payload` middleware has been invoked
This also cause the function to not work.
ubuntu 18.04
0.6.11
3.8.8
Title is pretty self explanatory. Making the lib a partly async and thread based model should greatly increase performance.
ERROR:asyncio:Task exception was never retrieved
future: <Task finished name='Task-14' coro=<OnReadyCog.on_ready() done, defined at D:\Pincer\dev\basic_cogs\cogs\on_ready.py:8> exception=AttributeError("'OnReadyCog' object has no attribute 'client'")>
Traceback (most recent call last):
File "D:\Pincer\dev\basic_cogs\cogs\on_ready.py", line 12, in on_ready
f"Started client on {self.client.bot}\n"
AttributeError: 'OnReadyCog' object has no attribute 'client'
for cog_class in start_config:
self.load_cog(f".cogs.{flatten_name(cog_class)}")
Traceback (most recent call last):
File "D:\Pincer-Bot\run.py", line 12, in <module>
main()
File "D:\Pincer-Bot\run.py", line 8, in main
Bot().run()
File "D:\Pincer-Bot\app\bot.py", line 16, in __init__
self.load_cogs()
File "D:\Pincer-Bot\app\bot.py", line 25, in load_cogs
self.load_cog(f".cogs.{flatten_name(cog_class)}")
File "D:\Pincer-Bot\venv\lib\site-packages\pincer\client.py", line 323, in load_cog
module = import_module(path)
File "C:\Users\Sigmanificient\AppData\Local\Programs\Python\Python39\lib\importlib\__init__.py", line 122, in import_module
raise TypeError(msg.format(name))
TypeError: the 'package' argument is required to perform a relative import for '.cogs.info'
Process finished with exit code 1
``
Describe the bug
When you send a notification to a bot in a DM, it causes an exception and the on_message()
event does not run.
https://pastebin.com/YGHtuWuu
To Reproduce
Steps to reproduce the behavior:
from pincer import Client
from pincer.objects.app.intents import Intents
bot = Client(token, intents=Intents.DIRECT_MESSAGES)
bot.run()
Expected behavior
There should not be an exception. Additionally. on_message()
should run.
Desktop (please complete the following information):
Describe the bug
Look in the file pincer/objects/message/user_message.py
in the function UserMessage.react
.
Issue:
The react
function calls HTTPClient.put
which requires route and data as an argument but it only supplies route.
Expected behavior
It should either be optional or there is a missing argument.
Additional context
Using Pincer 0.10.0
Describe the bug
Circular imports for pincer.objects.interactions
Error:
Traceback (most recent call last):
File "/home/docs/checkouts/readthedocs.org/user_builds/pincer-test/checkouts/latest/pincer/__init__.py", line 17, in <module>
from pincer.client import Client, Bot
File "/home/docs/checkouts/readthedocs.org/user_builds/pincer-test/checkouts/latest/pincer/client.py", line 37, in <module>
from pincer.objects.user import User
File "/home/docs/checkouts/readthedocs.org/user_builds/pincer-test/checkouts/latest/pincer/objects/__init__.py", line 41, in <module>
from .interactions import Interaction, MessageInteraction
File "/home/docs/checkouts/readthedocs.org/user_builds/pincer-test/checkouts/latest/pincer/objects/interactions.py", line 33, in <module>
from pincer.objects.message import Message
File "/home/docs/checkouts/readthedocs.org/user_builds/pincer-test/checkouts/latest/pincer/objects/message.py", line 36, in <module>
from pincer.objects.interactions import MessageInteraction
ImportError: cannot import name 'MessageInteraction' from partially initialized module 'pincer.objects.interactions' (most likely due to a circular import) (/home/docs/checkouts/readthedocs.org/user_builds/pincer-test/checkouts/latest/pincer/objects/interactions.py)
Describe the bug
An unhandled payload cause the dispatcher the raise an UnhandldException
The payload received is the following:
{
"op": 0,
"d": {
"v": 9,
"user_settings": {},
"user": {
"verified": true,
"username": "Pincer",
"mfa_enabled": true,
"id": "881583379504582727",
"flags": 0,
"email": null,
"discriminator": "9011",
"bot": true,
"avatar": "4a50719d099a6dd1e385dfe5367ff77b"
},
"session_id": "5bc3022b8cfda8224bcb8b8e22ff236f",
"relationships": [],
"private_channels": [],
"presences": [],
"guilds": [
{
"unavailable": true,
"id": "813915317867642910"
},
{
"unavailable": true,
"id": "846838746833747968"
},
{
"unavailable": true,
"id": "881531065859190804"
}
],
"guild_join_requests": [],
"geo_ordered_rtc_regions": [
"europe",
"st-pete",
"russia",
"dubai",
"india"
],
"application": {
"id": "881583379504582727",
"flags": 303104
},
"_trace": [
(
"[\"gateway-prd-main-xcl8\",{\"micros\":82707,\"calls\":[\"discord-sessions-blue-prd-2-124\","
"{\"micros\":80697,\"calls\":[\"start_session\",{\"micros\":55991,\"calls\":[\"api-prd-main-5v7v\","
"{\"micros\":49593,\"calls\":[\"get_user\",{\"micros\":5644},\"add_authorized_ip\",{\"micros\":1403},"
"\"get_guilds\",{\"micros\":5424},\"coros_wait\",{\"micros\":0}]}]},\"guilds_connect\",{\"micros\":2,"
"\"calls\":[]},\"presence_connect\",{\"micros\":19581,\"calls\":[]}]}]}]"
)
]
},
"s": 1,
"t": "READY"
}
To Reproduce
Steps to reproduce the behavior:
from pincer.core.gateway import Dispatcher
BOT_TOKEN: str = ...
bot = Dispatcher(BOT_TOKEN)
bot.run()
module organization within the library is crucial, and the current objects
package isn't very well organized, with almost all object put at the root. This is the actual tree of the pincer.objects
folder:
objects
ββ events
β βββ channel.py
β βββ error.py
β βββ gateway_commands.py
β βββ guild.py
β βββ hello_ready.py
β βββ integration.py
β βββ invite.py
β βββ message.py
β βββ presence.py
β βββ thread.py
β βββ typing_start.py
β βββ voice.py
β βββ webhook.py
β βββ __init__.py
βββ application.py
βββ app_command.py
βββ attachment.py
βββ audit_log.py
βββ ban.py
βββ button.py
βββ channel.py
βββ connection.py
βββ embed.py
βββ emoji.py
βββ followed_channel.py
βββ guild.py
βββ guild_features.py
βββ guild_member.py
βββ guild_template.py
βββ guild_widget.py
βββ integration.py
βββ intents.py
βββ interactions.py
βββ interaction_base.py
βββ invite.py
βββ message.py
βββ message_component.py
βββ message_context.py
βββ message_reference.py
βββ overwrite.py
βββ reaction.py
βββ role.py
βββ select_menu.py
βββ session_start_limit.py
βββ stage.py
βββ sticker.py
βββ thread.py
βββ throttle_scope.py
βββ throttling.py
βββ user.py
βββ user_message.py
βββ voice_region.py
βββ voice_state.py
βββ webhook.py
βββ welcome_screen.py
βββ __init__.py
Moving each module to a separate package would make thing easier.
objects
βββ events
β βββ ...
β βββ __init__.py
βββ app
β βββ ...
β βββ __init__.py
βββ guild
β βββ ...
β βββ __init__.py
βββ message
β βββ ...
β βββ __init__.py
βββ user
β βββ ...
β βββ __init__.py
βββ voice
βββ ...
βββ __init__.py
Describe the bug
This error occurs
content_type: APINullable[str] = MISSING
TypeError: 'MissingType' object is not subscriptable
To Reproduce
Run code that has this line or build docs.
Expected behavior
There shouldn't be an error
Additional context
APINullable can be
APINullable = Union[S, MissingType]
This should allow it to use generics.
Describe the bug
When running a basic command, there is an error that prints out but the command still works.
To Reproduce
Steps to reproduce the behavior:
from pincer import Client, command
from pincer.objects import Intents
class Bot(Client):
@Client.event
async def on_ready(self):
print(f'Bot logged in on as {self.bot}')
@command(guild=GUILD_ID_HERE)
async def ping(self):
return f'Pong!'
bot = Bot(TOKEN_HERE, intents=Intents.all())
bot.run()
/ping
Pong!
to Discord but raises an error.Expected behavior
No error.
Full Console Out/Input
$ python main.py
<function on_ready_middleware at 0x7f2adec9e040> True
Bot logged in on as BOTNAME#XXXX
<function interaction_create_middleware at 0x7f2adec8fdc0> True
<function message_create_middleware at 0x7f2adec8fee0> False
ERROR:asyncio:Task exception was never retrieved
future: <Task finished name='Task-15' coro=<Client.event_handler() done, defined at Pincer/pincer/client.py:337> exception=TypeError("__init__() got an unexpected keyword argument 'member'")>
Traceback (most recent call last):
File "Pincer/pincer/client.py", line 352, in event_handler
key, args, kwargs = await self.handle_middleware(payload, event_name)
File "Pincer/pincer/client.py", line 315, in handle_middleware
extractable = await ware(self, payload, *args, **kwargs)
File "Pincer/pincer/client.py", line 142, in wrapper
return await (
File "Pincer/pincer/middleware/message_create.py", line 32, in message_create_middleware
return "on_message", [UserMessage.from_dict(payload.data)]
File "Pincer/pincer/utils/api_object.py", line 105, in from_dict
return cls(**{
File "<string>", line 33, in __init__
File "Pincer/pincer/objects/user_message.py", line 337, in __post_init__
self.interaction = convert(
File "Pincer/pincer/utils/conversion.py", line 50, in convert
return MISSING if value is MISSING else handle_factory()
File "Pincer/pincer/utils/conversion.py", line 47, in handle_factory
else fin_fac(value)
File "Pincer/pincer/utils/conversion.py", line 41, in fin_fac
else factory(v)
File "Pincer/pincer/utils/api_object.py", line 105, in from_dict
return cls(**{
TypeError: __init__() got an unexpected keyword argument 'member'
Implement the support of Image
type from the Pillow library.
You might want to use the standard IO
and not saving the image afile.
from PIL import Image
...
@Client.command()
async def image_example(self) -> Image:
img = Image.new("RGBA", (200, 100), "white")
...
# returning a single image
return img
@Client.command()
async def image_example(self) -> Message:
img = Image.new("RGBA", (200, 100), "white")
...
# Sending the image within a custom message, as a file
return Message(..., file=img)
The current cog system does not support an event to be called within multiples cogs.
- cogs
- yt_statistics.py
- bot.py
class Bot(Client):
...
@Client.event
async def on_ready(self):
print(
" _____ _ _ _____ _",
" _____| |___ _| |_|___ ___ | __ |___| |_",
"| | --| . | . | | | . | | __ -| . | _|",
"|_|_|_|_____|___|___|_|_|_|_ | |_____|___|_|",
" |___|" "",
sep="\n",
)
class YtStatistics(commands.Cog):
def __init__(self, client: Bot):
self.client = client
@Client.event
async def on_ready(self):
task = TaskScheduler(self.client)
@task.loop(seconds=2)
async def update_channels():
print("Updating channels...")
update_channels.start()
setup = YtStatistics
pincer.exceptions.InvalidEventName: The event
on_ready has already been registered or is not a valid event name.
This may be improved by forwarding every event of the same name one after an other?
Implemented a channel.edit
method. In this method you can pass named arguments for the channel attribute(s) that have to change.
@command()
async def update_channel():
channel = await Channel.from_id(...)
# the method to add
await channel.edit(name="foo")
Make a system where commands can be properly structured using several files.
Something in the lines of the following:
main file
from pincer import Client
class Bot(Client):
@Client.event
async def on_ready(self):
self.load_cog("cogs.example")
if __name__ == "__main__":
Bot(token).run()
cogs/example.py
from pincer import command, Cog
class Example(Cog):
def __init__(self, client):
self.client = client
@command()
async def example(self):
...
def setup(bot):
Example(bot)
Describe the bug
Many packages and features do not support Python 3.6 anymore.
aiohttp
-> >= 3.7
typing.Protocol
>= 3.7
__future__.annotations
>= 3.7
dataclasses
>= 3.7
async
and await
being reserved keywords >= 3.7
asyncio
is a lot faster from 3.6 to 3.7
UTF-8 encoding is default (unless specified) - we wont need # -*- coding: utf-8 -*
__getattr__()
can be defined for classes
To Reproduce
Either run in Python 3.6 or set your IDE to Python 3.6.
Solution
Change the version to 3.7
βImplementing event compression to save bandwidth, which can be useful especially for bigger bots.
Describe the bug
When using @client.event
, the current working directory is changed to Lib/pincer/middlewares
as the chdir
is used within the __init__.py
of middlewares
.
To Reproduce
import os
from pincer import Client
class Bot(Client):
def __init__(self):
super().__init__(token='')
print(os.getcwd())
D:\Pincer\pincer\middleware
Expected behavior
D:\Pincer\dev
Desktop (please complete the following information):
os:
windows
python:3.9.6
pincer:0.6.10
Is your feature request related to a problem? Please describe.
The only way to respond to a slash command is returning a message from the function. This is great for small things but makes it impossible to continue doing a task after you respond.
Describe the solution you'd like
You should be able to pass interaction in the slash command function. We already have something similar for MessageContext but that can be changed a bit.
Implementation Ideas
Typehint interaction
Use a system like flask's url parameter handling where you specify the variable in the decorator.
Get Interaction from ctx (ctx.interaction
)
Hello, as a faithful supporter of the Piscord project, I think it's not fair to take this name.
Effectively, you could choose another name, because actually, the two names are too similar and can confuse the people who can use Piscord, or redirect the people searching for Pyscord on Piscord.
So, for the better understanding of everyone, can you please change the name of your library not to be too similar to Piscord.
Best regards,
RedsTom.
Make a decorator that transform a asynchronous function to a task object.
@task.loop(minute=30)
async def my_task(self):
...
When calling my_task.start()
this will register the task to repeat the given amount of time.
Describe the bug
The given example for cog doesn't work as expected:
Traceback (most recent call last):
File "D:\Pincer\dev\basic_cogs\cogs\on_ready.py", line 11, in on_ready
f"Started client on {self.client.bot}\n"
AttributeError: 'Bot' object has no attribute 'client'
The method causing the issue:
@Client.event
async def on_ready(self):
print(
f"Started client on {self.client.bot}\n"
"Registered commands: " + ", ".join(self.client.chat_commands)
)
A simple print(type(self)
reveals the problem lies in self
being the instance of the bot, and not the cog.
Further document docstrings &/or create documentation where none is present but is needed.
Pincer come with an integrated debug logging mode that can be activated using this line of code
logging.basicConfig(level=logging.DEBUG)
Tho, the current implementation isn't particularity easy to read.
...
DEBUG:pincer.core:Waiting for new event.
DEBUG:pincer.core:Resting heart for 41s
DEBUG:pincer:`payload` middleware has been invoked
DEBUG:websockets.client:< TEXT '{"t":"READY","s":1,"op":0,"d":{"v":9,"user_sett...\"calls\\":[]}]}]}]"]}}' [1051 bytes]
DEBUG:pincer.core:New event received, checking if handler exists for opcode: 0
DEBUG:pincer.core:Event handler found, ensuring async future in current loop.
DEBUG:pincer.core:Waiting for new event.
DEBUG:pincer:`ready` middleware has been invoked
DEBUG:root:1 commands registered.
DEBUG:pincer.core:GET applications/891738511311515708/commands | null
DEBUG:pincer:`payload` middleware has been invoked
DEBUG:pincer.core:Received response for applications/891738511311515708/commands | []
DEBUG:pincer.core:Request has been sent successfully. Returning json response.
DEBUG:pincer.core:POST applications/891738511311515708/guilds/813915317867642910/commands | {"type": 1, "name": "choose", "description": "Description not set", "options": [{"type": 3, "name": "choice", "description": "Description not set", "required": true, "choices": [{"name": "This will be the test value", "value": "Test"}, {"name": "Sample lol", "value": "Sample lol"}, {"name": "Geheh", "value": "Geheh"}]}], "guild_id": 813915317867642910, "default_permission": true}
DEBUG:pincer.core:Received response for applications/891738511311515708/guilds/813915317867642910/commands | {"id": "893854037093527562", "application_id": "891738511311515708", "name": "choose", "description": "Description not set", "version": "894012817345245255", "default_permission": true, "type": 1, "guild_id": "813915317867642910", "options": [{"type": 3, "name": "choice", "description": "Description not set", "required": true, "choices": [{"name": "This will be the test value", "value": "Test"}, {"name": "Sample lol", "value": "Sample lol"}, {"name": "Geheh", "value": "Geheh"}]}]}
DEBUG:pincer.core:Request has been sent successfully. Returning json response.
Make the debug mode prettier, while still being toggable by the first line.
Custom coloring, colorama, termcolor or even rich can be used as long as the used features is supported by most OS.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.