def json_api(request, model, function, format=None): if format is None: format = 'json' vars = dict((str(k),v) for k, v in request.REQUEST.iteritems()) vars.update(dict((str(k), v) for k, v in request.FILES.iteritems())) if format == 'jsonp': if 'callback' in request.REQUEST: callback = request.REQUEST['callback'] del vars['callback'] else: return CerealResponse({'error': '"callback" parameter required for json-p'}, 200, 'json').http() if '_' in vars: del vars['_'] # jQuery's cache=false parameter else: callback=None if model not in cereal.funcs or function not in cereal.funcs[model]: return CerealResponse({'error': 'Service not found'}, 404, format, callback).http() #TODO: probably a cleaner way than doing this twice. if request.method == 'GET' and hasattr(cereal.funcs[model][function], 'cache_time'): vars_list = vars.items() vars_list.sort(key = lambda item: item[0]) cache_key = '.'.join(['cereal', model, function, format, urlencode(vars_list)]) cached = cache.get(cache_key) if cached and isinstance(cached, HttpResponse): return cached elif cached: return CerealResponse.from_cache(cached).http(format = format, callback = callback) try: cereal_response = cereal.call_with(model, function, vars, request) if not isinstance(cereal_response, (HttpResponse, CerealResponse)): cereal_response = CerealResponse(cereal_response) except Http404: cereal_response = CerealResponse({'error': 'Service not found'}, 404) except cereal.IncorrectArgumentsError, err: cereal_response = CerealResponse({'error': 'Incorrect arguments', 'message': str(err)}, 403)