This is an automated email from the ASF dual-hosted git repository.

yasithdev pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airavata-portals.git


The following commit(s) were added to refs/heads/main by this push:
     new 92a14564a feat(portal): repoint experiment search to gRPC (Track D, 
D2) (#163)
92a14564a is described below

commit 92a14564ad64bfa05d6ab52024e31b4fbf41898d
Author: Yasith Jayawardana <[email protected]>
AuthorDate: Mon Jun 8 18:46:47 2026 -0400

    feat(portal): repoint experiment search to gRPC (Track D, D2) (#163)
    
    ExperimentSearchViewSet.get_list now calls request.airavata.research.
    search_experiments instead of the Thrift searchExperiments; filters are 
passed
    as the gRPC map<string,string> keyed by ExperimentSearchFields member name 
(the
    query-param key already is one). grpc_adapters.experiment_summary maps the
    ExperimentSummaryModel protobuf to the Thrift attribute shape the serializer
    reads (clean 1:1; experiment_status is a plain string in both). The 
serializer's
    userHasWriteAccess moves to the gRPC sharing helper.
    
    Validated end-to-end against the running backend with a Bearer token:
    GET /api/experiment-search/ -> 200 paginated; and the sibling /api/projects/
    returns a real seeded project with all fields, correct timestamp, working
    hyperlinks, and userHasWriteAccess=true (gRPC sharing).
---
 .../django_airavata/apps/api/grpc_adapters.py           | 17 +++++++++++++++++
 .../django_airavata/apps/api/serializers.py             |  5 +----
 .../django_airavata/apps/api/views.py                   | 17 +++++++++--------
 3 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/airavata-django-portal/django_airavata/apps/api/grpc_adapters.py 
b/airavata-django-portal/django_airavata/apps/api/grpc_adapters.py
index 5255f2c68..dd4280f49 100644
--- a/airavata-django-portal/django_airavata/apps/api/grpc_adapters.py
+++ b/airavata-django-portal/django_airavata/apps/api/grpc_adapters.py
@@ -38,3 +38,20 @@ def application_module(pb):
         appModuleVersion=pb.app_module_version,
         appModuleDescription=pb.app_module_description,
     )
+
+
+def experiment_summary(pb):
+    """gRPC ``ExperimentSummaryModel`` protobuf -> 
``ExperimentSummarySerializer`` shape."""
+    return SimpleNamespace(
+        experimentId=pb.experiment_id,
+        projectId=pb.project_id,
+        gatewayId=pb.gateway_id,
+        creationTime=pb.creation_time or None,
+        userName=pb.user_name,
+        name=pb.name,
+        description=pb.description,
+        executionId=pb.execution_id,
+        resourceHostId=pb.resource_host_id,
+        experimentStatus=pb.experiment_status,
+        statusUpdateTime=pb.status_update_time or None,
+    )
diff --git a/airavata-django-portal/django_airavata/apps/api/serializers.py 
b/airavata-django-portal/django_airavata/apps/api/serializers.py
index 658612f7b..0a45162c3 100644
--- a/airavata-django-portal/django_airavata/apps/api/serializers.py
+++ b/airavata-django-portal/django_airavata/apps/api/serializers.py
@@ -734,10 +734,7 @@ class 
ExperimentSummarySerializer(BaseExperimentSummarySerializer):
     userHasWriteAccess = serializers.SerializerMethodField()
 
     def get_userHasWriteAccess(self, experiment):
-        request = self.context['request']
-        return request.airavata_client.userHasAccess(
-            request.authz_token, experiment.experimentId,
-            ResourcePermissionType.WRITE)
+        return user_has_access(self.context['request'], 
experiment.experimentId)
 
 
 class UserProfileSerializer(
diff --git a/airavata-django-portal/django_airavata/apps/api/views.py 
b/airavata-django-portal/django_airavata/apps/api/views.py
index 728631f6a..431d95d1b 100644
--- a/airavata-django-portal/django_airavata/apps/api/views.py
+++ b/airavata-django-portal/django_airavata/apps/api/views.py
@@ -315,18 +315,19 @@ class ExperimentSearchViewSet(mixins.ListModelMixin, 
GenericAPIBackedViewSet):
     def get_list(self):
         view = self
 
+        # gRPC SearchExperiments takes filters as a map<string, string> keyed 
by
+        # ExperimentSearchFields member name (the query-param key already is 
one).
         filters = {}
-        for filter_item in self.request.query_params.items():
-            if filter_item[0] in ExperimentSearchFields.__members__:
-                # Lookup enum value for this ExperimentSearchFields
-                search_field = ExperimentSearchFields[filter_item[0]]
-                filters[search_field] = filter_item[1]
+        for key, value in self.request.query_params.items():
+            if key in ExperimentSearchFields.__members__:
+                filters[key] = value
 
         class ExperimentSearchResultIterator(APIResultIterator):
             def get_results(self, limit=-1, offset=0):
-                return view.request.airavata_client.searchExperiments(
-                    view.authz_token, view.gateway_id, view.username, filters,
-                    limit, offset)
+                summaries = view.request.airavata.research.search_experiments(
+                    gateway_id=view.gateway_id, user_name=view.username,
+                    filters=filters, limit=limit, offset=offset)
+                return [grpc_adapters.experiment_summary(s) for s in summaries]
 
         # Preserve query parameters when moving to next and previous links
         return 
ExperimentSearchResultIterator(query_params=self.request.query_params.copy())

Reply via email to