Mercurial > hg > GlobalNeighbors
view globalneighbors/web.py @ 5:7e27e874655b
test a larger grid + move distance insertion to its own function
author | Jeff Hammel <k0scist@gmail.com> |
---|---|
date | Sat, 24 Jun 2017 15:16:10 -0700 |
parents | 1b94f3bf97e5 |
children | 316e1d54ffd4 |
line wrap: on
line source
#!/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 def autocomplete(cities, startswith=None): """autocomplete function for city names""" ### TODO: sort once, ahead of time if startswith: retval = [] for i in cities: try: if i[name].startswith(startswith): retval.append(i[name]) except Exception as e: import pdb; pdb.set_trace() return sorted(retval) else: return sorted([i[name] for i in cities]) 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""" return autocomplete(self._cities, startswith=startswith) 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()