All notable changes to the Blast application will be documented in this file.
The format is based on Keep a Changelog, and this project (mostly) adheres to Semantic Versioning.
Types of changes:
Added: for new features.Changed: for changes in existing functionality.Deprecated: for soon-to-be removed features.Removed: for now removed features.Fixed: for any bug fixes.Security: in case of vulnerabilities.
- Refactored the
dustmapsconfig to use theDUSTMAPS_DATA_ROOTenvironment variable, simplifying its use by eliminating the need to override the value within Python modules that usedustmaps. - Added a
utils.pymodule loaded by the management command defined inapp/host/management/commands/blast_admin.pywith example functions that have been useful to Blast developers and operators.
- Added support for usage monitoring with InfluxDB and Grafana. When
USAGE_METRICS_LOGROLLER_ENABLEDandUSAGE_METRICS_LOGROLLER_INFLUXDB_ENABLEDare true, the buffer of usage logs will be periodically exported to InfluxDB as well as to the object store, providing a Grafana-compatible data source for real-time monitoring.
- Added a
robots.txtfile to reduce system load caused by web crawlers when serving Blast publicly on the internet.
- Added SCIMMA logo and link to scimma.org to header.
- Added NSF logo to footer linking to the existing Acknowledgements page.
- Added a Django admin command
blast_adminto execute functions defined in alocal_util.pymodule in the same directory. This is useful in local dev environments, allowing the developer to add/modify functions dynamically and executing code in the Django environment usingpython manage.py blast_admin [custom_func]. - Updated GitHub Action versions used in
.github/workflows/docker_image_workflow.yml
- Revised layout and styling of webpages, primarily the transient results page. Information cards are collapsable and tables are formatted more legibly. Buttons controlling workflow retriggering/reprocessing, as well as buttons for downloading transient data products, were moved to the navbar. Improved image loading indicator animation.
- Updated and revised documentation
- Fixed a bug in the issue reporting & resolving API endpoints.
- Fixed a bug in the workflow progress calculation introduced by the refactoring of transient task prerequisites.
- Implemented support for importing and exporting self-contained transient datasets in the form of
compressed archive files (.tar.gz), including API endpoint
/api/transient/export/[2026abc]/[all], where2026abcrepresents the target transient name andallis an optional parameter that will include the cutout and SED fit files in the generated archive file. - Added a third option to the Add Transients page for importing a transient by uploading an archive file.
- Added an API endpoint to delete a transient:
/api/transient/delete/[2026abc]/[all], where2026abcrepresents the target transient name andallis an optional parameter that will delete the cutout and SED fit files in addition to the transient database objects (e.g.Cutout,Aperture,AperturePhotometry,SEDFittingResultobjects). - Dataset archive files for transients 2026dgt, 2026dix, and 2026dkf were added to the
app/entrypoints/blast-data.jsoninitial file manifest and uploaded to the public object store.
- Removed the 2010H, 2010ag, and 2010ai transient datasets from the data initialization routine. The
associated database objects were removed from
app/host/migrations/0024_load_fixtures.pyand the files were removed from theapp/entrypoints/blast-data.jsoninitial file manifest.
- Modified the unit tests to remove references to the 2010H, 2010ag, and 2010ai transients and instead import transient 2026dix from its dataset archive file.
- Modifed the data initialization routine to import transients 2026dgt, 2026dix, and 2026dkf from their dataset archive files.
- Updated the documentation with better screenshots and information about the dataset portation system.
- Increased
client_max_body_sizein NGINX proxy to support transient archive file uploads.
- Reduced the prerequisites for the
GenerateThumbnailSEDLocalandGenerateThumbnailSEDGlobaltasks that were inadvertently preventing SED fit thumbnails from being generated. - Fixed a database foreign key constraint violation triggered by the
GlobalApertureConstructiontask that sometimes deletedApertureobjects with associatedSEDFittingResult,AperturePhotometry, and/orStarFormationHistoryResultobjects.
- Removed unused Catalog and CatalogPhotometry models
- Removed Acknowledgement model and copied content statically into HTML template.
- Removed obsolete analytics webpage.
- Removed obsolete Celery Flower webpage. Flower is deployed as a separate Docker Compose service with routing handled by the NGINX web proxy that is also deployed independently via Compose.
- Deleted TaskRegisterSnapshot model and associated periodic task.
- Added migration script that adds the
Transient.namevalidation function
- Fixed a bug caused by searching for transients whose name included space characters.
- Defined rules for transient names, allowing only alphanumeric values, underscores, hyphens,
and plus signs. Existing invalid transient names are renamed via a migration script, and the
original invalid names are set as the new
display_namefield value. This display name is shown in the transient table and as the header of the result pages. The actualnamevalue, which is the unique identifier for the transient in the database, is still shown in the transient information panel. - Reorganized
settings.pyto consolidate configuration into modular blocks to aid development.
- Removed
revproxyDjango app and the obsoleteFlowerProxyViewclass.
- Added a
croppedfield to theCutoutmodel to record whether the image has been cropped
- Fixed a bug in photometry caused by previously cropped images being used instead of downloading original data again from source catalogs when reprocessing a transient. Improved the cutout download function logic.
- Temporarily running a fork of Prost that supports a custom PanSTARRS catalog API timeout value
- Better error handling in the Global Aperture Construction task
- Added a custom sorting function for the transient table "discovery date" column that always sorts transients lacking discovery dates last whether ascending or descending.
- Revised the data initialization routine to compare test transient dataset files (e.g. 2010H) without downloading them by S3 etag checksum, and, if a file needs to be installed, only download to local scratch space temporarily in order to upload to the Blast dataset S3 bucket.
- The local
/data/cutout_cdnand/data/sed_outputdirectories are no longer provisioned.
- Fixed bug in the image cropping task introduced by the transition to using local scratch space instead of a shared persistent volume for generated transient data files.
- Since the switch to PostgreSQL, there have been failures when rerunning aperture tasks due to
foreign key constraint violations. The
_overwrite_or_create_object(Aperture, query, data)calls have been replaced by a more deliberate algorithm for updating associated objects if they exist.
- Fixed regression that broke SED fitting result display
- Fixed variable initialization bug in
host.prospector.build_obs() - Fixed bug where result page renders can fail due to
Nonetype forglobal_aperturebecause of an unhandled possibility in theselect_aperture()function. - Fixed bug in
tns_data_ingestion()that caused the task to fail if there are no active tasks.
- Added new workflow tasks to generate thumbnail images (JPEG format) of the interactive Bokeh plots for the data image cutout display and both SED fit plots.
- Added a new workflow task that crops the data image cutouts. Replaces the previous "trimming" mechanism.
- Changed the result pages to display lightweight "thumbnail" images instead of downloading the files and rendering the Bokeh plots. Clicking on a thumbnail triggers the Bokeh render via an AJAX request and replaces the thumbnail with the interactive plot. This will reduce the page load time and reduce system load on the API server replicas.
- User-selected cutout filters are now loaded via AJAX instead of reloading the entire page.
- The results page rendering function was refactored to organize logically independent code into reusable functions.
- The task status table on the result pages now orders tasks by order of their execution.
- The workflow structure was altered to incorporate the new tasks, and due to a shortcoming of the Celery Canvas system (see celery/celery#893 and celery/celery#4562), the new structure will not in general run as fast as its optimal DAG.
- Improved temporary file handling and cleanup:
- Temporary server-side downloads from the object store use ephemeral
tmpdirectories in the responding API server replica container instead of in the shared data volume. - The periodic garbage collection task now removes unneeded files regardless of free space.
- Temporary server-side downloads from the object store use ephemeral
- Removed the unnecessary "Transient information" workflow task.
- Hid the workflow diagram from the result pages until a more automated method is devised to generate it when the workflow structure changes.
- Removed "Transient information" task from
app/host/fixtures/test/test_2010H_onefilter.yamlso unit tests pass.
- Increased transient name length limit from 20 to 64 characters
- Updated to version
actions/checkout@v6for GitHub CI/CD
- Improved detection of duplicate transients when users add transients by CSV-formatted definition. In addition to searching for existing transients with the same names, the coordinates of submitted transients are also checked for proximity to existing transients; those within 1 arcsecond of an existing transient are rejected.
- Transients added by definition are no longer allowed to have names with prefixes "AT" or "SN".
- Upgraded Django to v5.1.14 to address CVE-2025-64458 and CVE-2025-64459. Set static versions for docs dependencies.
- Added a
DISABLE_CELERY_BEATenvironment variable that when set totruewill prevent Celery Beat from running. This is occasionally useful during local development and testing. - Added scratch file pruning to a new "Workflow init" task in the transient workflow. If the JOB_SCRATCH_MAX_SIZE value minus the calculated disk space consumed is less than the JOB_SCRATCH_FREE_SPACE value, the pruning function is invoked.
- Replaced RabbitMQ with Redis, supporting high-availability mode with Redis Sentinel. Redis now performs the functions of Django caching, Celery results backend, and Celery message broker.
- Replaced MariaDB with PostgreSQL database.
- Configuration of Celery Flower instance is now consistent with the workers using
-A app
- Error handling was added in a few places where errors were noticed in the application logs.
- Updated associated institutions in footer.
- Added a Blast team member page with photos and bios.
- Upgraded Django to v5.1.13
- Use TaskLock for global rate limiting of SDSS queries.
- Bypass need for file locking in aperture tasks by redundant downloads named uniquely to each task. There were occasional failures of the file lock mechanism that are not worth debugging.
- Refactored and revised logic in HostInformation task.
- Use TaskLock for global rate limiting of NED queries.
- Fix minor bug in TransientTaskRunner task
- Update Prost host galaxy matcher to v1.2.13.
- Added plaintext email for support requests or contacts.
- Disabled celery-beat when running in batch mode.
- Revamped the "Add Transient" web form:
- Improved CSV handling to handle whitespace surrounding values.
- Changed the wording from "upload" to "add", "define", and "import" to reflect the two distinct ways users can add transients to the database.
- Redesigned the form structure to make the two addition methods mutually exclusive and not simultaneously visible.
- Improved algorithm for reporting when added transients are ignored because they already exist in the database.
- Upgraded Django to v5.1.12
- Added a privacy policy about the usage data collection.
- Ensure usage metric object character fields do not exceed the length limits.
- Fixed two API endpoints that should require authentication: "report" and "resolve" on transient result pages.
- Added a decorator function to capture HTTP requests to specific endpoints as
UsageMetricsLogobjects. - Added a periodic task
UsageLogRollerto roll the usage logs by exporting logs to archive files uploaded to the object store and pruning the Django database table.
- Added a new "garbage collector" periodic task that purges the
cutout_cdnandsed_outputscratch space of orphaned data.
- Fixed a bug introduced in v1.5.2 when loading some transient result pages.
- Fixed a bug when loading result pages, where the page would fail with a "Server Error (500)" message if there were missing data files expected by the page renderer. These errors are now handled more gracefully by rendering empty plots and a message sayingt o reprocess the transient.
- Restructured the navigation bar to separate the user account interface and ancillary information from application tools. Links to documentation, source code repo, and acknowledgements were moved to a dropdown menu.
- Improved the responsiveness of the web pages and support for browser scaling.
- Retrigger and reprocess buttons are now displayed on the result pages based on user permissions.
- The static landing page was not populating the support email address in the email template defined by the
mailtolink in the footer. Instead of supplying the value via context processor, it was supplied via template tag such that the information is available to the periodic rendering functionupdate_home_page_statistics().
- Added support for OIDC-based authentication and role-based access control (RBAC). Anyone can authenticate but only authorized users are allowed to use protected API functions such as transient upload, reprocessing, or retriggering. Django admins can authorize users by granting them the custom permission "Can launch a new transient workflow". The recommended approach is to grant the permission to a group created for the purpose (e.g. "users-default"), and then add users to that group.
- There is a new registration process for new Blast users. Upon login users are redirected to the uploads page, where they encounter a message informing them that they need to request authorization to access this feature by clicking a link that will prepopulate an email using a template. The template instructs the new user to provide their name, and email address (these are not supplied by all identity providers) as well as an explanation for the request.
- Transient result pages indicate when SED data is loading or if that data is unavailable.
- Fixed a minor bug in the Blast documentation
developer_guide/dev_system_pages.mdpreventing images from being rendered.
- Improved workflow execution speed by using ThreadPoolExecutor to download cutouts in parallel.
- Added a graphical SVG-based view of the workflow and task status to the transient result pages.
- The Python package "GHOST" that was used for associating transients with a host galaxy was replaced with its successor "Prost", a library by the same author with improved accuracy.
- When workflows are manually retriggered via the
retrigger_transient/[transient]API endpoint, failed tasks are retried. The automated retriggering periodic task does not retry failed tasks. - Consolidated object storage interface into a unified class used for data initialization and generated data storage.
- Improved the workflow initialization algorithm to prune redundant TaskRegister objects and handle the addition of new tasks to the transient workflow.
- Improved the accuracy of the workflow progress calculation with a new algorithm. This change necessitated a revision of the task prerequisites to more accurately reflect the actual workflow definition used by the Celery Canvas to execute tasks.
- Consolidated, minimized, and updated the versions of the set of Python package dependencies in
requirements.txt. - Update the MariaDB version for the Django database used in the Docker Compose deployment from v10 to v11.1.
- Secured two API endpoints that should require authentication to run:
reprocess_transient/[transient],retrigger_transient/[transient]. - Fixed a bug in the aperture construction unit test to support downloading cutouts for a subset of filters.
- Implemented a file locking mechanism to prevent concurrent processes from deleting data files prematurely in the
GlobalApertureConstruction,GlobalAperturePhotometry, andLocalAperturePhotometryworkflow tasks. - Updated the NGINX proxy configuration in the Docker Compose deployment to fix problems with localhost routing in the development environment.
- Implemented an automated retriggering mechanism executed periodically by Celery Beat to resume aborted workflows.
- There was an error related to the angle value in
/app/host/plotting_utils.py, where the reference totheta_radinplot_aperture()was preventing transient result pages from rendering due to an invalid value type. It was fixed by referencingtheta_rad.valueinstead.