Get argparse exec to properly load variables from python config file
Question:
I am trying to get Argparse exec should load the variables user_token and channel_id from the config.py file inputted by the user (--config-file
argparse argument).
For whatever reason it will only load the main config file (from config import *
) even when running the proper commands to load in another one besides the main:
I’ve tried to remove config import * and have parser() return user_token after the exec call but that ends up return None type. yet if i print out the result of config_file in it returns whatever was input into –config-file part of the command, meaning it’s parsing the command but not able to properly read the config.py file
python3 bot.py --config-file config1.py
would run account1
python3 bot.py --config-file config2.py
would run account2
config file template(all are located in same directory as main.py):
channel_id = XXXXX
user_token = "XXXXX"
main.py file:
from asyncio import sleep
import argparse
import discord, datetime
import tweepy
from config import *
def parser():
parser = argparse.ArgumentParser()
parser.add_argument("--config-file", type=str, required=True)
args = parser.parse_args()
config_file = args.config_file
exec(open(config_file).read())
parser()
class Client(discord.Client):
active = True
async def pauseBump(self):
self.active = False
print("Bump paused.")
async def continueBump(self):
self.active = True
print("Bump restored.")
async def clean(self, user_message=None, bot_message=None):
await sleep(3)
if user_message is not None:
await user_message.delete()
if bot_message is not None:
await bot_message.delete()
print("Chat cleaned")
async def send(self, ctx, content):
message = await ctx.channel.send(f"{ctx.author.mention} {content}")
print(f"Sent '{content}' to '{ctx.author}'")
await self.clean(ctx, message)
async def bumpCheck(self):
channels_ids = []
for server in self.guilds:
for channel in server.channels:
if str(channel.type) == 'text':
channels_ids.append(channel.id)
print(channels_ids)
#channels_ids = [channel.id for channel in channels]
# Get a list of all chanells in the current server
for channel_id in channels_ids:
channel = self.get_channel(channel_id)
async for message in channel.history(limit=50):
if message.author != self.user:
if "react" in message.content.lower():
await message.add_reaction("N{THUMBS UP SIGN}")
# Code from original auto-bump author
if str(message.author) == "DISCORD_ADMIN_NAME":
if "Bump done" in message.embeds[0].description:
now = datetime.datetime.utcnow()
two = datetime.timedelta(hours=2)
min = datetime.timedelta(minutes=1)
difference = now - message.created_at
difference = two - difference + min
print(f"Time until next bump {difference}")
return difference.seconds
return 120
# Code from original auto-bump author
async def bump(self):
self.diff = await self.bumpCheck()
await sleep(self.diff)
channel = self.get_channel(channel_id)
command = await channel.send("bump")
print("Server bumped")
return command
async def on_ready(self):
print(f"Logged as {self.user}")
while self.active == True:
command = await self.bump()
await self.clean(command)
async def on_message(self, message):
if message.author == self.user:
if message.content == "!pause":
await self.pauseBump()
await self.send(message, "Bot is paused :sleeping:")
elif message.content == "!continue":
await self.continueBump()
await self.send(
message,
f"Bump is activated, next bump in {self.diff} seconds :hourglass_flowing_sand:",
)
Client().run( user_token, bot=False)
Answers:
This works, but i DO NOT recommend it! Do NOT use python files as config files by loading the content via exec. This can have unwanted effects, depending on what is in the config.py file. Use a json file and override the imported config variables.
from asyncio import sleep
import argparse
import discord, datetime
import tweepy
from config import *
def parser():
parser = argparse.ArgumentParser()
parser.add_argument("--config-file", type=str, required=True)
args = parser.parse_args()
config_file = args.config_file
return open(config_file).read()
exec(parser())
I am trying to get Argparse exec should load the variables user_token and channel_id from the config.py file inputted by the user (--config-file
argparse argument).
For whatever reason it will only load the main config file (from config import *
) even when running the proper commands to load in another one besides the main:
I’ve tried to remove config import * and have parser() return user_token after the exec call but that ends up return None type. yet if i print out the result of config_file in it returns whatever was input into –config-file part of the command, meaning it’s parsing the command but not able to properly read the config.py file
python3 bot.py --config-file config1.py
would run account1
python3 bot.py --config-file config2.py
would run account2
config file template(all are located in same directory as main.py):
channel_id = XXXXX
user_token = "XXXXX"
main.py file:
from asyncio import sleep
import argparse
import discord, datetime
import tweepy
from config import *
def parser():
parser = argparse.ArgumentParser()
parser.add_argument("--config-file", type=str, required=True)
args = parser.parse_args()
config_file = args.config_file
exec(open(config_file).read())
parser()
class Client(discord.Client):
active = True
async def pauseBump(self):
self.active = False
print("Bump paused.")
async def continueBump(self):
self.active = True
print("Bump restored.")
async def clean(self, user_message=None, bot_message=None):
await sleep(3)
if user_message is not None:
await user_message.delete()
if bot_message is not None:
await bot_message.delete()
print("Chat cleaned")
async def send(self, ctx, content):
message = await ctx.channel.send(f"{ctx.author.mention} {content}")
print(f"Sent '{content}' to '{ctx.author}'")
await self.clean(ctx, message)
async def bumpCheck(self):
channels_ids = []
for server in self.guilds:
for channel in server.channels:
if str(channel.type) == 'text':
channels_ids.append(channel.id)
print(channels_ids)
#channels_ids = [channel.id for channel in channels]
# Get a list of all chanells in the current server
for channel_id in channels_ids:
channel = self.get_channel(channel_id)
async for message in channel.history(limit=50):
if message.author != self.user:
if "react" in message.content.lower():
await message.add_reaction("N{THUMBS UP SIGN}")
# Code from original auto-bump author
if str(message.author) == "DISCORD_ADMIN_NAME":
if "Bump done" in message.embeds[0].description:
now = datetime.datetime.utcnow()
two = datetime.timedelta(hours=2)
min = datetime.timedelta(minutes=1)
difference = now - message.created_at
difference = two - difference + min
print(f"Time until next bump {difference}")
return difference.seconds
return 120
# Code from original auto-bump author
async def bump(self):
self.diff = await self.bumpCheck()
await sleep(self.diff)
channel = self.get_channel(channel_id)
command = await channel.send("bump")
print("Server bumped")
return command
async def on_ready(self):
print(f"Logged as {self.user}")
while self.active == True:
command = await self.bump()
await self.clean(command)
async def on_message(self, message):
if message.author == self.user:
if message.content == "!pause":
await self.pauseBump()
await self.send(message, "Bot is paused :sleeping:")
elif message.content == "!continue":
await self.continueBump()
await self.send(
message,
f"Bump is activated, next bump in {self.diff} seconds :hourglass_flowing_sand:",
)
Client().run( user_token, bot=False)
This works, but i DO NOT recommend it! Do NOT use python files as config files by loading the content via exec. This can have unwanted effects, depending on what is in the config.py file. Use a json file and override the imported config variables.
from asyncio import sleep
import argparse
import discord, datetime
import tweepy
from config import *
def parser():
parser = argparse.ArgumentParser()
parser.add_argument("--config-file", type=str, required=True)
args = parser.parse_args()
config_file = args.config_file
return open(config_file).read()
exec(parser())