support versioned apis

This commit is contained in:
j 2012-07-07 18:51:46 +02:00
parent 9c7b985295
commit a4271fd81a
3 changed files with 35 additions and 14 deletions

View file

@ -50,6 +50,7 @@ def trim(docstring):
class ApiActions(dict): class ApiActions(dict):
properties = {} properties = {}
versions = {}
def __init__(self): def __init__(self):
def api(request): def api(request):
@ -79,34 +80,51 @@ class ApiActions(dict):
data = json.loads(request.POST.get('data', '{}')) data = json.loads(request.POST.get('data', '{}'))
docs = data.get('docs', False) docs = data.get('docs', False)
code = data.get('code', False) code = data.get('code', False)
_actions = self.keys() version = getattr(request, 'version', None)
if version:
_actions = self.versions.get(version, {}).keys()
_actions = list(set(_actions + self.keys()))
else:
_actions = self.keys()
_actions.sort() _actions.sort()
actions = {} actions = {}
for a in _actions: for a in _actions:
actions[a] = self.properties[a] actions[a] = self.properties[a]
if docs: if docs:
actions[a]['doc'] = self.doc(a) actions[a]['doc'] = self.doc(a, version)
if code: if code:
actions[a]['code'] = self.code(a) actions[a]['code'] = self.code(a, version)
response = json_response({'actions': actions}) response = json_response({'actions': actions})
return render_to_json_response(response) return render_to_json_response(response)
self.register(api) self.register(api)
def doc(self, f): def doc(self, name, version=None):
return trim(self[f].__doc__) if version:
f = self.versions[version].get(name, self.get(name))
else:
f = self[name]
return trim(f.__doc__)
def code(self, name): def code(self, name, version=None):
f = self[name] if version:
f = self.versions[version].get(name, self.get(name))
else:
f = self[name]
if name != 'api' and hasattr(f, 'func_closure') and f.func_closure: if name != 'api' and hasattr(f, 'func_closure') and f.func_closure:
f = f.func_closure[0].cell_contents f = f.func_closure[0].cell_contents
info = f.func_code.co_filename[len(settings.PROJECT_ROOT)+1:] info = f.func_code.co_filename[len(settings.PROJECT_ROOT)+1:]
info = u'%s:%s' % (info, f.func_code.co_firstlineno) info = u'%s:%s' % (info, f.func_code.co_firstlineno)
return info, trim(inspect.getsource(f)) return info, trim(inspect.getsource(f))
def register(self, method, action=None, cache=True): def register(self, method, action=None, cache=True, version=None):
if not action: if not action:
action = method.func_name action = method.func_name
self[action] = method if version:
if not version in self.versions:
self.versions[version] = {}
self.versions[version][action] = method
else:
self[action] = method
self.properties[action] = {'cache': cache} self.properties[action] = {'cache': cache}
def unregister(self, action): def unregister(self, action):

View file

@ -25,14 +25,17 @@ def api(request):
context = RequestContext(request, {'api': api, context = RequestContext(request, {'api': api,
'sitename': settings.SITENAME}) 'sitename': settings.SITENAME})
return render_to_response('api.html', context) return render_to_response('api.html', context)
function = request.POST['action'] action = request.POST['action']
version = getattr(request, 'version', None)
f = actions.get(function) if version:
f = actions.versions.get(version, {}).get(action, actions.get(action))
else:
f = actions.get(action)
if f: if f:
response = f(request) response = f(request)
else: else:
response = render_to_json_response(json_response(status=400, response = render_to_json_response(json_response(status=400,
text='Unknown function %s' % function)) text='Unknown action %s' % action))
response['Access-Control-Allow-Origin'] = '*' response['Access-Control-Allow-Origin'] = '*'
return response return response

View file

@ -27,7 +27,7 @@ def render_to_json_response(dictionary, content_type="text/json", status=200):
if settings.DEBUG: if settings.DEBUG:
content_type = "text/javascript" content_type = "text/javascript"
indent = 2 indent = 2
if settings.JSON_DEBUG: if getattr(settings, 'JSON_DEBUG', False):
print json.dumps(dictionary, indent=2, default=_to_json) print json.dumps(dictionary, indent=2, default=_to_json)
return HttpResponse(json.dumps(dictionary, indent=indent, default=_to_json), return HttpResponse(json.dumps(dictionary, indent=indent, default=_to_json),