You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by ma...@apache.org on 2017/09/14 14:21:29 UTC
[4/4] airavata-django-portal git commit: Using ViewSet for project
REST API mappings
Using ViewSet for project REST API mappings
Project: http://git-wip-us.apache.org/repos/asf/airavata-django-portal/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata-django-portal/commit/4253233f
Tree: http://git-wip-us.apache.org/repos/asf/airavata-django-portal/tree/4253233f
Diff: http://git-wip-us.apache.org/repos/asf/airavata-django-portal/diff/4253233f
Branch: refs/heads/master
Commit: 4253233ffe87928781cde0da90f1c2c8aa361e9e
Parents: c10a85d
Author: Marcus Christie <ma...@iu.edu>
Authored: Thu Sep 14 10:21:09 2017 -0400
Committer: Marcus Christie <ma...@iu.edu>
Committed: Thu Sep 14 10:21:09 2017 -0400
----------------------------------------------------------------------
django_airavata/apps/api/serializers.py | 7 +-
django_airavata/apps/api/urls.py | 11 ++-
django_airavata/apps/api/views.py | 110 +++++++++++++++++++--------
django_airavata/apps/workspace/views.py | 2 +-
4 files changed, 92 insertions(+), 38 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/4253233f/django_airavata/apps/api/serializers.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/api/serializers.py b/django_airavata/apps/api/serializers.py
index 4a56838..d13b718 100644
--- a/django_airavata/apps/api/serializers.py
+++ b/django_airavata/apps/api/serializers.py
@@ -42,6 +42,7 @@ class GatewayIdDefaultField(serializers.CharField):
self.default = settings.GATEWAY_ID
class ProjectSerializer(serializers.Serializer):
+ url = FullyEncodedHyperlinkedIdentityField(view_name='project-detail', lookup_field='projectID', lookup_url_kwarg='pk')
projectID = serializers.CharField(read_only=True)
name = serializers.CharField(required=True)
description = serializers.CharField(required=False)
@@ -53,7 +54,9 @@ class ProjectSerializer(serializers.Serializer):
return Project(**validated_data)
def update(self, instance, validated_data):
- raise Exception("Not implemented")
+ instance.name = validated_data.get('name', instance.name)
+ instance.description = validated_data.get('description', instance.description)
+ return instance
def get_username(self):
return self.context.request.user.username
@@ -62,7 +65,7 @@ class ExperimentSerializer(serializers.Serializer):
experimentId = serializers.CharField(read_only=True)
projectId = serializers.CharField(required=True)
- project = FullyEncodedHyperlinkedIdentityField(view_name='api_project_detail', lookup_field='projectId', lookup_url_kwarg='project_id')
+ project = FullyEncodedHyperlinkedIdentityField(view_name='project-detail', lookup_field='projectId', lookup_url_kwarg='project_id')
gatewayId = GatewayIdDefaultField()
experimentType = serializers.CharField(required=True)
userName = GatewayUsernameDefaultField()
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/4253233f/django_airavata/apps/api/urls.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/api/urls.py b/django_airavata/apps/api/urls.py
index 9cd7d75..544c07b 100644
--- a/django_airavata/apps/api/urls.py
+++ b/django_airavata/apps/api/urls.py
@@ -1,17 +1,22 @@
from . import views
-from django.conf.urls import url
+from django.conf.urls import include, url
+from rest_framework import routers
from rest_framework.urlpatterns import format_suffix_patterns
+router = routers.SimpleRouter()
+router.register(r'projects', views.ProjectViewSet, base_name='project')
+
urlpatterns = [
url(r'^$', views.api_root),
- url(r'^projects/$', views.ProjectList.as_view(), name='api_project_list'),
+ # url(r'^projects/$', views.ProjectList.as_view(), name='api_project_list'),
# More specific, longer URLs should come before less specific, shorter ones
# since the regular expression for project_id allows any character, even '/'
url(r'^projects/(?P<project_id>.+)/experiments/$', views.ProjectExperimentList.as_view(), name='api_project_experiments_list'),
- url(r'^projects/(?P<project_id>.+)/$', views.ProjectDetail.as_view(), name='api_project_detail'),
+ # url(r'^projects/(?P<project_id>.+)/$', views.ProjectDetail.as_view(), name='api_project_detail'),
url(r'^experiments/$', views.ExperimentList.as_view(), name='api_experiment_list'),
+ url(r'^', include(router.urls)),
]
urlpatterns = format_suffix_patterns(urlpatterns)
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/4253233f/django_airavata/apps/api/views.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/api/views.py b/django_airavata/apps/api/views.py
index 0d0a052..2de3ba8 100644
--- a/django_airavata/apps/api/views.py
+++ b/django_airavata/apps/api/views.py
@@ -1,14 +1,15 @@
from . import serializers
-from rest_framework import status
+from rest_framework import status, mixins
from rest_framework.decorators import api_view
from rest_framework.views import APIView
+from rest_framework.viewsets import GenericViewSet
from rest_framework.response import Response
from rest_framework.reverse import reverse
from django.conf import settings
-from django.http import JsonResponse
+from django.http import JsonResponse, Http404
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
@@ -16,42 +17,87 @@ from django.views.decorators.csrf import csrf_exempt
@api_view(['GET'])
def api_root(request, format=None):
return Response({
- 'projects': reverse('api_project_list', request=request, format=format),
+ 'projects': reverse('project-list', request=request, format=format),
'experiments': reverse('api_experiment_list', request=request, format=format)
})
-class ProjectList(APIView):
- def get(self, request, format=None):
- gateway_id = settings.GATEWAY_ID
- username = request.user.username
+class GenericAPIBackedViewSet(GenericViewSet):
- projects = request.airavata_client.getUserProjects(request.authz_token, gateway_id, username, -1, 0)
- serializer = serializers.ProjectSerializer(projects, many=True, context={'request': request})
- return Response(serializer.data)
+ def get_list(self):
+ """
+ Subclasses must implement.
+ """
+ raise NotImplementedError()
- def post(self, request, format=None):
- gateway_id = settings.GATEWAY_ID
- username = request.user.username
- serializer = serializers.ProjectSerializer(data=request.data, context={'request': request})
- if serializer.is_valid():
- project = serializer.create(serializer.validated_data)
- project_id = request.airavata_client.createProject(request.authz_token, gateway_id, project)
- project.projectID = project_id
- serializer = serializers.ProjectSerializer(project, context={'request': request})
- return Response(serializer.data, status=status.HTTP_201_CREATED)
- else:
- return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
-
-class ProjectDetail(APIView):
- def get(self, request, project_id, format=None):
- gateway_id = settings.GATEWAY_ID
- username = request.user.username
+ def get_instance(self, lookup_value):
+ """
+ Subclasses must implement.
+ """
+ raise NotImplementedError()
+
+ def get_queryset(self):
+ return self.get_list()
+
+ def get_object(self):
+ lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
+ lookup_value = self.kwargs[lookup_url_kwarg]
+ inst = self.get_instance(lookup_value)
+ if inst is None:
+ raise Http404
+ self.check_object_permissions(self.request, inst)
+ return inst
+
+ @property
+ def username(self):
+ return self.request.user.username
+
+ @property
+ def gateway_id(self):
+ return settings.GATEWAY_ID
+
+ @property
+ def authz_token(self):
+ return self.request.authz_token
+
+class CreateUpdateRetrieveListViewSet(mixins.CreateModelMixin,
+ mixins.RetrieveModelMixin,
+ mixins.UpdateModelMixin,
+ mixins.DestroyModelMixin,
+ mixins.ListModelMixin,
+ GenericAPIBackedViewSet):
+ """
+ A viewset that provides default `create()`, `retrieve()`, `update()`,
+ `partial_update()` and `list()` actions.
+
+ Subclasses must implement the following:
+ * get_list(self)
+ * get_instance(self, lookup_value)
+ * perform_create(self, serializer) - should return instance with id populated
+ * perform_update(self, serializer)
+ """
+ pass
+
+
+class ProjectViewSet(CreateUpdateRetrieveListViewSet):
+
+ serializer_class = serializers.ProjectSerializer
+
+ def get_list(self):
+ # TODO: support pagination
+ return self.request.airavata_client.getUserProjects(self.authz_token, self.gateway_id, self.username, -1, 0)
+
+ def get_instance(self, lookup_value):
+ return self.request.airavata_client.getProject(self.authz_token, lookup_value)
+
+ def perform_create(self, serializer):
+ project = serializer.save()
+ project_id = self.request.airavata_client.createProject(self.authz_token, self.gateway_id, project)
+ project.projectID = project_id
+
+ def perform_update(self, serializer):
+ project = serializer.save()
+ self.request.airavata_client.updateProject(self.authz_token, project.projectID, project)
- print(project_id)
- project = request.airavata_client.getProject(request.authz_token, project_id)
- serializer = serializers.ProjectSerializer(project, context={'request': request})
- return Response(serializer.data)
- # TODO: add project update (PUT)
class ExperimentList(APIView):
def get(self, request, format=None):
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/4253233f/django_airavata/apps/workspace/views.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/workspace/views.py b/django_airavata/apps/workspace/views.py
index 4e8b4bd..6967f25 100644
--- a/django_airavata/apps/workspace/views.py
+++ b/django_airavata/apps/workspace/views.py
@@ -1,5 +1,5 @@
-from django_airavata.apps.api.views import ProjectList
+from django_airavata.apps.api.views import ProjectViewSet
from rest_framework.renderers import JSONRenderer
from django.conf import settings
from django.contrib.auth.decorators import login_required