Discord.py how do I run code from another file?

Viewed 1908

I want to clean up the code of my Discord bot a little with splitting commands up into different files instead of having just one huge main file. I know that I can "import" code directly from other files simply with import [file], but I fail to make it work with Discord code. If I try something like:

test1.py

await ctx.send("successful")

main.py

@client.command()
asnyc def test(ctx):
   import test1

I always get the error SyntaxError: 'await' outside function. I know that it's because the await is outside any async function, but I don't know how to fix it. If I replace test1.py with something like print("successful"), it prints the correct response to console. I tried looking solutions up already but am rather getting more and more confused by it.

3 Answers

Discord has a system called "extensions" which are specifically designed for splitting up commands into different files. Make sure you put whole functions in files not just parts of functions otherwise Python will give errors. Here's an example taken straight from the docs:

Main file:

...create bot etc...
bot.load_extension("test")  # use name of python file here
...run bot etc...

Other file (called test.py in this example):

from discord.ext import commands

@commands.command()
async def hello(ctx):
    await ctx.send('Hello {0.display_name}.'.format(ctx.author))

def setup(bot):
    bot.add_command(hello)

The key points are: (1) create python file with setup function (2) load the extension.

For more information see: https://discordpy.readthedocs.io/en/stable/ext/commands/extensions.html https://discordpy.readthedocs.io/en/stable/ext/commands/cogs.html

You should import functions, and call them:

test1.py

async def run(ctx):
    await ctx.send("successful")

main.py

import test1

@client.command()
async def test(ctx):
   await test1.run(ctx)

(I think I got the awaits and asyncs correct.)

An import statement functions differently than C++ or PHP's include, which effectively copy-and-pastes the included code in-place. Python's import effectively runs the file you're importing, and (in its simplest form) adds any items created to your current scope.

You do well to clean up your code a bit :) Every now and then you have to do it. To solve your SyntaxError problem: 'await' outside function, caused for the reason you said yourself you have to use the "import" statement, and then you have to put the complete functions in the files, and not pieces of functions.

In test1.py, you need to write your await ctx.send ("successful") inside a function, then you need to write async def example (ctx): and then below enter async def example (ctx):

#test1.py

async def example(ctx):
    await ctx.send("successful")

In main.py, you have to change a few things. You imported test1 inside the function, instead you have to import it outside the function. Then inside your async function def test (ctx):, instead, you have to write await test1.example (ctx), where test1 is the file and example is the name of the test1 function.

    #main.py
    
    #import your file here, and not inside the function
    import test1
    
    @client.command()
    async def test(ctx):
       await test1.example(ctx)
Related