cuebook/CueObserve

View on GitHub
api/anomaly/views.py

Summary

Maintainability
A
3 hrs
Test Coverage
B
89%
import json
from django.shortcuts import render
from rest_framework.decorators import api_view
from rest_framework.views import APIView
from rest_framework.response import Response
from django.http import HttpRequest

from anomaly.services import (
    Datasets,
    Connections,
    Querys,
    AnomalyDefinitions,
    Anomalys,
    ScheduleService,
    AnomalyDefJobServices,
    Settings,
    DetectionRules,
    RootCauseAnalyses,
)
from anomaly.services.telemetry import getInstallationId


class AnomalysView(APIView):
    """
    Provides views on datasets(many)
    """

    publishedOnly = False

    def get(self, request):
        """get request"""
        offset = int(request.GET.get("offset", 0))
        limit = int(request.GET.get("limit", 50))
        searchQuery = request.GET.get("searchText", "")
        sorter = json.loads(request.GET.get("sorter", "{}"))
        res = Anomalys.getAnomalys(
            publishedOnly=self.publishedOnly,
            offset=offset,
            limit=limit,
            searchQuery=searchQuery,
            sorter=sorter,
        )
        return Response(res.json())


class AnomalyView(APIView):
    """
    Provided views on Dataset(single)
    """

    def get(self, request, anomalyId: int):
        """get request"""
        res = Anomalys.getAnomaly(anomalyId)
        return Response(res.json())


class DatasetsView(APIView):
    """
    Provides views on datasets(many)
    """

    def get(self, request):
        """get request"""
        res = Datasets.getDatasets()
        return Response(res.json())


class DatasetView(APIView):
    """
    Provided views on Dataset(single)
    """

    def get(self, request, datasetId: int):
        """get request"""
        res = Datasets.getDataset(datasetId)
        return Response(res.json())

    def post(self, request, datasetId: int):
        """post request"""
        data = request.data
        res = Datasets.updateDataset(datasetId, data)
        return Response(res.json())

    def delete(self, request, datasetId: int):
        """delete request"""
        res = Datasets.deleteDataset(datasetId)
        return Response(res.json())


class CreateDatasetView(APIView):
    """
    Provides view on creating Dataset
    """

    def post(self, request):
        """post request"""
        data = request.data
        res = Datasets.createDataset(data)
        return Response(res.json())


# TODO
# class for connections
@api_view(["GET", "POST"])
def connections(request: HttpRequest) -> Response:
    """
    Method to get or add connection
    :param request: HttpRequest
    """
    if request.method == "GET":
        res = Connections.getConnections()
        return Response(res.json())
    elif request.method == "POST":
        res = Connections.addConnection(request.data)
        return Response(res.json())


@api_view(["GET", "PUT", "DELETE"])
def connection(request: HttpRequest, connection_id: int) -> Response:
    """
    Method for crud operations on a single connection
    :param request: HttpRequest
    :param connection_id: Connection Id
    """
    if request.method == "GET":
        res = Connections.getConnection(connection_id)
        return Response(res.json())
    elif request.method == "DELETE":
        res = Connections.removeConnection(connection_id)
        return Response(res.json())
    elif request.method == "PUT":
        res = Connections.updateConnection(connection_id, request.data)
        return Response(res.json())


@api_view(["GET", "POST"])
def connectionTypes(request: HttpRequest) -> Response:
    """
    Method to get all connection types
    :param request: HttpRequest
    """
    if request.method == "GET":
        res = Connections.getConnectionTypes()
        return Response(res.json())


class QueryView(APIView):
    """
    Provides view on creating Dataset
    """

    def post(self, request):
        """post request"""
        data = request.data
        sql = data["sql"]
        connectionId = data["connectionId"]
        connectionType, connectionParams = Connections.getConnectionParams(connectionId)
        res = Querys.runQuery(connectionType, connectionParams, sql)
        return Response(res.json())


class AnomalyDefView(APIView):
    """
    Provides view on Anomaly Operation
    """

    def get(self, request):
        offset = int(request.GET.get("offset", 0))
        limit = int(request.GET.get("limit", 50))
        searchQuery = request.GET.get("searchText", "")
        sorter = json.loads(request.GET.get("sorter", "{}"))
        res = AnomalyDefinitions.getAllAnomalyDefinition(
            offset=offset, limit=limit, searchQuery=searchQuery, sorter=sorter
        )
        return Response(res.json())

    def post(self, request):
        datasetId = int(request.data.get("datasetId", 0))
        metric = request.data.get("measure", None)
        highOrLow = request.data.get("highOrLow", None)
        operation = request.data.get("operation", None)
        value = request.data.get("operationValue", 0)
        dimension = request.data.get("dimension", None)
        detectionRuleTypeId = request.data.get("detectionRuleTypeId", 1)
        detectionRuleParams = request.data.get("detectionRuleParams", {})
        res = AnomalyDefinitions.addAnomalyDefinition(
            metric,
            dimension,
            operation,
            highOrLow,
            value,
            datasetId,
            detectionRuleTypeId,
            detectionRuleParams,
        )
        return Response(res.json())

    def delete(self, request, anomalyId: int):
        res = AnomalyDefinitions.deleteAnomalyDefinition(anomalyId)
        return Response(res.json())

    def put(self, request):
        anomalyDefId = request.data.get("anomalyDefId", 0)
        highOrLow = request.data.get("highOrLow", None)
        detectionRuleParams = request.data.get("detectionRuleParams", {})
        res = AnomalyDefinitions.editAnomalyDefinition(anomalyDefId, highOrLow, detectionRuleParams)
        return Response(res.json())


class ScheduleView(APIView):
    """
    Class to get and add available crontab schedules
    """

    def get(self, request):
        res = ScheduleService.getSchedules()
        return Response(res.json())

    def post(self, request):
        name = request.data["name"]
        cron = request.data["crontab"]
        timezone = request.data["timezone"]
        res = ScheduleService.addSchedule(cron=cron, timezone=timezone, name=name)
        return Response(res.json())

    def put(self, request):
        id = request.data["id"]
        name = request.data["name"]
        crontab = request.data["crontab"]
        timezone = request.data["timezone"]
        res = ScheduleService.updateSchedule(
            id=id, crontab=crontab, timezone=timezone, name=name
        )
        return Response(res.json())


@api_view(["GET", "PUT", "DELETE"])
def schedule(request: HttpRequest, scheduleId: int) -> Response:
    """
    Method for crud operations on a single connection
    :param request: HttpRequest
    :param connection_id: Connection Id
    """
    if request.method == "GET":
        res = ScheduleService.getSingleSchedule(scheduleId)
        return Response(res.json())
    if request.method == "DELETE":
        res = ScheduleService.deleteSchedule(scheduleId)
        return Response(res.json())


class TimzoneView(APIView):
    """
    Class to get standard pytz timezones
    """

    def get(self, request):
        res = ScheduleService.getTimezones()
        return Response(res.json())


class AnomalyDefJob(APIView):
    """
    Class to get, add and update a NotebookJob details
    The put and post methods only require request body and not path parameters
    The get method requires the notebookJobId as the path parameter
    """

    # def get(self, request, notebookId=None):
    #     offset = int(request.GET.get("offset", 0))
    #     res = AnomalyDefJobServices.getNotebookJobDetails(notebookId=notebookId, runStatusOffset=offset)
    #     return Response(res.json())

    def post(self, request):
        anomalyDefId = request.data["anomalyDefId"]
        scheduleId = request.data["scheduleId"]
        res = AnomalyDefJobServices.addAnomalyDefJob(
            anomalyDefId=anomalyDefId, scheduleId=scheduleId
        )
        return Response(res.json())

    def delete(self, request, anomalyDefId=None):
        res = AnomalyDefJobServices.deleteAnomalyDefJob(anomalyDefId=anomalyDefId)
        return Response(res.json())


@api_view(["POST"])
def runAnomalyDef(request: HttpRequest, anomalyDefId: int) -> Response:
    """
    Method for run anomaly detection for a given anomaly definition
    :param request: HttpRequest
    :param anomalyDefId: ID of the anomaly definition
    """
    res = AnomalyDefinitions.runAnomalyDetection(anomalyDefId)
    return Response(res.json())


@api_view(["GET"])
def runStatusAnomalies(request: HttpRequest, runStatusId: int) -> Response:
    """
    Method for fetch anomalies of a RunStatus and their urls
    :param request: HttpRequest
    :param anomalyDefId: ID of the anomaly definition
    """
    res = AnomalyDefinitions.runStatusAnomalies(runStatusId)
    return Response(res.json())


@api_view(["GET"])
def getDetectionRuns(request: HttpRequest, anomalyDefId: int) -> Response:
    """
    Method for fetching run statuses for a given anomaly definition
    :param request: HttpRequest
    :param anomalyDefId: ID of the anomaly definition
    """
    offset = int(request.GET.get("offset", 0))
    res = AnomalyDefinitions.getDetectionRuns(anomalyDefId, offset)
    return Response(res.json())


@api_view(["GET"])
def isTaskRunning(request: HttpRequest, anomalyDefId: int) -> Response:
    """
    Method for checking whether anomaly task is running
    :param request: HttpRequest
    :param anomalyDefId: ID of the anomaly definition
    """
    res = AnomalyDefinitions.isTaskRunning(anomalyDefId)
    return Response(res.json())


class SettingsView(APIView):
    """
    Provides views on settings
    """

    def get(self, request):
        """get request"""
        res = Settings.getSettings()
        return Response(res.json())

    def post(self, request):
        """post request"""
        data = request.data
        res = Settings.updateSettings(data)
        return Response(res.json())


class DetectionRuleTypeView(APIView):
    """
    Provides views on Detection Rule Types
    """

    def get(self, request):
        """get request"""
        res = DetectionRules.getDetectionRuleTypes()
        return Response(res.json())


class RCAView(APIView):
    """
    Provides views on RCA (Root Cause Analysis)
    """

    def get(self, request, anomalyId: int):
        """get rca"""
        res = RootCauseAnalyses.getRCA(anomalyId)
        return Response(res.json())

    def post(self, request, anomalyId: int):
        """make RCA request"""
        res = RootCauseAnalyses.calculateRCA(anomalyId)
        return Response(res.json())

    def delete(self, request, anomalyId: int):
        """make RCA request"""
        res = RootCauseAnalyses.abortRCA(anomalyId)
        return Response(res.json())

class InstallationView(APIView):
    """ Provides views on Installation """
    def get(self, request):
        res = getInstallationId()
        return Response(res.json())