如何根据Flask中的条件触发REST API?

时间:2018-02-24 21:54:41

标签: python flask flask-restful

我有一个Flask应用程序,我允许用户访问第三方应用程序并从中获取数据并执行一些可视化。现在,用户必须提供应用程序名称及其凭据才能获取数据。现在我想避免将应用程序名称放在url中,而是应该将所有数据作为POST请求发送,我将解析POST数据,使用给定的凭据连接到所需的应用程序,执行一些可视化。这是用户将作为{ "application_name": "appdynamics", "account_id": "sdf632sef", "username": "kuhku86tg", "password": "oihsd832" } 数据发送的内容

POST

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

我计划的方法是创建一个单独的文件,包括使用请求解析器获取parse.py数据,然后在主应用程序中调用它,我将使用基于应用程序的if条件触发我的REST API类name.Below是文件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)

中调用它
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

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

    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.

但是我收到以下错误

class Attribute < ApplicationRecord
  validates :name, presence: true
  validates :name, uniqueness: true

  has_many :attribute_vals
end

1 个答案:

答案 0 :(得分:0)

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

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

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