Mercurial > hg > GlobalNeighbors
diff globalneighbors/web.py @ 0:5dba84370182
initial commit; half-working prototype
author | Jeff Hammel <k0scist@gmail.com> |
---|---|
date | Sat, 24 Jun 2017 12:03:39 -0700 |
parents | |
children | 1b94f3bf97e5 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/globalneighbors/web.py Sat Jun 24 12:03:39 2017 -0700 @@ -0,0 +1,124 @@ +#!/usr/bin/env python + +""" +web handler for GlobalNeighbors +""" + +# imports +import argparse +import json +import sys +import time +from webob import Request, Response, exc +from wsgiref import simple_server +from .locations import locations +from .locations import city_dict +from .read import read_cities +from .read import read_city_list +from .schema import fields +from .schema import name + + +class Handler(object): + """base class for HTTP handler""" + + def __call__(self, environ, start_response): + request = Request(environ) + method = getattr(self, request.method, None) + response = None + if method is not None: + response = method(request) + if response is None: + response = exc.HTTPNotFound() + return response(environ, start_response) + + +class CitiesHandler(Handler): + """cities ReST API""" + + content_type = 'application/json' + + def __init__(self, locations, cities): + self.locations = locations + self._cities = cities + + + def cities(self, startswith=None): + """return list of cities""" + + if startswith: + return sorted([i[name] for i in self._cities + if i[name].startswith(startswith)]) + else: + return sorted([i[name] for i in self._cities]) + + def GET(self, request): + return Response(content_type=self.content_type, + body=json.dumps(self.cities( + startswith=request.GET.get('q')))) + + +class GlobalHandler(Handler): + """WSGI HTTP Handler""" + + content_type = 'text/plain' + + def __init__(self, datafile): + self.datafile = datafile + + # parse data + self.cities = read_city_list(self.datafile, + fields=fields) + self.locations = locations(self.cities) + + # TODO: declare handlers + self.handlers = {'/cities': + CitiesHandler(self.locations, + self.cities)} + + + def GET(self, request): + if request.path_info in ('', '/'): + # Landing page + return Response(content_type=self.content_type, + body="""Global Neighbors + Serving {} cities""".format(len(self.cities))) + else: + handler = self.handlers.get(request.path_info) + if handler: + return request.get_response(handler) + + + +def main(args=sys.argv[1:]): + """CLI""" + + # parse command line + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('cities', + help="cities1000 data file") + parser.add_argument('-p', '--port', dest='port', + type=int, default=8080, + help="port to serve on") + parser.add_argument('--hostname', dest='hostname', + default='localhost', + help="host name [DEFAULT: %(default)]") + options = parser.parse_args(args) + + # instantiate WSGI handler + app = GlobalHandler(datafile=options.cities) + + # serve it (Warning! Single threaded!) + server = simple_server.make_server(host='0.0.0.0', + port=options.port, + app=app) + try: + print ("Serving on http://{hostname}:{port}/".format(**options.__dict__)) + server.serve_forever() + except KeyboardInterrupt: + pass + + +if __name__ == '__main__': + main() +