You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
115 lines
3.0 KiB
115 lines
3.0 KiB
import sys
|
|
import json, datetime
|
|
|
|
from flask import Flask, request, Response
|
|
from flask_httpauth import HTTPBasicAuth
|
|
from werkzeug.security import generate_password_hash, check_password_hash
|
|
from flasgger import Swagger
|
|
from pymongo import MongoClient, TEXT
|
|
from bson import json_util
|
|
|
|
|
|
app = Flask(__name__)
|
|
auth = HTTPBasicAuth()
|
|
swagger_template = {"securityDefinitions": {"basicAuth": {"type": "basic"}}}
|
|
users = {
|
|
"admin": generate_password_hash("changeme"),
|
|
}
|
|
|
|
|
|
@auth.verify_password
|
|
def verify_password(username, password):
|
|
if username in users and check_password_hash(users.get(username), password):
|
|
return username
|
|
|
|
|
|
swagger = Swagger(app, template=swagger_template)
|
|
mongo_host = "mongodb"
|
|
if len(sys.argv) == 2:
|
|
mongo_host = sys.argv[1]
|
|
fulltext_search = MongoClient(mongo_host, 27017).demo.fulltext_search
|
|
|
|
|
|
@app.route("/search/<string:searched_expression>")
|
|
@auth.login_required
|
|
def search(searched_expression: str):
|
|
"""Search by an expression
|
|
---
|
|
parameters:
|
|
- name: searched_expression
|
|
in: path
|
|
type: string
|
|
required: true
|
|
definitions:
|
|
Result:
|
|
type: object
|
|
properties:
|
|
app_text:
|
|
type: string
|
|
indexed_date:
|
|
type: date
|
|
responses:
|
|
200:
|
|
description: List of results
|
|
schema:
|
|
$ref: '#/definitions/Result'
|
|
"""
|
|
results = (
|
|
fulltext_search.find(
|
|
{"$text": {"$search": searched_expression}},
|
|
{"score": {"$meta": "textScore"}},
|
|
)
|
|
.sort([("score", {"$meta": "textScore"})])
|
|
.limit(10)
|
|
)
|
|
results = [
|
|
{"text": result["app_text"], "date": result["indexed_date"].isoformat()}
|
|
for result in results
|
|
]
|
|
return Response(
|
|
json.dumps(list(results), default=json_util.default),
|
|
status=200,
|
|
mimetype="application/json",
|
|
)
|
|
|
|
|
|
@app.route("/fulltext", methods=["PUT"])
|
|
@auth.login_required
|
|
def add_expression():
|
|
"""Add an expression to fulltext index
|
|
---
|
|
parameters:
|
|
- name: expression
|
|
in: formData
|
|
type: string
|
|
required: true
|
|
responses:
|
|
200:
|
|
description: Creation succeded
|
|
"""
|
|
request_params = request.form
|
|
if "expression" not in request_params:
|
|
return Response(
|
|
'"Expression" must be present as a POST parameter!',
|
|
status=404,
|
|
mimetype="application/json",
|
|
)
|
|
document = {
|
|
"app_text": request_params["expression"],
|
|
"indexed_date": datetime.datetime.utcnow(),
|
|
}
|
|
fulltext_search.save(document)
|
|
return Response(
|
|
json.dumps(document, default=json_util.default),
|
|
status=200,
|
|
mimetype="application/json",
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# create the fulltext index
|
|
fulltext_search.create_index(
|
|
[("app_text", TEXT)], name="fulltextsearch_index", default_language="english"
|
|
)
|
|
# starts the app in debug mode, bind on all ip's and on port 5000
|
|
app.run(debug=True, host="0.0.0.0", port=5000)
|
|
|