Skip to content

Commit

Permalink
Add search tag on sitewithobservations (#1089)
Browse files Browse the repository at this point in the history
* patch: swagger fake view check and safe observation pk retrieval

* patch: add search tag to sites with observations api

* patch: show user friendly errors

* patch: add missing foward slash

* patch: add missing foward slash
  • Loading branch information
tinashechiraya authored Oct 7, 2024
1 parent 2f19ff6 commit f83b9f9
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ interface DownloadObservationFormProps {
dateRange: string[];
}

const DOWNLOAD_OBSERVATIONS_URL = globalVariables.baseUrl + '/monitor/observations/download-v2'
const DOWNLOAD_OBSERVATIONS_URL = globalVariables.baseUrl + '/monitor/observations/download-v2/'

const DownloadObservationForm: React.FC<DownloadObservationFormProps> = ({ isOpen, onClose,
siteId, dateRange}) => {
Expand Down Expand Up @@ -55,7 +55,6 @@ const DownloadObservationForm: React.FC<DownloadObservationFormProps> = ({ isOpe

useEffect(() => {
setFormData({ ...formData, startDate: dayjs(dateRange[0]), endDate: dayjs(dateRange[1]) });
console.log('provided date ranges ',dateRange)
}, [dateRange]);

const handleSubmit = (e: FormEvent) => {
Expand Down Expand Up @@ -91,12 +90,12 @@ const DownloadObservationForm: React.FC<DownloadObservationFormProps> = ({ isOpe
} else {
setIsError(true);
setShowHeading(false);
setResponseMessage(JSON.stringify(response.data));
setResponseMessage('Error failed to download Observations');
}
} catch (error) {
setIsError(true);
setShowHeading(false);
setResponseMessage(error.message);
setResponseMessage('Error failed to download Observations');
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ const ScoreForm: React.FC<ScoreFormProps> = ({ onCancel, additionalData, setSide
const parsedState = JSON.parse(storedState);
const user_email = parsedState.userData.email;
const user_level = await axios.get(
`${globalVariables.baseUrl}/authentication/api/user-profile/is-expert/${user_email}`
`${globalVariables.baseUrl}/authentication/api/user-profile/is-expert/${user_email}/`
);

if(user_level.data.is_expert){
Expand Down
82 changes: 43 additions & 39 deletions django_project/monitor/observation_views.py
Original file line number Diff line number Diff line change
@@ -1,70 +1,59 @@
# Standard library imports
import json
import multiprocessing
from queue import Queue
import os
from queue import Queue
from datetime import datetime
from decimal import Decimal
import botocore

# dependencies for ai score calculations
# Third-party dependencies
import numpy as np
import tensorflow as tf
from tensorflow import keras
from PIL import Image
import botocore
from minio import Minio
from minio.error import S3Error

# Django imports
from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from django.contrib.gis.geos import Point
from django.core.exceptions import PermissionDenied
from django.core.exceptions import ValidationError
from django.core.exceptions import PermissionDenied, ValidationError
from django.db import transaction
from django.db.models import Max
from django.http import Http404
from django.http import JsonResponse
from django.http import Http404, JsonResponse
from django.shortcuts import get_object_or_404
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from minio import Minio
from minio.error import S3Error
from rest_framework import generics, mixins

# Django REST framework imports
from rest_framework import generics, mixins, status
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import GenericViewSet
from tensorflow import keras
from django.contrib.auth.models import User
from rest_framework import status


# Project-specific imports (minisass and monitor)
from minisass.models import GroupScores
from minisass.utils import get_s3_client
from minisass_authentication.models import UserProfile
from minisass_authentication.permissions import IsAuthenticatedOrWhitelisted
from monitor.models import (
Observations, Sites, SiteImage, ObservationPestImage
Observations, Sites, SiteImage, ObservationPestImage
)
from monitor.serializers import (
ObservationsSerializer,
ObservationPestImageSerializer,
ObservationsAllFieldsSerializer
ObservationsSerializer,
ObservationPestImageSerializer,
ObservationsAllFieldsSerializer
)



def clear_tensorflow_session():
tf.keras.backend.clear_session()


def get_observations_by_site(request, site_id, format=None):
try:
site = Sites.objects.get(gid=site_id)
observations = Observations.objects.filter(site=site)
serializer = ObservationsAllFieldsSerializer(observations, many=True)

return JsonResponse({'status': 'success', 'observations': serializer.data})

except Sites.DoesNotExist as e:
return JsonResponse({'status': 'error', 'message': 'Site does not exist'}, status=404)


# Use environment variables for Minio configuration
minio_access_key = settings.MINIO_ACCESS_KEY
minio_secret_key = settings.MINIO_SECRET_KEY
Expand All @@ -89,6 +78,18 @@ def get_observations_by_site(request, site_id, format=None):
]


def get_observations_by_site(request, site_id, format=None):
try:
site = Sites.objects.get(gid=site_id)
observations = Observations.objects.filter(site=site)
serializer = ObservationsAllFieldsSerializer(observations, many=True)

return JsonResponse({'status': 'success', 'observations': serializer.data})

except Sites.DoesNotExist as e:
return JsonResponse({'status': 'error', 'message': 'Site does not exist'}, status=404)


def retrieve_file_from_minio(file_name):
try:
minio_client = Minio(
Expand All @@ -97,7 +98,6 @@ def retrieve_file_from_minio(file_name):
secret_key=minio_secret_key,
secure=secure_connection
)

# Download the file from Minio
file_path = os.path.join(
settings.MINIO_ROOT, settings.MINIO_BUCKET, file_name)
Expand Down Expand Up @@ -130,8 +130,6 @@ def retrieve_file_from_minio(file_name):
else:
model = None

# section for ai score calculations
# TODO move this into seperate file


def classify_image(image):
Expand Down Expand Up @@ -590,11 +588,17 @@ class ObservationImageViewSet(
serializer_class = ObservationPestImageSerializer

def get_queryset(self):
"""Return queryset."""
observation = get_object_or_404(
Observations, pk=self.kwargs['observation_pk']
)
return observation.observationpestimage_set.all()
"""Return queryset."""
# Short-circuit during schema generation for Swagger
if getattr(self, 'swagger_fake_view', False):
return ObservationPestImage.objects.none()

observation_pk = self.kwargs.get('observation_pk')
if not observation_pk:
raise ValueError("Missing 'observation_pk' in URL")

observation = get_object_or_404(Observations, pk=observation_pk)
return observation.observationpestimage_set.all()

def destroy(self, request, *args, **kwargs):
# TODO:
Expand Down
23 changes: 14 additions & 9 deletions django_project/monitor/site_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,19 @@
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from monitor.models import SiteImage, Sites, Assessment, Observations, ObservationPestImage
from monitor.models import (
SiteImage,
Sites,
Assessment,
Observations,
ObservationPestImage
)
from django.contrib.gis.measure import D
from rest_framework.parsers import MultiPartParser, FormParser, JSONParser
from rest_framework.parsers import (
MultiPartParser,
FormParser,
JSONParser
)
from minisass.models import GroupScores
from django.utils.dateparse import parse_date
from drf_yasg.utils import swagger_auto_schema
Expand All @@ -26,9 +36,7 @@ class SaveObservationImagesView(generics.CreateAPIView):
serializer_class = ObservationPestImageSerializer

def create(self, request, *args, **kwargs):
# Extract site ID from the URL
observation_id = kwargs.get('observationId')

try:
observation_id = int(observation_id)
except ValueError:
Expand Down Expand Up @@ -61,9 +69,7 @@ class SaveSiteImagesView(generics.CreateAPIView):
serializer_class = SiteImageSerializer

def create(self, request, *args, **kwargs):
# Extract site ID from the URL
site_id = kwargs.get('site_id')

try:
site_id = int(site_id)
except ValueError:
Expand Down Expand Up @@ -117,9 +123,7 @@ def list(self, request):
return Response(serializer.data)

def create(self, request, *args, **kwargs):
# Get the highest gid value
highest_gid = Sites.objects.latest('gid').gid if Sites.objects.exists() else 0
# Increment the gid value
new_gid = highest_gid + 1

# Extract data from the request payload
Expand Down Expand Up @@ -260,7 +264,8 @@ class SitesWithObservationsView(APIView):
}
),
400: openapi.Response(description="Invalid date format"),
}
},
tags=['Sites with Observations']
)
def get(self, request):
start_date_str = request.query_params.get('start_date', None)
Expand Down

0 comments on commit f83b9f9

Please sign in to comment.