Coverage for webgeodyn/server/datahandlers.py: 0%
231 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-12-18 09:33 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-12-18 09:33 +0000
1from tornado.web import *
2from concurrent.futures import ThreadPoolExecutor
3from tornado.concurrent import run_on_executor
4from tornado.web import HTTPError
6import re
7import json
9globalExecutor = ThreadPoolExecutor(max_workers=10)
12class ServerError(HTTPError):
13 def __init__(self, reason, **kwargs):
14 super().__init__(reason=reason, **kwargs)
17class GenericDataHandler(RequestHandler):
18 def initialize(self, models, obsdata):
19 self.models = models
20 print("{0} initialisation...".format(type(self).__name__))
21 self.obsdata = obsdata
23 def getModel(self, dataName):
24 if self.models.isCached(dataName):
25 return self.models[dataName]
26 else:
27 raise ValueError("No model named " + dataName)
29 @run_on_executor
30 def async_getModel(self, dataName):
31 # Loads model from data directory, async = ask to load and return nothing
32 if not self.models.isCached(dataName) and not self.models.isModelLoading(dataName):
33 self.getModel(dataName)
34 return True
36 def write_error(self, status_code, **kwargs):
37 print("Raised error '{}' (status code {}) in {}".format(self._reason, status_code, type(self).__name__))
38 self.finish(json.dumps({
39 'SUCCESS': False,
40 'ERROR': self._reason,
41 'error_code': status_code
42 }))
45class DataListHandler(GenericDataHandler):
46 def get(self):
47 json_output_data = {"datalist": {}}
48 for dataName in self.models.getModelList():
49 model = self.getModel(dataName)
50 if not model:
51 continue
52 json_output_data["datalist"][dataName] = model.getDataInfo()
53 self.write(json.dumps(json_output_data))
56class ExportFileInfoHandler(GenericDataHandler):
57 """ Handler that gets the info of files to export for all the models but the ones with export set to False. """
58 def get(self):
59 json_output_data = {"exportfileinfo": {}}
60 for dataName in self.models.getModelList():
61 model = self.getModel(dataName)
62 if model.export:
63 # Skip CHAOS and COV-OBS model that will not be available for export
64 json_output_data["exportfileinfo"][dataName] = model.getFileInfo()
66 self.write(json.dumps(json_output_data))
69class ObservatoryDataHandler(GenericDataHandler):
70 executor = globalExecutor
72 @tornado.gen.coroutine
73 def post(self):
74 str_data = tornado.escape.url_unescape(self.request.body)
75 json_request = json.loads(str_data)
76 json_output_data = {}
77 json_output_data["SUCCESS"] = False
78 print("ObservatoryDataHandler post", json_request)
80 if "theta" not in json_request:
81 json_output_data["obsdata"] = self.obsdata.getDataInfo()
82 json_output_data["SUCCESS"] = True
83 elif "phi" not in json_request:
84 json_output_data["ERROR"] = "Invalid data request, please specify theta and phi"
85 elif "selecteddata" not in json_request:
86 json_output_data["ERROR"] = "Invalid data request, please specify selecteddata"
87 elif "obstypes" not in json_request:
88 json_output_data["ERROR"] = "Invalid data request, please specify obstypes"
89 else:
90 theta = json_request.get("theta")
91 phi = json_request.get("phi")
92 obstypes = json_request.get("obstypes")
93 selecteddata = json_request.get("selecteddata")
94 measuretype = json_request.get("measuretype")
96 r = self.obsdata.getObsR(theta,phi,obstypes)
98 json_output_data["modeldata"] = {}
99 for data in selecteddata:
100 dataName = data.get("dataname")
101 measureName = data.get("measurename")
102 if dataName not in json_output_data["modeldata"]:
103 json_output_data["modeldata"][dataName] = {}
104 json_output_data["modeldata"][dataName][measureName] = \
105 self.getModel(dataName).getObservatoryData(measureName, r, theta, phi)
107 json_output_data["obsdata"] = self.obsdata.getData(measuretype, theta, phi, obstypes)
108 json_output_data["SUCCESS"] = True
110 self.write(json.dumps(json_output_data))
113class GlobeDataHandler(GenericDataHandler):
114 executor = globalExecutor
116 @tornado.gen.coroutine
117 def post(self):
118 async_compute = False
119 str_data = tornado.escape.url_unescape(self.request.body)
120 json_request = json.loads(str_data)
121 json_output_data = {}
122 json_output_data["SUCCESS"] = False
124 if "dataname" not in json_request:
125 json_output_data["ERROR"] = "Invalid data request, please specify dataname"
126 elif "measure" not in json_request:
127 if self.models.isCached(json_request["dataname"]):
128 json_output_data = self.getModel(json_request["dataname"]).getDataInfo()
129 else:
130 json_output_data["computing"] = "loading " + json_request["dataname"] + " data files"
131 self.async_getModel(json_request["dataname"]) # Get model data for further
132 json_output_data["SUCCESS"] = True
133 elif "time" not in json_request:
134 json_output_data["ERROR"] = "Invalid data request, please specify time"
135 else:
136 datatime = json_request.get("time")
137 measureName = json_request.get("measure")
138 vectorComponent = json_request.get("vectorcomponent")
139 removemean = json_request.get("removemean")
140 dataName = json_request.get("dataname")
141 toCompute, isComputing = \
142 self.getModel(dataName).canGetGlobeData(measureName, vectorComponent)
143 if (not toCompute) and (not isComputing):
144 # Return cached value
145 json_output_data["computing"] = False
146 json_output_data["data"] = \
147 yield self.async_getData(dataName, measureName, vectorComponent, datatime, removemean)
148 else:
149 # Return computing in progress
150 json_output_data["computing"] = "computing real space grid"
151 json_output_data["computingState"] = self.getModel(dataName).getGlobeDataComputingState(measureName)
152 if not isComputing:
153 # Tell to compute
154 async_compute = True
156 json_output_data["SUCCESS"] = True
158 self.write(json.dumps(json_output_data))
159 self.finish()
161 if async_compute:
162 #self.executor.submit(self.getModel(dataName).getGlobeData,*(measureName,vectorComponent,datatime,removemean))
163 #Compute after anwser
164 #self.async_getData(dataName, measureName, vectorComponent, datatime, removemean)
165 self.async_getData(dataName, measureName, vectorComponent, datatime, removemean)
167 @run_on_executor
168 def async_getData(self, dataName, measureName, vectorComponent, datatime, removemean):
169 return self.getModel(dataName).getGlobeData(measureName, vectorComponent, datatime, removemean)
172class LodDataHandler(GenericDataHandler):
173 executor = globalExecutor
175 @tornado.gen.coroutine
176 def post(self):
177 str_data = tornado.escape.url_unescape(self.request.body)
178 json_request = json.loads(str_data)
179 json_output_data = {"SUCCESS": False}
181 print("LodDataHandler post", json_request)
183 if "selecteddata" not in json_request:
184 raise ServerError("Invalid data request, please select some data")
186 if "removemean" not in json_request:
187 raise ServerError("Invalid data request, please specify removemean")
189 selected_data = json_request.get("selecteddata")
190 removemean = json_request.get("removemean")
192 for data in selected_data:
193 data_name = data.get("dataname")
194 if data_name not in json_output_data:
195 json_output_data[data_name] = {}
196 try:
197 json_output_data[data_name] = self.getModel(data_name).getLodData(removemean)
198 except ValueError as e:
199 # Transform the ValueError in HTTPError that will be caught by tornado write_error
200 raise ServerError("Error while getting LOD data of {}: {}".format(data_name, e))
202 json_output_data["SUCCESS"] = True
203 self.write(json.dumps(json_output_data))
206class SpectraDataHandler(GenericDataHandler):
207 executor = globalExecutor
209 @tornado.gen.coroutine
210 def post(self):
211 str_data = tornado.escape.url_unescape(self.request.body)
212 json_request = json.loads(str_data)
213 json_output_data = {"SUCCESS": False}
215 print("SpectraDataHandler post", json_request)
217 if "selecteddata" not in json_request:
218 raise ServerError("Invalid data request, please select some data")
220 if "type" not in json_request:
221 raise ServerError("Invalid data request, please specify a spectra type")
223 if "date" not in json_request:
224 raise ServerError("Invalid data request, please specify a date")
226 selected_data = json_request.get("selecteddata")
227 spectra_type = json_request.get("type")
228 spectra_date = json_request.get("date")
230 if type(spectra_date) is not float:
231 spectra_date = float(spectra_date)
233 for data in selected_data:
234 data_name = data.get("dataname")
235 measure_name = data.get("measurename")
236 if data_name not in json_output_data:
237 json_output_data[data_name] = {}
238 try:
239 json_output_data[data_name][measure_name] = self.getModel(data_name).getSpectraData(measure_name, spectra_type, spectra_date)
240 except ValueError as e:
241 # Transform the ValueError in HTTPError that will be catched by tornado write_error
242 raise ServerError("Error while computing spectra of {}: {}".format(data_name, e))
244 json_output_data["SUCCESS"] = True
245 self.write(json.dumps(json_output_data))
248class SpherHarmDataHandler(GenericDataHandler):
249 executor = globalExecutor
251 @tornado.gen.coroutine
252 def post(self):
253 str_data = tornado.escape.url_unescape(self.request.body)
254 json_request = json.loads(str_data)
255 json_output_data = {}
256 json_output_data["SUCCESS"] = False
257 print("SpherHarmDataHandler post", json_request)
259 if "selecteddata" not in json_request:
260 json_output_data["ERROR"] = "Invalid data request, please specify selecteddata"
261 elif "m" not in json_request:
262 json_output_data["ERROR"] = "Invalid data request, please specify l"
263 elif "l" not in json_request:
264 json_output_data["ERROR"] = "Invalid data request, please specify l"
265 else:
266 l = json_request.get("l")
267 m = json_request.get("m")
268 removemean = json_request.get("removemean")
269 selecteddata = json_request.get("selecteddata")
271 for data in selecteddata:
272 dataName = data.get("dataname")
273 measureName = data.get("measurename")
274 if dataName not in json_output_data:
275 json_output_data[dataName] = {}
276 json_output_data[dataName][measureName] = \
277 self.getModel(dataName).getSpherHarmData(measureName, l, m, removemean)
279 json_output_data["SUCCESS"] = True
281 self.write(json.dumps(json_output_data))
284class TimeSerieDataHandler(GenericDataHandler):
285 executor = globalExecutor
287 @tornado.gen.coroutine
288 def post(self):
289 str_data = tornado.escape.url_unescape(self.request.body)
290 json_request = json.loads(str_data)
291 json_output_data = {}
292 json_output_data["SUCCESS"] = False
293 print("TimeSerieDataHandler post", json_request)
295 if "dataname" not in json_request:
296 json_output_data["ERROR"] = "Invalid data request, please specify dataname"
297 elif "measure" not in json_request:
298 if self.models.isCached(json_request["dataname"]):
299 json_output_data = self.getModel(json_request["dataname"]).getDataInfo() # True is for analysis times only
300 else:
301 json_output_data["computing"] = "loading " + json_request["dataname"] + " data files"
302 self.async_getModel(json_request["dataname"]) # Get model data for further
303 json_output_data["SUCCESS"] = True
304 elif "cutvalue" not in json_request:
305 json_output_data["ERROR"] = "Invalid data request, please specify cutvalue"
306 elif "cutvariable" not in json_request:
307 json_output_data["ERROR"] = "Invalid data request, please specify cutvariable"
308 else:
309 measureName = json_request.get("measure")
310 vectorComponent = json_request.get("vectorcomponent")
311 removemean = json_request.get("removemean")
312 cutvalue = json_request.get("cutvalue")
313 cutvariable = json_request.get("cutvariable")
314 dataName = json_request.get("dataname")
315 coordtype = json_request.get("coordtype")
316 print("getting timeSerieData", measureName, vectorComponent, cutvariable, cutvalue, coordtype)
317 json_output_data = \
318 self.getModel(dataName).getTimeSerieData(measureName, vectorComponent, cutvariable, cutvalue, removemean, coordtype)
319 json_output_data["SUCCESS"] = True
321 self.write(json.dumps(json_output_data))