mirror of
				https://github.com/Rapptz/discord.py.git
				synced 2025-10-31 05:23:03 +00:00 
			
		
		
		
	Add advanced startup example
shows setup_hook and async context manager use with examples approximating real world use cases
This commit is contained in:
		
							
								
								
									
										94
									
								
								examples/advanced_startup.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								examples/advanced_startup.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | ||||
| # This example covers advanced startup options and uses some real world examples for why you may need them. | ||||
|  | ||||
| import asyncio | ||||
| import logging | ||||
| import logging.handlers | ||||
| import os | ||||
|  | ||||
| from typing import List, Optional | ||||
|  | ||||
| import asyncpg  # asyncpg is not a dependency of the discord.py, and is only included here for illustrative purposes. | ||||
| import discord | ||||
| from discord.ext import commands | ||||
| from aiohttp import ClientSession | ||||
|  | ||||
|  | ||||
| class CustomBot(commands.Bot): | ||||
|     def __init__( | ||||
|         self, | ||||
|         *args, | ||||
|         initial_extensions: List[str], | ||||
|         db_pool: asyncpg.Pool, | ||||
|         web_client: ClientSession, | ||||
|         testing_guild_id: Optional[int] = None, | ||||
|         **kwargs, | ||||
|     ): | ||||
|         super().__init__(*args, **kwargs) | ||||
|         self.db_pool = db_pool | ||||
|         self.web_client = web_client | ||||
|         self.testing_guild_id = testing_guild_id | ||||
|         self.initial_extensions = initial_extensions | ||||
|  | ||||
|     async def setup_hook(self) -> None: | ||||
|  | ||||
|         # here, we are loading extensions prior to sync to ensure we are syncing interactions defined in those extensions. | ||||
|  | ||||
|         for extension in self.initial_extensions: | ||||
|             await self.load_extension(extension) | ||||
|  | ||||
|         # In overriding setup hook, | ||||
|         # we can do things that require a bot prior to starting to process events from the websocket. | ||||
|         # In this case, we are using this to ensure that once we are connected, we sync for the testing guild. | ||||
|         # You should not do this for every guild or for global sync, those should only be synced when changes happen. | ||||
|         if self.testing_guild_id: | ||||
|             guild = discord.Object(self.testing_guild_id) | ||||
|             # We'll copy in the global commands to test with: | ||||
|             self.tree.copy_global_to(guild=guild) | ||||
|             # followed by syncing to the testing guild. | ||||
|             await self.tree.sync(guild=guild) | ||||
|  | ||||
|         # This would also be a good place to connect to our database and | ||||
|         # load anything that should be in memory prior to handling events. | ||||
|  | ||||
|  | ||||
| async def main(): | ||||
|  | ||||
|     # When taking over how the bot process is run, you become responsible for a few additional things. | ||||
|  | ||||
|     # 1. logging | ||||
|  | ||||
|     # for this example, we're going to set up a rotating file logger. | ||||
|     # for more info on setting up logging, | ||||
|     # see https://discordpy.readthedocs.io/en/latest/logging.html and https://docs.python.org/3/howto/logging.html | ||||
|  | ||||
|     logger = logging.getLogger('discord') | ||||
|     logger.setLevel(logging.INFO) | ||||
|  | ||||
|     handler = logging.handlers.RotatingFileHandler( | ||||
|         filename='discord.log', | ||||
|         encoding='utf-8', | ||||
|         maxBytes=32 * 1024 * 1024,  # 32 MiB | ||||
|         backupCount=5,  # Rotate through 5 files | ||||
|     ) | ||||
|     dt_fmt = '%Y-%m-%d %H:%M:%S' | ||||
|     formatter = logging.Formatter('[{asctime}] [{levelname:<8}] {name}: {message}', dt_fmt, style='{') | ||||
|     handler.setFormatter(formatter) | ||||
|     logger.addHandler(handler) | ||||
|  | ||||
|     # One of the reasons to take over more of the process though | ||||
|     # is to ensure use with other libraries or tools which also require their own cleanup. | ||||
|  | ||||
|     # Here we have a web client and a database pool, both of which do cleanup at exit. | ||||
|     # We also have our bot, which depends on both of these. | ||||
|  | ||||
|     async with ClientSession() as our_client, asyncpg.create_pool(user='postgres', command_timeout=30) as pool: | ||||
|         # 2. We become responsible for starting the bot. | ||||
|  | ||||
|         exts = ['general', 'mod', 'dice'] | ||||
|         async with CustomBot(commands.when_mentioned, db_pool=pool, web_client=our_client, initial_extensions=exts) as bot: | ||||
|  | ||||
|             await bot.start(os.getenv('TOKEN', '')) | ||||
|  | ||||
|  | ||||
| # For most use cases, after defining what needs to run, we can just tell asyncio to run it: | ||||
| asyncio.run(main()) | ||||
		Reference in New Issue
	
	Block a user