Simple REST service with a Flask for MAT2
Not an issue, but it may be worthful for someone.
I have created a simple container that offers one endpoint that takes a file to clear and returned a clear one.
Dockerfile
FROM python:3.7.3-stretch
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
curl \
pkg-config \
python3-gi-cairo \
gir1.2-poppler-0.18 \
gir1.2-gdkpixbuf-2.0 \
libimage-exiftool-perl \
libgirepository1.0-dev \
&& apt-get autoremove \
&& rm -r /var/lib/apt/lists/*
RUN pip install \
Flask==1.0.2 \
mat2==0.9.0 \
Werkzeug==0.15.2
WORKDIR /usr/src/metadata
ADD app.py .
ENTRYPOINT ["python"]
CMD ["app.py"]
app.py
import os
from flask import Flask, jsonify, request, send_file, after_this_request
from werkzeug import secure_filename
import tempfile
import shutil
import subprocess
class InvalidUsage(Exception):
status_code = 400
def __init__(self, message, status_code=None, payload=None):
Exception.__init__(self)
self.message = message
if status_code is not None:
self.status_code = status_code
self.payload = payload
def to_dict(self):
rv = dict(self.payload or ())
rv['message'] = self.message
return rv
app = Flask(__name__)
@app.errorhandler(InvalidUsage)
def handle_invalid_usage(error):
response = jsonify(error.to_dict())
response.status_code = error.status_code
return response
@app.route("/")
def form():
return '''
<!doctype html>
<title>MAT2</title>
<h1>Upload File to clear</h1>
<form method="post" enctype="multipart/form-data" action="/clear-metadata">
<input type="file" name="file">
<input type="submit" value="Clear metadata">
</form>
'''
@app.route('/clear-metadata', methods=['POST'])
def clear_file():
if 'file' not in request.files: raise InvalidUsage('File is missing.')
file = request.files['file']
if file.filename == '': raise InvalidUsage('Empty filename.')
filename = secure_filename(file.filename)
dirpath = tempfile.mkdtemp()
targetFilename = os.path.join(dirpath, filename)
file.save(targetFilename)
subprocess.check_output(['mat2', targetFilename])
fname, extension = os.path.splitext(targetFilename)
outputFilename = fname + '.cleaned' + extension
@after_this_request
def remove_file(response):
try:
shutil.rmtree(dirpath)
except Exception as error:
app.logger.error("Error removing or closing downloaded file handle", error)
return response
return send_file(outputFilename, as_attachment=True, attachment_filename=os.path.basename(targetFilename))
app.run(host='0.0.0.0')