33from pathlib import Path
44
55from fastapi import FastAPI , HTTPException
6- from fastapi .responses import HTMLResponse
6+ from fastapi .responses import HTMLResponse , JSONResponse , FileResponse
77
88BASE_DIR = Path (__file__ ).resolve ().parent .parent
99WEB_DIR = BASE_DIR / "web"
@@ -18,73 +18,14 @@ def read_index() -> str:
1818
1919
2020@app .get ("/aladin" )
21- async def aladin () -> Response :
21+ async def aladin () -> FileResponse :
2222 return FileResponse ("web/aladin.html" )
2323
2424
2525@app .get ("/" )
2626async def root () -> JSONResponse :
2727 return JSONResponse ({"status" : "ok" , "message" : "Visit /app for the prototype UI." })
2828
29-
30- @app .get ("/tile" )
31- async def get_tile (
32- target : Optional [str ] = Query (None , description = "Named target resolvable by SIMBAD/NED" ),
33- ra : Optional [float ] = Query (None , description = "Right ascension in decimal degrees" ),
34- dec : Optional [float ] = Query (None , description = "Declination in decimal degrees" ),
35- width : float = Query (60.0 , gt = 0.0 , description = "Width of the requested cutout in degrees" ),
36- height : Optional [float ] = Query (None , description = "Height of the cutout in degrees" ),
37- pixels : int = Query (1024 , gt = 32 , le = 8192 , description = "Output resolution of the cutout" ),
38- survey : str = Query ("DSS2 Red" , description = "SkyView survey name" ),
39- projection : str = Query ("Car" , description = "Projection identifier (Car, Tan, Ait, etc.)" ),
40- overwrite : bool = Query (True , description = "Overwrite cached files on disk" ),
41- ) -> FileResponse :
42- """Return a PNG tile generated via NASA SkyView.
43-
44- The heavy lifting is performed by :func:`fetch_survey_image`, which writes to disk and
45- gives us a PNG we can stream back to the browser.
46- """
47-
48- if not target and (ra is None or dec is None ):
49- raise HTTPException (status_code = 422 , detail = "Provide either target or (ra, dec)" )
50-
51- loop = asyncio .get_event_loop ()
52-
53- logger .info (
54- "Requesting tile — survey=%s target=%s ra=%.5f dec=%.5f width=%.2f height=%s pixels=%d" ,
55- survey ,
56- target or "(RA/Dec)" ,
57- ra if ra is not None else float ("nan" ),
58- dec if dec is not None else float ("nan" ),
59- width ,
60- f"{ height :.2f} " if height is not None else "auto" ,
61- pixels ,
62- )
63-
64- try :
65- product = await loop .run_in_executor (
66- None ,
67- lambda : fetch_survey_image (
68- target = target ,
69- ra = ra ,
70- dec = dec ,
71- survey = survey ,
72- width_deg = width ,
73- height_deg = height ,
74- pixels = pixels ,
75- projection = projection ,
76- output_dir = OUTPUT_DIR ,
77- overwrite = overwrite ,
78- ),
79- )
80- except Exception as exc : # pragma: no cover - best effort surface to caller
81- logger .exception ("SkyView tile request failed" )
82- raise HTTPException (status_code = 500 , detail = str (exc )) from exc
83-
84- logger .info ("Tile ready — %s" , product .png_path )
85- return FileResponse (product .png_path , media_type = "image/png" )
86-
87-
8829if __name__ == "__main__" :
8930 import uvicorn
9031
0 commit comments