@@ -307,6 +307,78 @@ def series(self, datasource_id, match, start, end, access="proxy"):
307
307
r = self .client .POST (post_series_path , data = {"match[]" : match , "start" : start , "end" : end })
308
308
return r
309
309
310
+ def smartquery_old (self , datasource : Union [DatasourceIdentifier , Dict ], expression : str , store : Optional [str ] = None ):
311
+ """
312
+ Send a query to the designated data source and return its response.
313
+
314
+ TODO: This is by far not complete. The `query_factory` function has to
315
+ be made more elaborate in order to query different data source
316
+ types.
317
+ """
318
+
319
+ if isinstance (datasource , DatasourceIdentifier ):
320
+ datasource = self .get (datasource )
321
+
322
+ datasource_id = datasource ["id" ]
323
+ datasource_type = datasource ["type" ]
324
+ datasource_dialect = datasource .get ("jsonData" , {}).get ("version" , "InfluxQL" )
325
+ access_type = datasource ["access" ]
326
+
327
+ # Sanity checks.
328
+ if not expression :
329
+ raise ValueError ("Expression must be given" )
330
+
331
+ # Build the query payload. Each data source has different query attributes.
332
+ query = query_factory (datasource , expression , store )
333
+
334
+ logger .info (f"Submitting query: { query } " )
335
+
336
+ # Compute request method, body, and endpoint.
337
+ send_request = self .client .POST
338
+
339
+ # Certain data sources like InfluxDB 1.x, still use the `/datasources/proxy` route.
340
+ if datasource_type == "influxdb" and datasource_dialect == "InfluxQL" :
341
+ url = f"/datasources/proxy/{ datasource_id } /query"
342
+ if store is not None :
343
+ url += f"?db={ store } "
344
+ payload = {"q" : query ["q" ]}
345
+ request_kwargs = {"data" : payload }
346
+
347
+ elif datasource_type == "graphite" :
348
+ url = f"/datasources/proxy/{ datasource_id } /render"
349
+ request_kwargs = {"data" : query }
350
+
351
+ # This case is very special. It is used for Elasticsearch and Testdata.
352
+ elif expression .startswith ("url://" ):
353
+ url = expression .replace ("url://" , "" )
354
+ url = url .format (
355
+ datasource_id = datasource .get ("id" ),
356
+ datasource_uid = datasource .get ("uid" ),
357
+ database_name = datasource .get ("database" ),
358
+ )
359
+ request_kwargs = {}
360
+ send_request = self .client .GET
361
+
362
+ # For all others, use the generic data source communication endpoint.
363
+ elif access_type in ["server" , "proxy" ]:
364
+ url = "/ds/query"
365
+ payload = {"queries" : [query ]}
366
+ request_kwargs = {"json" : payload }
367
+
368
+ else :
369
+ raise NotImplementedError (f"Unable to submit query to data source with access type '{ access_type } '" )
370
+
371
+ # Submit query.
372
+ try :
373
+ r = send_request (url , ** request_kwargs )
374
+ # logger.debug(f"Response from generic data source query: {r}")
375
+ return r
376
+ except (GrafanaClientError , GrafanaServerError ) as ex :
377
+ logger .error (
378
+ f"Querying data source failed. id={ datasource_id } , type={ datasource_type } . "
379
+ f"Reason: { ex } . Response: { ex .response or '<empty>' } "
380
+ )
381
+ raise
310
382
#**********************************************************************************
311
383
def smartquery (self , datasource : Union [DatasourceIdentifier , Dict ], expression : str , attrs : Optional [dict ] = None , request : Optional [dict ] = None ):
312
384
"""
@@ -332,11 +404,10 @@ def smartquery(self, datasource: Union[DatasourceIdentifier, Dict], expression:
332
404
model = {
333
405
"refId" : "test" ,
334
406
}
335
- if expression is not None :
336
- if attrs is not None :
337
- model .update (attrs )
338
- if attrs is None or ( attrs is not None and 'query' not in attrs ):
339
- model ['query' ] = expression
407
+ if expression is not None and ( attrs is None or (attrs is not None and 'query' not in attrs )):
408
+ model ['query' ] = expression
409
+ if attrs is not None :
410
+ model .update (attrs )
340
411
request = query_factory (datasource , model )
341
412
342
413
# Compute request method, body, and endpoint.
@@ -359,15 +430,15 @@ def smartquery(self, datasource: Union[DatasourceIdentifier, Dict], expression:
359
430
request_kwargs = {"data" : request ["data" ]}
360
431
361
432
# This case is very special. It is used for Elasticsearch and Testdata.
362
- # elif expression.startswith("url://"):
363
- # url = expression.replace("url://", "")
364
- # url = url.format(
365
- # datasource_id=datasource.get("id"),
366
- # datasource_uid=datasource.get("uid"),
367
- # database_name=datasource.get("database"),
368
- # )
369
- # request_kwargs = {}
370
- # send_request = self.client.GET
433
+ elif expression .startswith ("url://" ):
434
+ url = expression .replace ("url://" , "" )
435
+ url = url .format (
436
+ datasource_id = datasource .get ("id" ),
437
+ datasource_uid = datasource .get ("uid" ),
438
+ database_name = datasource .get ("database" ),
439
+ )
440
+ request_kwargs = {}
441
+ send_request = self .client .GET
371
442
372
443
# For all others, use the generic data source communication endpoint.
373
444
elif access_type in ["server" , "proxy" ]:
0 commit comments