【问题标题】:How to trigger a REST API based on a condition in Flask?如何根据 Flask 中的条件触发 REST API?
【发布时间】:2018-02-24 21:54:41
【问题描述】:

我有一个 Flask 应用程序,让用户可以访问第三方应用程序并从中获取数据并执行一些可视化。现在用户必须提供应用程序名称及其凭据才能获取数据。现在我想避免将应用程序名称放在 url 中,而所有数据都应作为 POST 请求发送,我将在其中解析 POST 数据,使用给定凭据连接到所需的应用程序并执行一些可视化。这就是用户将作为POST 数据发送

{
    "application_name": "appdynamics",
    "account_id": "sdf632sef",
    "username": "kuhku86tg",
    "password": "oihsd832"
}

现在我想根据用户提供的应用程序名称触发我的特定 REST API 类。

我计划的方式是创建一个单独的文件,其中涉及使用请求解析器获取POST 数据,然后在主应用程序中调用它,在主应用程序中我将根据应用程序名称使用 if 条件触发我的 REST API 类。下面是文件parse.py

from flask_restful import reqparse

# create a parser object
parser = reqparse.RequestParser()
# add agruments to the parser object
parser.add_argument('account_id', type=str, required=False, help="Please define 'account_id'")
parser.add_argument('username', type=str, required=False, help="Please define 'username'")
parser.add_argument('password', type=str, required=False, help="Please define 'password'")
parser.add_argument('application_name', type=str, required=False, help="Please define 'application name'")

data = parser.parse_args()

现在我在主应用程序中调用它app.py

from parser import data
from flask import Flask
from flask_restful import Api

app = Flask(__name__)
# create an API for the Flask app
api = Api(app)

# if the user demands info for appdynamics, trigger the Appdynamics API class
if data['application_name'] == "appdynamics":
    api.add_resource(AppdynamicsAPI, "/<string:name>")  # the string will contain the metric requirement

if __name__ == "__main__":
    app.run(port=5000, debug=True)

下面是编写 REST API 逻辑的部分

from parser import data
from flask_restful import Resource, reqparse
from fetch_data.appdynamics import fetch_all_apps, fetch_avg_resp_time, calls_per_min
from models.user import *

class AppdynamicsAPI(Resource):
    # authenticate users
    def post(self, name):
        first_data = data
        # if the user passes the credentials, insert it into the database otherwise use the last known credentials
        # ensure you only insert valid credentials
        if all([first_data['account_id'], first_data['password'], first_data['username']]):
            users.update(first_data, {i: j for i, j in first_data.items()}, upsert=True)
            print({i: j for i, j in first_data.items()})
        credentials = users.find_one({})
        print("Credentials", credentials)
        account_id = credentials['account_id']
        username = credentials['username']
        password = credentials['password']
        t_duration = first_data['t_duration']


        if name == "allapps":
            status_code, result = fetch_all_apps(account_id, username, password)
            if status_code == 200:
                return {"information": result}, status_code
            return {"message": "Please enter correct credentials"}, status_code

但是我收到以下错误

    Traceback (most recent call last):
  File "/home/souvik/PycharmProjects/ServiceHandler/app.py", line 3, in <module>
    from resource.appdynamics_resource import AppdynamicsAPI
  File "/home/souvik/PycharmProjects/ServiceHandler/resource/appdynamics_resource.py", line 4, in <module>
    from authentication.parser import data
  File "/home/souvik/PycharmProjects/ServiceHandler/authentication/parser.py", line 14, in <module>
    data = parser.parse_args()
  File "/home/souvik/utorapp/lib/python3.5/site-packages/flask_restful/reqparse.py", line 302, in parse_args
    req.unparsed_arguments = dict(self.argument_class('').source(req)) if strict else {}
  File "/home/souvik/utorapp/lib/python3.5/site-packages/werkzeug/local.py", line 364, in <lambda>
    __setattr__ = lambda x, n, v: setattr(x._get_current_object(), n, v)
  File "/home/souvik/utorapp/lib/python3.5/site-packages/werkzeug/local.py", line 306, in _get_current_object
    return self.__local()
  File "/home/souvik/utorapp/lib/python3.5/site-packages/flask/globals.py", line 37, in _lookup_req_object
    raise RuntimeError(_request_ctx_err_msg)
RuntimeError: Working outside of request context.

This typically means that you attempted to use functionality that needed
an active HTTP request.  Consult the documentation on testing for
information about how to avoid this problem.

【问题讨论】:

    标签: python flask flask-restful


    【解决方案1】:

    您当前在模块的顶级代码中调用data = parser.parse_args()。这在导入时运行,但是在导入模块时没有什么要解析的,因为这发生在启动期间,而不是在处理请求时。

    改为从您的视图函数(即处理请求时运行的代码)调用它。您还需要重组代码 - 调用 api.add_resource() 是您在启动/初始化期间执行的操作,而不是在处理请求时。

    要理解的重要一点是,这不是 PHP 在收到请求时运行所有代码的地方。相反,Python 模块会在您启动应用程序时导入(flask runapp.run(),或在 WSGI 容器中运行它)。当收到请求时,只会运行与处理该请求相关的代码。

    【讨论】:

    • 是的,我同意。最初我的代码结构与它应该的完全一样;仅在触发 REST API 时调用解析器并获取数据。因此我能够读取用户的数据并执行某些操作。但这不是我想要的。所以我需要一个解决方法并认为这可能是一种方法.那么你能建议一种理想的方式,让我可以读取用户的 POST 数据,然后决定调用哪个 REST API,而不必读取 url 然后触发 REST API。有什么解决方法吗?
    • rest api 不是这样工作的。如果您想这样做,请使用普通烧瓶(只需根据发布数据调用不同的函数)
    • 好的,这就是我需要澄清的。如果是这样的话,很好。
    猜你喜欢
    • 2021-10-10
    • 2021-06-03
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2016-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多