Динамическое добавление правил URL в приложение Flask

#python #flask

#python #flask

Вопрос:

Я пишу приложение, в котором пользователи смогут хранить информацию, для которой они могут указать интерфейс REST. Т.е. хранить список продуктов в /<username>/rest/products . Поскольку URL-адреса, очевидно, заранее неизвестны, я пытался придумать наилучший способ реализовать динамическое создание URL-адресов в Flask. Первым способом, о котором я подумал, было бы написать всеобъемлющее правило и перенаправить URL оттуда. Но тогда я в основном дублирую возможности маршрутизации URL, когда они уже встроены в Flask. Итак, мне было интересно, не было бы плохой идеей использовать .add_url_rule() (документы здесь, прокрутите немного вниз), чтобы прикрепить их непосредственно к приложению. Есть ли конкретная причина, по которой этого не следует делать?

Ответ №1:

Каждый раз, когда вы выполняете add_url_rule() внутреннюю маршрутизацию, карта URL переназначается. Это не является ни потокобезопасным, ни быстрым. Честно говоря, я прямо сейчас не понимаю, зачем вам нужны правила URL для конкретного пользователя. Звучит так, как будто вы действительно хотите, чтобы были установлены приложения, специфичные для пользователя?

Возможно, это полезно:http://flask.pocoo.org/docs/patterns/appdispatch /

Комментарии:

1. У меня такое же требование, т. Е. я ищу способ динамического добавления новых конечных точек в API, созданный с помощью Eve , используя его register_resource метод, который вызывается add_url_rule внутри. Обратите внимание, что это произойдет не для каждого запроса, а только с помощью перехвата, когда будет получен ответ POST на определенную конечную точку, поэтому производительность не должна быть проблемой.

2. Здесь точно такое же требование. API, который требует добавления и удаления нового маршрута всякий раз, когда запрос PUT выполняется на определенном маршруте. В моем случае я использую flask-restful, но в основном это то же самое.

3. Кажется, я могу сделать это в before_request, если я использую threading.lock , однако я не уверен, как остановить проблемы с url_for, связанные со следующей ошибкой: ОШИБКА ValueError: список изменен во время сортировки: ошибка приложения: ошибка внутреннего сервера, список изменен во время сортировки

Ответ №2:

У меня было аналогичное требование для моего приложения, где каждая конечная точка /<SOMEID>/rest/other для данного SOMEID должна быть ограничена другой функцией. Один из способов добиться этого — сохранить словарь поиска, где значения являются функцией, которая обрабатывает конкретное SOMEID . Например, взгляните на этот фрагмент:

 func_look_up_dict = {...}
@app.route('<SOMEID>/rest/other', methods=['GET'])
def multiple_func_router_endpoint(SOMEID):
    if SOMEID in func_look_up_dict.keys():
        return jsonify({'result' = func_look_up_dict[SOMEID]()}), 200
    else:
        return jsonify({'result'='unknown', 'reason'='invalid id in url'}), 404
  

итак, для этого вам на самом деле не нужно «динамически» добавлять правила URL, а скорее использовать правило URL с параметром и обрабатывать различные случаи с помощью одной функции. Еще одна вещь, которую следует учитывать, — это действительно подумать о варианте использования такой конечной точки URL. Если <username> есть параметр, который необходимо передать, почему бы не использовать правило URL, такое как /rest/product/<username> или передать его в качестве аргумента в запросе GET?
Надеюсь, это поможет.