def wsgi_app(environ, start_response, enable_static=False): if environ['REQUEST_METHOD'] == 'OPTIONS': # This is to hanle the preflight request for CORS. # See https://developer.mozilla.org/en/http_access_control response = Response() response.status = "200 OK" else: params = extract_params(environ) log('------') path = environ['PATH_INFO'].split(environ['HTTP_HOST'])[-1] if BASE_PATH: path = path.split(BASE_PATH)[1] log(path) try: if '/pico/' in path: path = path.replace('/pico/', '/') try: response = handle_api_v1(path, params, environ) except APIError: try: response = handle_pico_js(path, params) except APIError: try: response = handle_api_v2(path, params, environ) except APIError: response = not_found_error(path) elif enable_static: try: response = static_file_handler(path) except OSError, e: response = not_found_error(path) else:
def call(params, request): func = params.get('_function', '') module_name = params.get('_module', '') args = {} for k in params.keys(): if not (k.startswith('_') or k.startswith('pico_')): params[k] = params[k] try: args[k] = json.loads(params[k]) except Exception: try: args[k] = json.loads(params[k].replace("'", '"')) except Exception: args[k] = params[k] callback = params.get('_callback', None) init_args = json.loads(params.get('_init', '[]')) class_name = params.get('_class', None) usecache = json.loads(params.get('_usecache', 'true')) x_session_id = params.get('_x_session_id', None) if x_session_id: request['X-SESSION-ID'] = x_session_id response = Response() if usecache and os.path.exists(CACHE_PATH): try: response = serve_file(CACHE_PATH + cache_key(params)) log("Serving from cache") except OSError: pass if not response.content: module = pico.modules.load(module_name, RELOAD) json_loaders = getattr(module, "json_loaders", []) from_json = lambda s: pico.from_json(s, json_loaders) for k in args: args[k] = from_json(args[k]) if class_name: init_args = map(from_json, init_args) response = call_method(module, class_name, func, args, init_args) else: response = call_function(module, func, args) response.json_dumpers = getattr(module, "json_dumpers", {}) log(usecache, response.cacheable) if usecache and response.cacheable: log("Saving to cache") try: os.stat(CACHE_PATH) except Exception: os.mkdir(CACHE_PATH) f = open(CACHE_PATH + cache_key(params) + '.json', 'w') out = response.output if hasattr(out, 'read'): out = out.read() response.output.seek(0) else: out = out[0] f.write(out) f.close() response.callback = callback return response
def serve_file(file_path): response = Response() size = os.path.getsize(file_path) mimetype = mimetypes.guess_type(file_path) response.set_header("Content-type", mimetype[0] or 'text/plain') response.set_header("Content-length", str(size)) response.set_header("Cache-Control", 'public, max-age=22222222') response.content = open(file_path, 'rb') response.type = "file" return response
def generate_exception_report(e, path, params): response = Response() full_tb = traceback.extract_tb(sys.exc_info()[2]) tb_str = '' for tb in full_tb: tb_str += "File '%s', line %s, in %s; " % (tb[0], tb[1], tb[2]) report = {} report['exception'] = str(e) report['traceback'] = tb_str report['url'] = path.replace('/pico/', '/') report['params'] = dict([(k, _value_summary(params[k])) for k in params]) log(json.dumps(report, indent=1)) response.content = report response.status = '500 ' + str(e) return response
def call_function(module, function_name, parameters): try: f = getattr(module, function_name) except AttributeError: raise Exception("No matching function availble. " "You asked for %s with these parameters %s!" % (function_name, parameters)) results = f(**parameters) response = Response(content=results) if hasattr(f, 'cacheable') and f.cacheable: response.cacheable = True if hasattr(f, 'stream') and f.stream and STREAMING: response.type = "stream" elif response.content.__class__.__name__ == 'generator': response.type = "chunks" return response
def call_function(module, function_name, parameters): try: f = getattr(module, function_name) except AttributeError: raise Exception("No matching function availble. " "You asked for %s with these parameters %s!" % ( function_name, parameters)) results = f(**parameters) response = Response(content=results) if hasattr(f, 'cacheable') and f.cacheable: response.cacheable = True if hasattr(f, 'stream') and f.stream and STREAMING: response.type = "stream" elif response.content.__class__.__name__ == 'generator': response.type = "chunks" return response
def wsgi_app(self, environ, start_response, enable_static=False): if environ['REQUEST_METHOD'] == 'OPTIONS': # This is to hanle the preflight request for CORS. # See https://developer.mozilla.org/en/http_access_control response = Response() response.status = "200 OK" else: params = self.extract_params(environ) self.log('------') path = environ['PATH_INFO'].split(environ['HTTP_HOST'])[-1] if BASE_PATH: path = path.split(BASE_PATH)[1] self.log(path) path = path.replace('/pico/', '/') try: response = self.handle_api_v2(path, params, environ) except PicoError, e: response = e.response except False, e: response = self.generate_exception_report(e, path, params)
def not_found_error(path): response = Response() response.status = '404 NOT FOUND' response.content = '404 File not found' response.type = 'plaintext' return response
def serve_file(file_path): response = Response() fs = os.stat(file_path) mimetype = mimetypes.guess_type(file_path) response.set_header("Content-length", str(fs.st_size)) if file_path.endswith('.manifest'): response.set_header("Content-type", 'text/cache-manifest') response.set_header("Expires", 'access') else: response.set_header("Content-type", mimetype[0] or 'text/plain') response.set_header("Last-Modified", date_time_string(fs.st_mtime)) response.content = open(file_path, 'rb') response.type = "file" return response