disco.server — HTTP API Reference
The GUI backend is implemented as a FastAPI application (app) served by
Uvicorn on http://0.0.0.0:8000. The application maintains a single
in-memory session via the module-level singleton state (an instance of
GlobalState). All state is cleared on startup and on server shutdown.
CORS is enabled for all origins (allow_origins=["*"]) to permit
access from the bundled React application.
Global State
The GlobalState class holds the current session data:
Attribute |
Description |
|---|---|
|
|
|
FITS header object, or |
|
Resolved file path of the loaded FITS file, or |
|
|
|
|
|
|
Pydantic Request Models
- class disco.server.PlotParams[source]
Request body for
POST /render_plot.- Parameters:
type (str) – Image type to render. One of:
"data","deproj","model","residuals","polar","profile".cmap (str) – Matplotlib colormap name. Default:
"magma".stretch (str) – Intensity stretch. One of:
"asinh"(default),"log","linear","sqrt".vmax_percentile (float | None) – If set, the vmax is computed as this percentile of the image data.
vmin (float | None) – Manual lower intensity limit.
vmax (float | None) – Manual upper intensity limit.
contours (bool) – Overlay contours. Default:
False.contour_levels (int) – Number of contour levels. Default: 5.
show_beam (bool) – Overlay beam ellipse. Default:
False.show_grid (bool) – Overlay grid lines. Default:
False.show_axes (bool) – Show axes and labels. Default:
True.show_colorbar (bool) – Show colorbar. Default:
True.title (str | None) – Optional plot title.
dpi (int) – Figure DPI. Default: 150.
- class disco.server.PipelineParams[source]
Request body for
POST /run_pipeline.- Parameters:
cx (float) – Disk centre x-coordinate in pixels.
cy (float) – Disk centre y-coordinate in pixels (GUI convention: measured from the top of the image).
pa (float) – Position angle in degrees.
incl (float) – Inclination in degrees.
rout (float) – Outer disk radius in arcseconds.
fit_rmin (float) – Inner radius for Gaussian ring fitting. Default: 0.0.
fit_rmax (float) – Outer radius for Gaussian ring fitting. Default: 0.0.
- class disco.server.OptimizeParams[source]
Request body for
POST /optimize_geometry.- Parameters:
cx (float) – Centre x in pixels.
cy (float) – Centre y in pixels.
pa (float) – Current position angle in degrees.
incl (float) – Current inclination in degrees.
rout (float) – Outer radius in arcseconds.
fit_rmin (float) – Inner fitting radius in arcseconds. Default: 0.0.
fit_rmax (float) – Outer fitting radius in arcseconds. Default: 0.0.
Endpoints
Session Management
File Loading
- POST /upload
Accept a multipart FITS file upload, save it to
.disco_uploads/, load the primary HDU intostate.dataandstate.header, and return basic image metadata.If the data maximum is below 0.1, the array is multiplied by 1 000 (Jy/beam → mJy/beam normalisation).
Form field:
file— the FITS file.- Status Codes:
200 OK – JSON object with keys:
filename(str),status("loaded"),shape(list[int, int]),pixel_scale(float, arcsec/pixel).500 Internal Server Error – On any read or FITS parse error.
- POST /load_local
Load a previously-uploaded FITS file from
.disco_uploads/by base filename. Applies the same unit normalisation as/upload.Request body:
LoadLocalParams- Status Codes:
200 OK – JSON object with keys:
status("loaded"),filename(str),shape(list[int, int]),pixel_scale(float).404 Not Found – If the file does not exist in the upload directory.
500 Internal Server Error – On parse error.
- GET /preview
Return a base64-encoded PNG preview of the currently-loaded image, rendered with the
infernocolormap and anAsinhStretchnormalisation (stretch_val=0.02).- Status Codes:
200 OK –
{"image": "data:image/png;base64,<...>"}404 Not Found – If no data is loaded.
Pipeline and Optimisation
- POST /run_pipeline
Execute the deprojection pipeline on the currently-loaded image with the supplied geometry, and store the results in
state.results.Procedure:
Convert GUI pixel-y to image-y convention.
Generate the deprojected image by applying the inclination and PA transform on a \(1000 \times 1000\) grid using
scipy.ndimage.map_coordinates(order 3).Compute the polar map (radius vs azimuth, 361 × 500 pixels).
Build the azimuthal model (mean profile tiled over the polar grid, then reprojected to Cartesian).
Compute the residual map (deprojected − model).
Extract the azimuthally-averaged profile via
disco.core.fits_utils.extract_profile().If
fit_rmin < fit_rmax, fit a Gaussian to the profile segment usingscipy.optimize.curve_fitwith the model \(G(r) = a\exp(-(r-r_0)^2/(2\sigma^2)) + c\).Read beam geometry from the header and construct a beam info dict.
Store all results in
state.
Request body:
PipelineParams- Status Codes:
200 OK – JSON object with the following structure:
{ "images": { "deproj": "data:image/png;base64,...", "polar": "data:image/png;base64,...", "model": "data:image/png;base64,...", "residuals": "data:image/png;base64,..." }, "profile": { "radius": [...], "intensity": [...], "raw_intensity": [...] }, "geometry": { "fov_cartesian": <float>, "fov_polar": <float>, "beam": {"major": <float>, "minor": <float>, "pa": <float>}, "pixel_scale": <float> }, "fit": { "peak_radius": <float>, "fwhm": <float> } }The
fitkey isnullif no fit range is specified or fitting fails.- Status Codes:
400 Bad Request – If no data is loaded.
500 Internal Server Error – On internal error.
- POST /optimize_geometry
Run a grid-seeded Nelder-Mead optimisation of
disco.core.optimization.geometric_loss()to refine inclination and position angle.Procedure:
Convert GUI coordinates to image-space.
Apply zero-padding (1000 pixels) and crop around the centre.
Evaluate the loss at a grid of \((i, \phi)\) candidates:
test_incls = [10, 30, 50, 70]degrees,test_pas = range(0, 180, 30)degrees.Run Nelder-Mead (bounds
[0,85] × [0,180] × [-10,10]²,dim=400,order=3) starting from the best grid point.
Request body:
OptimizeParams- Status Codes:
200 OK –
{ "optimized_incl": <float>, "optimized_pa": <float> }- Status Codes:
400 Bad Request – If no data is loaded.
Rendering
- POST /render_plot
Render a Matplotlib figure of the requested image type and return it as a base64-encoded PNG.
For 2D image types (
"data","deproj","model","residuals","polar"):Intensity normalisation uses the selected stretch function (
AsinhStretch,LogStretch,LinearStretch, orSqrtStretch).If
show_axesisTrue, axis labels, title, and optionally a colorbar and grid are rendered.If
show_beamisTrueandBMAJ/BMINare present in the header, a beam ellipse is overlaid in the lower-left region.If
contoursisTrue,ax.contouris called withcontour_levelslevels.
For
"profile"type:A log-scale 1D plot of the brightness temperature profile is generated.
Request body:
PlotParams- Status Codes:
200 OK –
{ "image": "data:image/png;base64,...", "stats": { "min": <float>, "max": <float>, "vmin_used": <float>, "vmax_used": <float>, "cmap_used": <str> } }- Status Codes:
400 Bad Request – If data for the requested type is not available.
Download and Metadata
- GET /download_fits
Return a pipeline output array as a binary FITS file, preserving the original FITS header.
Query parameter:
type— one of"data","deproj","model","residuals","polar".- Status Codes:
200 OK – Binary FITS file with
Content-Disposition: attachment; filename=result_<type>.fits400 Bad Request – If the requested data type is not available.
- GET /query_simbad
Query CDS SIMBAD for objects within 2 arcmin of the loaded FITS image centre. Reads the WCS from the header to compute the sky position.
Requests the following VOTable fields:
otype,flux(V),distance.Requires
astroqueryto be installed.- Status Codes:
200 OK –
{"found": true, "data": [...]}— list of row objects with all returned SIMBAD columns, or{"found": false, "data": []}if no sources are found.400 Bad Request – If no header is loaded.
501 Not Implemented – If
astroqueryis not installed.500 Internal Server Error – On SIMBAD query error.
Static File Serving
- GET /assets/<path>
Serves static assets from
disco/static/assets/(Vite build output).
- GET /{full_path}
Catch-all route. If the path resolves to an existing file in
disco/static/, serves it directly; otherwise servesdisco/static/index.html(enabling React client-side routing).All responses include
Cache-Control: no-cacheheaders to prevent stale asset delivery.
Server Lifecycle
- disco.server.start_server()[source]
Called by
disco.main.run()whenguiis the first argument. Prints the server address to stdout, starts a background thread that opens the default browser athttp://localhost:8000after a 1.5-second delay, and starts Uvicorn:uvicorn.run(app, host="0.0.0.0", port=8000, log_level="warning")
On shutdown, the
@app.on_event("shutdown")handler callswipe_session_logic()to clean up the upload directory and reset session state.