From d6d4cd1ec02e041316582cc51dfbfdaba1c690c1 Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Fri, 18 May 2012 00:44:46 -0400 Subject: [PATCH] Experimenting with ActiveResource client against a non-ARes server --- ares/app.py | 152 +++++++++++++++++++++++++++++++++++++++++++++++++ ares/person.rb | 16 ++++++ 2 files changed, 168 insertions(+) create mode 100644 ares/app.py create mode 100644 ares/person.rb diff --git a/ares/app.py b/ares/app.py new file mode 100644 index 0000000..03d601f --- /dev/null +++ b/ares/app.py @@ -0,0 +1,152 @@ +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.rb b/ares/person.rb new file mode 100644 index 0000000..252e345 --- /dev/null +++ b/ares/person.rb @@ -0,0 +1,16 @@ +require 'active_resource' +require 'awesome_print' + +class Person < ActiveResource::Base + self.site = 'http://localhost:9282' +end + +def main + Person.all.each do |person| + ap person + end +end + +if $0 == __FILE__ + main +end