[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#824912: tracker.d.o: add an API for action items



Raphael Hertzog <hertzog@debian.org> writes:

Hello,

thx for detailed answers. i'm attaching a new set of patches trying to
include what we discussed.

> If you contribute regularly, I would certainly welcome if you had
> your own repository that I can merge from. That said I like to
> have patches by email so that I can review and comment just by
> reading and responding.

Good. So i mirrored the repo and you can find the specific branch where
i'm working atm here:

https://gitlab.com/efkin/distro-tracker/commits/api

> You could have access to the repository on alioth.debian.org,
> but you would need to join the qa project. I'm not opposed to that
> but I would rather wait until you have contributed a bit more
> and until I know you a bit more as well.

I think it's not strictly necessary after the mirror setup. But i'm happy in
the future to keep collaborating regularly with this project. Let see
how starts next year and i'll know better too.


> Cheers,
> -- 
> Raphaël Hertzog ◈ Debian Developer
>
> Support Debian LTS: http://www.freexian.com/services/debian-lts.html
> Learn to master Debian: http://debian-handbook.info/get/

Cheers,


-- 
efkin.

>From 5874f6a104700011f52b1f15f60c4a2be168e90b Mon Sep 17 00:00:00 2001
From: efkin <efkin@riseup.net>
Date: Wed, 14 Dec 2016 13:04:52 +0100
Subject: [PATCH 1/3] Include rest_framework dependency

---
 distro_tracker/project/settings/defaults.py | 1 +
 docs/setup/setup.rst                        | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/distro_tracker/project/settings/defaults.py b/distro_tracker/project/settings/defaults.py
index ad7defd..0f27309 100644
--- a/distro_tracker/project/settings/defaults.py
+++ b/distro_tracker/project/settings/defaults.py
@@ -249,6 +249,7 @@ INSTALLED_APPS = (
     'django.contrib.staticfiles',
     'django.contrib.admin',
     'django_email_accounts',
+    'rest_framework',
     'distro_tracker.html',
     'distro_tracker.core',
     'distro_tracker.accounts',
diff --git a/docs/setup/setup.rst b/docs/setup/setup.rst
index dad9ac0..0728dbd 100644
--- a/docs/setup/setup.rst
+++ b/docs/setup/setup.rst
@@ -15,6 +15,7 @@ Distro Tracker currently depends on the following Debian packages:
 - python-django-jsonfield (>= 1.0.0)
 - python-django-debug-toolbar (in development mode only)
 - python-django-captcha (optional)
+- python-djangorestframework
 - python-debian
 - python-apt
 - python-gpgme
@@ -35,7 +36,7 @@ For Python2.7, the following additional packages are required:
 
 Here is the list of required packages for development on Debian Jessie::
 
- $ sudo apt install python-django python-requests python-django-jsonfield python-django-debug-toolbar python-debian python-apt python-gpgme python-yaml python-bs4 python-soappy python-ldap python-pyinotify python-tox python-mock python-lzma python-selenium python3-django python3-requests python3-django-jsonfield python3-django-debug-toolbar python3-debian python3-apt python3-gpgme python3-yaml python3-bs4 python3-pyinotify python3-selenium chromium chromedriver
+ $ sudo apt install python-django python-requests python-django-jsonfield python-django-debug-toolbar python-debian python-apt python-gpgme python-yaml python-bs4 python-soappy python-ldap python-pyinotify python-tox python-mock python-lzma python-selenium python-djangorestframework python3-django python3-requests python3-django-jsonfield python3-djangorestframework python3-django-debug-toolbar python3-debian python3-apt python3-gpgme python3-yaml python3-bs4 python3-pyinotify python3-selenium chromium chromedriver
 
 .. _database_setup:
 
-- 
2.1.4

>From 5373c50f253922f00502715e8a34e8de7a0b9216 Mon Sep 17 00:00:00 2001
From: efkin <efkin@riseup.net>
Date: Wed, 14 Dec 2016 13:14:35 +0100
Subject: [PATCH 2/3] Create distro_tracker submodule for API development

---
 distro_tracker/api/__init__.py              | 0
 distro_tracker/api/tests.py                 | 3 +++
 distro_tracker/api/views.py                 | 3 +++
 distro_tracker/project/settings/defaults.py | 1 +
 4 files changed, 7 insertions(+)
 create mode 100644 distro_tracker/api/__init__.py
 create mode 100644 distro_tracker/api/tests.py
 create mode 100644 distro_tracker/api/views.py

diff --git a/distro_tracker/api/__init__.py b/distro_tracker/api/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/distro_tracker/api/tests.py b/distro_tracker/api/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/distro_tracker/api/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/distro_tracker/api/views.py b/distro_tracker/api/views.py
new file mode 100644
index 0000000..91ea44a
--- /dev/null
+++ b/distro_tracker/api/views.py
@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.
diff --git a/distro_tracker/project/settings/defaults.py b/distro_tracker/project/settings/defaults.py
index 0f27309..0d42a37 100644
--- a/distro_tracker/project/settings/defaults.py
+++ b/distro_tracker/project/settings/defaults.py
@@ -250,6 +250,7 @@ INSTALLED_APPS = (
     'django.contrib.admin',
     'django_email_accounts',
     'rest_framework',
+    'distro_tracker.api',
     'distro_tracker.html',
     'distro_tracker.core',
     'distro_tracker.accounts',
-- 
2.1.4

>From e4336cb0549d1aae395de328dafb8f2f209400a5 Mon Sep 17 00:00:00 2001
From: efkin <efkin@riseup.net>
Date: Wed, 14 Dec 2016 18:45:09 +0100
Subject: [PATCH 3/3] Create basic API list/detail endpoint for ActionItem
 model instances

Reported_by: pabs@debian.org
---
 distro_tracker/api/tests.py    | 95 +++++++++++++++++++++++++++++++++++++++++-
 distro_tracker/api/views.py    | 42 ++++++++++++++++++-
 distro_tracker/project/urls.py |  8 ++++
 3 files changed, 141 insertions(+), 4 deletions(-)

diff --git a/distro_tracker/api/tests.py b/distro_tracker/api/tests.py
index 7ce503c..7c53110 100644
--- a/distro_tracker/api/tests.py
+++ b/distro_tracker/api/tests.py
@@ -1,3 +1,94 @@
-from django.test import TestCase
+from django.core.urlresolvers import reverse
 
-# Create your tests here.
+from rest_framework import status
+from rest_framework.test import APITestCase
+
+from distro_tracker.core.models import ActionItem
+from distro_tracker.core.models import ActionItemType
+from distro_tracker.core.models import SourcePackageName
+
+
+class ActionItemListAPIViewTest(APITestCase):
+    """
+    Test for the :class:`distro_tracker.api.views.ActionItemListAPIView`.
+    """
+
+    def setUp(self):
+        self.url = reverse('dtracker-api-v1-action-items')
+        
+    def test_empty_list(self):
+        """
+        Test when the queryset is empty.
+        """
+        response = self.client.get(self.url)
+        self.assertEqual(response.status_code, status.HTTP_200_OK)
+        self.assertEqual(
+            0,
+            response.data['count'],
+        )
+
+    def test_account_item(self):
+        """
+        Test with actual content.
+        """
+        package = SourcePackageName.objects.create(name='dummy-package')
+        action_type = ActionItemType.objects.create(
+            type_name='test',
+            full_description_template='action-item-test.html',
+        )
+        action_item = ActionItem.objects.create(
+            package=package,
+            item_type=action_type,
+            short_description="Short description of item",
+        )
+        response = self.client.get(self.url)
+        self.assertEqual(response.status_code, status.HTTP_200_OK)
+        self.assertEqual(
+            1,
+            response.data['count'],
+        )
+        result = response.data['results'][0]
+        self.assertEqual(
+            'dummy-package',
+            result['package_name'],
+        )
+
+        
+class ActionItemDetailAPIViewTest(APITestCase):
+    """
+    Test for the :class:`distro_tracker.api.views.ActionItemDetailAPIView`.
+    """
+
+    def setUp(self):
+        self.url = reverse('dtracker-api-v1-action-items', kwargs={'pk':1})
+
+    def test_404_on_non_existing_pk(self):
+        """
+        Test when the pk does not return any instance.
+        """
+        response = self.client.get(self.url)
+
+        self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
+        
+    def test_existing_instance(self):
+        """
+        Test when the pk does return an actual instance.
+        """
+        package = SourcePackageName.objects.create(name='dummy-package')
+        action_type = ActionItemType.objects.create(
+            type_name='test',
+            full_description_template='action-item-test.html',
+        )
+        action_item = ActionItem.objects.create(
+            package=package,
+            item_type=action_type,
+            short_description="Short description of item",
+        )
+        response = self.client.get(self.url)
+        self.assertEqual(response.status_code, status.HTTP_200_OK)
+        self.assertEqual(
+            'dummy-package',
+            response.data['package_name'],
+        )
+
+        
diff --git a/distro_tracker/api/views.py b/distro_tracker/api/views.py
index 91ea44a..62b5f37 100644
--- a/distro_tracker/api/views.py
+++ b/distro_tracker/api/views.py
@@ -1,3 +1,41 @@
-from django.shortcuts import render
+from django.http import Http404
 
-# Create your views here.
+from rest_framework import status
+from rest_framework import generics
+from rest_framework.response import Response
+
+from distro_tracker.api.serializers import ActionItemSerializer
+from distro_tracker.core.models import ActionItem
+
+
+class ActionItemListAPIView(generics.ListAPIView):
+    """
+    List all ActionItem instances.
+    """
+
+    serializer_class = ActionItemSerializer
+
+    # this next block assume DRF 2.X (as in debian stable)
+    # and assume pagination will break with DRF 3.X
+    paginate_by = 100
+    paginate_by_param = 'page_size'
+    max_paginate_by = 500
+    
+    def get_queryset(self):
+        queryset = ActionItem.objects.all()
+        package_name = self.request.GET.get('package_name', None)
+        if package_name is not None:
+            queryset = queryset.filter(package__name=package_name)
+        return queryset
+
+
+class ActionItemDetailAPIView(generics.RetrieveAPIView):
+    """
+    Retrieve an ActionItem instance.
+    """
+
+    queryset = ActionItem.objects.all()
+    serializer_class = ActionItemSerializer
+    
+    
+    
diff --git a/distro_tracker/project/urls.py b/distro_tracker/project/urls.py
index 5a5b091..3a29e10 100644
--- a/distro_tracker/project/urls.py
+++ b/distro_tracker/project/urls.py
@@ -67,6 +67,7 @@ from distro_tracker.accounts.views import PasswordChangeView
 from distro_tracker.accounts.views import ModifyKeywordsView
 from distro_tracker.accounts.views import AccountMergeConfirmView
 from distro_tracker.accounts.views import AccountMergeConfirmedView
+from distro_tracker.api import views as api_views
 
 from django.contrib import admin
 admin.autodiscover()
@@ -229,6 +230,13 @@ urlpatterns = [
     url(r'^pkg/(?P<package_name>.+)/rss$', PackageNewsFeed(),
         name='dtracker-package-rss-news-feed'),
 
+    # API v1
+    url(r'^api/v1/action-items/?$',
+        api_views.ActionItemListAPIView.as_view(),
+        name='dtracker-api-v1-action-items'),
+    url(r'^api/v1/action-items/(?P<pk>[0-9]+)/?$',
+        api_views.ActionItemDetailAPIView.as_view(),
+        name='dtracker-api-v1-action-items'),
     # Uncomment the admin/doc line below to enable admin documentation:
     # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
 ]
-- 
2.1.4


Reply to: