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 31f7446b0 feat(portal): repoint parser + notification reads to gRPC
(Track D, D2) (#173)
31f7446b0 is described below
commit 31f7446b08fdf0f2342304521983fb6097abedfe
Author: Yasith Jayawardana <[email protected]>
AuthorDate: Mon Jun 8 20:14:05 2026 -0400
feat(portal): repoint parser + notification reads to gRPC (Track D, D2)
(#173)
Migrate ParserViewSet.get_list/get_instance and
ManageNotificationViewSet.get_list/get_instance from the Thrift client to
the gRPC research facade (research.list_all_parsers / get_parser /
get_all_notifications / get_notification). Write actions stay on Thrift
pending D3.
New parser adapter recursively adapts the nested inputFiles (ParserInput)
and outputFiles (ParserOutput); their IOType field renders as a raw int,
bridged by name with the proto IO_TYPE_ prefix stripped. The new
notification adapter bridges priority via the prefix helper too, but
NotificationSerializer renders priority through a ThriftEnumField (the
name), so the adapter produces the Thrift enum member rather than the
int. publishedTime/expirationTime keep their int (non-nullable UTC
fields); creationTime maps proto-zero -> None. userHasWriteAccess on both
is gateway-admin-based (unchanged).
Verified: manage.py check clean; both list endpoints return 200 live;
offline serializer render confirms notification priority renders as the
name ('HIGH') and parser IOType bridges to the correct Thrift int.
---
.../django_airavata/apps/api/grpc_adapters.py | 60 ++++++++++++++++++++++
.../django_airavata/apps/api/views.py | 24 ++++++---
2 files changed, 76 insertions(+), 8 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 7be0311ff..848b3614f 100644
--- a/airavata-django-portal/django_airavata/apps/api/grpc_adapters.py
+++ b/airavata-django-portal/django_airavata/apps/api/grpc_adapters.py
@@ -22,6 +22,7 @@ from airavata.model.appcatalog.groupresourceprofile.ttypes
import (
from airavata.model.appcatalog.parallelism.ttypes import (
ApplicationParallelismType as _ThriftParallelismType,
)
+from airavata.model.appcatalog.parser.ttypes import IOType as _ThriftIOType
from airavata.model.application.io.ttypes import DataType as _ThriftDataType
from airavata.model.credential.store.ttypes import SummaryType as
_ThriftSummaryType
from airavata.model.data.movement.ttypes import (
@@ -37,6 +38,9 @@ from airavata.model.status.ttypes import (
TaskState as _ThriftTaskState,
)
from airavata.model.task.ttypes import TaskTypes as _ThriftTaskTypes
+from airavata.model.workspace.ttypes import (
+ NotificationPriority as _ThriftNotificationPriority,
+)
def _thrift_enum(pb, field, thrift_enum):
@@ -826,3 +830,59 @@ def experiment(pb):
# legacy workflow-engine subsystem not adapted (rarely populated).
workflow=None,
)
+
+
+def notification(pb):
+ """gRPC ``Notification`` -> ``NotificationSerializer`` shape."""
+ return SimpleNamespace(
+ notificationId=pb.notification_id,
+ gatewayId=pb.gateway_id,
+ title=pb.title,
+ notificationMessage=pb.notification_message,
+ creationTime=pb.creation_time or None,
+ # publishedTime/expirationTime use non-nullable UTC fields -> keep int.
+ publishedTime=pb.published_time,
+ expirationTime=pb.expiration_time,
+ # priority renders via ThriftEnumField (the NAME), so produce the
Thrift
+ # member; proto prefixes only the zero UNKNOWN sentinel.
+ priority=_thrift_enum_prefixed(
+ pb, 'priority', _ThriftNotificationPriority,
'NOTIFICATION_PRIORITY_'),
+ )
+
+
+def _parser_input(pb):
+ """gRPC ``ParserInput`` -> auto-generated serializer shape."""
+ return SimpleNamespace(
+ id=pb.id,
+ name=pb.name,
+ requiredInput=pb.required_input,
+ parserId=pb.parser_id,
+ # type (IOType) renders as a raw int; bridge by name (proto
FILE/PROPERTY
+ # align, only IO_TYPE_UNKNOWN is prefixed).
+ type=_thrift_enum_prefixed(pb, 'type', _ThriftIOType, 'IO_TYPE_'),
+ )
+
+
+def _parser_output(pb):
+ """gRPC ``ParserOutput`` -> auto-generated serializer shape."""
+ return SimpleNamespace(
+ id=pb.id,
+ name=pb.name,
+ requiredOutput=pb.required_output,
+ parserId=pb.parser_id,
+ type=_thrift_enum_prefixed(pb, 'type', _ThriftIOType, 'IO_TYPE_'),
+ )
+
+
+def parser(pb):
+ """gRPC ``Parser`` -> ``ParserSerializer`` shape."""
+ return SimpleNamespace(
+ id=pb.id,
+ imageName=pb.image_name,
+ outputDirPath=pb.output_dir_path,
+ inputDirPath=pb.input_dir_path,
+ executionCommand=pb.execution_command,
+ inputFiles=[_parser_input(i) for i in pb.input_files],
+ outputFiles=[_parser_output(o) for o in pb.output_files],
+ gatewayId=pb.gateway_id,
+ )
diff --git a/airavata-django-portal/django_airavata/apps/api/views.py
b/airavata-django-portal/django_airavata/apps/api/views.py
index 5e306c64e..4e7be0ac2 100644
--- a/airavata-django-portal/django_airavata/apps/api/views.py
+++ b/airavata-django-portal/django_airavata/apps/api/views.py
@@ -1549,12 +1549,16 @@ class ParserViewSet(mixins.CreateModelMixin,
lookup_field = 'parser_id'
def get_list(self):
- return self.request.airavata_client.listAllParsers(
- self.authz_token, settings.GATEWAY_ID)
+ return [
+ grpc_adapters.parser(p)
+ for p in self.request.airavata.research.list_all_parsers(
+ settings.GATEWAY_ID)
+ ]
def get_instance(self, lookup_value):
- return self.request.airavata_client.getParser(
- self.authz_token, lookup_value, settings.GATEWAY_ID)
+ return grpc_adapters.parser(
+ self.request.airavata.research.get_parser(
+ lookup_value, settings.GATEWAY_ID))
def perform_create(self, serializer):
parser = serializer.save()
@@ -1724,12 +1728,16 @@ class ManageNotificationViewSet(APIBackedViewSet):
lookup_field = 'notification_id'
def get_instance(self, lookup_value):
- return self.request.airavata_client.getNotification(
- self.authz_token, settings.GATEWAY_ID, lookup_value)
+ return grpc_adapters.notification(
+ self.request.airavata.research.get_notification(
+ settings.GATEWAY_ID, lookup_value))
def get_list(self):
- return self.request.airavata_client.getAllNotifications(
- self.authz_token, self.gateway_id)
+ return [
+ grpc_adapters.notification(n)
+ for n in self.request.airavata.research.get_all_notifications(
+ self.gateway_id)
+ ]
def perform_destroy(self, instance):
self.request.airavata_client.deleteNotification(