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