Skip to content

Support for type=spin/repoint/thruster/kernels for the spice-query api#1250

Open
vineetbansal wants to merge 3 commits into
IMAP-Science-Operations-Center:devfrom
vineetbansal:vb/issue911a
Open

Support for type=spin/repoint/thruster/kernels for the spice-query api#1250
vineetbansal wants to merge 3 commits into
IMAP-Science-Operations-Center:devfrom
vineetbansal:vb/issue911a

Conversation

@vineetbansal
Copy link
Copy Markdown
Collaborator

@vineetbansal vineetbansal commented Apr 15, 2026

Change Summary

Fixes issue #911

Added support to query non-SPICE tables (spin/repoint/thruster) using the /spice-query endpoint.

The type parameter decides which table to query - kernels searches through the spice table. Other possible values are spin, thruster, or repoint, which delegate to the existing lambda in non_spice_table_api.py.

When the type parameter is not set, it is assumed to be kernels, preserving legacy behavior. A type parameter set to a specific kernel type like spacecraft_clock still works as before.

Parameters like file_name, start_time and end_time that the SPICE api already supports are now mapped to the non-SPICE API, so the caller has to go through minimal changes to start using these.

File changes

  • Main functionality added to spice_query_api.py that internally calls non_spice_tables_api.
  • I had to move an import in spice_metakernel_api.py to where it is used to get around a circular import issue (spice_utilities.py imports spice_metakernel_api and spice_metakernel_api.py imports spice_utilities).

Testing

  • Added a test to test_spice_query_api.py to ensure that type parameter is interpreted correctly for SPICE tables.
  • Added tests to test_spin_api.py to ensure that calls made through spice_query.api return expected responses. Existing tests left intact, so the old API endpoints work as well.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support for querying non-SPICE tables (spin/repoint/thruster) through the existing /spice-query lambda by routing based on a new type query parameter, while preserving legacy “kernels” behavior.

Changes:

  • Route /spice-query requests to non_spice_table_api when type is spin|repoint|thruster, including parameter remapping (file_name→file_path, start_time/end_time→start_date/end_date).
  • Adjust spice_metakernel_api import timing to avoid a circular import involving spice_utilities.
  • Add tests covering type behavior for SPICE tables and end-to-end non-SPICE queries via /spice-query.

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/api_lambdas/spice_query_api.py Adds type routing to non-SPICE tables + query param remapping logic.
sds_data_manager/lambda_code/SDSCode/api_lambdas/spice_metakernel_api.py Moves furnish_best_spice_file import into the usage site to break a circular import.
tests/lambda_endpoints/test_spice_query_api.py Adds coverage for type parameter behavior on SPICE table queries.
tests/lambda_endpoints/test_spin_api.py Adds end-to-end tests for non-SPICE queries going through spice_query_api.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +194 to +201
if "start_time" in query_params:
query_params["start_date"] = spiceypy.et2datetime(
float(query_params.pop("start_time"))
).strftime("%Y%m%d")
if "end_time" in query_params:
query_params["end_date"] = spiceypy.et2datetime(
float(query_params.pop("end_time"))
).strftime("%Y%m%d")
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point. Done. However, if the incoming (float) start/end times are outside the range, we have bigger problems.

Comment on lines +273 to +283
assert len(json.loads(returned_query["body"])) == 1

# Record returned with `type` filter set to `kernels`.
event = {"queryStringParameters": {"type": "kernels"}}
returned_query = spice_query_api.lambda_handler(event=event, context={})
assert len(json.loads(returned_query["body"])) == 1

# Record returned with `type` filter set to the kernel type.
event = {"queryStringParameters": {"type": "attitude_history"}}
returned_query = spice_query_api.lambda_handler(event=event, context={})
assert len(json.loads(returned_query["body"])) == 1
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Done.

"""
logger.debug("SPICE Query Event: " + json.dumps(event, indent=2))

query_params = event["queryStringParameters"] or {}
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point - done.

try:
query_params = _remap_to_non_spice_params(query_params)
except ValueError:
return {"statusCode": 400, "body": "Expected start/end times in ET."}
Copy link
Copy Markdown
Collaborator Author

@vineetbansal vineetbansal Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No other 400 return code path is setting headers. But they do json.dumps the message, even if it's just a plain str, not a dict. I've modified the code to do the same here, to be consistent with the rest of the code.

Comment on lines +75 to +79
return non_spice_table_api.lambda_handler(
{
"rawPath": _NON_SPICE_RAW_PATHS[table_type],
"queryStringParameters": query_params,
},
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The essential problem is that non-spice-api is not returning the headers. We shouldn't simply add the headers when calling them from somewhere else.

Changes to non-spice-api are outside the scope of this PR (since they raise cognitive load on the reviewer), but fine - I've made the change there.

Comment on lines 7 to 8
import spiceypy
from imap_data_access import SPICEFilePath
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point. Change made.

@vineetbansal
Copy link
Copy Markdown
Collaborator Author

vineetbansal commented Apr 18, 2026

@tech3371 - I've acted on Copilot's suggestions, but don't agree with it on all of them, and have tweaked my fix accordingly. The broader issue is whether we're fixing historical technical debt in these PRs or doing the minimum to fix issues and make it easy on the reviewer (applicable for 1 out of the 6 comments by Copilot).

Also let me know if the protocol is to as Copilot for a review first before I ask a review from real people.

@tech3371
Copy link
Copy Markdown
Contributor

@vineetbansal Thank you for those changes. I will review it sometime this week. @bryan-harter can you review this also since you know SPICE API code more.

logger.info(
"Attempting to load leapseconds kernel needed for time conversion."
)
from ..spice_utilities import furnish_best_spice_file # noqa: PLC0415
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one minor comment. Can you move this up to the top? we keep all imports at the top of file

Copy link
Copy Markdown
Collaborator Author

@vineetbansal vineetbansal Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't - I've had to move this to break a circular import (spice_utilities.py imports spice_metakernel_api and spice_metakernel_api.py imports spice_utilities). The only reason we don't come across this error in existing code is because the specific order of imports encountered in existing code paths causes one of these to be preloaded. This is purely an accident. But trying to import either of these independently (as we're doing here in test_spin_api.py) surfaces this bug.

@tech3371 tech3371 linked an issue Apr 21, 2026 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG - Thruster files not available via the SPICE query API

3 participants