aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar wookie184 <[email protected]>2025-04-09 10:15:30 +0100
committerGravatar wookie184 <[email protected]>2025-04-09 10:15:30 +0100
commit60075c4354566f222afc5bcb3384701d2845d65e (patch)
treec5d2da90431a76218cf377f51cf91d07cb5acac9
parentOnly fetch PEP data when needed, and fix function call (diff)
Tidy PEP code + improve caching
-rw-r--r--bot/exts/info/pep.py40
1 files changed, 25 insertions, 15 deletions
diff --git a/bot/exts/info/pep.py b/bot/exts/info/pep.py
index a954ddbac..7f1823d8b 100644
--- a/bot/exts/info/pep.py
+++ b/bot/exts/info/pep.py
@@ -1,9 +1,8 @@
from datetime import UTC, datetime, timedelta
-from typing import Optional
+from typing import TypedDict
from discord import Colour, Embed
from discord.ext.commands import Cog, Context, command
-from pydis_core.utils.caching import AsyncCache
from bot.bot import Bot
from bot.log import get_logger
@@ -13,23 +12,35 @@ log = get_logger(__name__)
ICON_URL = "https://www.python.org/static/opengraph-icon-200x200.png"
PEP_API_URL = "https://peps.python.org/api/peps.json"
+class PEPInfo(TypedDict):
+ """
+ Useful subset of the PEP API response.
+
+ Full structure documented at https://peps.python.org/api/
+ """
+
+ number: int
+ title: str
+ url: str
+ status: str
+ python_version: str | None
+ created: str
+ type: str
+
class PythonEnhancementProposals(Cog):
"""Cog for displaying information about PEPs."""
def __init__(self, bot: Bot):
self.bot = bot
- self.peps: dict[int, dict[str, Optional[str]]] = {}
- self.last_refreshed_peps: Optional[datetime] = None
+ self.peps: dict[int, PEPInfo] = {}
+ self.last_refreshed_peps: datetime | None = None
async def refresh_pep_data(self) -> None:
"""Refresh PEP data."""
# Putting this first should prevent any race conditions
self.last_refreshed_peps = datetime.now(tz=UTC)
- # Wait until HTTP client is available
- await self.bot.wait_until_ready()
-
log.trace("Started refreshing PEP data.")
async with self.bot.http_session.get(PEP_API_URL) as resp:
if resp.status != 200:
@@ -44,11 +55,10 @@ class PythonEnhancementProposals(Cog):
log.info("Successfully refreshed PEP data.")
- def generate_pep_embed(self, pep_number: int) -> Embed:
+ def generate_pep_embed(self, pep: PEPInfo) -> Embed:
"""Generate PEP embed."""
- pep = self.peps[pep_number]
embed = Embed(
- title=f"**PEP {pep_number} - {pep['title']}**",
+ title=f"**PEP {pep['number']} - {pep['title']}**",
description=f"[Link]({pep['url']})",
)
embed.set_thumbnail(url=ICON_URL)
@@ -64,24 +74,24 @@ class PythonEnhancementProposals(Cog):
@command(name="pep", aliases=("get_pep", "p"))
async def pep_command(self, ctx: Context, pep_number: int) -> None:
"""Fetches information about a PEP and sends it to the channel."""
+ # Refresh the PEP data up to every hour, as e.g. the PEP status might have changed.
if (
self.last_refreshed_peps is None or (
- pep_number not in self.peps
- and (self.last_refreshed_peps + timedelta(minutes=30)) <= datetime.now()
+ (self.last_refreshed_peps + timedelta(hours=1)) <= datetime.now(tz=UTC)
and len(str(pep_number)) < 5
)
):
await self.refresh_pep_data()
- if pep_number not in self.peps:
+ if pep := self.peps.get(pep_number):
+ embed = self.generate_pep_embed(pep)
+ else:
log.trace(f"PEP {pep_number} was not found")
embed = Embed(
title="PEP not found",
description=f"PEP {pep_number} does not exist.",
colour=Colour.red(),
)
- else:
- embed = self.generate_pep_embed(pep_number)
await ctx.send(embed=embed)