Beispiel #1
0
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')
Beispiel #2
0
                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_by_id_and_org(widget_id, self.current_org)
        require_admin_or_owner(widget.dashboard.user_id)
        widget.delete_instance()

        return {'layout': widget.dashboard.layout}


api.add_org_resource(WidgetListAPI, '/api/widgets', endpoint='widgets')
api.add_org_resource(WidgetAPI,
                     '/api/widgets/<int:widget_id>',
                     endpoint='widget')
Beispiel #3
0
    def get(self, alert_id):
        alert = models.Alert.get_by_id_and_org(alert_id, self.current_org)
        require_access(alert.groups, self.current_user, view_only)

        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)
        require_admin_or_owner(subscriber_id)

        self.record_event({
            'action': 'unsubscribe',
            'timestamp': int(time.time()),
            'object_id': alert_id,
            'object_type': 'alert'
        })


api.add_org_resource(AlertResource, '/api/alerts/<alert_id>', endpoint='alert')
api.add_org_resource(AlertSubscriptionListResource,
                     '/api/alerts/<alert_id>/subscriptions',
                     endpoint='alert_subscriptions')
api.add_org_resource(AlertSubscriptionResource,
                     '/api/alerts/<alert_id>/subscriptions/<subscriber_id>',
                     endpoint='alert_subscription')
api.add_org_resource(AlertListResource, '/api/alerts', endpoint='alerts')
Beispiel #4
0
    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_and_org(dashboard_slug,
                                                       self.current_org)
        dashboard.layout = dashboard_properties['layout']
        dashboard.name = dashboard_properties['name']
        dashboard.save()

        return dashboard.to_dict(with_widgets=True, user=self.current_user)

    @require_permission('edit_dashboard')
    def delete(self, dashboard_slug):
        dashboard = models.Dashboard.get_by_slug_and_org(
            dashboard_slug, self.current_org)
        dashboard.is_archived = True
        dashboard.save()

        return dashboard.to_dict(with_widgets=True, user=self.current_user)


api.add_org_resource(DashboardListAPI,
                     '/api/dashboards',
                     endpoint='dashboards')
api.add_org_resource(DashboardRecentAPI,
                     '/api/dashboards/recent',
                     endpoint='recent_dashboards')
api.add_org_resource(DashboardAPI,
                     '/api/dashboards/<dashboard_slug>',
                     endpoint='dashboard')
Beispiel #5
0
from redash import models
from redash.wsgi import api
from redash.permissions import require_admin
from redash.query_runner import query_runners, validate_configuration
from redash.handlers.base import BaseResource, get_object_or_404


class DataSourceTypeListAPI(BaseResource):
    @require_admin
    def get(self):
        return [q.to_dict() for q in query_runners.values()]


api.add_org_resource(DataSourceTypeListAPI,
                     '/api/data_sources/types',
                     endpoint='data_source_types')


class DataSourceAPI(BaseResource):
    @require_admin
    def get(self, data_source_id):
        data_source = models.DataSource.get_by_id_and_org(
            data_source_id, self.current_org)
        return data_source.to_dict(all=True)

    @require_admin
    def post(self, data_source_id):
        data_source = models.DataSource.get_by_id_and_org(
            data_source_id, self.current_org)
        req = request.get_json(True)
Beispiel #6
0
        q = get_object_or_404(models.Query.get_by_id_and_org, query_id, self.current_org)
        require_access(q.groups, self.current_user, view_only)

        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):
        query = get_object_or_404(models.Query.get_by_id_and_org, query_id, self.current_org)
        require_admin_or_owner(query.user_id)
        query.archive()


class QueryRefreshResource(BaseResource):
    def post(self, query_id):
        query = get_object_or_404(models.Query.get_by_id_and_org, query_id, self.current_org)
        require_access(query.groups, self.current_user, not_view_only)

        parameter_values = collect_parameters_from_request(request.args)

        return run_query(query.data_source, parameter_values, query.query, query.id)


api.add_org_resource(QuerySearchAPI, '/api/queries/search', endpoint='queries_search')
api.add_org_resource(QueryRecentAPI, '/api/queries/recent', endpoint='recent_queries')
api.add_org_resource(QueryListAPI, '/api/queries', endpoint='queries')
api.add_org_resource(QueryRefreshResource, '/api/queries/<query_id>/refresh', endpoint='query_refresh')
api.add_org_resource(QueryAPI, '/api/queries/<query_id>', endpoint='query')
Beispiel #7
0
            'object_id': group_id,
            'object_type': 'group',
            'member_id': data_source.id,
            'view_only': view_only
        })

        return data_source.to_dict(with_permissions=True)

    @require_admin
    def delete(self, group_id, data_source_id):
        data_source = models.DataSource.get_by_id_and_org(data_source_id, self.current_org)
        group = models.Group.get_by_id_and_org(group_id, self.current_org)

        data_source.remove_group(group)

        self.record_event({
            'action': 'remove_data_source',
            'timestamp': int(time.time()),
            'object_id': group_id,
            'object_type': 'group',
            'member_id': data_source.id
        })


