Loading in leapseconds kernel in Metakernel API#1172
Conversation
There was a problem hiding this comment.
Pull request overview
This PR aims to ensure SPICE leapseconds (LSK) are loaded before converting YYYYMMDD-style inputs to J2000 in the metakernel API, and factors shared SPICE download/furnish logic out of spice_indexer.py into a reusable utility module.
Changes:
- Added leapseconds-kernel furnishing before
datetime2etconversion inspice_metakernel_api. - Extracted shared S3 download + “furnish latest kernel” logic into a new
spice_utilities.pymodule and updatedspice_indexerto use it. - Updated the metakernel API Lambda config to include S3/data-dir environment variables and S3 read permissions.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| sds_data_manager/lambda_code/SDSCode/spice_utilities.py | New shared utilities for downloading kernels from S3 and furnishing the “latest” kernel. |
| sds_data_manager/lambda_code/SDSCode/pipeline_lambdas/spice_indexer.py | Removes inlined helpers and imports the shared furnish_best_spice_file. |
| sds_data_manager/lambda_code/SDSCode/api_lambdas/spice_metakernel_api.py | Attempts to load leapseconds kernel before converting YYYYMMDD to J2000. |
| sds_data_manager/constructs/sds_api_manager_construct.py | Adds env vars + S3 permissions for metakernel API Lambda; adjusts timeout/memory. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
tech3371
left a comment
There was a problem hiding this comment.
looks good besides one minor request.
| logger.info( | ||
| "Attempt failed, continuing in hopes that it is already loaded." | ||
| ) |
There was a problem hiding this comment.
This message confused me little bit. can we rephrase this? or add more context of why we can continue?
There was a problem hiding this comment.
I got rid of it since I'm checking if an LSK is loaded now. If nothing is loaded, it should just throw an error!
| logger.error() | ||
| raise FileNotFoundError( | ||
| f"Failed to download {s3_key} from bucket {bucket_name}: {e}" | ||
| ) from e |
There was a problem hiding this comment.
nice refactor and clean up of error raise!
| logger.info(f"Downloaded SPICE file: {highest_version_spice_file}") | ||
| # Furnish the SPICE file | ||
| spiceypy.furnsh(str(highest_version_spice_file)) | ||
| return highest_version_spice_file |
tmplummer
left a comment
There was a problem hiding this comment.
Just two suggestions to consider.
| logger.setLevel(logging.INFO) | ||
|
|
||
|
|
||
| def download_from_s3(s3_key: str, bucket_name: Optional[str] = None) -> Path: |
There was a problem hiding this comment.
Is there a reason that this is not using the imap-data-access library to download files?
There was a problem hiding this comment.
I think it would simplify the code a little bit, I just didn't know if it was worth invoking the API and whatnot from inside of our own SDC. I do see now that some of the ialirt lambdas use the .download() function from there though. I'm fine with it either way!
| ) | ||
| furnish_best_spice_file("leapseconds") | ||
| except FileNotFoundError: | ||
| logger.info( |
There was a problem hiding this comment.
You could think about using spiceypy tools to check to see if a leapsecond kernel is furnished here. I suppose it doesn't hurt to furnish it more than once, but the flow could be:
- check if lsk kernel is furnished
- if not furnished try to furnish one
- except: raise error
There was a problem hiding this comment.
I forgot you could check what has already been loaded, I switched it to use that logic!
Change Summary
Overview
This is a simple fix to load in the leapsecond kernel in the metakernel API before converting times between datetime and J2000. It only looks like a lot because I moved some of the functions around. The SPICE indexer lambda code already had a function to do what I wanted in the metakernel, so I broke off that code into a spice_utilities.py file. Now both the metakernel API and the SPICE indexer will just import that function from spice_utilities.py.
File changes
sds_data_manager/constructs/sds_api_manager_construct.py
sds_data_manager/lambda_code/SDSCode/api_lambdas/spice_metakernel_api.py
sds_data_manager/lambda_code/SDSCode/pipeline_lambdas/spice_indexer.py
sds_data_manager/lambda_code/SDSCode/spice_utilities.py
Testing
I un-skipped the unit test that already checked for this, and I put the leapsecond file in the mock S3 bucket.