def __init__(self, httpd_path): self.httpd_path = httpd_path route('/static/<filepath:path>')(self.server_static) route('/')(self.index) route('/device-manager')(self.manage) route('/settings/<addr:int>', method='GET')(self.settings) route('/timers/<addr:int>', method='GET')(self.timers)
def __new__(cls, *args, **kwargs): obj = super(VncApiServer, cls).__new__(cls, *args, **kwargs) bottle.route('/', 'GET', obj.homepage_http_get) for act_res in _ACTION_RESOURCES: method = getattr(obj, act_res['method_name']) bottle.route(act_res['uri'], 'POST', method) return obj
def run_lambda(): if _start_args['all_interfaces'] == True: HOST = '0.0.0.0' else: HOST = _start_args['host'] app = _start_args['app'] # type: btl.Bottle for route_path, route_params in BOTTLE_ROUTES.items(): route_func, route_kwargs = route_params btl.route(path=route_path, callback=route_func, **route_kwargs) if _start_args['ssl_cert'] == False or _start_args['ssl_key'] == False: return btl.run(host=HOST, port=_start_args['port'], server=wbs.GeventWebSocketServer, quiet=True, app=app) else: ssldict = { 'keyfile': _start_args['ssl_key'], 'certfile': _start_args['ssl_cert'] } return btl.run(host=HOST, port=_start_args['port'], server=wbs.GeventWebSocketServer, quiet=True, app=app, **ssldict)
def main(): import sys, os, socket test_root = os.path.dirname(os.path.abspath(__file__)) os.chdir(test_root) sys.path.insert(0, os.path.dirname(test_root)) sys.path.insert(0, test_root) try: server = sys.argv[1] port = int(sys.argv[2]) if server == 'gevent': from gevent import monkey monkey.patch_all() elif server == 'eventlet': import eventlet eventlet.monkey_patch() try: import coverage coverage.process_startup() except ImportError: pass from bottle import route, run route('/test', callback=lambda: 'OK') run(port=port, server=server, quiet=True) except socket.error: sys.exit(3) except ImportError: sys.exit(128) except KeyboardInterrupt: pass
def __init__(self, db): self.db = db route(self.route_user, method='PUT')(self.registerUser) route(self.route_user, method='DELETE')(self.unregisterUser) route(self.route_connect, method='PUT')(self.connectUser) route(self.route_disconnect, method='PUT')(self.disconnectUser) route(self.route_get_connected_list, method='GET')(self.getConnectedUsers)
def routing(obj): """ Set the routes for the app """ for kw in dir(obj): attr = getattr(obj, kw) if hasattr(attr, "route"): route(attr.route)(attr)
def deco(func): def wrapper(**urlargs): fmt = urlargs.pop('fmt') if 'fmt' in urlargs else 'json' if fmt not in ENCODERS: raise Exception('Unsupported encoding') encoder = ENCODERS[fmt] # Handle older bottle versions try: urlargs.update(bottle.request.query) except AttributeError: urlargs.update(bottle.request.GET) if method in ('POST', 'PUT'): data = encoder.decode(bottle.request.body) result = func(data, **urlargs) else: result = func(**urlargs) bottle.response.set_header('Content-Type', encoder.ctype) return encoder.encoder(result) bottle.route(path, method, wrapper, **options) bottle.route(path + '.:fmt', method, wrapper, **options) return func
def init(): """Initialize configuration and web application.""" global app if app: return app bottle.TEMPLATE_PATH.insert(0, conf.TemplatePath) defconfigfile = os.path.join(conf.RootPath, "etc", "%s.ini" % conf.Name) configfile = os.getenv("%sCONF" % conf.Name.upper(), defconfigfile) util.ini_load(configfile, conf) util.init_logger(conf.LogLevel, conf.LogPath, conf.ErrorLogPath, conf.LogFormat, conf.LogExclusions) translate.init(conf.DefaultLanguage, conf.TranslationTemplate, conf.AutoReload) model.init() logger.info("Initializing app, using configuration file %s.", configfile) bottle.route("/<url:path>", unsupported) sys.path.append(conf.RootPath) myapp = bottle.default_app() myapp.get_url = (lambda f: (lambda r, **k: conf.ServerPrefix + f(r, **k)))( myapp.get_url) bottle.BaseTemplate.defaults.update(get_url=myapp.get_url, _=translate.translate) app = beaker.middleware.SessionMiddleware( myapp, { "session.auto": True, # Data saved automatically, without save() "session.data_dir": conf.SessionPath, "session.cookie_expires": False, # Expires on closing browser "session.type": "file", }) return app
def app_cert(): if request.headers["content-type"] == "application/json": body = request.body.read() logger.debug(body) j = json.loads(body) client_cert_pem = base64.b64decode(j["cert"]) # client_addr = j["client_addr"] session_name = j["session_name"] access_url = j["access_url"] else: msg = "content-type must be application/json" logger.error(msg) response.status = 400 return msg client_cert_file = session_name + ".crt" with open(client_cert_file, "wb+") as fd: fd.write(client_cert_pem) route_key = access_url[access_url.rindex("/"):] cert_tab[route_key] = { "cert": base64.b64encode(client_cert_pem).decode("utf-8"), "session_name": session_name } route(route_key, method="POST", callback=responder) return
def runbottle(host='0.0.0.0', port=9278, pthstr='', pathprefix=''): global datadir uplog("runbottle: version %s host %s port %d pthstr %s pathprefix %s" % (bottle.__version__, host, port, pthstr, pathprefix)) datadir = os.path.dirname(__file__) datadir = os.path.join(datadir, 'bottle') bottle.TEMPLATE_PATH = (os.path.join(datadir, 'views'), ) # All the file urls must be like /some/prefix/path where # /some/prefix must be in the path translation map (which I'm not # sure what the use of is). By default the map is an identical # translation of all topdirs entries. We create one route for each # prefix. As I don't know how a bottle method can retrieve the # route it was called from, we create a callable for each prefix. # Each route is built on the translation input, and the processor # uses the translated path as root lpth = pthstr.split(',') for ptt in lpth: l = ptt.split(':') rt = l[0] if rt[-1] != '/': rt += '/' rt += '<filepath:path>' uplog("runbottle: adding route for: %s" % rt) # We build the streamer with the translated streamer = Streamer(l[1]) bottle.route(rt, 'GET', streamer) bottle.run(server='waitress', host=host, port=port)
def setup_webserver(self): bottle.route('/')(bottle.view('index')(self.index)) bottle.post('/clear_log')(self.clear_log) bottle.post('/config')(self.config) bottle.post('/function/<function_id>')(self.function) bottle.run(host='0.0.0.0', port=8080)
def routeapp(obj): for kw in dir(obj): attr = getattr(obj, kw) if hasattr(attr, 'routes'): for route in attr.routes: if hasattr(attr, 'method'): method = getattr(attr, 'method') else: method = 'GET' if hasattr(attr, 'callback'): callback = getattr(attr, 'callback') else: callback = None if hasattr(attr, 'name'): name = getattr(attr, 'name') else: name = None if hasattr(attr, 'apply'): aply = getattr(attr, 'apply') else: aply = None if hasattr(attr, 'skip'): skip = getattr(attr, 'skip') else: skip = None bottle.route(route, method, callback, name, aply, skip)(attr)
def __init__(self, app, manager): self.app = app self.highlight = Highlight() self.manager = manager route("/json", "GET", self.api_index) self.manager.add_api_route( "GET /test/<test variable>", """A test route. Doesn't actually exist, just here for illustration purposes. """) self.manager.add_api_route( "GET /json", """<p> The list of routes in JSON format. You could use this for service or capability discovery, for example. </p> <div class="ui horizontal icon divider"> <i class="circular code icon"></i> </div> {0} """.format( self.highlight.highlight( """ { "routes": { "GET /test/<test variable>": "A test route.", "GET /json": "The list of routes in JSON format. You could use this for service or capability discovery, for example." } } """, "json")))
def add_static_route(self, fdir, m_dir): logger.debug("[WebUI] add static route: %s", fdir) static_route = '/static/' + fdir + '/:path#.+#' def plugin_static(path): return static_file(path, root=os.path.join(m_dir, 'htdocs')) route(static_route, callback=plugin_static)
def init(host='0.0.0.0', port='8080'): app = Service() bottle.route('/process/text', method="POST")(app.process) bottle.route('/info')(app.info) bottle.debug(False) run(host=host, port=port, debug=True)
def _register_plugin_actions(self, plugin_class, metadata, cls_instance, fn_name, fn, class_help): fq_fn_name = "{}.{}".format(plugin_class, fn_name) if fn.__doc__: self._help['human'][class_help][fq_fn_name] = self._parse_human_help(fn.__doc__) for action, config in metadata['plugin_actions'].items(): if action == 'process': event_type = config['event_type'] event_handlers = self._plugin_actions['process'].get(event_type, {}) event_handlers[fq_fn_name] = { 'class': cls_instance, 'class_name': plugin_class, 'function': fn } self._plugin_actions['process'][event_type] = event_handlers if action == 'respond_to' or action == 'listen_to': for regex in config['regex']: event_handler = { 'class': cls_instance, 'class_name': plugin_class, 'function': fn, 'regex': regex } key = "{}-{}".format(fq_fn_name, regex.pattern) self._plugin_actions[action][key] = event_handler self._help['robot'][class_help].append(self._parse_robot_help(regex, action)) if action == 'schedule': Scheduler.get_instance().add_job(fq_fn_name, trigger='cron', args=[cls_instance], id=fq_fn_name, replace_existing=True, **config) if action == 'route': for route_config in config: bottle.route(**route_config)(fn)
def blackport(): if pagename == route('/blackport/wiekie'): print("hey alex! hi CINDY! was up DJ") elif pagename == route('/blackport/LGT'): print("Was up Light Fam!!!") print("<img> source = /desktop/buinessss/sunflower.jpg") return
def run(argv): parser = argparse.ArgumentParser(parents=[serverParser, genericParser]) parser.description = """ Launch a web server that generate the tiles on demand in the current folder, unless a different root is specified in the parameters. The format of the images... Other details here. """ parser.add_argument("-d", "--dir", default=".", help="Directory that contains the image") conf = parser.parse_args(argv) print conf tileServer = StaticTileServer.fromArgsConf(conf) bottle.route('/hello', 'GET', tileServer.hello) bottle.route('/tile/<z:int>/<x:int>/<y:int>/<filename:path>', 'GET', tileServer.tile) bottle.run(host=conf.host, port=conf.port, debug=conf.debug, quiet=conf.quiet, server='gevent')
def main(): # Setup argument parser, then run either cmdline or web parser = argparse.ArgumentParser( description='Process Oracle info reports.') parser.add_argument('-w', '--web', action='store_const', const=True, dest="runWeb", help="Start as webpage (requires cherrypy module)") parser.add_argument('-f', '--file', action='append', dest='inFiles', default=[], help="Add list of files to run against") args = parser.parse_args() if args.runWeb: #from bottle import run, route, request import webbrowser o = OraWeb() route("/", method='GET')(o.index) route("/", method='POST')(o.upload) webbrowser.open("http://localhost:8080") run(host='localhost', port=8080, debug=True, reloader=True) elif args.inFiles: o = OraReport() o.printReport(o.parseReportFile(args.inFiles[0]))
def setup_routing(): setup_tictactoe() # Static Routes bottle.route("/css/<filepath:re:.*\.css>", ['GET'], serve_css) bottle.route("/img/<filepath:re:.*\.(jpg|png|gif|ico|svg)>", ['GET'], serve_img) """
def run(self): route('/')(self.handle_index) route('/cmds')(self.handle_cmds) post('/cmd')(self.handle_cmd_post) if self.ssl: run(server=self.ssl_server, debug=DEBUG) else: run(host=self.host, port=self.port, debug=DEBUG)
def __route_farms(): global PUBLISHED_FARMS permissions_dict = datautils.get_permissions_dict() for farmname in permissions_dict['farms']: farm_content = datautils.get_farm_content(farmname) if farm_content.get('publish', ['no'])[0] == 'yes': PUBLISHED_FARMS.append(farmname) route('/%s' % farmname, 'GET', partial(farmprofile, farmname))
def existing_action(): session = authenticate() cur = connect_db() if session.has_key('user_name'): cur.execute(""" UPDATE hnc_users SET user_email = %s WHERE user_id = %s """, request.forms.get('user_email'), session['user_id']) route('/u/%s' % session['user_id'])
def _routeClass(self): for kw in dir(self): attr = getattr(self, kw) if hasattr(attr, 'route'): if hasattr(attr, 'method'): bottle.route(attr.route, method=attr.method)(attr) else: bottle.route(attr.route)(attr)
def __init__(self, url, port): """Set url, port and routes""" self.url = url self.port = port # Setup routes route('/')(self.root) route('/<path:path>')(self.sub)
def setup_routes(obj): for kw in dir(obj): attr = getattr(obj, kw) if hasattr(attr, 'route'): if hasattr(attr, 'method'): print('routing ' + str(attr) + ' with ' + attr.route + ', ' + attr.method) bottle.route(attr.route, attr.method)(attr) else: bottle.route(attr.route)(attr)
def __new__(self, *args, **kwargs): """ We use __new__ to use route in order to connect our http endpoints to functions """ obj = super(SoapServer, self).__new__(self, *args, **kwargs) route("/status", method="GET")(obj.status) route("/play", method="POST")(obj.playStream) return obj
def wrapper(callback): if path is None or not path.rstrip('/'): return route(path, method, **kargs)(callback) elif path.endswith('/'): return route(path[:-1], method, **kargs)( route(path, method, **kargs)(callback)) else: return route(path, method, **kargs)( route(path+'/', method, **kargs)(callback))
def initTobiiEyeTracker(self): __tobiiConfigSection = "TOBII" tobiiSensor = Tobii.Tobii(__tobiiConfigSection) self.tobiiEyeTracker = ThreadedSensor.ThreadedSensor(tobiiSensor, __tobiiConfigSection) __tobiiEyeTrackerServerHostRoute = config.getConfig().get(__tobiiConfigSection, "HostRoute") print "Starting http server on http://",self.serverHostIP,':',self.serverHostPort, __tobiiEyeTrackerServerHostRoute bottle.route(__tobiiEyeTrackerServerHostRoute)(self.tobiiEyeTracker.sensor.respondTracker)
def __init__(self): config = configs.read(os.environ['BOSS_CONFIG_REAL'], set_globals=False) self.auth_url = config['openstack']['auth']['auth_url'] self.fake_auth_url = configs.openstack.auth.auth_url for kw in dir(self): attr = getattr(self, kw) if hasattr(attr, 'route'): bottle.route(attr.route, method=['GET', 'POST', 'PUT', 'DELETE'])(attr)
def route_plugins(): for cls, function_name in self.bottle_routes: instantiated_cls = cls() instantiated_fn = getattr(instantiated_cls, function_name) bottle_route_args = {} for k, v in instantiated_fn.metadata.items(): if "bottle_" in k and k != "bottle_route": bottle_route_args[k[len("bottle_"):]] = v bottle.route(instantiated_fn.metadata["bottle_route"], **bottle_route_args)(instantiated_fn)
def decorator(func): def wrapper(*args, **kwargs): return execute(func, *args, **kwargs) if isinstance(path, str): bottle.route(path=path, method=method, callback=wrapper, name=name, apply=apply, skip=skip, **kwconfig) else: for p in path: bottle.route(path=p, method=method, callback=wrapper, name=name, apply=apply, skip=skip, **kwconfig) return wrapper
def import_routes(route_location): # import route module_obj = None __import__(route_location, globals(), locals()) module_obj = sys.modules[route_location] url_properties = { 'urls' : ['GET', 'POST', 'PUT', 'DELETE'], 'gets' : ['GET'], 'posts': ['POST'], 'puts' : ['PUT'], 'deletes': ['DELETE'] } # urls for url_property in url_properties: methods = url_properties[url_property] if hasattr(module_obj, url_property): for url_pair in getattr(module_obj, url_property): # address route_address = url_pair[0] slashed_url = add_begining_slash(add_trailing_slash(route_address)) unslashed_url = add_begining_slash(remove_trailing_slash(route_address)) # callback if len(url_pair)==1: route_callback = 'Undefined callback' else: route_callback = url_pair[1] if isinstance(route_callback, str): content = route_callback def wrapper(): return content route_callback = wrapper # default values name, apply_, skip, configs = None, None, None, {} # name if len(url_pair)>2: name = url_pair[2] # apply if len(url_pair)>3: apply_ = url_pair[3] # skip if len(url_pair)>4: skip = url_pair[4] # configs if len(url_pair)>5: configs = url_pair[5] # call the routes route(slashed_url, methods, route_callback, name, apply_, skip, **configs) route(unslashed_url, methods, route_callback, name, apply_, skip, **configs) # hooks if hasattr(module_obj, 'hooks'): for hook_pair in module_obj.hooks: hook(hook_pair[0])(hook_pair[1]) # errors if hasattr(module_obj, 'errors'): for error_pair in module_obj.errors: error(error_pair[0])(error_pair[1])
def setup(adapter=None, dev=False): if adapter is None: adapter = ADAPTER if dev: jsonrpc.endpoint(path='/dev')(deploy_adapter) else: _setup_adapter(adapter) route('/log/<log>')(_log)
def __init__(self, registrar, config): self.registrar = registrar self.config = config # routing route("/static/<appid>/<token>/<uri:path>")(self.rengine_side) route("/upload/<request_id>/<uri:path>", method='POST')(self.sfk_side) # {request_id: event} , request_id: str(uuid) - unique for each content request self.request_id_events = {}
def route_instance(thing): for kw in dir(thing): attr = getattr(thing, kw) route = getattr(attr, '__route__', None) if route: bottle.route(route)(attr) hook = getattr(attr, '__hook__', None) if hook: bottle.hook(hook)(attr)
def route_server(self, sconfig): resource = '/server/' if 'web' in sconfig and 'hook_route' in sconfig['web']: resource = sconfig['web']['hook_route'] else: logging.error( "Webrouter: No valid resource route found. Taking defaults {}". format(resource)) logging.info("Webrouter: starting routing on {}".format(resource)) bottle.route(resource, 'POST')(self.wsapp.exf_server)
def _route(self): route('/', method="GET", callback=self.index) route('/<toiminto>', method="GET", callback=self.index) route('/tunnistautuminen/<laite>/<toiminto>', method="GET", callback=self.tunnistautuminen) route('/<laite>/<toiminto>', method="POST", callback=self.aseta_anturin_ohjaus) route('/tiedot', method="GET", callback=self.tieto_sivu)
def __init__(self, app, manager): self.app = app self.highlight = Highlight() self.manager = manager route("/highlight.css", ["GET", "POST"], self.highlight_css) route("/static/<path:path>", ["GET", "POST"], self.static) route("/static/", ["GET", "POST"], self.static_403) route("/static", ["GET", "POST"], self.static_403) route("/.well-known/keybase.txt", ["GET", "POST"], self.static_keybase)
def init(host='0.0.0.0', port='8080'): app = Service() bottle.route('/process/links', method="POST")(app.create_links) bottle.route('/process/all', method="POST")(app.process) bottle.route('/process/tc', method="POST")(app.mark_critical_temperature) bottle.route('/process/formula', method="POST")(app.resolve_class) bottle.route('/info')(app.info) bottle.debug(False) run(host=host, port=port, debug=True)
def run(self): """ Start the servers """ route("/")(self.serve) if self.config.html: route("/<filepath:path>")(self.custom_html) if self.config.fuzz_web: self.request_checker.start() self.httpd.start() self.httpsd.start()
def bootstrap_bottle(self): print "Bootstrapping bottle..." bootstrapped = False try: for cls, function_name in self.bottle_routes: instantiated_cls = cls() instantiated_fn = getattr(instantiated_cls, function_name) bottle.route(instantiated_fn.bottle_route)(instantiated_fn) bootstrapped = True except Exception, e: self.startup_error("Error bootstrapping bottle", e)
def test_routebuild(self): """ WSGI: Test route builder """ bottle.route('/a/:b/c', name='named')(5) bottle.request.environ['SCRIPT_NAME'] = '' self.assertEqual('/a/xxx/c', bottle.url('named', b='xxx')) self.assertEqual('/a/xxx/c', bottle.app().get_url('named', b='xxx')) bottle.request.environ['SCRIPT_NAME'] = '/app' self.assertEqual('/app/a/xxx/c', bottle.url('named', b='xxx')) bottle.request.environ['SCRIPT_NAME'] = '/app/' self.assertEqual('/app/a/xxx/c', bottle.url('named', b='xxx')) bottle.request.environ['SCRIPT_NAME'] = 'app/' self.assertEqual('/app/a/xxx/c', bottle.url('named', b='xxx'))
def __call__(self, func): """builds the decorator""" frame = inspect.stack()[1] module = inspect.getmodule(frame[0]) folder = os.path.dirname(os.path.abspath(module.__file__)) app_name = folder[len(os.environ['WEB3PY_APPLICATIONS_FOLDER'])+1:].split(os.sep)[0] path = ('/' if app_name == '_default' else '/%s/' % app_name) + self.path # the _default app has no prefix func = action.catch_errors(app_name, func) func = bottle.route(path, **self.kwargs)(func) if path.endswith('/index'): # /index is always optional func = bottle.route(path[:-6] or '/', **self.kwargs)(func) return func
def inner(callable_): def to_json(*args, **kwargs): response.set_header("Content-Type", "application/json") try: return json.dumps(callable_(*args, **kwargs)) except Exception as e: logger.exception("Error on route: {0}".format(route_)) return json.dumps({"error": str(e)}) route("/<:re:(?i)json>/{0}".format(route_), methods, to_json)
def routeapp(obj): for kw in dir(obj): attr = getattr(obj, kw) if hasattr(attr, 'error'): bottle.error(attr.error)(attr) if hasattr(attr, 'delete'): bottle.delete(attr.delete)(attr) if hasattr(attr, 'put'): bottle.put(attr.put)(attr) if hasattr(attr, 'post'): bottle.post(attr.post)(attr) if hasattr(attr, 'route'): bottle.route(attr.route)(attr)
def routeapp(obj): for kw in dir(obj): #print kw,type(kw) attr = getattr(obj, kw) if hasattr(attr, 'route'): #print 'aaaa:',kw,attr.route ll = kw.split('_') ll.insert(0,'/pcc') path = '/'.join(ll) print path,kw,attr.route,'@',attr.route or path,attr.method bottle.route(attr.route or path,method= attr.method or 'GET')(attr)#)
def test_decorators(self): app = bottle.Bottle() app.route('/g')('foo') bottle.route('/g')('foo') app.route('/g2', method='GET')('foo') bottle.get('/g2')('foo') app.route('/p', method='POST')('foo') bottle.post('/p')('foo') app.route('/p2', method='PUT')('foo') bottle.put('/p2')('foo') app.route('/d', method='DELETE')('foo') bottle.delete('/d')('foo') self.assertEqual(app.routes, bottle.app().routes)
def read(self,token): self.sc = SlackClient(token) if self.sc.rtm_connect(): start = time.time() while True: try: str = self.sc.rtm_read() if str and ('text' in str[0]) and ('reply_to' not in str[0]): # if str is not null key = str[0].get('text') user = str[0].get('user') info = self.sc.api_call('users.info', user= user) if user not in self.dict: user_name = info.get('user').get('name') self.names[user_name] = user self.dict[user] = [] self.dict[user].append(float(key)) self.dict[user].append(1) self.dict[user].append(float(key)) print(float(key)) else: self.dict[user][0] += float(key) self.dict[user][1] += 1 print(float(self.dict[user][0])/self.dict[user][1]) self.dict[user][2] = self.dict[user][0]/self.dict[user][1] count , avg = 0,0 for key, value in self.dict.items(): avg += float(self.dict[key][0]) count += self.dict[key][1] self.summ = avg/count time.sleep(1) end = time.time() if(end - start >= 60): start = time.time() for key, value in self.dict.items(): avg += float(self.dict[key][0]) count += self.dict[key][1] str = "{:.9f}".format(avg/count) self.sc.rtm_send_message("general", str) count , avg = 0,0 bottle.route("/average")(myapp.average) bottle.route("/average/:name")(myapp.user) try: server = bottle.run() except (KeyboardInterrupt, SystemExit): pass else: time.sleep(1) except Exception as e: print("Exception: ", e.message)
def bootstrap_bottle(self): bootstrapped = False try: for cls, function_name in self.bottle_routes: instantiated_cls = cls() instantiated_fn = getattr(instantiated_cls, function_name) bottle_route_args = {} for k, v in instantiated_fn.will_fn_metadata.items(): if "bottle_" in k and k != "bottle_route": bottle_route_args[k[len("bottle_"):]] = v bottle.route(instantiated_fn.will_fn_metadata["bottle_route"], **bottle_route_args)(instantiated_fn) bootstrapped = True except Exception, e: self.startup_error("Error bootstrapping bottle", e)
def setup(root_path): # Map request URL's to their handlers route('/', callback=RootController.get) route('/get-playlist/', callback=RootController.get_playlist) @route('/img/<filename:path>') def send_image(filename): return static_file(filename, root=root_path+'/img/') @route('/js/<filename:path>') def send_js(filename): return static_file(filename, root=root_path+'/js/') @route('/css/<filename:path>') def send_css(filename): return static_file(filename, root=root_path+'/css/')