From 627390c596c2488d9d0a93aa9eba984f27d13e8b Mon Sep 17 00:00:00 2001 From: Daniel Perrefort Date: Wed, 4 Dec 2024 19:32:31 +0000 Subject: [PATCH] Adds `_search` query parameter (#493) * Enables search backend * Defines searchable fields * Updates openapi spec --------- Co-authored-by: Nickolas Comeau --- docs/api.yml | 78 ++++++++++++++++++++ keystone_api/apps/allocations/views.py | 5 ++ keystone_api/apps/logging/views.py | 3 + keystone_api/apps/research_products/views.py | 2 + keystone_api/apps/users/admin.py | 1 + keystone_api/apps/users/views.py | 2 + keystone_api/main/settings.py | 5 +- 7 files changed, 94 insertions(+), 2 deletions(-) diff --git a/docs/api.yml b/docs/api.yml index 2cb788e2..382f107b 100644 --- a/docs/api.yml +++ b/docs/api.yml @@ -46,6 +46,12 @@ paths: operationId: allocations_allocations_list description: Manage HPC resource allocations. parameters: + - name: _search + required: false + in: query + description: A search term. + schema: + type: string - in: query name: awarded schema: @@ -372,6 +378,12 @@ paths: operationId: allocations_attachments_list description: Files submitted as attachments to allocation requests parameters: + - name: _search + required: false + in: query + description: A search term. + schema: + type: string - in: query name: id schema: @@ -653,6 +665,12 @@ paths: operationId: allocations_clusters_list description: Configuration settings for managed Slurm clusters. parameters: + - name: _search + required: false + in: query + description: A search term. + schema: + type: string - in: query name: description schema: @@ -921,6 +939,12 @@ paths: operationId: allocations_requests_list description: Manage allocation requests. parameters: + - name: _search + required: false + in: query + description: A search term. + schema: + type: string - in: query name: active schema: @@ -1422,6 +1446,12 @@ paths: operationId: allocations_reviews_list description: Manage administrator reviews of allocation requests. parameters: + - name: _search + required: false + in: query + description: A search term. + schema: + type: string - in: query name: id schema: @@ -1934,6 +1964,12 @@ paths: operationId: logs_apps_list description: Returns application log data. parameters: + - name: _search + required: false + in: query + description: A search term. + schema: + type: string - in: query name: func schema: @@ -2293,6 +2329,12 @@ paths: operationId: logs_requests_list description: Returns HTTP request log data. parameters: + - name: _search + required: false + in: query + description: A search term. + schema: + type: string - in: query name: body_request schema: @@ -2640,6 +2682,12 @@ paths: operationId: logs_tasks_list description: Returns results from scheduled background tasks. parameters: + - name: _search + required: false + in: query + description: A search term. + schema: + type: string - in: query name: content_encoding schema: @@ -3230,6 +3278,12 @@ paths: operationId: research_grants_list description: Track funding awards and grant information. parameters: + - name: _search + required: false + in: query + description: A search term. + schema: + type: string - in: query name: agency schema: @@ -3711,6 +3765,12 @@ paths: operationId: research_publications_list description: Manage metadata for research publications. parameters: + - name: _search + required: false + in: query + description: A search term. + schema: + type: string - in: query name: abstract schema: @@ -4096,6 +4156,12 @@ paths: operationId: users_membership_list description: Manage team membership. parameters: + - name: _search + required: false + in: query + description: A search term. + schema: + type: string - in: query name: id schema: @@ -4378,6 +4444,12 @@ paths: operationId: users_teams_list description: Manage user teams. parameters: + - name: _search + required: false + in: query + description: A search term. + schema: + type: string - in: query name: id schema: @@ -4617,6 +4689,12 @@ paths: operationId: users_users_list description: Manage user account data. parameters: + - name: _search + required: false + in: query + description: A search term. + schema: + type: string - in: query name: date_joined schema: diff --git a/keystone_api/apps/allocations/views.py b/keystone_api/apps/allocations/views.py index 43e75a9c..a8311575 100644 --- a/keystone_api/apps/allocations/views.py +++ b/keystone_api/apps/allocations/views.py @@ -42,6 +42,7 @@ class AllocationRequestViewSet(viewsets.ModelViewSet): queryset = AllocationRequest.objects.all() serializer_class = AllocationRequestSerializer + search_fields = ['title', 'description', 'team__name'] permission_classes = [permissions.IsAuthenticated, TeamAdminCreateMemberRead] def get_queryset(self) -> list[AllocationRequest]: @@ -71,6 +72,7 @@ class AllocationReviewViewSet(viewsets.ModelViewSet): queryset = AllocationReview.objects.all() serializer_class = AllocationReviewSerializer + search_fields = ['public_comments', 'private_comments', 'request__team__name', 'request__title'] permission_classes = [permissions.IsAuthenticated, StaffWriteMemberRead] def get_queryset(self) -> list[Allocation]: @@ -101,6 +103,7 @@ class AllocationViewSet(viewsets.ModelViewSet): queryset = Allocation.objects.all() serializer_class = AllocationSerializer + search_fields = ['request__team__name', 'request__title', 'cluster__name'] permission_classes = [permissions.IsAuthenticated, StaffWriteMemberRead] def get_queryset(self) -> list[Allocation]: @@ -118,6 +121,7 @@ class AttachmentViewSet(viewsets.ModelViewSet): queryset = Attachment.objects.all() serializer_class = AttachmentSerializer + search_fields = ['path', 'request__title', 'request__submitter'] permission_classes = [permissions.IsAuthenticated, StaffWriteMemberRead] def get_queryset(self) -> list[Allocation]: @@ -135,4 +139,5 @@ class ClusterViewSet(viewsets.ModelViewSet): queryset = Cluster.objects.all() serializer_class = ClusterSerializer + search_fields = ['name', 'description'] permission_classes = [permissions.IsAuthenticated, StaffWriteAuthenticatedRead] diff --git a/keystone_api/apps/logging/views.py b/keystone_api/apps/logging/views.py index e6f70387..220c8514 100644 --- a/keystone_api/apps/logging/views.py +++ b/keystone_api/apps/logging/views.py @@ -17,6 +17,7 @@ class AppLogViewSet(viewsets.ReadOnlyModelViewSet): queryset = AppLog.objects.all() serializer_class = AppLogSerializer + search_fields = ['name', 'level', 'pathname', 'message', 'func', 'sinfo'] permission_classes = [permissions.IsAuthenticated, permissions.IsAdminUser] @@ -25,6 +26,7 @@ class RequestLogViewSet(viewsets.ReadOnlyModelViewSet): queryset = RequestLog.objects.all() serializer_class = RequestLogSerializer + search_fields = ['endpoint', 'method', 'response_code', 'body_request', 'body_response', 'remote_address'] permission_classes = [permissions.IsAuthenticated, permissions.IsAdminUser] @@ -33,4 +35,5 @@ class TaskResultViewSet(viewsets.ReadOnlyModelViewSet): queryset = TaskResult.objects.all() serializer_class = TaskResultSerializer + search_fields = ['periodic_task_name', 'task_name', 'status', 'worker', 'result', 'traceback'] permission_classes = [permissions.IsAuthenticated, permissions.IsAdminUser] diff --git a/keystone_api/apps/research_products/views.py b/keystone_api/apps/research_products/views.py index 28098c45..05bb71d5 100644 --- a/keystone_api/apps/research_products/views.py +++ b/keystone_api/apps/research_products/views.py @@ -18,6 +18,7 @@ class PublicationViewSet(viewsets.ModelViewSet): queryset = Publication.objects.all() serializer_class = PublicationSerializer + search_fields = ['title', 'abstract', 'journal', 'doi', 'team__name'] permission_classes = [ permissions.IsAuthenticated, permissions.IsAdminUser | TeamMemberAll @@ -37,6 +38,7 @@ class GrantViewSet(viewsets.ModelViewSet): queryset = Grant.objects.all() serializer_class = GrantSerializer + search_fields = ['title', 'agency', 'team__name'] permission_classes = [ permissions.IsAuthenticated, permissions.IsAdminUser | TeamMemberReadTeamAdminWrite diff --git a/keystone_api/apps/users/admin.py b/keystone_api/apps/users/admin.py index edde2b42..28bd947a 100644 --- a/keystone_api/apps/users/admin.py +++ b/keystone_api/apps/users/admin.py @@ -38,6 +38,7 @@ def deactivate_selected_users(self, request, queryset) -> None: readonly_fields = ("last_login", "date_joined", "is_ldap_user") actions = [activate_selected_users, deactivate_selected_users] + search_fields = ['username', 'first_name', 'last_name', 'email', 'department', 'role'] fieldsets = ( ("User Info", {"fields": ("first_name", "last_name", "email", "department", "role", "last_login", "date_joined", 'is_ldap_user')}), ("Credentials", {"fields": ("username", "password")}), diff --git a/keystone_api/apps/users/views.py b/keystone_api/apps/users/views.py index 0321f880..003ab8e3 100644 --- a/keystone_api/apps/users/views.py +++ b/keystone_api/apps/users/views.py @@ -28,6 +28,7 @@ class TeamViewSet(viewsets.ModelViewSet): queryset = Team.objects.all() permission_classes = [TeamPermissions] serializer_class = TeamSerializer + search_fields = ['name'] class TeamMembershipRoleChoicesView(APIView): @@ -55,6 +56,7 @@ class UserViewSet(viewsets.ModelViewSet): queryset = User.objects.all() permission_classes = [UserPermissions] + search_fields = ['username', 'first_name', 'last_name', 'email', 'department', 'role'] def get_serializer_class(self) -> type[Serializer]: """Return the appropriate data serializer based on user roles/permissions.""" diff --git a/keystone_api/main/settings.py b/keystone_api/main/settings.py index 7c56f550..3e7ae7e5 100644 --- a/keystone_api/main/settings.py +++ b/keystone_api/main/settings.py @@ -178,9 +178,10 @@ ], 'DEFAULT_FILTER_BACKENDS': ( 'plugins.filter.AdvancedFilterBackend', - 'rest_framework.filters.OrderingFilter' - + 'rest_framework.filters.OrderingFilter', + 'rest_framework.filters.SearchFilter' ), + 'SEARCH_PARAM': '_search', 'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema', }