Skip to content

Commit ceae15b

Browse files
fix(seo): address Copilot review feedback for og:images
- Use asyncio.gather for parallel image fetching (faster) - Remove unused spec_id parameter from create_og_collage - Add Cache-Control headers (public, max-age=3600) to all /og/ responses 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 8ebf85c commit ceae15b

2 files changed

Lines changed: 14 additions & 15 deletions

File tree

api/routers/og_images.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
"""OG Image endpoints for branded social media preview images."""
22

3+
import asyncio
4+
35
import httpx
46
from fastapi import APIRouter, Depends, HTTPException
57
from fastapi.responses import Response
@@ -37,7 +39,7 @@ async def get_branded_impl_image(
3739
key = cache_key("og", spec_id, library)
3840
cached = get_cache(key)
3941
if cached:
40-
return Response(content=cached, media_type="image/png")
42+
return Response(content=cached, media_type="image/png", headers={"Cache-Control": "public, max-age=3600"})
4143

4244
if db is None:
4345
raise HTTPException(status_code=503, detail="Database not available")
@@ -62,7 +64,9 @@ async def get_branded_impl_image(
6264
# Cache the result
6365
set_cache(key, branded_bytes, ttl=OG_IMAGE_CACHE_TTL)
6466

65-
return Response(content=branded_bytes, media_type="image/png")
67+
return Response(
68+
content=branded_bytes, media_type="image/png", headers={"Cache-Control": "public, max-age=3600"}
69+
)
6670

6771
except httpx.HTTPError as e:
6872
raise HTTPException(status_code=502, detail=f"Failed to fetch image: {e}") from e
@@ -79,7 +83,7 @@ async def get_spec_collage_image(spec_id: str, db: AsyncSession | None = Depends
7983
key = cache_key("og", spec_id, "collage")
8084
cached = get_cache(key)
8185
if cached:
82-
return Response(content=cached, media_type="image/png")
86+
return Response(content=cached, media_type="image/png", headers={"Cache-Control": "public, max-age=3600"})
8387

8488
if db is None:
8589
raise HTTPException(status_code=503, detail="Database not available")
@@ -101,22 +105,19 @@ async def get_spec_collage_image(spec_id: str, db: AsyncSession | None = Depends
101105
selected_impls = sorted_impls[:6]
102106

103107
try:
104-
# Fetch all images
105-
images: list[bytes] = []
106-
labels: list[str] = []
107-
for impl in selected_impls:
108-
image_bytes = await _fetch_image(impl.preview_url)
109-
images.append(image_bytes)
110-
# Label format: "spec_id · library" like in og-image.png
111-
labels.append(f"{spec_id} · {impl.library_id}")
108+
# Fetch all images in parallel for better performance
109+
images = list(await asyncio.gather(*[_fetch_image(impl.preview_url) for impl in selected_impls]))
110+
labels = [f"{spec_id} · {impl.library_id}" for impl in selected_impls]
112111

113112
# Create collage
114-
collage_bytes = create_og_collage(images, spec_id=spec_id, labels=labels)
113+
collage_bytes = create_og_collage(images, labels=labels)
115114

116115
# Cache the result
117116
set_cache(key, collage_bytes, ttl=OG_IMAGE_CACHE_TTL)
118117

119-
return Response(content=collage_bytes, media_type="image/png")
118+
return Response(
119+
content=collage_bytes, media_type="image/png", headers={"Cache-Control": "public, max-age=3600"}
120+
)
120121

121122
except httpx.HTTPError as e:
122123
raise HTTPException(status_code=502, detail=f"Failed to fetch images: {e}") from e

core/images.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,6 @@ def create_branded_og_image(
438438
def create_og_collage(
439439
images: list[str | Path | Image.Image | bytes],
440440
output_path: str | Path | None = None,
441-
spec_id: str | None = None,
442441
labels: list[str] | None = None,
443442
) -> Image.Image | bytes:
444443
"""Create a collage OG image from multiple plot images.
@@ -451,7 +450,6 @@ def create_og_collage(
451450
Args:
452451
images: List of plot images (paths, PIL Images, or bytes), up to 6
453452
output_path: If provided, save to this path
454-
spec_id: Optional spec ID for subtitle
455453
labels: Optional list of labels for each image (e.g., library names)
456454
457455
Returns:

0 commit comments

Comments
 (0)