aboutsummaryrefslogtreecommitdiffstats
path: root/bot
diff options
context:
space:
mode:
Diffstat (limited to 'bot')
-rw-r--r--bot/__main__.py10
-rw-r--r--bot/constants.py164
-rw-r--r--bot/exts/events/hacktoberfest/hacktober-issue-finder.py2
-rw-r--r--bot/exts/events/hacktoberfest/hacktoberstats.py4
-rw-r--r--bot/exts/fun/game.py4
-rw-r--r--bot/exts/fun/movie.py4
-rw-r--r--bot/exts/fun/snakes/_snakes_cog.py6
-rw-r--r--bot/exts/fun/space.py2
-rw-r--r--bot/exts/holidays/easter/earth_photos.py6
-rw-r--r--bot/exts/holidays/halloween/scarymovie.py4
-rw-r--r--bot/exts/holidays/halloween/spookygif.py2
-rw-r--r--bot/exts/holidays/valentines/be_my_valentine.py6
-rw-r--r--bot/exts/holidays/valentines/lovecalculator.py6
-rw-r--r--bot/exts/utilities/cheatsheet.py2
-rw-r--r--bot/exts/utilities/githubinfo.py2
-rw-r--r--bot/exts/utilities/reddit.py2
-rw-r--r--bot/exts/utilities/wolfram.py2
17 files changed, 141 insertions, 87 deletions
diff --git a/bot/__main__.py b/bot/__main__.py
index d39e93bf..1b6b9f1e 100644
--- a/bot/__main__.py
+++ b/bot/__main__.py
@@ -19,11 +19,11 @@ log = logging.getLogger(__name__)
async def _create_redis_session() -> RedisSession:
"""Create and connect to a redis session."""
redis_session = RedisSession(
- host=constants.RedisConfig.host,
- port=constants.RedisConfig.port,
- password=constants.RedisConfig.password,
+ host=constants.Redis.host,
+ port=constants.Redis.port,
+ password=constants.Redis.password.get_secret_value(),
max_connections=20,
- use_fakeredis=constants.RedisConfig.use_fakeredis,
+ use_fakeredis=constants.Redis.use_fakeredis,
global_namespace="bot",
decode_responses=True,
)
@@ -81,7 +81,7 @@ async def main() -> None:
if constants.Client.in_ci:
await test_bot_in_ci(_bot)
else:
- await _bot.start(constants.Client.token)
+ await _bot.start(constants.Client.token.get_secret_value())
asyncio.run(main())
diff --git a/bot/constants.py b/bot/constants.py
index 7e5fa1d9..a5f12fe2 100644
--- a/bot/constants.py
+++ b/bot/constants.py
@@ -1,7 +1,8 @@
import enum
import logging
from os import environ
-from typing import NamedTuple
+
+from pydantic import BaseSettings, SecretStr
__all__ = (
"Branding",
@@ -13,13 +14,12 @@ __all__ = (
"Colours",
"Emojis",
"Icons",
- "Lovefest",
"Month",
"Roles",
"Tokens",
"Wolfram",
"Reddit",
- "RedisConfig",
+ "Redis",
"RedirectOutput",
"PYTHON_PREFIX",
"MODERATION_ROLES",
@@ -36,21 +36,38 @@ log = logging.getLogger(__name__)
PYTHON_PREFIX = "!"
-class Branding:
- cycle_frequency = int(environ.get("CYCLE_FREQUENCY", 3)) # 0: never, 1: every day, 2: every other day, ...
+class EnvConfig(BaseSettings):
+ """Our default configuration for models that should load from .env files."""
+
+ class Config:
+ """Specify what .env files to load, and how to load them."""
+
+ env_file = ".env",
+ env_file_encoding = "utf-8"
+
+
+class _Branding(EnvConfig):
+ EnvConfig.Config.env_prefix = "branding_"
+
+ cycle_frequency = 3 # 0: never, 1: every day, 2: every other day, ...
+
+
+Branding = _Branding()
class Cats:
cats = ["ᓚᘏᗢ", "ᘡᘏᗢ", "🐈", "ᓕᘏᗢ", "ᓇᘏᗢ", "ᓂᘏᗢ", "ᘣᘏᗢ", "ᕦᘏᗢ", "ᕂᘏᗢ"]
-class Channels(NamedTuple):
+class _Channels(EnvConfig):
+ EnvConfig.Config.env_prefix = "channels_"
+
algos_and_data_structs = 650401909852864553
bot_commands = 267659945086812160
community_meta = 267659945086812160
organisation = 551789653284356126
data_science_and_ai = 366673247892275221
- devlog = int(environ.get("CHANNEL_DEVLOG", 622895325144940554))
+ devlog = 622895325144940554
dev_contrib = 635950537262759947
mod_meta = 775412552795947058
mod_tools = 775413915391098921
@@ -58,40 +75,57 @@ class Channels(NamedTuple):
off_topic_1 = 463035241142026251
off_topic_2 = 463035268514185226
python_help = 1035199133436354600
- sir_lancebot_playground = int(environ.get("CHANNEL_COMMUNITY_BOT_COMMANDS", 607247579608121354))
+ sir_lancebot_playground = 607247579608121354
voice_chat_0 = 412357430186344448
voice_chat_1 = 799647045886541885
staff_voice = 541638762007101470
- reddit = int(environ.get("CHANNEL_REDDIT", 458224812528238616))
+ reddit = 458224812528238616
-class Categories(NamedTuple):
- help_in_use = 696958401460043776
+Channels = _Channels()
+
+
+class _Categories(EnvConfig):
+ EnvConfig.Config.env_prefix = "categories_"
+
+ python_help_system = 691405807388196926
development = 411199786025484308
devprojects = 787641585624940544
media = 799054581991997460
staff = 364918151625965579
-codejam_categories_name = "Code Jam" # Name of the codejam team categories
+Categories = _Categories()
+
+CODEJAM_CATEGORY_NAME = "Code Jam" # Name of the codejam team categories
+
+class _Client(EnvConfig):
+ EnvConfig.Config.env_prefix = "client_"
-class Client(NamedTuple):
name = "Sir Lancebot"
- guild = int(environ.get("BOT_GUILD", 267624335836053506))
- prefix = environ.get("PREFIX", ".")
- token = environ.get("BOT_TOKEN")
- debug = environ.get("BOT_DEBUG", "true").lower() == "true"
- in_ci = environ.get("IN_CI", "false").lower() == "true"
- github_bot_repo = "https://github.com/python-discord/sir-lancebot"
+ guild = 267624335836053506
+ prefix = "."
+ token: SecretStr
+ debug = True
+ in_ci = False
+ github_repo = "https://github.com/python-discord/sir-lancebot"
# Override seasonal locks: 1 (January) to 12 (December)
- month_override = int(environ["MONTH_OVERRIDE"]) if "MONTH_OVERRIDE" in environ else None
+ month_override: int | None = None
-class Logging(NamedTuple):
+Client = _Client()
+
+
+class _Logging(EnvConfig):
+ EnvConfig.Config.env_prefix = "logging_"
+
debug = Client.debug
- file_logs = environ.get("FILE_LOGS", "false").lower() == "true"
- trace_loggers = environ.get("BOT_TRACE_LOGGERS")
+ file_logs = False
+ trace_loggers = ""
+
+
+Logging = _Logging()
class Colours:
@@ -208,10 +242,6 @@ class Icons:
)
-class Lovefest:
- role_id = int(environ.get("LOVEFEST_ROLE_ID", 542431903886606399))
-
-
class Month(enum.IntEnum):
JANUARY = 1
FEBRUARY = 2
@@ -236,39 +266,59 @@ if Client.month_override is not None:
Month(Client.month_override)
-class Roles(NamedTuple):
+class _Roles(EnvConfig):
+
+ EnvConfig.Config.env_prefix = "roles_"
+
owners = 267627879762755584
- admins = int(environ.get("BOT_ADMIN_ROLE_ID", 267628507062992896))
+ admins = 267628507062992896
moderation_team = 267629731250176001
- helpers = int(environ.get("ROLE_HELPERS", 267630620367257601))
+ helpers = 267630620367257601
core_developers = 587606783669829632
- everyone = int(environ.get("BOT_GUILD", 267624335836053506))
+ everyone = Client.guild
+
+ lovefest = 542431903886606399
+
+
+Roles = _Roles()
+
+class _Tokens(EnvConfig):
+ EnvConfig.Config.env_prefix = "tokens_"
-class Tokens(NamedTuple):
- giphy = environ.get("GIPHY_TOKEN")
- aoc_session_cookie = environ.get("AOC_SESSION_COOKIE")
- omdb = environ.get("OMDB_API_KEY")
- youtube = environ.get("YOUTUBE_API_KEY")
- tmdb = environ.get("TMDB_API_KEY")
- nasa = environ.get("NASA_API_KEY")
- igdb_client_id = environ.get("IGDB_CLIENT_ID")
- igdb_client_secret = environ.get("IGDB_CLIENT_SECRET")
- github = environ.get("GITHUB_TOKEN")
- unsplash_access_key = environ.get("UNSPLASH_KEY")
+ giphy: SecretStr = ""
+ youtube: SecretStr = ""
+ tmdb: SecretStr = ""
+ nasa: SecretStr = ""
+ igdb_client_id: SecretStr = ""
+ igdb_client_secret: SecretStr = ""
+ github: SecretStr = ""
+ unsplash: SecretStr = ""
-class Wolfram(NamedTuple):
- user_limit_day = int(environ.get("WOLFRAM_USER_LIMIT_DAY", 10))
- guild_limit_day = int(environ.get("WOLFRAM_GUILD_LIMIT_DAY", 67))
- key = environ.get("WOLFRAM_API_KEY")
+Tokens = _Tokens()
-class RedisConfig(NamedTuple):
- host = environ.get("REDIS_HOST", "redis.default.svc.cluster.local")
- port = environ.get("REDIS_PORT", 6379)
- password = environ.get("REDIS_PASSWORD")
- use_fakeredis = environ.get("USE_FAKEREDIS", "false").lower() == "true"
+class _Wolfram(EnvConfig):
+ EnvConfig.Config.env_prefix = "wolfram_"
+ user_limit_day = 10
+ guild_limit_day = 67
+ key: SecretStr = ""
+
+
+Wolfram = _Wolfram()
+
+
+class _Redis(EnvConfig):
+ EnvConfig.Config.env_prefix = "redis_"
+
+ host = "redis.default.svc.cluster.local"
+ port = 6379
+ password: SecretStr = ""
+ use_fakeredis = False
+
+
+Redis = _Redis()
class Source:
@@ -280,13 +330,17 @@ class RedirectOutput:
delete_delay: int = 10
-class Reddit:
+class _Reddit(EnvConfig):
+ EnvConfig.Config.env_prefix = "reddit_"
+
subreddits = ["r/Python"]
- client_id = environ.get("REDDIT_CLIENT_ID")
- secret = environ.get("REDDIT_SECRET")
- webhook = int(environ.get("REDDIT_WEBHOOK", 635408384794951680))
+ client_id: SecretStr = ""
+ secret: SecretStr = ""
+ webhook = 635408384794951680
+
+Reddit = _Reddit()
# Default role combinations
MODERATION_ROLES = {Roles.moderation_team, Roles.admins, Roles.owners}
diff --git a/bot/exts/events/hacktoberfest/hacktober-issue-finder.py b/bot/exts/events/hacktoberfest/hacktober-issue-finder.py
index aeffc8d7..4f7bef5d 100644
--- a/bot/exts/events/hacktoberfest/hacktober-issue-finder.py
+++ b/bot/exts/events/hacktoberfest/hacktober-issue-finder.py
@@ -18,7 +18,7 @@ REQUEST_HEADERS = {
"User-Agent": "Python Discord Hacktoberbot",
"Accept": "application / vnd.github.v3 + json"
}
-if GITHUB_TOKEN := Tokens.github:
+if GITHUB_TOKEN := Tokens.github.get_secret_value():
REQUEST_HEADERS["Authorization"] = f"token {GITHUB_TOKEN}"
diff --git a/bot/exts/events/hacktoberfest/hacktoberstats.py b/bot/exts/events/hacktoberfest/hacktoberstats.py
index c29e24b0..0b4266d8 100644
--- a/bot/exts/events/hacktoberfest/hacktoberstats.py
+++ b/bot/exts/events/hacktoberfest/hacktoberstats.py
@@ -24,8 +24,8 @@ REQUEST_HEADERS = {"User-Agent": "Python Discord Hacktoberbot"}
# using repo topics API during preview period requires an accept header
GITHUB_TOPICS_ACCEPT_HEADER = {"Accept": "application/vnd.github.mercy-preview+json"}
if GITHUB_TOKEN := Tokens.github:
- REQUEST_HEADERS["Authorization"] = f"token {GITHUB_TOKEN}"
- GITHUB_TOPICS_ACCEPT_HEADER["Authorization"] = f"token {GITHUB_TOKEN}"
+ REQUEST_HEADERS["Authorization"] = f"token {GITHUB_TOKEN.get_secret_value()}"
+ GITHUB_TOPICS_ACCEPT_HEADER["Authorization"] = f"token {GITHUB_TOKEN.get_secret_value()}"
GITHUB_NONEXISTENT_USER_MESSAGE = (
"The listed users cannot be searched either because the users do not exist "
diff --git a/bot/exts/fun/game.py b/bot/exts/fun/game.py
index a8b0b3a0..c38dc063 100644
--- a/bot/exts/fun/game.py
+++ b/bot/exts/fun/game.py
@@ -20,8 +20,8 @@ from bot.utils.pagination import ImagePaginator, LinePaginator
# Base URL of IGDB API
BASE_URL = "https://api.igdb.com/v4"
-CLIENT_ID = Tokens.igdb_client_id
-CLIENT_SECRET = Tokens.igdb_client_secret
+CLIENT_ID = Tokens.igdb_client_id.get_secret_value()
+CLIENT_SECRET = Tokens.igdb_client_secret.get_secret_value()
# The number of seconds before expiry that we attempt to re-fetch a new access token
ACCESS_TOKEN_RENEWAL_WINDOW = 60*60*24*2
diff --git a/bot/exts/fun/movie.py b/bot/exts/fun/movie.py
index 422a83ac..73ef0a3c 100644
--- a/bot/exts/fun/movie.py
+++ b/bot/exts/fun/movie.py
@@ -22,7 +22,7 @@ THUMBNAIL_URL = "https://i.imgur.com/LtFtC8H.png"
# Define movie params, that will be used for every movie request
MOVIE_PARAMS = {
- "api_key": Tokens.tmdb,
+ "api_key": Tokens.tmdb.get_secret_value(),
"language": "en-US"
}
@@ -106,7 +106,7 @@ class Movie(Cog):
"""Return JSON of TMDB discover request."""
# Define params of request
params = {
- "api_key": Tokens.tmdb,
+ "api_key": Tokens.tmdb.get_secret_value(),
"language": "en-US",
"sort_by": "popularity.desc",
"include_adult": "false",
diff --git a/bot/exts/fun/snakes/_snakes_cog.py b/bot/exts/fun/snakes/_snakes_cog.py
index d0542c23..892a3dd2 100644
--- a/bot/exts/fun/snakes/_snakes_cog.py
+++ b/bot/exts/fun/snakes/_snakes_cog.py
@@ -773,7 +773,7 @@ class Snakes(Cog):
"query": "snake",
"page": page,
"language": "en-US",
- "api_key": Tokens.tmdb,
+ "api_key": Tokens.tmdb.get_secret_value(),
}
)
data = await response.json()
@@ -785,7 +785,7 @@ class Snakes(Cog):
f"https://api.themoviedb.org/3/movie/{movie}",
params={
"language": "en-US",
- "api_key": Tokens.tmdb,
+ "api_key": Tokens.tmdb.get_secret_value(),
}
)
data = await response.json()
@@ -1095,7 +1095,7 @@ class Snakes(Cog):
"part": "snippet",
"q": urllib.parse.quote_plus(query),
"type": "video",
- "key": Tokens.youtube
+ "key": Tokens.youtube.get_secret_value()
}
)
response = await response.json()
diff --git a/bot/exts/fun/space.py b/bot/exts/fun/space.py
index 22a89050..c688b281 100644
--- a/bot/exts/fun/space.py
+++ b/bot/exts/fun/space.py
@@ -210,7 +210,7 @@ class Space(Cog):
"""Fetch information from NASA API, return result."""
params = {}
if use_api_key:
- params["api_key"] = Tokens.nasa
+ params["api_key"] = Tokens.nasa.get_secret_value()
# Add additional parameters to request parameters only when they provided by user
if additional_params is not None:
diff --git a/bot/exts/holidays/easter/earth_photos.py b/bot/exts/holidays/easter/earth_photos.py
index e60e2626..013122c8 100644
--- a/bot/exts/holidays/easter/earth_photos.py
+++ b/bot/exts/holidays/easter/earth_photos.py
@@ -23,7 +23,7 @@ class EarthPhotos(commands.Cog):
async with ctx.typing():
async with self.bot.http_session.get(
API_URL,
- params={"query": "planet_earth", "client_id": Tokens.unsplash_access_key}
+ params={"query": "planet_earth", "client_id": Tokens.unsplash.get_secret_value()}
) as r:
jsondata = await r.json()
linksdata = jsondata.get("urls")
@@ -37,7 +37,7 @@ class EarthPhotos(commands.Cog):
rf = "?utm_source=Sir%20Lancebot&utm_medium=referral"
async with self.bot.http_session.get(
downloadlinksdata.get("download_location"),
- params={"client_id": Tokens.unsplash_access_key}
+ params={"client_id": Tokens.unsplash.get_secret_value()}
) as _:
pass
@@ -59,7 +59,7 @@ class EarthPhotos(commands.Cog):
async def setup(bot: Bot) -> None:
"""Load the Earth Photos cog."""
- if not Tokens.unsplash_access_key:
+ if not Tokens.unsplash:
log.warning("No Unsplash access key found. Cog not loading.")
return
await bot.add_cog(EarthPhotos(bot))
diff --git a/bot/exts/holidays/halloween/scarymovie.py b/bot/exts/holidays/halloween/scarymovie.py
index 9f1a95fd..00c96153 100644
--- a/bot/exts/holidays/halloween/scarymovie.py
+++ b/bot/exts/holidays/halloween/scarymovie.py
@@ -36,7 +36,7 @@ class ScaryMovie(commands.Cog):
"""Selects a random movie and returns a JSON of movie details from TMDb."""
url = "https://api.themoviedb.org/3/discover/movie"
params = {
- "api_key": Tokens.tmdb,
+ "api_key": Tokens.tmdb.get_secret_value(),
"with_genres": "27",
"vote_count.gte": "5",
"include_adult": "false"
@@ -65,7 +65,7 @@ class ScaryMovie(commands.Cog):
# Get full details and credits
async with self.bot.http_session.get(
url=f"https://api.themoviedb.org/3/movie/{selection_id}",
- params={"api_key": Tokens.tmdb, "append_to_response": "credits"}
+ params={"api_key": Tokens.tmdb.get_secret_value(), "append_to_response": "credits"}
) as selection:
return await selection.json()
diff --git a/bot/exts/holidays/halloween/spookygif.py b/bot/exts/holidays/halloween/spookygif.py
index 750e86ca..7a90a8a9 100644
--- a/bot/exts/holidays/halloween/spookygif.py
+++ b/bot/exts/holidays/halloween/spookygif.py
@@ -21,7 +21,7 @@ class SpookyGif(commands.Cog):
async def spookygif(self, ctx: commands.Context) -> None:
"""Fetches a random gif from the GIPHY API and responds with it."""
async with ctx.typing():
- params = {"api_key": Tokens.giphy, "tag": "halloween", "rating": "g"}
+ params = {"api_key": Tokens.giphy.get_secret_value(), "tag": "halloween", "rating": "g"}
# Make a GET request to the Giphy API to get a random halloween gif.
async with self.bot.http_session.get(API_URL, params=params) as resp:
data = await resp.json()
diff --git a/bot/exts/holidays/valentines/be_my_valentine.py b/bot/exts/holidays/valentines/be_my_valentine.py
index 5ffd14e6..3a2beef3 100644
--- a/bot/exts/holidays/valentines/be_my_valentine.py
+++ b/bot/exts/holidays/valentines/be_my_valentine.py
@@ -7,7 +7,7 @@ import discord
from discord.ext import commands
from bot.bot import Bot
-from bot.constants import Channels, Colours, Lovefest, Month, PYTHON_PREFIX
+from bot.constants import Channels, Colours, Month, PYTHON_PREFIX, Roles
from bot.utils.decorators import in_month
from bot.utils.exceptions import MovedCommandError
@@ -60,7 +60,7 @@ class BeMyValentine(commands.Cog):
# This command should only be used in the server
raise commands.UserInputError("You are supposed to use this command in the server.")
- if Lovefest.role_id not in [role.id for role in user.roles]:
+ if Roles.lovefest not in [role.id for role in user.roles]:
raise commands.UserInputError(
f"You cannot send a valentine to {user} as they do not have the lovefest role!"
)
@@ -95,7 +95,7 @@ class BeMyValentine(commands.Cog):
example : .bemyvalentine secret Iceman#6508 Hey I love you, wanna hang around ? (sends the custom message to
Iceman in DM making you anonymous)
"""
- if Lovefest.role_id not in [role.id for role in user.roles]:
+ if Roles.lovefest not in [role.id for role in user.roles]:
await ctx.message.delete()
raise commands.UserInputError(
f"You cannot send a valentine to {user} as they do not have the lovefest role!"
diff --git a/bot/exts/holidays/valentines/lovecalculator.py b/bot/exts/holidays/valentines/lovecalculator.py
index c212e833..eab3d083 100644
--- a/bot/exts/holidays/valentines/lovecalculator.py
+++ b/bot/exts/holidays/valentines/lovecalculator.py
@@ -12,7 +12,7 @@ from discord.ext import commands
from discord.ext.commands import BadArgument, Cog, clean_content
from bot.bot import Bot
-from bot.constants import Channels, Lovefest, Month, PYTHON_PREFIX
+from bot.constants import Channels, Month, PYTHON_PREFIX, Roles
from bot.utils.decorators import in_month
log = logging.getLogger(__name__)
@@ -45,8 +45,8 @@ class LoveCalculator(Cog):
Running .love @chrisjl#2655 @joe#6000 will yield the same result as before.
"""
if (
- Lovefest.role_id not in [role.id for role in who.roles]
- or (whom is not None and Lovefest.role_id not in [role.id for role in whom.roles])
+ Roles.lovefest not in [role.id for role in who.roles]
+ or (whom is not None and Roles.lovefest not in [role.id for role in whom.roles])
):
raise BadArgument(
"This command can only be ran against members with the lovefest role! "
diff --git a/bot/exts/utilities/cheatsheet.py b/bot/exts/utilities/cheatsheet.py
index 3141a050..d7eb4917 100644
--- a/bot/exts/utilities/cheatsheet.py
+++ b/bot/exts/utilities/cheatsheet.py
@@ -80,7 +80,7 @@ class CheatSheet(commands.Cog):
aliases=("cht.sh", "cheatsheet", "cheat-sheet", "cht"),
)
@commands.cooldown(1, 10, BucketType.user)
- @whitelist_override(categories=[Categories.help_in_use])
+ @whitelist_override(categories=[Categories.python_help_system])
async def cheat_sheet(self, ctx: Context, *search_terms: str) -> None:
"""
Search cheat.sh.
diff --git a/bot/exts/utilities/githubinfo.py b/bot/exts/utilities/githubinfo.py
index a7979718..4e008e9f 100644
--- a/bot/exts/utilities/githubinfo.py
+++ b/bot/exts/utilities/githubinfo.py
@@ -26,7 +26,7 @@ ISSUE_ENDPOINT = "https://api.github.com/repos/{user}/{repository}/issues/{numbe
PR_ENDPOINT = "https://api.github.com/repos/{user}/{repository}/pulls/{number}"
if Tokens.github:
- REQUEST_HEADERS["Authorization"] = f"token {Tokens.github}"
+ REQUEST_HEADERS["Authorization"] = f"token {Tokens.github.get_secret_value()}"
CODE_BLOCK_RE = re.compile(
r"^`([^`\n]+)`" # Inline codeblock
diff --git a/bot/exts/utilities/reddit.py b/bot/exts/utilities/reddit.py
index 028c16bc..43a82aef 100644
--- a/bot/exts/utilities/reddit.py
+++ b/bot/exts/utilities/reddit.py
@@ -36,7 +36,7 @@ class Reddit(Cog):
self.webhook = None
self.access_token = None
- self.client_auth = BasicAuth(RedditConfig.client_id, RedditConfig.secret)
+ self.client_auth = BasicAuth(RedditConfig.client_id.get_secret_value(), RedditConfig.secret.get_secret_value())
self.auto_poster_loop.start()
diff --git a/bot/exts/utilities/wolfram.py b/bot/exts/utilities/wolfram.py
index a2f1228a..a036b50f 100644
--- a/bot/exts/utilities/wolfram.py
+++ b/bot/exts/utilities/wolfram.py
@@ -15,7 +15,7 @@ from bot.utils.pagination import ImagePaginator
log = logging.getLogger(__name__)
-APPID = Wolfram.key
+APPID = Wolfram.key.get_secret_value()
DEFAULT_OUTPUT_FORMAT = "JSON"
QUERY = "http://api.wolframalpha.com/v2/{request}"
WOLF_IMAGE = "https://www.symbols.com/gi.php?type=1&id=2886&i=1"