如何在Python中正确映射用户定义的方法以获取/发布HTTP调用?
我不熟悉Python Flask,并尝试在其中实现API。 为此,我创建了两个API,它们将接收值,然后显示值。 代码: 对方法如何在Python中正确映射用户定义的方法以获取/发布HTTP调用?,python,flask,Python,Flask,我不熟悉Python Flask,并尝试在其中实现API。 为此,我创建了两个API,它们将接收值,然后显示值。 代码: 对方法POST和GET的调用工作正常,如图所示。 但是当我运行第三个API时,它提供了列表中的所有条目:vehicles,代码给出了一个错误,表示它需要一个参数name Traceback (most recent call last): File "/Users/bobby/PyCharmProjects/FlaskAPI/venv/lib/python3.
POST
和GET
的调用工作正常,如图所示。
但是当我运行第三个API时,它提供了列表中的所有条目:vehicles
,代码给出了一个错误,表示它需要一个参数name
Traceback (most recent call last):
File "/Users/bobby/PyCharmProjects/FlaskAPI/venv/lib/python3.7/site-packages/flask/app.py", line 2464, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/bobby/PyCharmProjects/FlaskAPI/venv/lib/python3.7/site-packages/flask/app.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "/Users/bobby/PyCharmProjects/FlaskAPI/venv/lib/python3.7/site-packages/flask_restful/__init__.py", line 272, in error_router
return original_handler(e)
File "/Users/bobby/PyCharmProjects/FlaskAPI/venv/lib/python3.7/site-packages/flask/app.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Users/bobby/PyCharmProjects/FlaskAPI/venv/lib/python3.7/site-packages/flask/_compat.py", line 38, in reraise
raise value.with_traceback(tb)
File "/Users/bobby/PyCharmProjects/FlaskAPI/venv/lib/python3.7/site-packages/flask/app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "/Users/bobby/PyCharmProjects/FlaskAPI/venv/lib/python3.7/site-packages/flask/app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/bobby/PyCharmProjects/FlaskAPI/venv/lib/python3.7/site-packages/flask_restful/__init__.py", line 272, in error_router
return original_handler(e)
File "/Users/bobby/PyCharmProjects/FlaskAPI/venv/lib/python3.7/site-packages/flask/app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/bobby/PyCharmProjects/FlaskAPI/venv/lib/python3.7/site-packages/flask/_compat.py", line 38, in reraise
raise value.with_traceback(tb)
File "/Users/bobby/PyCharmProjects/FlaskAPI/venv/lib/python3.7/site-packages/flask/app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/bobby/PyCharmProjects/FlaskAPI/venv/lib/python3.7/site-packages/flask/app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/bobby/PyCharmProjects/FlaskAPI/venv/lib/python3.7/site-packages/flask_restful/__init__.py", line 468, in wrapper
resp = resource(*args, **kwargs)
File "/Users/bobby/PyCharmProjects/FlaskAPI/venv/lib/python3.7/site-packages/flask/views.py", line 89, in view
return self.dispatch_request(*args, **kwargs)
File "/Users/bobby/PyCharmProjects/FlaskAPI/venv/lib/python3.7/site-packages/flask_restful/__init__.py", line 583, in dispatch_request
resp = meth(*args, **kwargs)
TypeError: get() missing 1 required positional argument: 'name'
我知道GET
调用调用的是代码中的GET()
,而不是getallvehicles()
。
是因为getallvehicles
是用户定义的方法吗?如果是这样的话,谁能告诉我如何将用户定义的方法映射到GET
或POST
或任何相应的调用。在这种情况下,如何映射getallvehicles
以获取http调用
方法1:
我可以向现有代码中添加一个额外的类,并在API中注册以返回列表中的所有数据:vehicles
class GetAllVehicles(Resource):
def get(self):
return {'vehicles': vehicles}
api.add_resource(GetAllVehicles, '/getallvehicles')
如何在不使用代码中的额外类的情况下实现相同的功能,并将
GET
映射到getallvehicles()
不完全符合您的要求,但我会使用关键字“all”作为获取API中所有车辆数据的可能输入
class VehicleData(Resource):
parser = reqparse.RequestParser()
parser.add_argument('vehicle', type=str, required=True, help='name cannot be empty')
parser.add_argument('type', type=str, required=True, help='vehicle type cannot be empty')
parser.add_argument('wheels', type=int, required=True, help='number of wheels cannot be empty')
parser.add_argument('suv', type=bool, required=False, help='SUV or not can be empty')
def get(self, name):
if name == 'all': # return all vehicles if 'all' keyword is passed
return {'vehicles': vehicles}
else:
vehicle = list(filter(lambda x: x['name'] == name, vehicles), None)
return {'vehicle': vehicle}, 200 if vehicle else 404
def post(self, name):
# data = request.get_json()
# sport.append({'sportname': data['sport_name'], 'team_size':data['team_size'], 'popularity':data['popularity']})
if next(filter(lambda x: x['name'] == name, vehicles), None) is not None:
print("in the IF BLOCK")
return {'message': 'The vehicle {n} already exists in the database'.format(n=name)}, 404
elif name == 'all': # prevent adding a vehicle named 'all'
return {'message': 'Invalid vehicle name'}, 404
v_data = VehicleData.parser.parse_args()
vehicle = {'name': name, 'type':v_data['type'], 'vehicle': v_data['vehicle'], 'suv': v_data['suv'], 'wheels': v_data['wheels']}
vehicles.append(vehicle)
return vehicle, 201
api.add_resource(VehicleData, '/addvehicle/<string:name>', '/getvehicle/<string:name>')
app.run(port=5000, debug=True)
class车辆数据(资源):
parser=reqparse.RequestParser()
parser.add_参数('vehicle',type=str,required=True,help='name不能为空')
parser.add_参数('type',type=str,required=True,help='vehicle type不能为空')
parser.add_参数('wheels',type=int,required=True,help='wheels的数量不能为空')
parser.add_参数('suv',type=bool,required=False,help='suv or not可以为空')
def get(自我,名称):
如果name==“all”:#如果传递了“all”关键字,则返回所有车辆
返回{'vehicles':车辆}
其他:
车辆=列表(过滤器(λx:x['name']==名称,车辆),无)
返回{'vehicle':vehicle},如果车辆为404,则返回200
def post(自我,姓名):
#data=request.get_json()
#追加({'sportname':数据['sport\u name'],'team\u size':数据['team\u size'],'popularity':数据['popularity']})
如果next(过滤器(λx:x['name']==名称,车辆),None)不是None:
打印(“在IF块中”)
返回{'message':'vehicle{n}已存在于数据库中。'format(n=name)},404
elif name=='all':#禁止添加名为'all'的车辆
返回{'message':'Invalid vehicle name'},404
v_data=VehicleData.parser.parse_args()
车辆={'name':名称,'type':车辆数据['type'],'vehicle':车辆数据['vehicle'],'suv':车辆数据['suv'],'wheels':车辆数据['wheels']}
车辆。附加(车辆)
返回车辆,201
api.add_资源(VehicleData,“/addvehicle/”,“/getvehicle/”)
运行(端口=5000,调试=True)
如果输入了url
/getvehicle/all
,上面修改的代码将返回所有车辆,并阻止在post()
函数中添加名为“all”的车辆。不确定我是否完全理解您的要求,但我的解释是您有三个端点:
from flask import Flask, request
global vehicles
vehicles = {}
my_app = Flask(__name__)
@my_app.route('/load_vehicle', methods=['POST'])
def load_vehicle():
"""
Example JSON:
{'compass':{'type':'car',
'vehicle':'automobile',
'suv':True,
'wheels':4}}
"""
global vehicles
json_in = request.get_json(silent=True)
if json_in != None:
vehicles.update(json_in)
@my_app.route('/get_vehicle', methods=['POST'])
def get_vehicle():
"""
Example JSON:
{'name':'compass'}
"""
global vehicles
json_in = request.get_json(silent=True)
if json_in != None:
output = vehicles[json_in['name']]
return output
@my_app.route('/get_all', methods=['GET'])
def get_all():
global vehicles
return vehicles
好啊代码中方法的名称是GET/PUT/POST等。我面临的错误是getallvehicles(),这是我给出的名称。我无法在类VehicleData中使用GET、PUT或POST来映射它。希望我现在明白了。是的,这是因为GET调用正在调用GET()。实现方法的唯一方法是使用一个新类将“/getallvehicles”映射到或扩展“get”方法。请参阅:该主题来自2013年,我使用的是Flask的最新版本。我想我现在不能用这个。
class VehicleData(Resource):
parser = reqparse.RequestParser()
parser.add_argument('vehicle', type=str, required=True, help='name cannot be empty')
parser.add_argument('type', type=str, required=True, help='vehicle type cannot be empty')
parser.add_argument('wheels', type=int, required=True, help='number of wheels cannot be empty')
parser.add_argument('suv', type=bool, required=False, help='SUV or not can be empty')
def get(self, name):
if name == 'all': # return all vehicles if 'all' keyword is passed
return {'vehicles': vehicles}
else:
vehicle = list(filter(lambda x: x['name'] == name, vehicles), None)
return {'vehicle': vehicle}, 200 if vehicle else 404
def post(self, name):
# data = request.get_json()
# sport.append({'sportname': data['sport_name'], 'team_size':data['team_size'], 'popularity':data['popularity']})
if next(filter(lambda x: x['name'] == name, vehicles), None) is not None:
print("in the IF BLOCK")
return {'message': 'The vehicle {n} already exists in the database'.format(n=name)}, 404
elif name == 'all': # prevent adding a vehicle named 'all'
return {'message': 'Invalid vehicle name'}, 404
v_data = VehicleData.parser.parse_args()
vehicle = {'name': name, 'type':v_data['type'], 'vehicle': v_data['vehicle'], 'suv': v_data['suv'], 'wheels': v_data['wheels']}
vehicles.append(vehicle)
return vehicle, 201
api.add_resource(VehicleData, '/addvehicle/<string:name>', '/getvehicle/<string:name>')
app.run(port=5000, debug=True)
from flask import Flask, request
global vehicles
vehicles = {}
my_app = Flask(__name__)
@my_app.route('/load_vehicle', methods=['POST'])
def load_vehicle():
"""
Example JSON:
{'compass':{'type':'car',
'vehicle':'automobile',
'suv':True,
'wheels':4}}
"""
global vehicles
json_in = request.get_json(silent=True)
if json_in != None:
vehicles.update(json_in)
@my_app.route('/get_vehicle', methods=['POST'])
def get_vehicle():
"""
Example JSON:
{'name':'compass'}
"""
global vehicles
json_in = request.get_json(silent=True)
if json_in != None:
output = vehicles[json_in['name']]
return output
@my_app.route('/get_all', methods=['GET'])
def get_all():
global vehicles
return vehicles