mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-09-05 17:36:15 +00:00
First pass at documentation reform.
This commit is contained in:
180
docs/faq.rst
180
docs/faq.rst
@ -16,7 +16,7 @@ Coroutines
|
||||
Questions regarding coroutines and asyncio belong here.
|
||||
|
||||
I get a SyntaxError around the word ``async``\! What should I do?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This ``SyntaxError`` happens because you're using a Python version lower than 3.5. Python 3.4 uses ``@asyncio.coroutine`` and
|
||||
``yield from`` instead of ``async def`` and ``await``.
|
||||
@ -52,7 +52,7 @@ Where can I use ``await``\?
|
||||
You can only use ``await`` inside ``async def`` functions and nowhere else.
|
||||
|
||||
What does "blocking" mean?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In asynchronous programming a blocking call is essentially all the parts of the function that are not ``await``. Do not
|
||||
despair however, because not all forms of blocking are bad! Using blocking calls is inevitable, but you must work to make
|
||||
@ -78,13 +78,14 @@ Consider the following example: ::
|
||||
r = requests.get('http://random.cat/meow')
|
||||
if r.status_code == 200:
|
||||
js = r.json()
|
||||
await client.send_message(channel, js['file'])
|
||||
await channel.send(js['file'])
|
||||
|
||||
# good
|
||||
async with aiohttp.get('http://random.cat/meow') as r:
|
||||
if r.status == 200:
|
||||
js = await r.json()
|
||||
await client.send_message(channel, js['file'])
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get('http://random.cat/meow') as r:
|
||||
if r.status == 200:
|
||||
js = await r.json()
|
||||
await channel.send(js['file'])
|
||||
|
||||
General
|
||||
---------
|
||||
@ -103,37 +104,41 @@ following: ::
|
||||
How do I send a message to a specific channel?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you have its ID then you can do this in two ways, first is by using :class:`Object`\: ::
|
||||
You must fetch the channel directly and then call the appropriate method. Example: ::
|
||||
|
||||
await client.send_message(discord.Object(id='12324234183172'), 'hello')
|
||||
|
||||
The second way is by calling :meth:`Client.get_channel` directly: ::
|
||||
|
||||
await client.send_message(client.get_channel('12324234183172'), 'hello')
|
||||
|
||||
I'm passing IDs as integers and things are not working!
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In the library IDs must be of type ``str`` not of type ``int``. Wrap it in quotes.
|
||||
channel = client.get_channel('12324234183172')
|
||||
await channel.send('hello')
|
||||
|
||||
How do I upload an image?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
There are two ways of doing it. Both of which involve using :meth:`Client.send_file`.
|
||||
To upload something to Discord you have to use the :class:`File` object.
|
||||
|
||||
The first is by opening the file and passing it directly: ::
|
||||
A :class:`File` accepts two parameters, the file-like object (or file path) and the filename
|
||||
to pass to Discord when uploading.
|
||||
|
||||
with open('my_image.png', 'rb') as f:
|
||||
await client.send_file(channel, f)
|
||||
If you want to upload an image it's as simple as: ::
|
||||
|
||||
The second is by passing the file name directly: ::
|
||||
await channel.send(file=discord.File('my_file.png'))
|
||||
|
||||
If you have a file-like object you can do as follows: ::
|
||||
|
||||
with open('my_file.png', 'rb') as fp:
|
||||
await channel.send(file=discord.File(fp, 'new_filename.png'))
|
||||
|
||||
To upload multiple files, you can use the ``files`` keyword argument instead of ``file``\: ::
|
||||
|
||||
my_files = [
|
||||
discord.File('result.zip'),
|
||||
discord.File('teaser_graph.png'),
|
||||
]
|
||||
await channel.send(files=my_files)
|
||||
|
||||
await client.send_file(channel, 'my_image.png')
|
||||
|
||||
How can I add a reaction to a message?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You use the :meth:`Client.add_reaction` method.
|
||||
You use the :meth:`Message.add_reaction` method.
|
||||
|
||||
If you want to use unicode emoji, you must pass a valid unicode code point in a string. In your code, you can write this in a few different ways:
|
||||
|
||||
@ -141,16 +146,32 @@ If you want to use unicode emoji, you must pass a valid unicode code point in a
|
||||
- ``'\U0001F44D'``
|
||||
- ``'\N{THUMBS UP SIGN}'``
|
||||
|
||||
In case you want to use emoji that come from a message, you already get their code points in the content without needing to do anything special.
|
||||
You **cannot** send ``':thumbsup:'`` style shorthands.
|
||||
Quick example: ::
|
||||
|
||||
For custom emoji, you should pass an instance of :class:`discord.Emoji`. You can also pass a ``'name:id'`` string, but if you can use said emoji,
|
||||
you should be able to use :meth:`Client.get_all_emojis`/:attr:`Server.emojis` to find the one you're looking for.
|
||||
await message.add_reaction('\N{THUMBS UP SIGN}')
|
||||
|
||||
In case you want to use emoji that come from a message, you already get their code points in the content without needing
|
||||
to do anything special. You **cannot** send ``':thumbsup:'`` style shorthands.
|
||||
|
||||
For custom emoji, you should pass an instance of :class:`Emoji`. You can also pass a ``'name:id'`` string, but if you
|
||||
can use said emoji, you should be able to use :meth:`Client.get_emoji` to get an emoji via ID or use :func:`utils.find`/
|
||||
:func:`utils.get` on :attr:`Client.emojis` or :attr:`Guild.emojis` collections.
|
||||
|
||||
Quick example: ::
|
||||
|
||||
# if you have the ID already
|
||||
emoji = client.get_emoji(310177266011340803)
|
||||
await message.add_reaction(emoji)
|
||||
|
||||
# no ID, do a lookup
|
||||
emoji = discord.utils.get(guild.emojis, name='LUL')
|
||||
if emoji:
|
||||
await message.add_reaction(emoji)
|
||||
|
||||
How do I pass a coroutine to the player's "after" function?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A StreamPlayer is just a ``threading.Thread`` object that plays music. As a result it does not execute inside a coroutine.
|
||||
The library's music player launches on a separate thread, ergo it does not execute inside a coroutine.
|
||||
This does not mean that it is not possible to call a coroutine in the ``after`` parameter. To do so you must pass a callable
|
||||
that wraps up a couple of aspects.
|
||||
|
||||
@ -169,7 +190,7 @@ However, this function returns a ``concurrent.Future`` and to actually call it w
|
||||
this together we can do the following: ::
|
||||
|
||||
def my_after():
|
||||
coro = client.send_message(some_channel, 'Song is done!')
|
||||
coro = some_channel.send('Song is done!')
|
||||
fut = asyncio.run_coroutine_threadsafe(coro, client.loop)
|
||||
try:
|
||||
fut.result()
|
||||
@ -177,48 +198,44 @@ this together we can do the following: ::
|
||||
# an error happened sending the message
|
||||
pass
|
||||
|
||||
player = await voice.create_ytdl_player(url, after=my_after)
|
||||
player.start()
|
||||
|
||||
Why is my "after" function being called right away?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``after`` keyword argument expects a *function object* to be passed in. Similar to how ``threading.Thread`` expects a
|
||||
callable in its ``target`` keyword argument. This means that the following are invalid:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
player = await voice.create_ytdl_player(url, after=self.foo())
|
||||
other = await voice.create_ytdl_player(url, after=self.bar(10))
|
||||
|
||||
However the following are correct:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
player = await voice.create_ytdl_player(url, after=self.foo)
|
||||
other = await voice.create_ytdl_player(url, after=lambda: self.bar(10))
|
||||
|
||||
Basically, these functions should not be called.
|
||||
|
||||
voice.play(discord.FFmpegPCMAudio(url), after=my_after)
|
||||
|
||||
How do I run something in the background?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
`Check the background_task.py example. <https://github.com/Rapptz/discord.py/blob/master/examples/background_task.py>`_
|
||||
`Check the background_task.py example. <https://github.com/Rapptz/discord.py/blob/rewrite/examples/background_task.py>`_
|
||||
|
||||
How do I get a specific User/Role/Channel/Server?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
How do I get a specific model?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
There are multiple ways of doing this. If you have a specific entity's ID then you can use
|
||||
There are multiple ways of doing this. If you have a specific model's ID then you can use
|
||||
one of the following functions:
|
||||
|
||||
- :meth:`Client.get_channel`
|
||||
- :meth:`Client.get_server`
|
||||
- :meth:`Server.get_member`
|
||||
- :meth:`Server.get_channel`
|
||||
- :meth:`Client.get_guild`
|
||||
- :meth:`Client.get_user`
|
||||
- :meth:`Client.get_emoji`
|
||||
- :meth:`Guild.get_member`
|
||||
- :meth:`Guild.get_channel`
|
||||
|
||||
The following use an HTTP request:
|
||||
|
||||
- :meth:`abc.Messageable.get_message`
|
||||
- :meth:`Client.get_user_info`
|
||||
|
||||
|
||||
If the functions above do not help you, then use of :func:`utils.find` or :func:`utils.get` would serve some use in finding
|
||||
specific entities. The documentation for those functions provide specific examples.
|
||||
specific models.
|
||||
|
||||
Quick example: ::
|
||||
|
||||
# find a guild by name
|
||||
guild = discord.utils.get(client.guilds, name='My Server')
|
||||
|
||||
# make sure to check if it's found
|
||||
if guild is not None:
|
||||
# find a channel by name
|
||||
channel = discord.utils.get(guild.text_channels, name='cool-channel')
|
||||
|
||||
Commands Extension
|
||||
-------------------
|
||||
@ -229,10 +246,10 @@ Is there any documentation for this?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Not at the moment. Writing documentation for stuff takes time. A lot of people get by reading the docstrings in the source
|
||||
code. Others get by via asking questions in the `Discord server <https://discord.gg/0SBTUU1wZTXZNJPa>`_. Others look at the
|
||||
code. Others get by via asking questions in the `Discord server <https://discord.gg/discord-api>`_. Others look at the
|
||||
source code of `other existing bots <https://github.com/Rapptz/RoboDanny>`_.
|
||||
|
||||
There is a `basic example <https://github.com/Rapptz/discord.py/blob/master/examples/basic_bot.py>`_ showcasing some
|
||||
There is a `basic example <https://github.com/Rapptz/discord.py/blob/rewrite/examples/basic_bot.py>`_ showcasing some
|
||||
functionality.
|
||||
|
||||
**Documentation is being worked on, it will just take some time to polish it**.
|
||||
@ -249,42 +266,36 @@ Overriding the default provided ``on_message`` forbids any extra commands from r
|
||||
|
||||
await bot.process_commands(message)
|
||||
|
||||
Can I use ``bot.say`` in other places aside from commands?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
No. They only work inside commands due to the way the magic involved works.
|
||||
|
||||
Why do my arguments require quotes?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In a simple command defined as: ::
|
||||
|
||||
@bot.command()
|
||||
async def echo(message: str):
|
||||
await bot.say(message)
|
||||
async def echo(ctx, message: str):
|
||||
await ctx.send(message)
|
||||
|
||||
Calling it via ``?echo a b c`` will only fetch the first argument and disregard the rest. To fix this you should either call
|
||||
it via ``?echo "a b c"`` or change the signature to have "consume rest" behaviour. Example: ::
|
||||
|
||||
@bot.command()
|
||||
async def echo(*, message: str):
|
||||
await bot.say(message)
|
||||
async def echo(ctx, *, message: str):
|
||||
await ctx.send(message)
|
||||
|
||||
This will allow you to use ``?echo a b c`` without needing the quotes.
|
||||
|
||||
How do I get the original ``message``\?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Ask the command to pass you the invocation context via ``pass_context``. This context will be passed as the first parameter.
|
||||
The :class:`~ext.commands.Context` contains an attribute, :attr:`~ext.commands.Context.message` to get the original
|
||||
message.
|
||||
|
||||
Example: ::
|
||||
|
||||
@bot.command(pass_context=True)
|
||||
@bot.command()
|
||||
async def joined_at(ctx, member: discord.Member = None):
|
||||
if member is None:
|
||||
member = ctx.message.author
|
||||
|
||||
await bot.say('{0} joined at {0.joined_at}'.format(member))
|
||||
member = member or ctx.author
|
||||
await ctx.send('{0} joined at {0.joined_at}'.format(member))
|
||||
|
||||
How do I make a subcommand?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@ -294,15 +305,14 @@ the group operating as "subcommands". These groups can be arbitrarily nested as
|
||||
|
||||
Example: ::
|
||||
|
||||
@bot.group(pass_context=True)
|
||||
@bot.group()
|
||||
async def git(ctx):
|
||||
if ctx.invoked_subcommand is None:
|
||||
await bot.say('Invalid git command passed...')
|
||||
|
||||
@git.command()
|
||||
async def push(remote: str, branch: str):
|
||||
await bot.say('Pushing to {} {}'.format(remote, branch))
|
||||
|
||||
async def push(ctx, remote: str, branch: str):
|
||||
await ctx.send('Pushing to {} {}'.format(remote, branch))
|
||||
|
||||
This could then be used as ``?git push origin master``.
|
||||
|
||||
|
Reference in New Issue
Block a user