简体   繁体   English

Flask-Restx Swagger 文档问题

[英]Flask-Restx Swagger Doc issue

I am getting AttributeError: module 'flask_restx.api' has no attribute 'doc' when it try add additional for API when using flask restx.我得到 AttributeError: module 'flask_restx.api' has no attribute 'doc' 当它尝试在使用 flask restx 时为 API 添加额外的。 How this error can be fixed.如何修复此错误。

api.py api.py

from flask import Flask
from flask_restx import Api, Resource
from hello import Hello

app = Flask(__name__)
api = Api(app)

api.add_resource(Hello, '/hello')

if __name__ == '__main__':
    app.run(debug=True)

hello.py你好.py

from flask_restx import Resource, api


@api.doc(params={'id': 'An ID'})
class Hello(Resource):
    def get(self):
        return {
            'data': {
                'names': ['one',
                          'two',
                          'three']
            }
        }

I don't know which tutorial you followed (if you followed any), but the我不知道您遵循了哪个教程(如果您遵循了任何教程),但是

@api.doc(params={'id': 'An ID'})

needs an instance of Api class and not flask-restx.api需要一个 Api class 的实例而不是 flask-restx.api

Usually, in tutorials (at least the ones I found), they show how to do all of that in the same file.通常,在教程(至少是我找到的那些)中,它们展示了如何在同一个文件中完成所有这些操作。 So your code would work if it was written like so:因此,如果这样编写,您的代码将起作用:

api.py api.py

from flask import Flask
from flask_restx import Api, Resource
from hello import Hello

app = Flask(__name__)
api = Api(app)

@api.doc(params={'id': 'An ID'})
class Hello(Resource):
    def get(self):
        return {
            'data': {
                'names': ['one',
                          'two',
                          'three']
            }
        }

api.add_resource(Hello, '/hello')

if __name__ == '__main__':
    app.run(debug=True)


Now, this is not what you want to achieve, as I guess you would like to split the file to have some structure (as I would like to as well).现在,这不是您想要实现的目标,因为我猜您想将文件拆分为具有某种结构(我也想这样做)。 Awfully, I couldn't find a proper tutorial for that online, but here is what I did in my project (using your example code):非常糟糕,我在网上找不到合适的教程,但这是我在项目中所做的(使用您的示例代码):

api > __init__.py api > __init__.py

from flask_restx import Namespace

default_namespace = Namespace("default", ordered=True)

api > hello.py api > hello.py

from flask_restx import Resource
from api import default_namespace as ns


@ns.doc(params={'id': 'An ID'})
class Hello(Resource):
    def get(self):
        return {
            'data': {
                'names': ['one',
                          'two',
                          'three']
            }
        }

app.py (your api.py file) located at root app.py(您的 api.py 文件)位于根目录

from flask import Flask
from flask_restx import Api
from hello import Hello
from api import default_namespace

app = Flask(__name__)
api = Api(app)

api.add_resource(Hello, '/hello')
api.add_namespace(default_namespace)

if __name__ == '__main__':
    app.run(debug=True)

Where the package structure is:其中package结构为:

.
+-- app.py
+-- api
   +-- __init__.py
   +-- hello.py

By declaring a namespace, you can actually group Resources together in Swagger.通过声明命名空间,您实际上可以将资源组合在 Swagger 中。 And the reason why I put the namespace in another file (here __init__.py ) is to not have a circular import.我将命名空间放在另一个文件(这里是__init__.py )的原因是没有循环导入。 And you can use all decorators with ns.doc, ns.route, ... as you could with the api.您可以将所有装饰器与 ns.doc、ns.route... 一起使用,就像使用 api 一样。 (where api is a variable;) ). (其中 api 是一个变量;))。 Btw, the ns is an Alias, if you prefer to put something else, it is up to you to change it in the import statement.顺便说一句, ns 是一个别名,如果你喜欢放别的东西,你可以在 import 语句中更改它。

Note that this might not be the best way, but it is clean enough for me and the structure I have.请注意,这可能不是最好的方法,但它对我和我所拥有的结构来说已经足够干净了。 If someone with more experience knows how to do this differently, please reply;)如果有更多经验的人知道如何以不同的方式做到这一点,请回复;)

It's nearly the same as @Jeremie's answer, but just would like to point to the official doc.这与@Jeremie 的答案几乎相同,但只是想指出官方文档。

There's following statements in flask-restx . flask-restx 中有以下语句。

Flask-RESTX provides a way to use almost the same pattern as Flask's blueprint. Flask-RESTX 提供了一种使用几乎与 Flask 蓝图相同的模式的方法。 The main idea is to split your app into reusable namespaces.主要思想是将您的应用程序拆分为可重用的命名空间。

And comes with an example:并附带一个例子:

# let's say the file name is `cat_controller`.
from flask_restx import Namespace, Resource, fields

api = Namespace('cats', description='Cats related operations')

cat = api.model('Cat', {
    'id': fields.String(required=True, description='The cat identifier'),
    'name': fields.String(required=True, description='The cat name'),
})

CATS = [
    {'id': 'felix', 'name': 'Felix'},
]

@api.route('/')
class CatList(Resource):
    @api.doc('list_cats')
    @api.marshal_list_with(cat)
    def get(self):
        '''List all cats'''
        return CATS

And we need both add_namespace() and add_resource() in app.py :我们需要 app.py 中的app.py add_namespace()add_resource()

from flask import Flask
from flask_restx import Api
from .cat_controller import CatList, api as ns1
from .dog_controller import DogList, api as ns2
# ...

app = Flask(__name__)
api = Api(
    app,
    version='1.0',
    title='A title',
    description='A description'
)

api.add_resource(CatList, '/cat')
api.add_resource(DogList, '/dog')
api.add_namespace(ns1)
api.add_namespace(ns2)

if __name__ == '__main__':
    app.run(debug=True)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM