diff --git a/ares/app.py b/ares/app.py deleted file mode 100644 index 03d601f..0000000 --- a/ares/app.py +++ /dev/null @@ -1,152 +0,0 @@ -from __future__ import print_function - -import json -import re -import sys - -from pprint import pformat -from traceback import print_exc -from wsgiref.simple_server import make_server - - -class PersonModel(object): - __people__ = [ - { - 'name': { - 'first': 'Hammy', - 'last': 'Spammy', - }, - 'age': 42, - 'id': 1, - }, - { - 'name': { - 'first': 'Sampers', - 'last': 'Dancer', - }, - 'age': 38, - 'id': 2 - }, - ] - - def __init__(self): - self._index() - - def _index(self): - self.__people_by_id__ = dict(((p['id'], p) for p in self.__people__)) - - def getall(self): - return self.__people__ - - def get(self, person_id): - return self.__people_by_id__[person_id] - - def add(self, person): - person['id'] = len(self.__people__) + 1 - self.__people__.append(person) - self._index() - return person['id'] - - -class PersonApp(object): - __routes__ = [ - (_m, _k, re.compile('^{}$'.format(_k)), _v) for _m, _k, _v in ( - ('GET', '/people.json', 'all'), - ('POST', '/people.json', 'new'), - ('GET', '/people/(.*)\.json', 'get'), - ('GET', '/', 'echo') - ) - ] - - def __init__(self): - self.people = PersonModel() - print('Routes = {}'.format(pformat(self.__routes__))) - - def __call__(self, environ, start_response): - path = '/' + environ.get('PATH_INFO', '').lstrip('/') - request_method = environ.get('REQUEST_METHOD', 'GET') - - environ.update({ - 'app.path': path, - 'app.request_method': request_method, - }) - - method_name = 'not_found' - for route_req_method, route, route_re, route_method in self.__routes__: - if route_req_method == request_method: - match = route_re.match(path) - if match: - print('Found match: {!r}'.format(match.re.pattern)) - environ['app.route_match'] = match - method_name = route_method - break - - try: - return getattr(self, method_name)(environ, start_response) - except AttributeError, exc: - print_exc() - return self.not_found(environ, start_response) - - def not_found(self, environ, start_response): - print('Nothing matched: {} {!r}'.format( - environ['app.request_method'], environ['app.path'] - )) - return self._return_json( - start_response, {'error': 'Not Found'}, - status='404 Not Found' - ) - - def bad_request(self, environ, start_response): - return self._return_json( - start_response, {'error': 'Bad Request'}, - status='400 Bad Request' - ) - - def get(self, environ, start_response): - person_id = environ['app.route_match'].group(1) - if not person_id.isdigit(): - return self.bad_request(environ, start_response) - - person = self.people.get(int(person_id)) - return self._return_json(start_response, {'person': person}) - - def all(self, environ, start_response): - return self._return_json(start_response, self.people.getall()) - - def new(self, environ, start_response): - person = json.loads( - environ['wsgi.input'].read(int(environ['CONTENT_LENGTH'])) - ) - person_id = self.people.add(person) - return self._return_json( - start_response, {}, status='201 Created', - extra_headers=[ - ('location', '/people/{}.json'.format(person_id)) - ] - ) - - def echo(self, environ, start_response): - return self._return_json(start_response, {'here?': 'yup'}) - - def _return_json(self, start_response, json_dict, status='200 OK', - extra_headers=()): - body = json.dumps(json_dict) - start_response(status, [ - ('content-type', 'application/x-json'), - ('content-length', str(len(body))) - ] + list(extra_headers)) - return [body] - - -def main(): - server = make_server('0.0.0.0', 9282, PersonApp()) - try: - print('Serving on 0.0.0.0:9282') - server.serve_forever() - return 1 - except KeyboardInterrupt: - return 0 - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/ares/person_model.py b/ares/person_model.py new file mode 100644 index 0000000..8fe3285 --- /dev/null +++ b/ares/person_model.py @@ -0,0 +1,42 @@ + +class PersonModel(object): + _people = [ + { + 'name': { + 'first': 'Hammy', + 'last': 'Spammy', + }, + 'age': 42, + 'id': 1, + }, + { + 'name': { + 'first': 'Sampers', + 'last': 'Dancer', + }, + 'age': 38, + 'id': 2 + }, + ] + + def __init__(self): + self._index() + + def _index(self): + self._people_by_id = dict(((p['id'], p) for p in self._people)) + + def getall(self): + return self._people + + def get(self, person_id): + return self._people_by_id[person_id] + + def add(self, person): + if None in (person.get('name'), person.get('age')): + raise ValueError('Missing required fields!: {}'.format(person)) + + person['id'] = len(self._people) + 1 + self._people.append(person) + self._index() + return person['id'] + diff --git a/ares/serve b/ares/serve new file mode 100755 index 0000000..16ffa51 --- /dev/null +++ b/ares/serve @@ -0,0 +1,8 @@ +#!/bin/bash +which aspen >/dev/null 2>&1 +if [ $? -ne 0 ]; then + echo "You need to 'pip install aspen'" + exit 1 +fi +cd $(dirname $(readlink -f $0)) +exec aspen -w ./www -a '0.0.0.0:9282' diff --git a/ares/www/people.json b/ares/www/people.json new file mode 100644 index 0000000..ed3983e --- /dev/null +++ b/ares/www/people.json @@ -0,0 +1,20 @@ +import json +from person_model import PersonModel +from aspen import Response + +__people__ = PersonModel() + + + +if GET: + response.body = __people__.getall() +elif POST: + person = json.loads( + request.body.s_iter.read(int(request.headers['Content-Length'])) + )['person'] + person_id = __people__.add(person) + response.headers['Location'] = '/people/{}.json'.format(person_id) + response.body = {} + raise Response(201) + +# vim:filetype=python diff --git a/ares/www/people/%id.json b/ares/www/people/%id.json new file mode 100644 index 0000000..89cd6e0 --- /dev/null +++ b/ares/www/people/%id.json @@ -0,0 +1,6 @@ +from person_model import PersonModel +__people__ = PersonModel() + +response.body = {'person': __people__.get(int(path['id']))} + +# vim:filetype=python