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.
 
 
 
 

209 lines
5.3 KiB

import json
import redis
from flask import Flask, request, Response
from pymongo import MongoClient, errors
from bson import json_util
from flasgger import Swagger
from utils import read_docker_secret
from caching import cache, cache_invalidate
app = Flask(__name__)
swagger = Swagger(app)
users = MongoClient("mongodb", 27017).demo.users
redis_cache = redis.Redis(
host="redis", port=6379, db=0, password=read_docker_secret("REDIS_PASSWORD")
)
@app.route("/users/<int:userid>", methods=["POST"])
def add_user(userid):
"""Create user
---
parameters:
- name: userid
in: path
type: string
required: true
- name: email
in: formData
type: string
required: true
- name: name
in: formData
type: string
required: true
responses:
200:
description: Creation succeded
"""
request_params = request.form
if "email" not in request_params or "name" not in request_params:
return Response(
"Email and name not present in parameters!",
status=404,
mimetype="application/json",
)
try:
users.insert_one(
{
"_id": userid,
"email": request_params["email"],
"name": request_params["name"],
}
)
except errors.DuplicateKeyError as e:
return Response("Duplicate user id!", status=404, mimetype="application/json")
return Response(
json.dumps(users.find_one({"_id": userid})),
status=200,
mimetype="application/json",
)
@app.route("/users/<int:userid>", methods=["PUT"])
@cache_invalidate(redis=redis_cache, key="userid")
def update_user(userid):
"""Update user information
---
parameters:
- name: userid
in: path
type: string
required: true
- name: email
in: formData
type: string
required: false
- name: name
in: formData
type: string
required: false
responses:
200:
description: Update succeded
"""
request_params = request.form
if "email" not in request_params and "name" not in request_params:
return Response(
"Email or name must be present in parameters!",
status=404,
mimetype="application/json",
)
set = {}
if "email" in request_params:
set["email"] = request_params["email"]
if "name" in request_params:
set["name"] = request_params["name"]
users.update_one({"_id": userid}, {"$set": set})
return Response(
json.dumps(users.find_one({"_id": userid})),
status=200,
mimetype="application/json",
)
@app.route("/users/<int:userid>", methods=["GET"])
@cache(redis=redis_cache, key="userid")
def get_user(userid):
"""Details about a user
---
parameters:
- name: userid
in: path
type: string
required: true
definitions:
User:
type: object
properties:
_id:
type: integer
email:
type: string
name:
type: string
responses:
200:
description: User model
schema:
$ref: '#/definitions/User'
404:
description: User not found
"""
user = users.find_one({"_id": userid})
print("getting user")
if None == user:
return Response("", status=404, mimetype="application/json")
return Response(json.dumps(user), status=200, mimetype="application/json")
@app.route("/users", methods=["GET"])
def get_users():
"""Example endpoint returning all users with pagination
---
parameters:
- name: limit
in: query
type: integer
required: false
- name: offset
in: query
type: integer
required: false
definitions:
Users:
type: array
items:
properties:
_id:
type: integer
email:
type: string
name:
type: string
responses:
200:
description: List of user models
schema:
$ref: '#/definitions/Users'
"""
request_args = request.args
limit = int(request_args.get("limit")) if "limit" in request_args else 10
offset = int(request_args.get("offset")) if "offset" in request_args else 0
user_list = users.find().limit(limit).skip(offset)
if None == users:
return Response(json.dumps([]), status=200, mimetype="application/json")
extracted = [
{"userid": d["_id"], "name": d["name"], "email": d["email"]} for d in user_list
]
return Response(
json.dumps(extracted, default=json_util.default),
status=200,
mimetype="application/json",
)
@app.route("/users/<int:userid>", methods=["DELETE"])
@cache_invalidate(redis=redis_cache, key="userid")
def delete_user(userid):
"""Delete operation for a user
---
parameters:
- name: userid
in: path
type: string
required: true
responses:
200:
description: User deleted
"""
users.delete_one({"_id": userid})
return Response("", status=200, mimetype="application/json")
if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0", port=5000)