[英]How to properly map user defined methods to GET/POST HTTP calls in Python Flask?
我是 Python-Flask 的新手,並試圖在其中實現 API。 為此,我創建了兩個 API,它們將接收值然后顯示值。 代碼:
from flask import Flask, jsonify, request
from flask_restful import Resource, Api, reqparse
app = Flask(__name__)
api = Api(app)
vehicles = []
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):
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 vehicel {n} already exists in the database'.format(n=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
def getallvehicles(self):
return {'vehicles': vehicles}
api.add_resource(VehicleData, '/addvehicle/<string:name>', '/getvehicle/<string:name>', '/getallvehicles')
app.run(port=5000, debug=True)
Api 調用:
http://127.0.0.1:5000/addvehicle/polo
http://127.0.0.1:5000/getvehicle/polo
http://127.0.0.1:5000/getallvehicles
但是當我運行第三個 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
是用戶定義的方法嗎? 如果是這樣,任何人都可以讓我知道如何POST
用戶定義的方法來GET
或發布或任何相應的調用。 在這種情況下,我如何 map getallvehicles
來 GET http 調用?
方法 1:我可以在我的 API 中的現有代碼和寄存器中添加額外的 class 以返回列表中的所有數據: vehicles
class GetAllVehicles(Resource):
def get(self):
return {'vehicles': vehicles}
api.add_resource(GetAllVehicles, '/getallvehicles')
如何在代碼中不使用額外的 class 和 map 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)
如果輸入了 url /getvehicle/all
,上面的修改后的代碼將返回所有車輛,並防止在post()
function 中添加名為“all”的汽車。
不確定我是否完全理解您的要求,但我的解釋是您有三個端點:
我建議將 output 存儲在嵌套字典中,因為這樣更容易操作。
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.