|
24 | 24 | from flask import Flask, request, jsonify, abort |
25 | 25 | from flask_cors import CORS, cross_origin |
26 | 26 | import pandas as pd |
27 | | -import numpy as np |
| 27 | + |
| 28 | +from grafana_pandas_datasource.util import dataframe_to_response, dataframe_to_json_table, annotations_to_response |
| 29 | + |
28 | 30 |
|
29 | 31 | app = Flask(__name__) |
30 | 32 |
|
@@ -87,105 +89,6 @@ def find_metrics(): |
87 | 89 | return jsonify(list(metric_finders[finder](target))) |
88 | 90 |
|
89 | 91 |
|
90 | | -def dataframe_to_response(target, df, freq=None): |
91 | | - response = [] |
92 | | - |
93 | | - if df.empty: |
94 | | - return response |
95 | | - |
96 | | - if freq is not None: |
97 | | - orig_tz = df.index.tz |
98 | | - df = df.tz_convert('UTC').resample(rule=freq, label='right', closed='right').mean().tz_convert(orig_tz) |
99 | | - |
100 | | - if isinstance(df, pd.Series): |
101 | | - response.append(_series_to_response(df, target)) |
102 | | - elif isinstance(df, pd.DataFrame): |
103 | | - for col in df: |
104 | | - response.append(_series_to_response(df[col], target)) |
105 | | - else: |
106 | | - abort(404, Exception('Received object is not a dataframe or series.')) |
107 | | - |
108 | | - return response |
109 | | - |
110 | | - |
111 | | -def dataframe_to_json_table(target, df): |
112 | | - response = [] |
113 | | - |
114 | | - if df.empty: |
115 | | - return response |
116 | | - |
117 | | - if isinstance(df, pd.DataFrame): |
118 | | - response.append({'type': 'table', |
119 | | - 'columns': df.columns.map(lambda col: {"text": col}).tolist(), |
120 | | - 'rows': df.where(pd.notnull(df), None).values.tolist()}) |
121 | | - else: |
122 | | - abort(404, Exception('Received object is not a dataframe.')) |
123 | | - |
124 | | - return response |
125 | | - |
126 | | - |
127 | | -def annotations_to_response(target, df): |
128 | | - response = [] |
129 | | - |
130 | | - # Single series with DatetimeIndex and values as text |
131 | | - if isinstance(df, pd.Series): |
132 | | - for timestamp, value in df.iteritems(): |
133 | | - response.append({ |
134 | | - "annotation": target, # The original annotation sent from Grafana. |
135 | | - "time": timestamp.value // 10 ** 6, # Time since UNIX Epoch in milliseconds. (required) |
136 | | - "title": value, # The title for the annotation tooltip. (required) |
137 | | - #"tags": tags, # Tags for the annotation. (optional) |
138 | | - #"text": text # Text for the annotation. (optional) |
139 | | - }) |
140 | | - # Dataframe with annotation text/tags for each entry |
141 | | - elif isinstance(df, pd.DataFrame): |
142 | | - for timestamp, row in df.iterrows(): |
143 | | - annotation = { |
144 | | - "annotation": target, # The original annotation sent from Grafana. |
145 | | - "time": timestamp.value // 10 ** 6, # Time since UNIX Epoch in milliseconds. (required) |
146 | | - "title": row.get('title', ''), # The title for the annotation tooltip. (required) |
147 | | - } |
148 | | - |
149 | | - if 'text' in row: |
150 | | - annotation['text'] = str(row.get('text')) |
151 | | - if 'tags' in row: |
152 | | - annotation['tags'] = str(row.get('tags')) |
153 | | - |
154 | | - response.append(annotation) |
155 | | - else: |
156 | | - abort(404, Exception('Received object is not a dataframe or series.')) |
157 | | - |
158 | | - return response |
159 | | - |
160 | | - |
161 | | -def _series_to_annotations(df, target): |
162 | | - if df.empty: |
163 | | - return {'target': '%s' % (target), |
164 | | - 'datapoints': []} |
165 | | - |
166 | | - sorted_df = df.dropna().sort_index() |
167 | | - timestamps = (sorted_df.index.astype(pd.np.int64) // 10 ** 6).values.tolist() |
168 | | - values = sorted_df.values.tolist() |
169 | | - |
170 | | - return {'target': '%s' % (df.name), |
171 | | - 'datapoints': list(zip(values, timestamps))} |
172 | | - |
173 | | - |
174 | | -def _series_to_response(df, target): |
175 | | - if df.empty: |
176 | | - return {'target': '%s' % (target), |
177 | | - 'datapoints': []} |
178 | | - |
179 | | - sorted_df = df.dropna().sort_index() |
180 | | - |
181 | | - timestamps = (sorted_df.index.astype(np.int64) // 10 ** 6).values.tolist() |
182 | | - |
183 | | - values = sorted_df.values.tolist() |
184 | | - |
185 | | - return {'target': '%s' % (df.name), |
186 | | - 'datapoints': list(zip(values, timestamps))} |
187 | | - |
188 | | - |
189 | 92 | @app.route('/query', methods=methods) |
190 | 93 | @cross_origin(max_age=600) |
191 | 94 | def query_metrics(): |
|
0 commit comments