Last active
December 15, 2015 05:59
-
-
Save stestagg/5212720 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import functools | |
import flask | |
import inspect | |
import sys | |
import traceback | |
def infer_args(func): | |
argspec = inspect.getargspec(func) | |
if argspec.defaults is None: | |
defaults = {} | |
else: | |
defaults = dict((d for d in zip(reversed(argspec.args), argspec.defaults))) | |
return dict((a, str) for a in argspec.args), defaults | |
class Api(object): | |
def __init__(self, name, mod_name, prefix=None, description=None, **kwargs): | |
if prefix is None: | |
prefix = "/%s" % name | |
self.description = description | |
self.name = name | |
self.url_prefix = prefix | |
self.app = flask.Blueprint(name, mod_name, url_prefix=prefix, **kwargs) | |
self.endpoints = {} | |
def endpoint(self, endpoint_name, types=None, data_key="data", defaults=None): | |
def annotate(func): | |
args, actual_defaults = infer_args(func) | |
if types is not None: | |
args.update(types) | |
if defaults is not None: | |
actual_defaults = defaults | |
@functools.wraps(func) | |
def endpoint(): | |
try: | |
view_args = actual_defaults.copy() | |
for key, value in flask.request.values.iteritems(): | |
view_args[key] = args[key](value) | |
return flask.jsonify({"success": True, data_key: func(**view_args)}) | |
except Exception, e: | |
rv = {"success": False} | |
if isinstance(e, (KeyError, )): | |
rv["message"] = "Item not Found: %s" % e.message | |
else: | |
rv["message"] = str(e.message or "Unknown Error") | |
print >>sys.stderr, traceback.format_exc() | |
rv["traceback"] = traceback.format_exc() | |
response = flask.jsonify(rv) | |
response.status_code = getattr(e, "code", 500) | |
flask.request.log("ERROR", "error", "Error with %s: '%r'", | |
flask.request.path, e) | |
return response | |
self.endpoints[endpoint_name] = (args, data_key, actual_defaults, func.__doc__ or "") | |
self.app.route("/%s" % endpoint_name, methods=("GET", "POST"))(endpoint) | |
return func | |
return annotate |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import path.to.api | |
api = path.to.api.Api("usage", __name__, description="Example") | |
@api.endpoint("add") | |
def add_numbers(a, b, c=0): | |
return a+b+c | |
# wget http://server:5000/usage/add?a=1&b=2 | |
# wget http://server:5000/usage/add?a=1&b=2&c=3 | |
# | |
# OR | |
# | |
# import usage | |
# usage.add_numbers(1, 2) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment