带有Mongo的Flask应用程序在可传递参数上出错



我在本地有一个flask应用程序和一个mongo实例,我正在使用lav设置,我想知道为什么当我将ID传递到API端点时会收到以下消息:

the-real-devops-challenge-devopschallenge-1  | Traceback (most recent call last):
the-real-devops-challenge-devopschallenge-1  |   File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2073, in wsgi_app
the-real-devops-challenge-devopschallenge-1  |     response = self.full_dispatch_request()
the-real-devops-challenge-devopschallenge-1  |   File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1518, in full_dispatch_request
the-real-devops-challenge-devopschallenge-1  |     rv = self.handle_user_exception(e)
the-real-devops-challenge-devopschallenge-1  |   File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1516, in full_dispatch_request
the-real-devops-challenge-devopschallenge-1  |     rv = self.dispatch_request()
the-real-devops-challenge-devopschallenge-1  |   File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1502, in dispatch_request
the-real-devops-challenge-devopschallenge-1  |     return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
the-real-devops-challenge-devopschallenge-1  |   File "./app.py", line 25, in restaurant
the-real-devops-challenge-devopschallenge-1  |     restaurants = find_restaurants(mongo, _id)
the-real-devops-challenge-devopschallenge-1  |   File "/code/src/mongoflask.py", line 30, in find_restaurants
the-real-devops-challenge-devopschallenge-1  |     query["_id"] = ObjectId(id)
the-real-devops-challenge-devopschallenge-1  |   File "/usr/local/lib/python3.7/site-packages/bson/objectid.py", line 105, in __init__
the-real-devops-challenge-devopschallenge-1  |     self.__validate(oid)
the-real-devops-challenge-devopschallenge-1  |   File "/usr/local/lib/python3.7/site-packages/bson/objectid.py", line 210, in __validate
the-real-devops-challenge-devopschallenge-1  |     "not %s" % (type(oid),))
the-real-devops-challenge-devopschallenge-1  | TypeError: id must be an instance of (bytes, str, ObjectId), not <class 'builtin_function_or_method'>

我尝试了很多方法让它返回JSON对象,但都不起作用。我知道这与我通过_id的方式有关,但我不确定如何解决:

app.py的代码:

from os import environ
from bson import json_util
from bson.objectid import ObjectId
from flask import Flask, jsonify
from flask_pymongo import PyMongo
from src.mongoflask  import MongoJSONEncoder, ObjectIdConverter, find_restaurants
app = Flask(__name__)
app.config["MONGO_URI"] = environ.get("MONGO_URI")
app.json_encoder = MongoJSONEncoder
app.url_map.converters["objectid"] = ObjectIdConverter
mongo = PyMongo(app)

@app.route("/api/v1/restaurant")
def restaurants():
restaurants = find_restaurants(mongo)
return jsonify(restaurants)

@app.route("/api/v1/restaurant/<_id>")
def restaurant(_id):
restaurants = find_restaurants(mongo, _id)
return jsonify(restaurants)
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=False, port=8080)

mongo.py 代码

from datetime import date, datetime
import isodate as iso
from bson import ObjectId
from flask.json import JSONEncoder
from werkzeug.routing import BaseConverter

class MongoJSONEncoder(JSONEncoder):
def default(self, o):
if isinstance(o, (datetime, date)):
return iso.datetime_isoformat(o)
if isinstance(o, ObjectId):
return str(o)
else:
return super().default(o)

class ObjectIdConverter(BaseConverter):
def to_python(self, value):
return ObjectId(value)
def to_url(self, value):
return str(value)
def find_restaurants(mongo, _id=""):
query = {}
if _id != "":
print(_id)
query["_id"] = ObjectId(id)
return list(mongo.db.restaurant.find(query))

当我卷曲时:

curl localhost:8080/api/v1/restaurant

它有效,但当我尝试时:

curl localhost:8080/api/v1/restaurant/55f14313c7447c3da7052485

它失败了:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>500 Internal Server Error</title>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.</p>

原来我在query["_id"] = ObjectId(id)中有一个类型,它应该是query["_id"] = ObjectId(_id):

from datetime import date, datetime
import isodate as iso
from bson import ObjectId
from flask.json import JSONEncoder
from werkzeug.routing import BaseConverter

class MongoJSONEncoder(JSONEncoder):
def default(self, o):
if isinstance(o, (datetime, date)):
return iso.datetime_isoformat(o)
if isinstance(o, ObjectId):
return str(o)
else:
return super().default(o)

class ObjectIdConverter(BaseConverter):
def to_python(self, value):
return ObjectId(value)
def to_url(self, value):
return str(value)
def find_restaurants(mongo, _id=""):
query = {}
if _id != "":
print(_id)
query["_id"] = ObjectId(_id)
return list(mongo.db.restaurant.find(query))

最新更新