折腾:
【已解决】CentOS服务器中搭建Python的Flask的REST API
期间,接着折腾。
去尝试连接远程的MongoDB,并且连接后,去查询gridfs中是否有想要的文件名的数据并返回
flask mongodb
Flask-PyMongo — Flask-PyMongo 0.5.1 documentation
Flask-MongoAlchemy
类似于SQLAlchemy
Flask-MongoKit
PyMongo
Flask PyMongo 中文文档 | Flask 扩展文档汇总
MongoKit in Flask — Flask Documentation (0.12)
PyMongo 3.6.1 Documentation — PyMongo 3.6.1 documentation
dcrosta/flask-pymongo: PyMongo support for Flask applications
决定用:flask-pymongo
先去安装:
<code>➜ robotDemo pipenv install flask-pymongo Installing flask-pymongo… Collecting flask-pymongo Downloading https://files.pythonhosted.org/packages/fa/71/ab920741dedd605ef4adbd57d0c7d9f43a6b6fe4068604fffbc6f64b2c9c/Flask_PyMongo-0.5.1-py3-none-any.whl Requirement already satisfied: Flask>=0.8 in /Users/crifan/.local/share/virtualenvs/robotDemo-HXjMJQEQ/lib/python3.6/site-packages (from flask-pymongo) (0.12.2) Collecting PyMongo>=2.5 (from flask-pymongo) Downloading https://files.pythonhosted.org/packages/5c/7f/1f7240883ec3fa768d7e066c9cbd42ceb42d699ba1a0fb9d231c098a542d/pymongo-3.6.1-cp36-cp36m-macosx_10_6_intel.whl (316kB) Requirement already satisfied: click>=2.0 in /Users/crifan/.local/share/virtualenvs/robotDemo-HXjMJQEQ/lib/python3.6/site-packages (from Flask>=0.8->flask-pymongo) (6.7) Requirement already satisfied: itsdangerous>=0.21 in /Users/crifan/.local/share/virtualenvs/robotDemo-HXjMJQEQ/lib/python3.6/site-packages (from Flask>=0.8->flask-pymongo) (0.24) Requirement already satisfied: Jinja2>=2.4 in /Users/crifan/.local/share/virtualenvs/robotDemo-HXjMJQEQ/lib/python3.6/site-packages (from Flask>=0.8->flask-pymongo) (2.10) Requirement already satisfied: Werkzeug>=0.7 in /Users/crifan/.local/share/virtualenvs/robotDemo-HXjMJQEQ/lib/python3.6/site-packages (from Flask>=0.8->flask-pymongo) (0.14.1) Requirement already satisfied: MarkupSafe>=0.23 in /Users/crifan/.local/share/virtualenvs/robotDemo-HXjMJQEQ/lib/python3.6/site-packages (from Jinja2>=2.4->Flask>=0.8->flask-pymongo) (1.0) Installing collected packages: PyMongo, flask-pymongo Successfully installed PyMongo-3.6.1 flask-pymongo-0.5.1 Adding flask-pymongo to Pipfile's [packages]… Pipfile.lock (09e966) out of date, updating to (36c54e)… Locking [dev-packages] dependencies… Locking [packages] dependencies… Updated Pipfile.lock (36c54e)! Installing dependencies from Pipfile.lock (36c54e)… 🐍 ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 12/12 — 00:00:03 To activate this project's virtualenv, run the following: $ pipenv shell ➜ robotDemo pipenv graph Flask-PyMongo==0.5.1 - Flask [required: >=0.8, installed: 0.12.2] - click [required: >=2.0, installed: 6.7] - itsdangerous [required: >=0.21, installed: 0.24] - Jinja2 [required: >=2.4, installed: 2.10] - MarkupSafe [required: >=0.23, installed: 1.0] - Werkzeug [required: >=0.7, installed: 0.14.1] - PyMongo [required: >=2.5, installed: 3.6.1] Flask-RESTful==0.3.6 - aniso8601 [required: >=0.82, installed: 3.0.0] - Flask [required: >=0.8, installed: 0.12.2] - click [required: >=2.0, installed: 6.7] - itsdangerous [required: >=0.21, installed: 0.24] - Jinja2 [required: >=2.4, installed: 2.10] - MarkupSafe [required: >=0.23, installed: 1.0] - Werkzeug [required: >=0.7, installed: 0.14.1] - pytz [required: Any, installed: 2018.4] - six [required: >=1.3.0, installed: 1.11.0] </code>
然后去写代码
结果出错:
【已解决】Flask-PyMongo出错:RuntimeError Working outside of application context
然后继续去find对应的gridfs中的文件:
【规避解决】Flask-PyMongo中如何查询gridfs中的文件
最后是去用代码:
<code>from flask import Flask from flask import jsonify from flask_restful import Resource, Api, reqparse import logging from logging.handlers import RotatingFileHandler # from flask_pymongo import PyMongo from gridfs import GridFS from pymongo import MongoClient import re app = Flask(__name__) FLASK_APP = "RobotQA" LOG_FILE_FILENAME = "logs/" + FLASK_APP + ".log" LOG_FORMAT = "[%(asctime)s %(levelname)s %(filename)s:%(lineno)d %(funcName)s] %(message)s" app.config['LOG_FILE_FILENAME'] = LOG_FILE_FILENAME app.config["LOG_FORMAT"] = LOG_FORMAT logFormatterStr = app.config["LOG_FORMAT"] logFormatter = logging.Formatter(logFormatterStr) fileHandler = RotatingFileHandler( app.config['LOG_FILE_FILENAME'], maxBytes=2*1024*1024, backupCount=3, encoding="UTF-8") fileHandler.setLevel(logging.DEBUG) fileHandler.setFormatter(logFormatter) app.logger.addHandler(fileHandler) streamHandler = logging.StreamHandler() streamHandler.setFormatter(logFormatter) streamHandler.setLevel(logging.INFO) app.logger.addHandler(streamHandler) app.logger.setLevel(logging.DEBUG) # set root log level log = app.logger log.debug("debug: app=%s", app) api = Api(app) log.info("api=%s", api) # Flask-PyMongo NOT work: gridfs can NOT find files # app.config.update( # MONGO_HOST='x.x.x.x', # MONGO_PORT=12345, # MONGO_USERNAME='gridfs', # MONGO_PASSWORD=‘xxx', # MONGO_DBNAME='gridfs' # ) # flaskPymongo = PyMongo(app) # log.info("flaskPymongo=%s", flaskPymongo) # purePymongo = MongoClient(mongodbUri) purePymongo = MongoClient( host="x.x.x.x", port=12345, username="gridfs", password=“xxx", authSource="gridfs" ) log.info("purePymongo=%s", purePymongo) # Pure PyMongo gridfsDb = purePymongo.gridfs # Database(MongoClient(host=['x.x.x.x:12345'], document_class=dict, tz_aware=False, connect=True, authsource='gridfs'), 'gridfs') logging.info("gridfsDb=%s", gridfsDb) fsCollection = GridFS(gridfsDb) # <gridfs.GridFS object at 0x1107b2390> logging.info("fsCollection=%s", fsCollection) class RobotAPI(Resource): def get(self): respDict = { "code": 200, "message": "generate answer ok", "data": { "answer": "None", "audio": {} } } parser = reqparse.RequestParser() parser.add_argument('q', type=str, help="input question") # play a Christmas song log.info("parser=%s", parser) parsedArgs = parser.parse_args() #{'q': 'play a sleep song'} log.info("parsedArgs=%s", parsedArgs) if not parsedArgs: respDict["data"]["answer"] = "Can not recognize question" return jsonify(respDict) q = parsedArgs["q"] log.info("q=%s", q) if not q: respDict["data"]["answer"] = "Can not recognize parameter q" return jsonify(respDict) foundSongName = re.search("play a (?P<songName>.+?) song", q) log.info("foundSongName=%s", foundSongName) if not foundSongName: respDict["data"]["answer"] = "Can not recognize song name" return jsonify(respDict) songName = foundSongName.group("songName") log.info("songName=%s", songName) # # Flask-PyMongo # mongoDb = flaskPymongo.db #Database(MongoClient(host=['x.x.x.x:12345'], document_class=dict, tz_aware=True, connect=True, replicaset=None), 'gridfs') # log.info("mongoDb=%s", mongoDb) # gridfsDb = mongoDb.gridfs #Collection(Database(MongoClient(host=['x.x.x.x:12345'], document_class=dict, tz_aware=True, connect=True, replicaset=None), 'gridfs'), 'gridfs') # log.info("gridfsDb=%s", gridfsDb) # fsCollection = gridfsDb.fs #Collection(Database(MongoClient(host=['x.x.x.x:12345'], document_class=dict, tz_aware=True, connect=True, replicaset=None), 'gridfs'), 'gridfs.fs') # log.info("fsCollection=%s", fsCollection) # filesCollection = fsCollection.files # Collection(Database(MongoClient(host=['x.x.x.x:12345'], document_class=dict, tz_aware=True, connect=True, replicaset=None), 'gridfs'), 'gridfs.fs.files') # log.info("filesCollection=%s", filesCollection) # fsFindOne = fsCollection.find_one() # <gridfs.grid_file.GridOut object at 0x110a87fd0> # log.info("fsFindOne=%s", fsFindOne) # gridFineOne = gridfsDb.find_one() # # log.info("gridFineOne=%s", gridFineOne) # # filesFindOne = filesCollection.find_one() # log.info("filesFindOne=%s", filesFindOne) filenameRegex = re.compile(songName, re.IGNORECASE) log.info("filenameRegex=%s", filenameRegex) # findFileCursor = gridfsDb.fs.find({"filename": findRegex}) # findFileCursor = gridfsDb.fs.find({"filename": {"$regex": findRegex, "$options": "i"}}) # findFileCursor = fsCollection.find({"filename": {"$regex": "sleep"}}) # findFileCursor = fsCollection.find({"filename": {"$regex": "sleep", "$options": "i"}}) findFileCursor = fsCollection.find({"filename": {"$regex": filenameRegex, "$options": "i"}}) log.info("findFileCursor=%s", findFileCursor) findFileCount = findFileCursor.count() log.info("findFileCount=%s", findFileCount) if findFileCount <= 0: respDict["data"]["answer"] = "Can not found any file for name %s" % (songName) return jsonify(respDict) lastFoundAudio = None for curIdx, eachFile in enumerate(findFileCursor): curNum = curIdx + 1 log.info("[%d] contentType=%s, filename=%s", curNum, eachFile.contentType, eachFile.filename) if re.match("audio/", eachFile.contentType): lastFoundAudio = eachFile if not lastFoundAudio: respDict["data"]["answer"] = "Found file but not found audio song" return jsonify(respDict) respDict["data"] = { "answer": "Now will play a %s song %s" % (songName, lastFoundAudio.filename), "audio": { "contentType": lastFoundAudio.contentType, "name": lastFoundAudio.filename, "url": "http://x.x.x.x/%s" % (lastFoundAudio.filename) } } return jsonify(respDict) api.add_resource(RobotAPI, '/qa', endpoint='qa') if __name__ == "__main__": # app.debug = True app.run() </code>
实现了想要的效果:
输入一段文字,格式是:
play a xxx song
然后内部连接mongo去find到对应的audio文件,并返回对应的信息:
期间还打印出其他的搜到的文件: