Skip to content

Commit 60075c4

Browse files
committed
Tidy PEP code + improve caching
1 parent 51b63b5 commit 60075c4

1 file changed

Lines changed: 25 additions & 15 deletions

File tree

bot/exts/info/pep.py

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
from datetime import UTC, datetime, timedelta
2-
from typing import Optional
2+
from typing import TypedDict
33

44
from discord import Colour, Embed
55
from discord.ext.commands import Cog, Context, command
6-
from pydis_core.utils.caching import AsyncCache
76

87
from bot.bot import Bot
98
from bot.log import get_logger
@@ -13,23 +12,35 @@
1312
ICON_URL = "https://www.python.org/static/opengraph-icon-200x200.png"
1413
PEP_API_URL = "https://peps.python.org/api/peps.json"
1514

15+
class PEPInfo(TypedDict):
16+
"""
17+
Useful subset of the PEP API response.
18+
19+
Full structure documented at https://peps.python.org/api/
20+
"""
21+
22+
number: int
23+
title: str
24+
url: str
25+
status: str
26+
python_version: str | None
27+
created: str
28+
type: str
29+
1630

1731
class PythonEnhancementProposals(Cog):
1832
"""Cog for displaying information about PEPs."""
1933

2034
def __init__(self, bot: Bot):
2135
self.bot = bot
22-
self.peps: dict[int, dict[str, Optional[str]]] = {}
23-
self.last_refreshed_peps: Optional[datetime] = None
36+
self.peps: dict[int, PEPInfo] = {}
37+
self.last_refreshed_peps: datetime | None = None
2438

2539
async def refresh_pep_data(self) -> None:
2640
"""Refresh PEP data."""
2741
# Putting this first should prevent any race conditions
2842
self.last_refreshed_peps = datetime.now(tz=UTC)
2943

30-
# Wait until HTTP client is available
31-
await self.bot.wait_until_ready()
32-
3344
log.trace("Started refreshing PEP data.")
3445
async with self.bot.http_session.get(PEP_API_URL) as resp:
3546
if resp.status != 200:
@@ -44,11 +55,10 @@ async def refresh_pep_data(self) -> None:
4455

4556
log.info("Successfully refreshed PEP data.")
4657

47-
def generate_pep_embed(self, pep_number: int) -> Embed:
58+
def generate_pep_embed(self, pep: PEPInfo) -> Embed:
4859
"""Generate PEP embed."""
49-
pep = self.peps[pep_number]
5060
embed = Embed(
51-
title=f"**PEP {pep_number} - {pep['title']}**",
61+
title=f"**PEP {pep['number']} - {pep['title']}**",
5262
description=f"[Link]({pep['url']})",
5363
)
5464
embed.set_thumbnail(url=ICON_URL)
@@ -64,24 +74,24 @@ def generate_pep_embed(self, pep_number: int) -> Embed:
6474
@command(name="pep", aliases=("get_pep", "p"))
6575
async def pep_command(self, ctx: Context, pep_number: int) -> None:
6676
"""Fetches information about a PEP and sends it to the channel."""
77+
# Refresh the PEP data up to every hour, as e.g. the PEP status might have changed.
6778
if (
6879
self.last_refreshed_peps is None or (
69-
pep_number not in self.peps
70-
and (self.last_refreshed_peps + timedelta(minutes=30)) <= datetime.now()
80+
(self.last_refreshed_peps + timedelta(hours=1)) <= datetime.now(tz=UTC)
7181
and len(str(pep_number)) < 5
7282
)
7383
):
7484
await self.refresh_pep_data()
7585

76-
if pep_number not in self.peps:
86+
if pep := self.peps.get(pep_number):
87+
embed = self.generate_pep_embed(pep)
88+
else:
7789
log.trace(f"PEP {pep_number} was not found")
7890
embed = Embed(
7991
title="PEP not found",
8092
description=f"PEP {pep_number} does not exist.",
8193
colour=Colour.red(),
8294
)
83-
else:
84-
embed = self.generate_pep_embed(pep_number)
8595

8696
await ctx.send(embed=embed)
8797

0 commit comments

Comments
 (0)