11"""OG Image endpoints for branded social media preview images."""
22
3+ import asyncio
4+
35import httpx
46from fastapi import APIRouter , Depends , HTTPException
57from 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
0 commit comments