# USAGE
# Start the server:
#     python app.py
# Submit a request via cURL:
#     curl -X POST -F image=@dog.jpg 'http://localhost:5000/predict'

# import the necessary packages
from tensorflow.keras.applications import ResNet50
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.applications import imagenet_utils
from tensorflow.python.keras.backend import set_session
from PIL import Image
import numpy as np
import flask
import io
import tensorflow as tf

from tensorflow.python.framework.ops import disable_eager_execution

disable_eager_execution()

# initialize our Flask application and the Keras model
app = flask.Flask(__name__)
app.config['UPLOAD_FOLDER'] = '/tmp'
model = None
sess = tf.compat.v1.Session()

def load_model():
    # load the pre-trained Keras model (here we are using a model
    # pre-trained on ImageNet and provided by Keras, but you can
    # substitute in your own networks just as easily)
    global model
    global sess
    set_session(sess)
    model = ResNet50(weights="imagenet")
    global graph
    graph = tf.compat.v1.get_default_graph()

def prepare_image(image, target):
    # if the image mode is not RGB, convert it
    if image.mode != "RGB":
        image = image.convert("RGB")

    # resize the input image and preprocess it
    image = image.resize(target)
    image = img_to_array(image)
    image = np.expand_dims(image, axis=0)
    image = imagenet_utils.preprocess_input(image)

    # return the processed image
    return image

@app.route("/predict", methods=["POST"])
def predict():
    # initialize the data dictionary that will be returned from the
    # view
    data = {"success": False}

    # ensure an image was properly uploaded to our endpoint
    if flask.request.method == "POST":
        if flask.request.files.get("image"):
            # read the image in PIL format
            image = flask.request.files["image"].read()
            image = Image.open(io.BytesIO(image))

            # preprocess the image and prepare it for classification
            image = prepare_image(image, target=(224, 224))

            # classify the input image and then initialize the list
            # of predictions to return to the client
            global sess
            with graph.as_default():
                set_session(sess)
                preds = model.predict(image)
                results = imagenet_utils.decode_predictions(preds)
                data["predictions"] = []

                # loop over the results and add them to the list of
                # returned predictions
                for (imagenetID, label, prob) in results[0]:
                    r = {"label": label, "probability": float(prob)}
                    data["predictions"].append(r)

                # indicate that the request was a success
                data["success"] = True

    # return the data dictionary as a JSON response
    return flask.jsonify(data)

# if this is the main thread of execution first load the model and
# then start the server
if __name__ == "__main__":
    print(("* Loading Keras model and Flask starting server..."
        "please wait until server has fully started"))
    load_model()
    app.run(host='0.0.0.0')

tensorflow.compat.v1.get_default_graph numpy.expand_dims tensorflow.keras.applications.imagenet_utils.preprocess_input tensorflow.keras.applications.imagenet_utils.decode_predictions tensorflow.compat.v1.Session tensorflow.keras.applications.ResNet50 tensorflow.python.keras.backend.set_session tensorflow.python.framework.ops.disable_eager_execution tensorflow.keras.preprocessing.image.img_to_array
[(20, 'tensorflow.python.framework.ops.disable_eager_execution', 'disable_eager_execution', ([], {}), False, 'from tensorflow.python.framework.ops import disable_eager_execution\n'), (23, 'flask.Flask', 'flask.Flask', (['__name__'], {}), False, 'import flask\n'), (26, 'tensorflow.compat.v1.Session', 'tf.compat.v1.Session', ([], {}), True, 'import tensorflow as tf\n'), (34, 'tensorflow.python.keras.backend.set_session', 'set_session', (['sess'], {}), False, 'from tensorflow.python.keras.backend import set_session\n'), (35, 'tensorflow.keras.applications.ResNet50', 'ResNet50', ([], {'weights': '"""imagenet"""'}), False, 'from tensorflow.keras.applications import ResNet50\n'), (37, 'tensorflow.compat.v1.get_default_graph', 'tf.compat.v1.get_default_graph', ([], {}), True, 'import tensorflow as tf\n'), (46, 'tensorflow.keras.preprocessing.image.img_to_array', 'img_to_array', (['image'], {}), False, 'from tensorflow.keras.preprocessing.image import img_to_array\n'), (47, 'numpy.expand_dims', 'np.expand_dims', (['image'], {'axis': '(0)'}), True, 'import numpy as np\n'), (48, 'tensorflow.keras.applications.imagenet_utils.preprocess_input', 'imagenet_utils.preprocess_input', (['image'], {}), False, 'from tensorflow.keras.applications import imagenet_utils\n'), (88, 'flask.jsonify', 'flask.jsonify', (['data'], {}), False, 'import flask\n'), (61, 'flask.request.files.get', 'flask.request.files.get', (['"""image"""'], {}), False, 'import flask\n'), (64, 'io.BytesIO', 'io.BytesIO', (['image'], {}), False, 'import io\n'), (73, 'tensorflow.python.keras.backend.set_session', 'set_session', (['sess'], {}), False, 'from tensorflow.python.keras.backend import set_session\n'), (75, 'tensorflow.keras.applications.imagenet_utils.decode_predictions', 'imagenet_utils.decode_predictions', (['preds'], {}), False, 'from tensorflow.keras.applications import imagenet_utils\n')]