models.Query.update_instance(query_id, **query_def) query = models.Query.get_by_id(query_id) return query.to_dict(with_visualizations=True) @require_permission('view_query') def get(self, query_id): q = models.Query.get(models.Query.id == query_id) if q: return q.to_dict(with_visualizations=True) else: abort(404, message="Query not found.") # TODO: move to resource of its own? (POST /queries/{id}/archive) def delete(self, query_id): q = models.Query.get(models.Query.id == query_id) if q: if q.user.id == self.current_user.id or self.current_user.has_permission('admin'): q.archive() else: abort(403) else: abort(404, message="Query not found.") api.add_resource(QuerySearchAPI, '/api/queries/search', endpoint='queries_search') api.add_resource(QueryRecentAPI, '/api/queries/recent', endpoint='recent_queries') api.add_resource(QueryListAPI, '/api/queries', endpoint='queries') api.add_resource(QueryAPI, '/api/queries/<query_id>', endpoint='query')
@staticmethod def make_csv_response(query_result): s = cStringIO.StringIO() query_data = json.loads(query_result.data) writer = csv.DictWriter(s, fieldnames=[col['name'] for col in query_data['columns']]) writer.writer = utils.UnicodeWriter(s) writer.writeheader() for row in query_data['rows']: writer.writerow(row) headers = {'Content-Type': "text/csv; charset=UTF-8"} return make_response(s.getvalue(), 200, headers) api.add_resource(QueryResultListAPI, '/api/query_results', endpoint='query_results') api.add_resource(QueryResultAPI, '/api/query_results/<query_result_id>', '/api/queries/<query_id>/results.<filetype>', '/api/queries/<query_id>/results/<query_result_id>.<filetype>', endpoint='query_result') class JobAPI(BaseResource): def get(self, job_id): # TODO: if finished, include the query result job = QueryTask(job_id=job_id) return {'job': job.to_dict()} def delete(self, job_id): job = QueryTask(job_id=job_id)
elif len(layout[-1]) == 1: neighbour_widget = models.Widget.get( models.Widget.id == layout[-1][0]) if neighbour_widget.width == 1: layout[-1].append(widget.id) new_row = False else: layout.append([widget.id]) else: layout.append([widget.id]) widget.dashboard.layout = json.dumps(layout) widget.dashboard.save() return { 'widget': widget.to_dict(), 'layout': layout, 'new_row': new_row } class WidgetAPI(BaseResource): @require_permission('edit_dashboard') def delete(self, widget_id): widget = models.Widget.get(models.Widget.id == widget_id) widget.delete_instance() api.add_resource(WidgetListAPI, '/api/widgets', endpoint='widgets') api.add_resource(WidgetAPI, '/api/widgets/<int:widget_id>', endpoint='widget')
from flask import request from redash import statsd_client from redash.wsgi import api from redash.tasks import record_event from redash.handlers.base import BaseResource class EventAPI(BaseResource): def post(self): events_list = request.get_json(force=True) for event in events_list: record_event.delay(event) api.add_resource(EventAPI, "/api/events", endpoint="events") class MetricsAPI(BaseResource): def post(self): for stat_line in request.data.split(): stat, value = stat_line.split(":") statsd_client._send_stat("client.{}".format(stat), value, 1) return "OK." api.add_resource(MetricsAPI, "/api/metrics/v1/send", endpoint="metrics")
if 'groups' in params and not self.current_user.has_permission('admin'): abort(403, message="Must be admin to change groups membership.") try: user.update_instance(**params) except IntegrityError as e: if "email" in e.message: message = "Email already taken." else: message = "Error updating record" abort(400, message=message) record_event.delay({ 'user_id': self.current_user.id, 'action': 'edit', 'timestamp': int(time.time()), 'object_id': user.id, 'object_type': 'user', 'updated_fields': params.keys() }) return user.to_dict(with_api_key=is_admin_or_owner(user_id)) api.add_resource(UserListResource, '/api/users', endpoint='users') api.add_resource(UserResource, '/api/users/<user_id>', endpoint='user')
from flask import request from redash import statsd_client from redash.wsgi import api from redash.handlers.base import BaseResource class EventAPI(BaseResource): def post(self): events_list = request.get_json(force=True) for event in events_list: self.record_event(event) api.add_org_resource(EventAPI, '/api/events', endpoint='events') class MetricsAPI(BaseResource): def post(self): for stat_line in request.data.split(): stat, value = stat_line.split(':') statsd_client._send_stat('client.{}'.format(stat), value, 1) return "OK." api.add_resource(MetricsAPI, '/api/metrics/v1/send', endpoint='metrics')
return current_user._get_current_object() def dispatch_request(self, *args, **kwargs): with statsd_client.timer('requests.{}.{}'.format(request.endpoint, request.method.lower())): response = super(BaseResource, self).dispatch_request(*args, **kwargs) return response class EventAPI(BaseResource): def post(self): events_list = request.get_json(force=True) for event in events_list: record_event.delay(event) api.add_resource(EventAPI, '/api/events', endpoint='events') class MetricsAPI(BaseResource): def post(self): for stat_line in request.data.split(): stat, value = stat_line.split(':') statsd_client._send_stat('client.{}'.format(stat), value, 1) return "OK." api.add_resource(MetricsAPI, '/api/metrics/v1/send', endpoint='metrics') class DataSourceTypeListAPI(BaseResource): @require_permission("admin")
class VisualizationAPI(BaseResource): @require_permission('edit_query') def post(self, visualization_id): kwargs = request.get_json(force=True) if 'options' in kwargs: kwargs['options'] = json.dumps(kwargs['options']) kwargs.pop('id', None) kwargs.pop('query_id', None) update = models.Visualization.update(**kwargs).where( models.Visualization.id == visualization_id) update.execute() vis = models.Visualization.get_by_id(visualization_id) return vis.to_dict(with_query=False) @require_permission('edit_query') def delete(self, visualization_id): vis = models.Visualization.get( models.Visualization.id == visualization_id) vis.delete_instance() api.add_resource(VisualizationListAPI, '/api/visualizations', endpoint='visualizations') api.add_resource(VisualizationAPI, '/api/visualizations/<visualization_id>', endpoint='visualization')
try: dashboard = models.Dashboard.get_by_slug(dashboard_slug) except models.Dashboard.DoesNotExist: abort(404) return dashboard.to_dict(with_widgets=True) @require_permission('edit_dashboard') def post(self, dashboard_slug): dashboard_properties = request.get_json(force=True) # TODO: either convert all requests to use slugs or ids dashboard = models.Dashboard.get_by_id(dashboard_slug) dashboard.layout = dashboard_properties['layout'] dashboard.name = dashboard_properties['name'] dashboard.save() return dashboard.to_dict(with_widgets=True) @require_permission('edit_dashboard') def delete(self, dashboard_slug): dashboard = models.Dashboard.get_by_slug(dashboard_slug) dashboard.is_archived = True dashboard.save() return dashboard.to_dict(with_widgets=True) api.add_resource(DashboardListAPI, '/api/dashboards', endpoint='dashboards') api.add_resource(DashboardRecentAPI, '/api/dashboards/recent', endpoint='recent_dashboards') api.add_resource(DashboardAPI, '/api/dashboards/<dashboard_slug>', endpoint='dashboard')
layout = json.loads(widget.dashboard.layout) new_row = True if len(layout) == 0 or widget.width == 2: layout.append([widget.id]) elif len(layout[-1]) == 1: neighbour_widget = models.Widget.get(models.Widget.id == layout[-1][0]) if neighbour_widget.width == 1: layout[-1].append(widget.id) new_row = False else: layout.append([widget.id]) else: layout.append([widget.id]) widget.dashboard.layout = json.dumps(layout) widget.dashboard.save() return {"widget": widget.to_dict(), "layout": layout, "new_row": new_row} class WidgetAPI(BaseResource): @require_permission("edit_dashboard") def delete(self, widget_id): widget = models.Widget.get(models.Widget.id == widget_id) widget.delete_instance() api.add_resource(WidgetListAPI, "/api/widgets", endpoint="widgets") api.add_resource(WidgetAPI, "/api/widgets/<int:widget_id>", endpoint="widget")
new_row = True if len(layout) == 0 or widget.width == 2: layout.append([widget.id]) elif len(layout[-1]) == 1: neighbour_widget = models.Widget.get(models.Widget.id == layout[-1][0]) if neighbour_widget.width == 1: layout[-1].append(widget.id) new_row = False else: layout.append([widget.id]) else: layout.append([widget.id]) widget.dashboard.layout = json.dumps(layout) widget.dashboard.save() return {'widget': widget.to_dict(), 'layout': layout, 'new_row': new_row} class WidgetAPI(BaseResource): @require_permission('edit_dashboard') def delete(self, widget_id): widget = models.Widget.get(models.Widget.id == widget_id) widget.delete_instance() return {'layout': widget.dashboard.layout } api.add_resource(WidgetListAPI, '/api/widgets', endpoint='widgets') api.add_resource(WidgetAPI, '/api/widgets/<int:widget_id>', endpoint='widget')
from flask import make_response, request from flask.ext.restful import abort from redash import models from redash.wsgi import api from redash.permissions import require_permission from redash.query_runner import query_runners, validate_configuration from redash.handlers.base import BaseResource class DataSourceTypeListAPI(BaseResource): @require_permission("admin") def get(self): return [q.to_dict() for q in query_runners.values()] api.add_resource(DataSourceTypeListAPI, '/api/data_sources/types', endpoint='data_source_types') class DataSourceAPI(BaseResource): @require_permission('admin') def get(self, data_source_id): data_source = models.DataSource.get_by_id(data_source_id) return data_source.to_dict(all=True) @require_permission('admin') def post(self, data_source_id): data_source = models.DataSource.get_by_id(data_source_id) req = request.get_json(True) if not validate_configuration(req['type'], req['options']): abort(400)
from flask import request from redash import statsd_client from redash.wsgi import api from redash.tasks import record_event from redash.handlers.base import BaseResource class EventAPI(BaseResource): def post(self): events_list = request.get_json(force=True) for event in events_list: record_event.delay(event) api.add_resource(EventAPI, '/api/events', endpoint='events') class MetricsAPI(BaseResource): def post(self): for stat_line in request.data.split(): stat, value = stat_line.split(':') statsd_client._send_stat('client.{}'.format(stat), value, 1) return "OK." api.add_resource(MetricsAPI, '/api/metrics/v1/send', endpoint='metrics')
self.add_cors_headers(headers) if filetype == 'json': data = json.dumps({'query_result': query_result.to_dict()}, cls=utils.JSONEncoder) headers.update(cache_headers) return make_response(data, 200, headers) else: return self.csv_response(query_result) else: abort(404) api.add_resource(QueryResultListAPI, '/api/query_results', endpoint='query_results') api.add_resource( QueryResultAPI, '/api/query_results/<query_result_id>', '/api/queries/<query_id>/results.<filetype>', '/api/queries/<query_id>/results/<query_result_id>.<filetype>', endpoint='query_result') class JobAPI(BaseResource): def get(self, job_id): # TODO: if finished, include the query result job = QueryTask(job_id=job_id) return {'job': job.to_dict()}
return current_user._get_current_object() def dispatch_request(self, *args, **kwargs): with statsd_client.timer("requests.{}.{}".format(request.endpoint, request.method.lower())): response = super(BaseResource, self).dispatch_request(*args, **kwargs) return response class EventAPI(BaseResource): def post(self): events_list = request.get_json(force=True) for event in events_list: record_event.delay(event) api.add_resource(EventAPI, "/api/events", endpoint="events") class MetricsAPI(BaseResource): def post(self): for stat_line in request.data.split(): stat, value = stat_line.split(":") statsd_client._send_stat("client.{}".format(stat), value, 1) return "OK." api.add_resource(MetricsAPI, "/api/metrics/v1/send", endpoint="metrics") class DataSourceTypeListAPI(BaseResource):
return current_user._get_current_object() def dispatch_request(self, *args, **kwargs): with statsd_client.timer('requests.{}.{}'.format(request.endpoint, request.method.lower())): response = super(BaseResource, self).dispatch_request(*args, **kwargs) return response class EventAPI(BaseResource): def post(self): events_list = request.get_json(force=True) for event in events_list: events.record_event(event) api.add_resource(EventAPI, '/api/events', endpoint='events') class MetricsAPI(BaseResource): def post(self): for stat_line in request.data.split(): stat, value = stat_line.split(':') statsd_client._send_stat('client.{}'.format(stat), value, 1) return "OK." api.add_resource(MetricsAPI, '/api/metrics/v1/send', endpoint='metrics') class DataSourceListAPI(BaseResource): def get(self):
return dashboard.to_dict(with_widgets=True) @require_permission('edit_dashboard') def post(self, dashboard_slug): dashboard_properties = request.get_json(force=True) # TODO: either convert all requests to use slugs or ids dashboard = models.Dashboard.get_by_id(dashboard_slug) dashboard.layout = dashboard_properties['layout'] dashboard.name = dashboard_properties['name'] dashboard.save() return dashboard.to_dict(with_widgets=True) @require_permission('edit_dashboard') def delete(self, dashboard_slug): dashboard = models.Dashboard.get_by_slug(dashboard_slug) dashboard.is_archived = True dashboard.save() return dashboard.to_dict(with_widgets=True) api.add_resource(DashboardListAPI, '/api/dashboards', endpoint='dashboards') api.add_resource(DashboardRecentAPI, '/api/dashboards/recent', endpoint='recent_dashboards') api.add_resource(DashboardAPI, '/api/dashboards/<dashboard_slug>', endpoint='dashboard')
def dispatch_request(self, *args, **kwargs): with statsd_client.timer('requests.{}.{}'.format( request.endpoint, request.method.lower())): response = super(BaseResource, self).dispatch_request(*args, **kwargs) return response class EventAPI(BaseResource): def post(self): events_list = request.get_json(force=True) for event in events_list: record_event.delay(event) api.add_resource(EventAPI, '/api/events', endpoint='events') class MetricsAPI(BaseResource): def post(self): for stat_line in request.data.split(): stat, value = stat_line.split(':') statsd_client._send_stat('client.{}'.format(stat), value, 1) return "OK." api.add_resource(MetricsAPI, '/api/metrics/v1/send', endpoint='metrics') class DataSourceTypeListAPI(BaseResource):
vis = models.Visualization(**kwargs) vis.save() return vis.to_dict(with_query=False) class VisualizationAPI(BaseResource): @require_permission('edit_query') def post(self, visualization_id): kwargs = request.get_json(force=True) if 'options' in kwargs: kwargs['options'] = json.dumps(kwargs['options']) kwargs.pop('id', None) kwargs.pop('query_id', None) update = models.Visualization.update(**kwargs).where(models.Visualization.id == visualization_id) update.execute() vis = models.Visualization.get_by_id(visualization_id) return vis.to_dict(with_query=False) @require_permission('edit_query') def delete(self, visualization_id): vis = models.Visualization.get(models.Visualization.id == visualization_id) vis.delete_instance() api.add_resource(VisualizationListAPI, '/api/visualizations', endpoint='visualizations') api.add_resource(VisualizationAPI, '/api/visualizations/<visualization_id>', endpoint='visualization')
subscription = models.AlertSubscription.create(alert=alert_id, user=self.current_user) record_event.delay({ 'user_id': self.current_user.id, 'action': 'subscribe', 'timestamp': int(time.time()), 'object_id': alert_id, 'object_type': 'alert' }) return subscription.to_dict() def get(self, alert_id): subscriptions = models.AlertSubscription.all(alert_id) return [s.to_dict() for s in subscriptions] class AlertSubscriptionResource(BaseResource): def delete(self, alert_id, subscriber_id): models.AlertSubscription.unsubscribe(alert_id, subscriber_id) record_event.delay({ 'user_id': self.current_user.id, 'action': 'unsubscribe', 'timestamp': int(time.time()), 'object_id': alert_id, 'object_type': 'alert' }) api.add_resource(AlertAPI, '/api/alerts/<alert_id>', endpoint='alert') api.add_resource(AlertSubscriptionListResource, '/api/alerts/<alert_id>/subscriptions', endpoint='alert_subscriptions') api.add_resource(AlertSubscriptionResource, '/api/alerts/<alert_id>/subscriptions/<subscriber_id>', endpoint='alert_subscription') api.add_resource(AlertListAPI, '/api/alerts', endpoint='alerts')
from redash import models from redash.wsgi import api from redash.permissions import require_permission from redash.query_runner import query_runners, validate_configuration from redash.handlers.base import BaseResource class DataSourceTypeListAPI(BaseResource): @require_permission("admin") def get(self): return [q.to_dict() for q in query_runners.values()] api.add_resource(DataSourceTypeListAPI, '/api/data_sources/types', endpoint='data_source_types') class DataSourceAPI(BaseResource): @require_permission('admin') def get(self, data_source_id): data_source = models.DataSource.get_by_id(data_source_id) return data_source.to_dict(all=True) @require_permission('admin') def post(self, data_source_id): data_source = models.DataSource.get_by_id(data_source_id) req = request.get_json(True) data_source.replace_secret_placeholders(req['options'])
'object_id': alert_id, 'object_type': 'alert' }) return subscription.to_dict() def get(self, alert_id): subscriptions = models.AlertSubscription.all(alert_id) return [s.to_dict() for s in subscriptions] class AlertSubscriptionResource(BaseResource): def delete(self, alert_id, subscriber_id): models.AlertSubscription.unsubscribe(alert_id, subscriber_id) record_event.delay({ 'user_id': self.current_user.id, 'action': 'unsubscribe', 'timestamp': int(time.time()), 'object_id': alert_id, 'object_type': 'alert' }) api.add_resource(AlertAPI, '/api/alerts/<alert_id>', endpoint='alert') api.add_resource(AlertSubscriptionListResource, '/api/alerts/<alert_id>/subscriptions', endpoint='alert_subscriptions') api.add_resource(AlertSubscriptionResource, '/api/alerts/<alert_id>/subscriptions/<subscriber_id>', endpoint='alert_subscription') api.add_resource(AlertListAPI, '/api/alerts', endpoint='alerts')
if "groups" in params and not self.current_user.has_permission("admin"): abort(403, message="Must be admin to change groups membership.") try: user.update_instance(**params) except IntegrityError as e: if "email" in e.message: message = "Email already taken." else: message = "Error updating record" abort(400, message=message) record_event.delay( { "user_id": self.current_user.id, "action": "edit", "timestamp": int(time.time()), "object_id": user.id, "object_type": "user", "updated_fields": params.keys(), } ) return user.to_dict(with_api_key=is_admin_or_owner(user_id)) api.add_resource(UserListResource, "/api/users", endpoint="users") api.add_resource(UserResource, "/api/users/<user_id>", endpoint="user")