Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow ALE NaifSpice Mixins to Access SpiceQL service #523

Closed
wants to merge 77 commits into from

Conversation

acpaquette
Copy link
Collaborator

@acpaquette acpaquette commented Mar 14, 2023

This update enables the default NaifSpice mixin to access the SpiceQL service, with an example driver updated to test (MroCtxIsisLabelNaifSpiceDriver and MroCtxPds3LabelNaifSpiceDriver).

Both work as expected and can be tested with:
MroCtxIsisLabelNaifSpiceDriver("/Path/to/my/isis/cube.cub", props={"web": True})
or
MroCtxPds3LabelNaifSpiceDriver("/Path/to/my/pds3/label.[lbl|img], props={"web": True})

Keep in mind that so far, this process is much slower over the net and we are still working to improve the speed of the SpiceQL service.

Copy link
Collaborator

@jlaura jlaura left a comment

Choose a reason for hiding this comment

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

I think this needs:

  • CHANGELOG entries
  • tests?
  • thought about the use of use_web all over the place now
  • tests that handle edge cases introduced by having 3 spice sources or docs describing how this was tested. My concern is unintended breakages due to the new features.

ale/base/data_naif.py Outdated Show resolved Hide resolved
ale/base/data_naif.py Outdated Show resolved Hide resolved
ale/base/data_naif.py Outdated Show resolved Hide resolved
@@ -344,23 +343,6 @@ def sensor_name(self):
"""
return "CONTEXT CAMERA"

@property
Copy link
Collaborator

Choose a reason for hiding this comment

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

This seems a weird change to include in the PR? CHANGELOG entry might clear up if this is a bug fix for something else or what.

# to ALE
return func(**function_args)

url = "https://spiceql-dev.prod-asc.chs.usgs.gov/v1/"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Even though this is only an incremental step towards turning this on, I would strongly advocate using an ENV variable here to encode. That seems the most likely way a user might want to set / change this. Sure, this might eventually be hard coded, but I would advocate against that since it tightly couples this ALE version to a specific spiceql server version.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

100% agree, I think providing some way to set it then defaulting might be a good middle ground?

'Content-Type': 'application/json'
}

r = requests.get(url, params=function_args, headers=headers, verify=False)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes, this verify=False is needed on a DOI network if the SSL certificates are not in place, but out in the wild this is a bad idea.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Also, requests is not in the meta.yaml so this will fail on install into a clean conda env.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Both good catches!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Revisiting this. Isn't requests is a default python library?

Copy link
Collaborator

Choose a reason for hiding this comment

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

No, it is not. If you want to use just standard library, use urllib (though it does not have the same nice to have stuff like urllib3 or requests).

r.raise_for_status()
response = r.json()

if r.status_code != 200:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Isn't raise_for_status catching this already? And aren't these redundant with themselves? How does one get a 200 and then a bad status code?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Kinda sorta, this is a weird quirk of our lambda setup that I think needs to change. Basically if the lambda function called fails, we still get a "valid" web return as we catch the failure.

I think we can just let the function itself fail and that should be handled as expected(?)

It may also be that all of our endpoints only handle returning 200 codes.

This likely needs to be ironed out before a full release

ale/kernel_access.py Outdated Show resolved Hide resolved
@@ -123,15 +124,20 @@ def from_spice(cls, sensor_frame, target_frame, center_ephemeris_time, ephemeris

constant_frames.extend(target_constant_frames)

frame_chain.compute_time_dependent_rotiations(sensor_time_dependent_frames, sensor_times)
frame_chain.compute_time_dependent_rotiations(target_time_dependent_frames, target_times)
# Add all time dependent frame chains to the graph
Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems that use_web is becoming ubiquitous in function signatures. Have other options been considered to not extend the signatures? For example, a module level variable or something?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The function structure is definitely scuffed. Currently the use_web variable is in the NaifSpice mixin, which makes some sense as you want it on a driver to driver level.

Then we have the kernel_access.py module with the spiceql_call wrapper. This wrapper function is then further wrapped in the NaifSpice mixin where the use_web variable is grabbed from the driver when the function is called.

The issue here is that transformation.py and specifically the FrameChain.from_spice code is not part of the driver and exists to support getting the reference frame rotations. This requires that either a variable be passed through or that the FrameChain itself assigns it's own use_web variable which may actually be worth while.

So, to answer your question, I had not considered other options but I don't think a module level define is good. But I think we can make it that any FrameChain constructed using from_spice can set a member variable defining web usage.

ale/transformation.py Outdated Show resolved Hide resolved
@acpaquette
Copy link
Collaborator Author

@jlaura This has not been fully tested yet as much of the mocking that happens in the test was not addressed. Basically anything that was mocking a spice call needs to now mock the spiceql_call function. Something that will be addressed in a future sprint where I will go in and basically fix every current NaifSpice driver/tests.

@acpaquette
Copy link
Collaborator Author

Also regarding testing the spice sources. I think it's going to be a trust issue, mainly when web is enabled. Pretty much every drivers load test will test passing in kernels manually, and the metakernel discovery function is also tested.

I am not sure if ALE has a responsibility to test if the server returns are accurate. I think we testing the spiceql_call function is necessary but outside of that it's spiceql's problem

}

clean_function_args = stringify_web_args(function_args)
async with session.get(url, params=clean_function_args, headers=headers, ssl=False) as response:
Copy link
Collaborator

Choose a reason for hiding this comment

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

ssl=False should probably be optional somehow

Copy link
Collaborator

Choose a reason for hiding this comment

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

ssl=False should be removed. Do we really want to support running without SSL?

(If this is an internal network/custom certificate thing, we can setup our work stations to have the proper self-signed certs.)

Copy link
Collaborator

@Kelvinrr Kelvinrr Jul 24, 2023

Choose a reason for hiding this comment

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

you're not wrong, but almost every tool I use on my command line has some kind of disable-ssl option.

import math
import requests

import aiohttp
Copy link
Collaborator

Choose a reason for hiding this comment

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

Needs to be added to environment.yml

Copy link
Collaborator

@Kelvinrr Kelvinrr left a comment

Choose a reason for hiding this comment

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

Probably need to wait until. conda-forge/staged-recipes#24039 is merged to merge this.

Comment on lines +3 to +7
spiceql_mission_map = {
"CHANDRAYAAN-1_M3": "m3",
"CHANDRAYAAN-1_MRFFR": "mrffr",
"CASSINI_ISS_NAC": "cassini",
"CASSINI_ISS_WAC": "cassini",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we put this in SpiceQL instead?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It could go in spiceql, the translation has to exist somewhere. I think it's better off in ALE since ALE is using the spiceql interface rather than spiceql conforming to ALE.

Granted all of the keys are from NAIF so 🤷

Comment on lines +420 to +423
try:
geodata = gdal.Open(self._file)
except:
geodata = None
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we not want an exception if the geodata cannot be loaded?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It may be worth reporting the exception to the user as a warning. When working with pds3 labels I was running into issues where the label was pointing to a data file causing the gdal.Open to fail but the label could be used as valid input for a driver.

Comment on lines +1178 to +1182
@property
def usgscsm_distortion_model(self):
"""
Kaguya uses a unique radial distortion model so we need to overwrite the
method packing the distortion model into the ISD.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should this be included here? Seems unrelated.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I saw this too and wasn't sure why this was part of the PR. I need to double check this and see if it was missed from a rebase

@Kelvinrr
Copy link
Collaborator

Kelvinrr commented Nov 5, 2024

Closing in favor of #621

@Kelvinrr Kelvinrr closed this Nov 5, 2024
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.

5 participants