1
1
"""Module providing SpiceQL endpoints"""
2
2
3
3
from ast import literal_eval
4
- from typing import Any
5
- from fastapi import FastAPI
4
+ from typing import Annotated , Any
5
+ from fastapi import FastAPI , Query
6
6
from pydantic import BaseModel , Field
7
7
from starlette .responses import RedirectResponse
8
8
import numpy as np
@@ -28,14 +28,27 @@ class ResponseModel(BaseModel):
28
28
statusCode : int
29
29
body : ResultModel | ErrorModel
30
30
31
+ class TargetStatesRequestModel (BaseModel ):
32
+ target : str
33
+ observer : str
34
+ frame : str
35
+ abcorr : str
36
+ mission : str
37
+ ets : Annotated [list [float ], Query ()] | float | str | None = None
38
+ startEts : float | None = None
39
+ exposureDuration : float | None = None
40
+ numOfExposures : int | None = None
41
+ ckQuality : str = "predicted"
42
+ spkQuality : str = "predicted"
43
+
31
44
# Create FastAPI instance
32
45
app = FastAPI ()
33
46
34
47
@app .get ("/" )
35
48
async def message ():
36
49
try :
37
- data_dir_exists = os .path .exists (pyspiceql .getDataDirectory ())
38
- return {"data_content" : os .listdir (pyspiceql .getDataDirectory ()),
50
+ data_dir_exists = os .path .exists (pyspiceql .getDataDirectory ())
51
+ return {"data_content" : os .listdir (pyspiceql .getDataDirectory ()),
39
52
"data_dir_exists" : data_dir_exists ,
40
53
"is_healthy" : data_dir_exists }
41
54
except Exception as e :
@@ -61,10 +74,17 @@ async def getTargetStates(
61
74
if ets is not None :
62
75
if isinstance (ets , str ):
63
76
ets = literal_eval (ets )
77
+ else :
78
+ # getTargetStates requires an iterable ets. If not iterable, make it a list.
79
+ try :
80
+ iter (ets )
81
+ except TypeError :
82
+ ets = [ets ]
64
83
else :
65
84
if all (v is not None for v in [startEts , exposureDuration , numOfExposures ]):
66
85
stopEts = (exposureDuration * numOfExposures ) + startEts
67
86
etsNpArray = np .arange (startEts , stopEts , exposureDuration )
87
+ # If ets is a single value, np.arange yields an empty array
68
88
ets = list (etsNpArray )
69
89
else :
70
90
raise Exception ("Verify that a startEts, exposureDuration, and numOfExposures are being passed correctly." )
@@ -75,6 +95,46 @@ async def getTargetStates(
75
95
body = ErrorModel (error = str (e ))
76
96
return ResponseModel (statusCode = 500 , body = body )
77
97
98
+
99
+ @app .post ("/getTargetStates" )
100
+ async def getTargetStates (params : TargetStatesRequestModel ):
101
+ target = params .target
102
+ observer = params .observer
103
+ frame = params .frame
104
+ abcorr = params .abcorr
105
+ mission = params .mission
106
+ ets = params .ets
107
+ startEts = params .startEts
108
+ exposureDuration = params .exposureDuration
109
+ numOfExposures = params .numOfExposures
110
+ ckQuality = params .ckQuality
111
+ spkQuality = params .spkQuality
112
+ try :
113
+ if ets is not None :
114
+ if isinstance (ets , str ):
115
+ ets = literal_eval (ets )
116
+ else :
117
+ # getTargetStates requires an iterable ets. If not iterable, make it a list.
118
+ try :
119
+ iter (ets )
120
+ except TypeError :
121
+ ets = [ets ]
122
+ else :
123
+ if all (v is not None for v in [startEts , exposureDuration , numOfExposures ]):
124
+ stopEts = (exposureDuration * numOfExposures ) + startEts
125
+ etsNpArray = np .arange (startEts , stopEts , exposureDuration )
126
+ # If ets is a single value, np.arange yields an empty array
127
+ ets = list (etsNpArray )
128
+ else :
129
+ raise Exception ("Verify that startEts, exposureDuration, and numOfExposures are being passed correctly." )
130
+ result = pyspiceql .getTargetStates (ets , target , observer , frame , abcorr , mission , ckQuality , spkQuality , SEARCH_KERNELS_BOOL )
131
+ body = ResultModel (result = result )
132
+ return ResponseModel (statusCode = 200 , body = body )
133
+ except Exception as e :
134
+ body = ErrorModel (error = str (e ))
135
+ return ResponseModel (statusCode = 500 , body = body )
136
+
137
+
78
138
@app .get ("/getTargetOrientations" )
79
139
async def getTargetOrientations (
80
140
toFrame : int ,
@@ -95,13 +155,14 @@ async def getTargetOrientations(
95
155
etsNpArray = np .arange (startEts , stopEts , exposureDuration )
96
156
ets = list (etsNpArray )
97
157
else :
98
- raise Exception ("Verify that a startEts, exposureDuration, and numOfExposures are being passed correctly." )
158
+ raise Exception ("Verify that startEts, exposureDuration, and numOfExposures are being passed correctly." )
99
159
result = pyspiceql .getTargetOrientations (ets , toFrame , refFrame , mission , ckQuality , SEARCH_KERNELS_BOOL )
100
160
body = ResultModel (result = result )
101
161
return ResponseModel (statusCode = 200 , body = body )
102
162
except Exception as e :
103
163
body = ErrorModel (error = str (e ))
104
164
return ResponseModel (statusCode = 500 , body = body )
165
+
105
166
106
167
@app .get ("/strSclkToEt" )
107
168
async def strSclkToEt (
@@ -132,7 +193,7 @@ async def doubleSclkToEt(
132
193
133
194
134
195
@app .get ("/doubleEtToSclk" )
135
- async def strSclkToEt (
196
+ async def doubleEtToSclk (
136
197
frameCode : int ,
137
198
et : float ,
138
199
mission : str ):
0 commit comments