diff options
author | 2025-04-09 10:15:30 +0100 | |
---|---|---|
committer | 2025-04-09 10:15:30 +0100 | |
commit | 60075c4354566f222afc5bcb3384701d2845d65e (patch) | |
tree | c5d2da90431a76218cf377f51cf91d07cb5acac9 | |
parent | Only fetch PEP data when needed, and fix function call (diff) |
Tidy PEP code + improve caching
-rw-r--r-- | bot/exts/info/pep.py | 40 |
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) |