โค้ด HTML และ JavaScript ที่ใช้ส่งข้อมูล (post) ให้ FastAPI (http://127.0.0.1:8000/submitform) โดยใช้ Server ของ Flask (http://127.0.0.1:5000/)
ซึ่งคิดว่าอาจจะส่งข้อมูลไม่ถูกต้องใน script tag
โค้ด: เลือกทั้งหมด
{% extends "layout.html" %}
{% block title %}
<title>Test ML</title>
{% endblock %}
{% block content %}
<div class="parent">
<header>
<h1>Predict an image</h1>
</header>
<p>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
</p>
{% if filename %}
<main>
<div>
<img src="{{ url_for('display_image', filename=filename) }}">
</div>
{% endif %}
<form id="form-data" enctype="multipart/form-data">
<div class="flex-container">
<select class="form-select" name="model" id="model" aria-label="select a model">
<option value="1" selected>1st model 224*224</option>
<option value="2">2nd model 90*96</option>
</select>
</div>
<div class="flex-container">
<input type="file" class="form-control" id="file" name="file" accept="image/png, image/jpg, image/jpeg" required>
<button type="submit" class="btn btn-primary mb-3">Predict</button>
</div>
</form>
<hr>
<div>
{% if gender_prediction %}
<h3>This's a picture of a {{gender_prediction}}.</h3>
<h4>It was processed by {{model}}</h4>
{% else %}
<h3>Nothing's here</h3>
{% endif %}
</div>
</div>
</main>
<script>
const myForm = document.getElementById("form-data")
const inFlie = document.getElementById("file")
const model = document.getElementById("model")
myForm.addEventListener("submit", e => {
e.preventDefault();
const endpoint = "http://127.0.0.1:8000/submitform";
const formData = new FormData();
console.log(inFlie.files);
console.log(model.value)
formData.append("file", inFlie.files[0])
formData.append("model", model.value)
fetch(endpoint, {
method: "post",
body: formData
}).catch(console.error)
.then(document.location.reload())
})
</script>
ฟังก์ชั่นที่ใช้ควบคุมการทำงานของหน้าเว็บ เป็น index() ซึ่งกำลังติดปัญหาเรียกใช้รูปจาก response ไม่ถูก (คาดว่าไม่ถูก)
โค้ด: เลือกทั้งหมด
from flask import Flask, url_for, render_template, request
import os
from flask.helpers import flash
from werkzeug.utils import redirect, secure_filename
import tensorflow as tf
from tensorflow.keras.preprocessing.image import load_img, img_to_array
from tensorflow import keras
import requests
app = Flask(__name__)
UPLOAD_FOLDER = 'static/uploads/'
app.secret_key = 'random string'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
# there're type of file that allowed types
ALLOWED_EXTENSIONS = set(['jpg', 'jpeg', 'png'])
last_file_path = ''
loaded_model = keras.models.load_model('../model/gender_classification_model224-224.h5')
prediction = ''
# return the tuple of prediction
# the first index's gender
# the second index's probability
def get_classes(data):
global loaded_model
prob = loaded_model.predict(data)
if prob[0][0] < 0.5:
return 'woman', 1 - prob[0][0]
else:
return 'man', prob[0][0]
# this function check the type of file
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
# http://127.0.0.1:5000/
@app.route('/')
def index(): # just render the index.html
url = 'http://127.0.0.1:8000/showdata'
response = requests.get(url)
if response.status_code == 200 and response.json() != {}:
print(response)
print(response.content)
print(type(response))
print(response.json())
if "file" not in response.json().keys(): # if file is not exist
flash('No file part')
return redirect(request.url)
file = (response.json())["file"]
print(file)
if file["filename"] == '': # if filename is empty string
flash('No image selected for uploading')
return redirect(request.url)
if file and allowed_file(file["filename"]): # if file is exist and allowed types of file
global prediction, loaded_model, last_file_path
filename = secure_filename(filename=file["filename"])
last_file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
# file.save(last_file_path)
# print(f'upload_image filename : {filename}')
# flash('Image successfully upload and displayed below')
# selected_model = request.form.get('model')
# model_predict = ''
# if selected_model == '1':
# loaded_img = tf.keras.utils.load_img(last_file_path, target_size=(244, 244, 3)) # load image from path and resize image
# model_predict = 'model224-224.h5'
# else:
# loaded_model = keras.models.load_model('../model/gender_classification_model90-96.h5')
# loaded_img = tf.keras.utils.load_img(last_file_path, target_size=(90, 96, 3))
# model_predict = 'model90-96.h5'
# img_array = tf.keras.utils.img_to_array(loaded_img) # convert image to array
# img_array = tf.expand_dims(img_array, 0) # create a batch
# prediction = get_classes(img_array) # use img_array to predict gender
# gender_prediction = prediction[0] # get gender from tuple "prediction[0]"
# return render_template('index.html', filename=filename, gender_prediction=gender_prediction, model=model_predict)
# else: # if file is exist and not allowed types of file
# flash('Allowed image types are - png, jpg, jpeg')
# return redirect(request.url)
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True) # debug mode is on
- http://127.0.0.1:8000/submitform เป็น url สำหรับ post method จะเรียกใช้ฟังก์ชั่น handle_form() มาใช้งาน ซึ่งใช้รับค่าจาก form (คาดว่าอาจจะเก็บข้อมูลได้ไม่ถูกตอนที่กำหนดค่าให้ตัวแปร data)
- http://127.0.0.1:8000/showdata เป็น url สำหรับ get method จะเรียกใช้ฟังก์ชั่น get_data() มาใช้งาน ซึ่งใช้ส่งค่าที่ได้จาก form เมื่อ Flask request มาที่ url นี้
โค้ด: เลือกทั้งหมด
from fastapi import FastAPI, Body, Request, File, UploadFile, Form
import uvicorn
from pathlib import Path
from fastapi.middleware.cors import CORSMiddleware
api = FastAPI() # Init FastAPI Ap
api.add_middleware(
CORSMiddleware,
allow_origins=["http://127.0.0.1:5000"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
data = {}
# FastAPI section
# http://127.0.0.1:8000/submitform
@api.post('/submitform')
async def handle_form(model: str = Form(...), file: UploadFile = File(...)):
global data
data = {'model': model, 'file': file}
return data
# http://127.0.0.1:8000/showdata
@api.get('/showdata')
async def get_data():
global data
return data
if __name__ == '__main__':
uvicorn.run(api, host='127.0.0.1', port=8000, debug=True)