Commit 11a48dc9 by Arthur Barrett

replacing lists with namedtuples to improve readability

parent ee1ee26c
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, Http404 from django.http import HttpResponse, Http404
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from notes.models import Note from notes.models import Note
from notes.utils import notes_enabled_for_course from notes.utils import notes_enabled_for_course
from courseware.courses import get_course_with_access from courseware.courses import get_course_with_access
import json import json
import logging import logging
import collections
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
API_SETTINGS = { API_SETTINGS = {
# Version
'META': {'name': 'Notes API', 'version': 1}, 'META': {'name': 'Notes API', 'version': 1},
# Maps resources to HTTP methods and actions # Maps resources to HTTP methods and actions
...@@ -25,6 +27,9 @@ API_SETTINGS = { ...@@ -25,6 +27,9 @@ API_SETTINGS = {
'MAX_NOTE_LIMIT': 1000, 'MAX_NOTE_LIMIT': 1000,
} }
# Wrapper class for HTTP response and data. All API actions are expected to return this.
ApiResponse = collections.namedtuple('ApiResponse', ['http_response', 'data'])
#----------------------------------------------------------------------# #----------------------------------------------------------------------#
# API requests are routed through api_request() using the resource map. # API requests are routed through api_request() using the resource map.
...@@ -72,33 +77,30 @@ def api_request(request, course_id, **kwargs): ...@@ -72,33 +77,30 @@ def api_request(request, course_id, **kwargs):
raise Http404 raise Http404
log.debug('API request: {0} {1}'.format(resource_method, resource_name)) log.debug('API request: {0} {1}'.format(resource_method, resource_name))
result = module[func](request, course_id, **kwargs)
# Format and output the results
data = None
response = result[0]
if len(result) == 2:
data = result[1]
formatted = api_format(request, response, data)
response['Content-type'] = formatted[0]
response.content = formatted[1]
log.debug('API response: {0}'.format(formatted)) api_response = module[func](request, course_id, **kwargs)
http_response = api_format(api_response)
return response return http_response
def api_format(request, response, data): def api_format(api_response):
''' '''
Returns a two-element list containing the content type and content. Takes an ApiResponse and returns an HttpResponse.
''' '''
http_response = api_response.http_response
content_type = 'application/json' content_type = 'application/json'
if data is None: content = ''
content = ''
else: if api_response.data is not None and api_response.data != '':
content = json.dumps(data) content = json.dumps(api_response.data)
return [content_type, content]
http_response['Content-type'] = content_type
http_response.content = content
log.debug('API response type: {0} content: {1}'.format(content_type, content))
return http_response
def _get_course(request, course_id): def _get_course(request, course_id):
...@@ -120,7 +122,7 @@ def index(request, course_id): ...@@ -120,7 +122,7 @@ def index(request, course_id):
notes = Note.objects.order_by('id').filter(course_id=course_id, notes = Note.objects.order_by('id').filter(course_id=course_id,
user=request.user)[:MAX_LIMIT] user=request.user)[:MAX_LIMIT]
return [HttpResponse(), [note.as_dict() for note in notes]] return ApiResponse(http_response=HttpResponse(), data=[note.as_dict() for note in notes])
def create(request, course_id): def create(request, course_id):
...@@ -133,13 +135,13 @@ def create(request, course_id): ...@@ -133,13 +135,13 @@ def create(request, course_id):
note.clean(request.body) note.clean(request.body)
except ValidationError as e: except ValidationError as e:
log.debug(e) log.debug(e)
return [HttpResponse('', status=500), None] return ApiResponse(http_response=HttpResponse('', status=500), data=None)
note.save() note.save()
response = HttpResponse('', status=303) response = HttpResponse('', status=303)
response['Location'] = note.get_absolute_url() response['Location'] = note.get_absolute_url()
return [response, None] return ApiResponse(http_response=response, data=None)
def read(request, course_id, note_id): def read(request, course_id, note_id):
...@@ -149,12 +151,12 @@ def read(request, course_id, note_id): ...@@ -149,12 +151,12 @@ def read(request, course_id, note_id):
try: try:
note = Note.objects.get(id=note_id) note = Note.objects.get(id=note_id)
except: except:
return [HttpResponse('', status=404), None] return ApiResponse(http_response=HttpResponse('', status=404), data=None)
if not note.user.id == request.user.id: if not note.user.id == request.user.id:
return [HttpResponse('', status=403)] return ApiResponse(http_response=HttpResponse('', status=403), data=None)
return [HttpResponse(), note.as_dict()] return ApiResponse(http_response=HttpResponse(), data=note.as_dict())
def update(request, course_id, note_id): def update(request, course_id, note_id):
...@@ -164,23 +166,23 @@ def update(request, course_id, note_id): ...@@ -164,23 +166,23 @@ def update(request, course_id, note_id):
try: try:
note = Note.objects.get(id=note_id) note = Note.objects.get(id=note_id)
except: except:
return [HttpResponse('', status=404), None] return ApiResponse(http_response=HttpResponse('', status=404), data=None)
if not note.user.id == request.user.id: if not note.user.id == request.user.id:
return [HttpResponse('', status=403)] return ApiResponse(http_response=HttpResponse('', status=403), data=None)
try: try:
note.clean(request.body) note.clean(request.body)
except ValidationError as e: except ValidationError as e:
log.debug(e) log.debug(e)
return [HttpResponse('', status=500), None] return ApiResponse(http_response=HttpResponse('', status=500), data=None)
note.save() note.save()
response = HttpResponse('', status=303) response = HttpResponse('', status=303)
response['Location'] = note.get_absolute_url() response['Location'] = note.get_absolute_url()
return [response, None] return ApiResponse(http_response=response, data=None)
def delete(request, course_id, note_id): def delete(request, course_id, note_id):
...@@ -190,14 +192,14 @@ def delete(request, course_id, note_id): ...@@ -190,14 +192,14 @@ def delete(request, course_id, note_id):
try: try:
note = Note.objects.get(id=note_id) note = Note.objects.get(id=note_id)
except: except:
return [HttpResponse('', status=404), None] return ApiResponse(http_response=HttpResponse('', status=404), data=None)
if not note.user.id == request.user.id: if not note.user.id == request.user.id:
return [HttpResponse('', status=403)] return ApiResponse(http_response=HttpResponse('', status=403), data=None)
note.delete() note.delete()
return [HttpResponse('', status=204), None] return ApiResponse(http_response=HttpResponse('', status=204), data=None)
def search(request, course_id): def search(request, course_id):
...@@ -238,11 +240,11 @@ def search(request, course_id): ...@@ -238,11 +240,11 @@ def search(request, course_id):
'rows': [note.as_dict() for note in rows] 'rows': [note.as_dict() for note in rows]
} }
return [HttpResponse(), result] return ApiResponse(http_response=HttpResponse(), data=result)
def root(request, course_id): def root(request, course_id):
''' '''
Returns version information about the API. Returns version information about the API.
''' '''
return [HttpResponse(), API_SETTINGS.get('META')] return ApiResponse(http_response=HttpResponse(), data=API_SETTINGS.get('META'))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment