Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SRM add time range filter and stats count api #843

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from rest_framework import serializers

from sequence_run_manager.models import Comment
from sequence_run_manager.serializers.base import SerializersBase, OptionalFieldsMixin, OrcabusIdSerializerMetaMixin
from sequence_run_manager.serializers.base import SerializersBase, OrcabusIdSerializerMetaMixin


class CommentBaseSerializer(SerializersBase):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,9 @@ class Meta(OrcabusIdSerializerMetaMixin):
model = Sequence
fields = "__all__"


class SequenceRunCountByStatusSerializer(serializers.Serializer):
all = serializers.IntegerField()
started = serializers.IntegerField()
succeeded = serializers.IntegerField()
failed = serializers.IntegerField()
aborted = serializers.IntegerField()
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from rest_framework import serializers

from sequence_run_manager.models import State, Sequence
from sequence_run_manager.serializers.base import SerializersBase, OptionalFieldsMixin, OrcabusIdSerializerMetaMixin
from sequence_run_manager.models import State
from sequence_run_manager.serializers.base import SerializersBase, OrcabusIdSerializerMetaMixin


class StateBaseSerializer(SerializersBase):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from sequence_run_manager.viewsets.sequence import SequenceViewSet
from sequence_run_manager.viewsets.state import StateViewSet
from sequence_run_manager.viewsets.comment import CommentViewSet
from sequence_run_manager.viewsets.sequence_run_stats import SequenceStatsViewSet
from sequence_run_manager.settings.base import API_VERSION

api_namespace = "api"
Expand All @@ -17,6 +18,7 @@

router.register("sequence/(?P<orcabus_id>[^/]+)/comment", CommentViewSet, basename="sequence-comment")
router.register("sequence/(?P<orcabus_id>[^/]+)/state", StateViewSet, basename="sequence-states")
router.register(r"sequence/stats", SequenceStatsViewSet, basename="sequence-stats")

urlpatterns = [
path(f"{api_base}", include(router.urls)),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from drf_spectacular.utils import extend_schema

from sequence_run_manager.viewsets.base import BaseViewSet
from sequence_run_manager.models.sequence import Sequence
from django.db.models import Q
from sequence_run_manager.models import Sequence
from sequence_run_manager.serializers.sequence import SequenceSerializer, SequenceListParamSerializer, \
SequenceMinSerializer

Expand All @@ -11,7 +11,27 @@ class SequenceViewSet(BaseViewSet):
search_fields = Sequence.get_base_fields()

def get_queryset(self):
return Sequence.objects.get_by_keyword(**self.request.query_params)
"""Pick up the start_time and end_time from the query params and exclude them from the rest of the query params"""

start_time = self.request.query_params.get('start_time', 0)
end_time = self.request.query_params.get('end_time', 0)

# exclude the custom query params from the rest of the query params
def exclude_params(params):
for param in params:
self.request.query_params.pop(param) if param in self.request.query_params.keys() else None

exclude_params([
'start_time',
'end_time',
])
result_set = Sequence.objects.get_by_keyword(**self.request.query_params)

if start_time and end_time:
result_set = result_set.filter(Q(start_time__range=[start_time, end_time]) | Q(end_time__range=[start_time, end_time]))

return result_set


@extend_schema(parameters=[
SequenceListParamSerializer
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
from rest_framework.viewsets import GenericViewSet
from rest_framework.decorators import action
from drf_spectacular.utils import extend_schema
from rest_framework.response import Response
from django.db import models
from django.db.models import Q

from sequence_run_manager.models.sequence import Sequence
from sequence_run_manager.serializers.sequence import SequenceRunCountByStatusSerializer


class SequenceStatsViewSet(GenericViewSet):
"""
ViewSet for sequence-related statistics
"""
@extend_schema(responses=SequenceRunCountByStatusSerializer)
@action(detail=False, methods=['GET'])
def status_counts(self, request):
"""Pick up the start_time and end_time from the query params and exclude them from the rest of the query params"""

start_time = self.request.query_params.get('start_time', 0)
end_time = self.request.query_params.get('end_time', 0)

# exclude the custom query params from the rest of the query params
def exclude_params(params):
for param in params:
self.request.query_params.pop(param) if param in self.request.query_params.keys() else None

exclude_params([
'start_time',
'end_time',
])

# Start with base queryset
qs = Sequence.objects.all()

# Apply time range filters if provided
if start_time and end_time:
qs = qs.filter(
Q(start_time__range=[start_time, end_time]) |
Q(end_time__range=[start_time, end_time])
)

# Get total count
total = qs.count()

# Get counts by status
status_counts = qs.values('status').annotate(count=models.Count('status'))

# Convert to dictionary with default 0 for missing statuses
counts = {
'all': total,
'started': 0,
'succeeded': 0,
'aborted': 0,
'failed': 0,
}

for item in status_counts:
status = item['status'].lower()
counts[status] = item['count']

return Response(counts, status=200)

# You can add more stats endpoints here in the future
# For example:

# @action(detail=False, methods=['GET'])
# def monthly_trends(self, request):
# """Example: Get sequence counts by month"""
# pass

# @action(detail=False, methods=['GET'])
# def instrument_stats(self, request):
# """Example: Get stats grouped by instrument"""
# pass