1

我正在使用 Python Flask 和 flask-restplus 构建一个 RESTful API。

这是一个缩放的 flask-restplus 应用程序,我按照这里给出的页面(缩放你的项目)来设计我的应用程序。

我想在对象实例化期间将参数传递给 Ratings 类。Ratings 类使用由 flask-restplus 提供的命名空间装饰器进行装饰。

我无法理解 Ratings 对象在何处被实例化,以便我可以将参数传递给该对象。我必须传递的参数是来自我的 app.py 文件的 Ratings 类的文件名 (settings.json)。

任何帮助都感激不尽。

我的目录结构如下:

|_>apis
|      |_> __init__.py
|      |_> ratings.py
|_>app.py

三个python文件是这样的:

#__init__.py

from flask_restplus import Api
from .ratings import api as ns1    

api = Api(version='1.0', title='Reviews Service',
          description='Hello Reviews',)

api.add_namespace(ns1)

# app.py

from flask import Flask
from apis import api

app = Flask(__name__)
api.init_app(app)
app.config.from_json('settings.json')

if __name__ == '__main__':
    logging.basicConfig(filename=app.config['LOGGING_FILE_LOCATION'], level=logging.INFO)

app.run()

# ratings.py

from db_interface import DBInterface
from flask_restplus import Resource, Namespace

api = Namespace('AppReviewRatings', description='"Ratings" related operations.',)


@api.route('/api/<version>/<metric_name>/<app_store_name>')
@api.doc(params={'version': '"1" (v1) or "2" (v2)',
                 'metric_name': '"rating" or "reviews"',
                 'app_store_name': '"apple" or "google"'})
class Ratings(Resource):
    @api.response(200, 'Success')
    @api.response(400, 'Validation Error')
    def get(self, version, metric_name, app_store_name):

        # I must receive settings.json as an argument from app.py file.
        db_interface = DBInterface(settings_file_path='settings.json')  
        parameters = {'app_store_name': app_store_name, 'hue_version': hue_version}

        result = db_interface.query(q_type=metric_name, params=parameters)
        return result
4

2 回答 2

1

__init__你可以像这样在你的类中定义一个函数:

# in your ratings.py
class Ratings(Resource):
    def __init__(self, *args, **kwargs):
        self.settings = self.kwargs.get('settings')
        # don't forget to call the super class
        super(Ratings, self).__init__(*args, **kwargs)

    def get(self, version, metric_name, app_store_name):

    # get the settings here
    db_interface = DBInterface(settings_file_path=self.settings)

# app.py
# Initialize like this
api.add_resource(ratings.Ratings, '/api/my/end/point/',
             resource_class_kwargs={'settings': "path_to_settings.json"})

您可以在这里 查看源代码。

于 2018-02-15T03:14:32.987 回答
0

对于那些有兴趣初始化Resource并在Namespace中使用它的人。该解决方案允许将参数从项目主体传递给资源。具有以下项目结构:

/project/src/python/
    app.py
    endpoints/
        __init__.py
       endpoint_a.py

Flask App 和 Api 初始化。

# file app.py
from flask import Blueprint
from flask import Flask

# load API modules as namespace
from endpoints.endpoint_a import api as namespace_endpoint_a

blueprint = Blueprint("My awsome webserver application", __name__, url_prefix="/")
# create main entry of the application (default namespace)
api = flask_restx.Api(
    blueprint,
    version="1.0",
)
# passing constructor parameters into resources
configuration_to_inject = {
    "my_custom_argument_1": "example",
    "my_custom_argument_2":"foo",
}
# first pass argument to RessourceA
for resource in namespace_endpoint_a.resources:
    # set config to ressource
    resource.kwargs['resource_class_kwargs'] = configuration_to_inject
    # then add Resource as Namespace to the API
    api.add_namespace(namespace_endpoint_a, path='/path/to/namespace_a')
    
# create a Flask WSGI application
app = Flask(__name__)
app.config["ERROR_INCLUDE_MESSAGE"] = True
app.register_blueprint(blueprint)
app.run(host='127.0.0.1', port='8080', debug=False)

在 Ressource 添加一个__init__函数,其参数在flask_restx Ressource 源中定义

# file endpoints/RessourceA.py
from flask_restx import Resource
from flask_restx import Namespace

api = Namespace('namespace-name', description='Operations related to Ressource A')

@api.route("/")
class CalculationRequestsInbound(Resource):
   
    def __init__(self, api=None, *args, **kwargs):
        self.my_custom_argument_1 = kwargs.get('my_custom_argument_1','foo')
        self.my_custom_argument_2 = kwargs.get('my_custom_argument_2','bar')
        #other staff...
        super(CalculationRequestsInbound, self).__init__(api, *args, **kwargs)

    def get(self):
        return {"argument_1":self.my_custom_argument_1}, 200

ResourceA.__init__(...)函数将在对资源端点的第一次 HTTP 调用时调用一次。例子

curl -X 'GET' \
  'http://127.0.0.1:8080/path/to/namespace_a' \
  -H 'accept: application/json'

使用包测试 Python 3.7.3和 基于flask_restx git repo 示例的werkzeug==2.0.1解决方案flask==2.0.2flask_restx==0.5.1

额外检查每个注册的命名空间有哪些资源可用

for _namespace in api.namespaces:
    print(f'Namespace:{_namespace.name}, {_namespace}')
    for resource in _namespace.resources:
        print(f'Ressource: {resource}')
于 2021-11-30T14:57:54.447 回答