api.add_org_resource(GroupListResource, '/api/groups', endpoint='groups')
api.add_org_resource(GroupResource, '/api/groups/<group_id>', endpoint='group')
api.add_org_resource(GroupMemberListResource, '/api/groups/<group_id>/members', endpoint='group_members')
api.add_org_resource(GroupMemberResource, '/api/groups/<group_id>/members/<user_id>', endpoint='group_member')
api.add_org_resource(GroupDataSourceListResource, '/api/groups/<group_id>/data_sources', endpoint='group_data_sources')
api.add_org_resource(GroupDataSourceResource, '/api/groups/<group_id>/data_sources/<data_source_id>', endpoint='group_data_source')
Beispiel #8
0
            'object_id': alert_id,
            'object_type': 'alert'
        })

        return subscription.to_dict()

    def get(self, alert_id):
        alert = models.Alert.get_by_id_and_org(alert_id, self.current_org)
        require_access(alert.groups, self.current_user, view_only)

        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)
        require_admin_or_owner(subscriber_id)

        self.record_event({
            'action': 'unsubscribe',
            'timestamp': int(time.time()),
            'object_id': alert_id,
            'object_type': 'alert'
        })

api.add_org_resource(AlertResource, '/api/alerts/<alert_id>', endpoint='alert')
api.add_org_resource(AlertSubscriptionListResource, '/api/alerts/<alert_id>/subscriptions', endpoint='alert_subscriptions')
api.add_org_resource(AlertSubscriptionResource, '/api/alerts/<alert_id>/subscriptions/<subscriber_id>', endpoint='alert_subscription')
api.add_org_resource(AlertListResource, '/api/alerts', endpoint='alerts')
Beispiel #9
0
            params.pop('old_password')

        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)

        self.record_event({
            '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_org_resource(UserListResource, '/api/users', endpoint='users')
api.add_org_resource(UserResource, '/api/users/<user_id>', endpoint='user')


Beispiel #10
0
    def delete(self, group_id, data_source_id):
        data_source = models.DataSource.get_by_id_and_org(
            data_source_id, self.current_org)
        group = models.Group.get_by_id_and_org(group_id, self.current_org)

        data_source.remove_group(group)

        self.record_event({
            'action': 'remove_data_source',
            'timestamp': int(time.time()),
            'object_id': group_id,
            'object_type': 'group',
            'member_id': data_source.id
        })


api.add_org_resource(GroupListResource, '/api/groups', endpoint='groups')
api.add_org_resource(GroupResource, '/api/groups/<group_id>', endpoint='group')
api.add_org_resource(GroupMemberListResource,
                     '/api/groups/<group_id>/members',
                     endpoint='group_members')
api.add_org_resource(GroupMemberResource,
                     '/api/groups/<group_id>/members/<user_id>',
                     endpoint='group_member')
api.add_org_resource(GroupDataSourceListResource,
                     '/api/groups/<group_id>/data_sources',
                     endpoint='group_data_sources')
api.add_org_resource(GroupDataSourceResource,
                     '/api/groups/<group_id>/data_sources/<data_source_id>',
                     endpoint='group_data_source')
Beispiel #11
0
        public_url = url_for('public_dashboard',
                             token=api_key.api_key,
                             org_slug=self.current_org.slug,
                             _external=True)

        return {'public_url': public_url, 'api_key': api_key.api_key}

    def delete(self, dashboard_id):
        dashboard = models.Dashboard.get_by_id_and_org(dashboard_id,
                                                       self.current_org)
        require_admin_or_owner(dashboard.user_id)
        api_key = models.ApiKey.get_by_object(dashboard)

        if api_key:
            api_key.active = False
            api_key.save()


api.add_org_resource(DashboardListResource,
                     '/api/dashboards',
                     endpoint='dashboards')
api.add_org_resource(RecentDashboardsResource,
                     '/api/dashboards/recent',
                     endpoint='recent_dashboards')
api.add_org_resource(DashboardResource,
                     '/api/dashboards/<dashboard_slug>',
                     endpoint='dashboard')
api.add_org_resource(DashboardShareResource,
                     '/api/dashboards/<dashboard_id>/share',
                     endpoint='dashboard_share')
Beispiel #12
0
        vis = get_object_or_404(models.Visualization.get_by_id_and_org,
                                visualization_id, self.current_org)
        require_admin_or_owner(vis.query.user_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)

        vis.update_instance(**kwargs)

        return vis.to_dict(with_query=False)

    @require_permission('edit_query')
    def delete(self, visualization_id):
        vis = get_object_or_404(models.Visualization.get_by_id_and_org,
                                visualization_id, self.current_org)
        require_admin_or_owner(vis.query.user_id)

        vis.delete_instance()


api.add_org_resource(VisualizationListResource,
                     '/api/visualizations',
                     endpoint='visualizations')
api.add_org_resource(VisualizationResource,
                     '/api/visualizations/<visualization_id>',
                     endpoint='visualization')
Beispiel #13
0
            return 'failed'
        dashboard = models.Dashboard.get_by_id(dashboard_id)
        if not dashboard.groups:
            dashboard.groups = [group_id]
        elif not group_id in dashboard.groups:
            dashboard.groups.append(group_id)
        dashboard.save()
        group = models.Group.get_by_id(group_id)
        return {'name':group.name,'id':str(group.id)}

class DashboardDelGroupAPI(BaseResource):

    @require_permission('edit_dashboard')
    def post(self):
        args = request.get_json(force=True)
        dashboard_id = args['dashboard_id']
        group_id = args['group_id']
        dashboard = models.Dashboard.get_by_id(dashboard_id)
        groups = set(dashboard.groups)
        groups = groups - set([group_id])
        dashboard.groups = list(groups)
        dashboard.save()
        return {'group_id':group_id}


api.add_org_resource(DashboardListAPI, '/api/dashboards', endpoint='dashboards')
api.add_org_resource(DashboardRecentAPI, '/api/dashboards/recent', endpoint='recent_dashboards')
api.add_org_resource(DashboardAPI, '/api/dashboards/<dashboard_slug>', endpoint='dashboard')
api.add_org_resource(DashboardGroupAPI, '/api/dashboards/group', endpoint='dashboard_group')
api.add_org_resource(DashboardDelGroupAPI, '/api/dashboards/delgroup', endpoint='dashboard_del_group')
Beispiel #14
0
from flask.ext.restful import abort
from funcy import project

from redash import models
from redash.wsgi import api
from redash.permissions import require_admin
from redash.query_runner import query_runners, validate_configuration
from redash.handlers.base import BaseResource, get_object_or_404


class DataSourceTypeListAPI(BaseResource):
    @require_admin
    def get(self):
        return [q.to_dict() for q in query_runners.values()]

api.add_org_resource(DataSourceTypeListAPI, '/api/data_sources/types', endpoint='data_source_types')


class DataSourceAPI(BaseResource):
    @require_admin
    def get(self, data_source_id):
        data_source = models.DataSource.get_by_id_and_org(data_source_id, self.current_org)
        return data_source.to_dict(all=True)

    @require_admin
    def post(self, data_source_id):
        data_source = models.DataSource.get_by_id_and_org(data_source_id, self.current_org)
        req = request.get_json(True)

        data_source.replace_secret_placeholders(req['options'])
Beispiel #15
0

class DashboardAPI(BaseResource):
    def get(self, dashboard_slug=None):
        dashboard = get_object_or_404(models.Dashboard.get_by_slug_and_org, dashboard_slug, self.current_org)

        return dashboard.to_dict(with_widgets=True, user=self.current_user)

    @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_and_org(dashboard_slug, self.current_org)
        dashboard.layout = dashboard_properties['layout']
        dashboard.name = dashboard_properties['name']
        dashboard.save()

        return dashboard.to_dict(with_widgets=True, user=self.current_user)

    @require_permission('edit_dashboard')
    def delete(self, dashboard_slug):
        dashboard = models.Dashboard.get_by_slug_and_org(dashboard_slug, self.current_org)
        dashboard.is_archived = True
        dashboard.save()

        return dashboard.to_dict(with_widgets=True, user=self.current_user)

api.add_org_resource(DashboardListAPI, '/api/dashboards', endpoint='dashboards')
api.add_org_resource(DashboardRecentAPI, '/api/dashboards/recent', endpoint='recent_dashboards')
api.add_org_resource(DashboardAPI, '/api/dashboards/<dashboard_slug>', endpoint='dashboard')
Beispiel #16
0
        return vis.to_dict(with_query=False)


class VisualizationResource(BaseResource):
    @require_permission('edit_query')
    def post(self, visualization_id):
        vis = get_object_or_404(models.Visualization.get_by_id_and_org, visualization_id, self.current_org)
        require_admin_or_owner(vis.query.user_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)

        vis.update_instance(**kwargs)

        return vis.to_dict(with_query=False)

    @require_permission('edit_query')
    def delete(self, visualization_id):
        vis = get_object_or_404(models.Visualization.get_by_id_and_org, visualization_id, self.current_org)
        require_admin_or_owner(vis.query.user_id)

        vis.delete_instance()

api.add_org_resource(VisualizationListResource, '/api/visualizations', endpoint='visualizations')
api.add_org_resource(VisualizationResource, '/api/visualizations/<visualization_id>', endpoint='visualization')
Beispiel #17
0
    @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_org_resource(QueryResultListAPI, '/api/query_results', endpoint='query_results')
api.add_org_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)
Beispiel #18
0
        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_by_id_and_org(widget_id, self.current_org)
        require_admin_or_owner(widget.dashboard.user_id)
        widget.delete_instance()

        return {'layout': widget.dashboard.layout}

api.add_org_resource(WidgetListAPI, '/api/widgets', endpoint='widgets')
api.add_org_resource(WidgetAPI, '/api/widgets/<int:widget_id>', endpoint='widget')
Beispiel #19
0
        q = get_object_or_404(models.Query.get_by_hash, query_hash)
        #require_access(q.groups, self.current_user, view_only)

        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):
        query = get_object_or_404(models.Query.get_by_id_and_org, query_id, self.current_org)
        require_admin_or_owner(query.user_id)
        query.archive()


class QueryRefreshResource(BaseResource):
    def post(self, query_id):
        query = get_object_or_404(models.Query.get_by_id_and_org, query_id, self.current_org)
        require_access(query.groups, self.current_user, not_view_only)

        parameter_values = collect_parameters_from_request(request.args)

        return run_query(query.data_source, parameter_values, query.query, query.id)


api.add_org_resource(QuerySearchAPI, '/api/queries/search', endpoint='queries_search')
api.add_org_resource(QueryRecentAPI, '/api/queries/recent', endpoint='recent_queries')
api.add_org_resource(QueryListAPI, '/api/queries', endpoint='queries')
api.add_org_resource(QueryRefreshResource, '/api/queries/<query_id>/refresh', endpoint='query_refresh')
api.add_org_resource(QueryAPI, '/api/queries/<query_id>', endpoint='query')
Beispiel #20
0
        column_names = []
        for (c, col) in enumerate(query_data['columns']):
            sheet.write(0, c, col['name'])
            column_names.append(col['name'])

        for (r, row) in enumerate(query_data['rows']):
            for (c, name) in enumerate(column_names):
                sheet.write(r+1, c, row[name])

        book.close()

        headers = {'Content-Type': "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}
        return make_response(s.getvalue(), 200, headers)


api.add_org_resource(QueryResultListAPI, '/api/query_results', endpoint='query_results')
api.add_org_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)
Beispiel #21
0
        dashboard = models.Dashboard.get_by_slug_and_org(dashboard_slug, self.current_org)
        dashboard.is_archived = True
        dashboard.save()

        return dashboard.to_dict(with_widgets=True, user=self.current_user)


class DashboardShareResource(BaseResource):
    def post(self, dashboard_id):
        dashboard = models.Dashboard.get_by_id_and_org(dashboard_id, self.current_org)
        require_admin_or_owner(dashboard.user_id)
        api_key = models.ApiKey.create_for_object(dashboard, self.current_user)
        public_url = url_for('public_dashboard', token=api_key.api_key, org_slug=self.current_org.slug, _external=True)

        return {'public_url': public_url, 'api_key': api_key.api_key}

    def delete(self, dashboard_id):
        dashboard = models.Dashboard.get_by_id_and_org(dashboard_id, self.current_org)
        require_admin_or_owner(dashboard.user_id)
        api_key = models.ApiKey.get_by_object(dashboard)

        if api_key:
            api_key.active = False
            api_key.save()


api.add_org_resource(DashboardListResource, '/api/dashboards', endpoint='dashboards')
api.add_org_resource(RecentDashboardsResource, '/api/dashboards/recent', endpoint='recent_dashboards')
api.add_org_resource(DashboardResource, '/api/dashboards/<dashboard_slug>', endpoint='dashboard')
api.add_org_resource(DashboardShareResource, '/api/dashboards/<dashboard_id>/share', endpoint='dashboard_share')