HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Simple REST API server

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
serverrestsimpleapi

Problem

This is a chunk of code I wrote for a job interview at some point - it is a remote key-value storage REST API supporting CRUD operations.

Maybe anyone has some feedback on this? It would be very helpful for me.

I did not attach the tests, since it might be a little bit too much code. You don't have to review both files - even commenting on just one can be extremely helpful.

remotekvs.py

```
# -- test-case-name: tests.remotekvs_test.RemoteKVSTest --

import json
import inspect

from twisted.internet import reactor
from twisted.web.resource import Resource
from twisted.web.server import Site

from keyvaluestorage import KeyValueStorage

class RemoteKVSResource(Resource):
"""
This is a Twisted Resource object used to serve requests for
KeyValueStorage operations. It supports POST, GET, PUT and DELETE
request methods and replies in JSON.
"""
isLeaf = True

def __init__(self):
self.kvs = KeyValueStorage()

def render(self, request):
operations = {
'POST': 'create',
'GET': 'read',
'PUT': 'update',
'DELETE': 'delete'}
if request.method in operations.keys():
response = {
'success': True}
try:
operation = getattr(self.kvs, operations[request.method])
args = {k: v[0] if isinstance(v, list) else v
for k, v in request.args.items()}
result = operation(**(args))
if result is not None:
response['result'] = result
except (TypeError, KeyValueStorage.KeyAlreadyExistsError,
KeyValueStorage.InvalidKeyError), exception:
response['success'] = False
response['error'] = exception.__class__.__name__
if isinstance(exception, TypeError):
response['error_message'] = (
"Valid request parameters: %s." % (

Solution

I'd write the error handling this way:

def render(self, request):
    operations = {
        'POST': 'create',
        'GET': 'read',
        'PUT': 'update',
        'DELETE': 'delete',
    }
    if request.method not in operations:
        response = {
            'success': False,
            'error': 'InvalidRequestMethod',
            'error_message': ("Valid request methods: %s" % (', '.join(operations.keys()))),
        }
        request.setResponseCode(http.NOT_ALLOWED)
    else:
        response = {'success': True}
        ...
    return json.dumps(response)


Note the changes:

  • Since the error handler is simpler than the main processing code, put it first to get it out of the way.



  • if request.method not in operations reads better than if request.method not in operations.keys() and might be slightly more efficient.



  • Reuse operations.keys() for the error message.



  • Set HTTP status 405 ("Method Not Allowed"). (The constant is in twisted.web.http.)



In KeyValueStorage, I suggest raising the standard KeyError instead of making your own exception classes.

Code Snippets

def render(self, request):
    operations = {
        'POST': 'create',
        'GET': 'read',
        'PUT': 'update',
        'DELETE': 'delete',
    }
    if request.method not in operations:
        response = {
            'success': False,
            'error': 'InvalidRequestMethod',
            'error_message': ("Valid request methods: %s" % (', '.join(operations.keys()))),
        }
        request.setResponseCode(http.NOT_ALLOWED)
    else:
        response = {'success': True}
        ...
    return json.dumps(response)

Context

StackExchange Code Review Q#45060, answer score: 2

Revisions (0)

No revisions yet.