为了账号安全,请及时绑定邮箱和手机立即绑定

Bottle Server:删除路由

Bottle Server:删除路由

胡说叔叔 2023-06-20 16:14:30
我想在我的Bottle服务器运行时添加和删除路由。我的一般问题:是否有删除路线的正确方法?换句话说:我怎样才能撤消我所做的事情app.route?在下文中,我将以更详细的方式描述我的问题。如果您知道我的一般问题的答案,请不要浪费时间阅读它。这是一个小演示脚本,描述了我如何解决我的问题:如果调用GET /add:添加“Hello World”路由如果调用GET /remove:所有具有相同前缀的路由(如“Hello World”路由)都会更改为触发 404 错误import bottlefrom bottle import redirect, abortdef addRoute():    app.route('/route/hello')(lambda :'Hello World')    print('Routes after calling /add:\n' + '\n'.join([str(route) for route in app.routes]))    redirect('route/hello')def removeRoute():    prefix = '/route/hello'    #making a list of all routes having the prefix    #because this is a testfile there is only one rule that startswith prefix    routes = [route for route in app.routes if route.rule.startswith(prefix)]    #because there could be multiple routes with the same rule and method,    #making a list without duplicates    ruleMethodTuples = list(dict.fromkeys([(route.rule, route.method) for route in routes]))    for ruleMethod in ruleMethodTuples :        #Workaround: Overwriting the existing route with a 404        #Here I'd prefer to make a statement that removes the existing route instead,        #so the default 404 would be called        app.route(ruleMethod[0], method = ruleMethod[1])(lambda **kwords: abort(404, 'Route deleted'))    print('Routes after calling /remove:\n' + '\n'.join([str(route) for route in app.routes]))    redirect('/route/hello')if __name__ == '__main__':    app = bottle.app()    app.route('/add')(addRoute)    app.route('/remove')(removeRoute)    print('Initial routes:\n' + '\n'.join([str(route) for route in app.routes]))    bottle.run(app, host = 'localhost', port = 8080)所以这是启动和调用后的输出:/添加/消除/添加在每次通话后显示app.routes中有哪些路线。因此,调用app.route不是替换GET '/route/hello',而是在列表末尾添加更多具有相同方法和规则的路由。然而,到目前为止这仍然有效,因为首先选择了最新的匹配路由,但我很确定这会(或早或晚)导致性能问题或在调用一些 /add s 和 /remove s 后导致服务器崩溃。此外我注意到,我可以在不更改实际路由的情况下更改app.routes ,所以次要问题:我可以从 app.routes 中删除“已弃用”的路由以防止计算器溢出吗?第三个问题:我做的事情完全错误吗?
查看完整描述

1 回答

?
慕丝7291255

TA贡献1859条经验 获得超6个赞

我检查了add_route的源代码

它添加route到两个对象:self.routesand self.routerapp.routesand app.router) 这会产生问题。

def add_route(self, route): 
   """ Add a route object, but do not change the :data:`Route.app`
        attribute."""
    self.routes.append(route)
    self.router.add(route.rule, route.method, route, name=route.name)    if DEBUG: route.prepare()

self.router是具有rulesbuilderstatic dyna_routes, _dyna_regexes

如果您在添加新路线之前和之后检查它们,那么您会看到builder和中的变化static

def addRoute():

    print('--- before ---')

    print(app.router.rules)

    print(app.router.builder)

    print(app.router.static)

    print(app.router.dyna_routes)

    

    app.route('/route/hello')(lambda :'Hello World')


    print('--- after ---')

    print(app.router.rules)

    print(app.router.builder)

    print(app.router.static)

    print(app.router.dyna_routes)


    print('Routes after calling /add:\n' + '\n'.join([str(route) for route in app.routes]))

    redirect('route/hello')

如果我'/route/hello'从中删除builder然后停止工作但仍然显示它们,那么你将不得不从两者中删除static-但它们没有为此的特殊功能:)'/route/hello'app.routes'/route/hello'app.routesapp.router


def removeRoute():

    prefix = '/route/hello'


    del app.router.builder[prefix]

    del app.router.static['GET'][prefix]

    

    print('Routes after calling /remove:\n' + '\n'.join([str(route) for route in app.routes]))

    redirect('/route/hello')

我的完整代码:


import bottle

from bottle import redirect, abort


def addRoute():

    print('--- before /add ---')

    print(app.router.rules)

    print(app.router.builder)

    print(app.router.static)

    print(app.router.dyna_routes)

    print(app.router.dyna_regexes)

    print('Routes before calling /add:\n' + '\n'.join([str(route) for route in app.routes]))

    

    app.route('/route/hello')(lambda :'Hello World')

    

    print('--- after /add ---')

    print(app.router.rules)

    print(app.router.builder)

    print(app.router.static)

    print(app.router.dyna_routes)

    print(app.router.dyna_regexes)

    print('Routes after calling /add:\n' + '\n'.join([str(route) for route in app.routes]))

    

    redirect('route/hello')


def removeRoute():

    prefix = '/route/hello'


    print('--- before /remove ---')

    print(app.router.rules)

    print(app.router.builder)

    print(app.router.static)

    print(app.router.dyna_routes)

    print(app.router.dyna_regexes)

    print('Routes before calling /remove:\n' + '\n'.join([str(route) for route in app.routes]))


    del app.router.builder[prefix]

    del app.router.static['GET'][prefix]

    

    print('--- after /remove ---')

    print(app.router.rules)

    print(app.router.builder)

    print(app.router.static)

    print(app.router.dyna_routes)

    print(app.router.dyna_regexes)

    print('Routes before calling /remove:\n' + '\n'.join([str(route) for route in app.routes]))


    redirect('/route/hello')


if __name__ == '__main__':

    app = bottle.app()

    app.route('/add')(addRoute)

    app.route('/remove')(removeRoute)

    print('Initial routes:\n' + '\n'.join([str(route) for route in app.routes]))

    bottle.run(app, host = 'localhost', port = 8080)


查看完整回答
反对 回复 2023-06-20
  • 1 回答
  • 0 关注
  • 110 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信