-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathapi.py
92 lines (71 loc) · 2.53 KB
/
api.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import logging
from io import BytesIO
from PIL import Image
from flask import Flask, request, send_file, abort
from flask_cors import CORS
from flask_limiter import Limiter
from recipe import parse_ingredients, run_action
from watermark import parse_watermark
logging.basicConfig(
format='%(asctime)s %(levelname)-8s %(message)s',
level=logging.INFO,
datefmt='%Y-%m-%d %H:%M:%S')
app = Flask(__name__)
CORS(app)
def get_remote_address():
return request.headers.get('X-Forwarded-For', request.remote_addr)
limiter = Limiter(
get_remote_address,
app=app,
storage_uri="memory://",
)
@app.route("/upload", methods=["POST"])
@limiter.limit("60 per minute")
def upload():
try:
quality = int(request.form.get('quality', '10'))
except ValueError:
return abort(400, "Cannot parse parameter/s")
try:
watermark = parse_watermark(request.form.get('watermark', ''))
except Exception as e:
return abort(400, "Cannot parse watermark", e)
try:
ingredients = parse_ingredients(request.form.get('ingredients', '[]'))
except Exception as exception:
return abort(400, exception)
# read body image
body_image = request.files['file']
if not body_image:
return abort(400, "It appears that you didn't upload an image.")
try:
img = Image.open(body_image.stream)
except Exception:
return abort(400, "The file you uploaded does not appear to be a valid image.")
logging.info(f"{get_remote_address()} requested to enhance to " +
f"quality = {quality} with watermark = {str(watermark)}")
# discard alpha channel (since JPEG can't handle alpha)
if img.mode != "RGB":
logging.info(" >> The uploaded image is not RGB. trying to convert.")
try:
img = img.convert("RGB")
except Exception:
return abort(400, "cannot convert image to RGB")
# run ingredients
for ingredient in ingredients:
try:
img = run_action(ingredient.identifier, ingredient.options, img)
except Exception as exception:
return abort(400, exception)
if img.mode != "RGB":
img = img.convert("RGB")
# add watermark (if enabled)
img = watermark.paint(img)
# "enhance" quality and return
out = BytesIO()
img.save(out, 'JPEG', quality=quality)
out.seek(0)
logging.info(f" >> Image enhanced to {out.getbuffer().nbytes} bytes")
return send_file(out, mimetype="image/jpeg")
if __name__ == "__main__":
app.run(debug=True)