Skip to content

Instantly share code, notes, and snippets.

@craigderington
Last active January 24, 2019 18:44
Show Gist options
  • Save craigderington/fe7e79515a4ec31f65ab079dbe51f8b6 to your computer and use it in GitHub Desktop.
Save craigderington/fe7e79515a4ec31f65ab079dbe51f8b6 to your computer and use it in GitHub Desktop.
Things API reworked with Responder
import responder
import random
import logging
import uuid
from datetime import datetime
from marshmallow import Schema, fields
api = responder.API(
title="ThingsAPI",
version="1.0",
openapi="3.0.0",
docs_route="/docs"
)
class StorageEngine(object):
"""
Local Things Storage
:return db
"""
def get_things(self, limit, marker):
return [{'id': str(uuid.uuid4()), 'color': 'orange'}]
def add_thing(self, thing):
thing['id'] = str(uuid.uuid4())
return thing
class StorageError(Exception):
"""
Exception to handle things database storage errors
"""
@staticmethod
def handle(ex, req, resp, params):
description = "Sorry, could not write your thing to the database..."
logging.critical('The database can not be reached.')
return None
class SinkAdapter(object):
"""
Allow calls to an external web service
"""
engines = {
'ddd': 'https://duckduckgo.com',
'yyy': 'https://search.yahoo.com'
}
def __call__(self, req, resp, engine):
url = self.engines[engine]
params = {'q': req.get_param('q', True)}
result = api.requests.get(url, params=params)
resp.status_code = result.status_code
resp.content_type = result.headers['content-type']
resp.body = result.text
def max_body(limit):
"""
Check max post body and limit
:param limit:
:return: req.content
"""
async def check_body(req, resp, resource, params):
length = req.content_length
if length is not None and length > limit:
msg = ('The size of the request is too large. The body must not '
'exceed {} bytes in length.'.format(str(limit)))
raise AssertionError('{}'.format(msg))
return check_body
class Thing(object):
"""
Thing class instance
"""
def __init__(self, id, color):
self.id = id
self.color = color
class ThingSchema(Schema):
"""
Thing schema
"""
id = fields.Integer()
color = fields.Str()
class ThingsResource(object):
"""
Things API Resource
"""
def __init__(self, db):
self.db = db
self.logger = logging.getLogger('thingsapp.' + __name__)
async def on_get(self, req, resp, user_id):
marker = req.get_param('marker') or ''
limit = req.get_param('limit') or 50
try:
things = self.db.get_things(marker, limit)
schema = ThingsSchema()
except Exception as ex:
self.logger.error(ex)
resp.context['result'] = schema.dump(things)
resp.set_header('Powered-By', 'responder')
resp.status_code = api.status_codes.HTTP_200
return resp
@api.before_requests(max_body(64 * 1024))
async def on_post(self, req, resp, user_id):
try:
doc = req.context['doc']
except KeyError as key_err:
self.logger.error(key_err)
proper_thing = self.db.add_thing(doc)
resp.status_code = api.status_codes.HTTP_201
resp.location = '{}/things/{}'.format(
user_id, proper_thing['id']
)
return resp
db = StorageEngine()
things = ThingsResource(db)
api.add_route('/{user_id}/things', things)
if __name__ == '__main__':
api.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment