Могу ли я использовать внешние методы в качестве декораторов маршрута в Python/Flask?

мой основной файл приложения в настоящее время представляет собой серию определений методов, каждое из которых прикреплено к маршруту. У меня есть 3 отдельные части моего приложения (main, admin, api). Я пытаюсь разделить методы на внешние файлы для лучшего обслуживания, но мне нравится простота Flask в использовании декораторов маршрутов для URL-адресов моего приложения.

один из моих маршрутов в настоящее время выглядит так:

# index.py
@application.route('/api/galleries')
def get_galleries():
    galleries = {
        "galleries": # get gallery objects here
    }
    return json.dumps(galleries)

но я хотел бы извлечь метод get_galleries в файл, содержащий методы для моего API:

import api
@application.route('/api/galleries')
api.get_galleries():

проблема в том, что когда я это делаю, я получаю ошибку. Возможно ли это, и если да, то как мне это сделать?

4 ответов


как указано в другом комментарии, Вы можете позвонить app.route('/')(api.view_home()) или использовать колбы app.add_url_rule() http://flask.pocoo.org/docs/api/#flask.Flask.add_url_rule

колбы @app.route() код:

def route(self, rule, **options):
    def decorator(f):
        endpoint = options.pop('endpoint', None)
        self.add_url_rule(rule, endpoint, f, **options)
        return f
    return decorator

вы можете сделать следующее:

## urls.py

from application import app, views

app.add_url_rule('/', 'home', view_func=views.home)
app.add_url_rule('/user/<username>', 'user', view_func=views.user)

и затем:

## views.py

from flask import request, render_template, flash, url_for, redirect

def home():
    render_template('home.html')

def user(username):
    return render_template('user.html', username=username)

это метод, который я использую для разрушения вещей. Определите все ваши urls в собственном файле, а затем import urls в своем __init__.py, который работает app.run()

In ваш случай:

|-- app/
|-- __init__.py (where app/application is created and ran)
|-- api/
|   |-- urls.py
|   `-- views.py

api/urls.py

from application import app

import api.views

app.add_url_rule('/call/<call>', 'call', view_func=api.views.call)

api/views.py

from flask import render_template

def call(call):
    # do api call code.

декораторы-это просто функции, поэтому вы можете просто сделать:

import api
api.get_galleries = application.route(api.get_galleries, '/api/galleries')

декоратор-это просто специальная функция.

routed_galleries = application.route('/api/galleries')(api.get_galleries)

и на самом деле, в зависимости от того, что делает декоратор, вам может не понадобиться вообще сохранять результат.

application.route('/api/galleries')(api.get_galleries)

Я не думаю, что вы можете украсить метод таким образом. Но я полагаю, что вместо обычного использования декоратора вы можете создать обратный вызов, чтобы украсить его вручную.

def wrap_api(cls, rt):
  return application.route(rt)(cls)

тогда вы можете использовать его следующим образом:

import api
galleries = wrap_api(api.get_galleries(), '/api/galleries')