总之,我一直在遵循烧瓶restx教程来创建api,但是我的端点没有出现在swagger页面上(“没有在规范中定义的操作!”)每当我给他们打电话的时候我就会得到404
我创建了我的api,主要遵循这个https://flask-restx.readthedocs.io/en/latest/scaling.html
我正在使用python 3.8.3作为参考。
下面是我正在做的一个简单的例子。
简而言之,我的问题是,我错过了什么?目前空白的原因是这不工作。
目录结构
project/
- __init__.py
- views/
- __init__.py
- test.py
manage.py
requirements.txt文件内容
requirements.txt
Flask-RESTX==0.2.0
Flask-Script==2.0.6manage.py
from flask_script import Manager
from project import app
manager = Manager(app)
if __name__ == '__main__':
manager.run()project/init.py
from flask import Flask
from project.views import api
app = Flask(__name__)
api.init_app(app)project/views/init.py
from flask_restx import Api, Namespace, fields
api = Api(
title='TEST API',
version='1.0',
description='Testing Flask-RestX API.'
)
# Namespaces
ns_test = Namespace('test', description='a test namespace')
# Models
custom_greeting_model = ns_test.model('Custom', {
'greeting': fields.String(required=True),
})
# Add namespaces
api.add_namespace(ns_test)project/views/test.py
from flask_restx import Resource
from project.views import ns_test, custom_greeting_model
custom_greetings = list()
@ns_test.route('/')
class Hello(Resource):
@ns_test.doc('say_hello')
def get(self):
return 'hello', 200
@ns_test.route('/custom')
class Custom(Resource):
@ns_test.doc('custom_hello')
@ns_test.expect(custom_greeting_model)
@ns_test.marshal_with(custom_greeting_model)
def post(self, **kwargs):
custom_greetings.append(greeting)
pos = len(custom_greetings) - 1
return [{'id': pos, 'greeting': greeting}], 200我是如何测试的&我所期望的
因此,转到swagger页面,我希望定义的两个端点都在那里,但我只看到了前面提到的错误。
仅在shell中使用Ipython,我就尝试跟踪使用请求的调用,然后只返回404。
import json
import requests as r
base_url = 'http://127.0.0.1:5000/'response = r.get(base_url + 'api/test')
responseresponse = r.get(base_url + 'api/test/')
responsedata = json.dumps({'greeting': 'hi'})
response = r.post(base_url + 'test/custom', data=data)
responsedata = json.dumps({'greeting': 'hi'})
response = r.post(base_url + 'test/custom/', data=data)
response发布于 2020-09-10 15:56:57
TL;DR
我在代码和测试中犯了一些错误:
post方法,做了一个简单的假设。expect装饰器中使用模型而不是请求解析器api/前缀调用测试中的端点。全数
我相信这是因为在声明任何路由之前,我在api上注册了名称空间。
我的理解是,当api在应用程序上注册时,应用程序上的“傲慢文档”和“路由”就会在那时设置好。因此,在此之后在api上定义的任何路由都不被认可。我认为这是因为当我在views/test.py文件中声明名称空间(也是避免该文件与views/__init__.py之间的循环引用的模型)时,swagger文档定义了路由,并且我的测试工作正常(在我更正了它们之后)。
在我的应用程序和测试中还有更多的错误,它们是
进一步的错误1
在我的应用程序中,在views/test.py文件中,我做了一个愚蠢的假设:变量将由预期的参数组成(我将神奇地让问候作为某个非局部变量)。查看文档,我了解到了RequestParser,我需要像这样声明一个
from flask_restx import reqparse
# Parser
custom_greeting_parser = reqparse.RequestParser()
custom_greeting_parser.add_argument('greeting', required=True, location='json')并在expect装饰器中使用这个。然后,我可以在post方法中检索参数的字典。用下面的
...
def post(self):
args = custom_greeting_parser.parse_args()
greeting = args['greeting']
...结果证明,**kwargs是不必要的。
进一步的错误2
在我的测试中,我调用端点api/test,这是不正确的,它只是test。对此端点的校正测试为
test 端点的校正测试
import json
import requests as r
base_url = 'http://127.0.0.1:5000/'
response = r.get(base_url + 'test')
print(response)
print(json.loads(response.content.decode()))进一步的错误3
对于另一个端点post的测试,我需要包含一个声明内容类型的头,以便解析器能够“看到”参数,因为我已经明确地将这个位置指定为json。下面的校正测试。
test/custom 端点的校正测试
import json
import requests as r
base_url = 'http://127.0.0.1:5000/'
data = json.dumps({'greeting': 'hi'})
headers = {'content-type': 'application/json'}
response = r.post(base_url + 'test/custom', data=data, headers=headers)
print(response)
print(json.loads(response.content.decode()))修正码
对于具有错误代码的文件。
views/init.py
from flask_restx import Api
from project.views.test import ns_test
api = Api(
title='TEST API',
version='1.0',
description='Testing Flask-RestX API.'
)
# Add namespaces
api.add_namespace(ns_test)views/test.py
from flask_restx import Resource, Namespace, fields, reqparse
# Namespace
ns_test = Namespace('test', description='a test namespace')
# Models
custom_greeting_model = ns_test.model('Custom', {
'greeting': fields.String(required=True),
'id': fields.Integer(required=True),
})
# Parser
custom_greeting_parser = reqparse.RequestParser()
custom_greeting_parser.add_argument('greeting', required=True, location='json')
custom_greetings = list()
@ns_test.route('/')
class Hello(Resource):
@ns_test.doc('say_hello')
def get(self):
return 'hello', 200
@ns_test.route('/custom')
class Custom(Resource):
@ns_test.doc('custom_hello')
@ns_test.expect(custom_greeting_parser)
@ns_test.marshal_with(custom_greeting_model)
def post(self):
args = custom_greeting_parser.parse_args()
greeting = args['greeting']
custom_greetings.append(greeting)
pos = len(custom_greetings) - 1
return [{'id': pos, 'greeting': greeting}], 200https://stackoverflow.com/questions/63763884
复制相似问题