Flask is a lightweight web application framework for Python.
What is a framework? It puts together the functions required when developing application software. A package that allows you to easily build a framework / template.
Rails for the language Ruby For Python, Django and Flask are the mainstream.
You can easily and lightweight develop web applications by fitting them into a template called Flask.
We will create a handwriting recognition application using MNIST. Process with the server using Flask and create the appearance of the application with HTML & CSS.
To experience what you can do with Flask, let's first run the smallest Flask web application.
hello.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return "Hello World!"
if __name__ == "__main__":
app.run()
Since it cannot be executed on Fastpyter, the following is the work in the local environment.
Create hello.py in your editor and copy and paste the above code
Type python hello.py in the terminal and run
Access http://127.0.0.1:5000/
After confirming, press Ctrl + C to end the process.
Let's take a closer look at this code.
First, declare that you want to use the Flask class of the flask package.
from flask import Flask
Next, create an instance of the Flask class called app.
app.<Flask class method name>
Allows you to use Flask class methods
app = Flask(__name__)
I get an unfamiliar @ here Lines starting with @ are called decorators Do something with the function or class defined in the next line.
app.route () specified a function defined on the next line We are processing to associate with URL. In the argument of app.route () Specify the URL after [http://127.0.0.1:5000/].
That is, in the code below, when you access http://127.0.0.1:5000/ This means that the hello_world () function will be called and will display Hello World !.
@app.route('/')#http://127.0.0.1:5000/Specify the subsequent path
def hello_world():
return "Hello World!"
name =='main' is True That is, only when this code is executed directly app.run () is executed and the Flask app is launched.
if __name__ == "__main__":
app.run()
By the description of if name =='main': earlier When you run the Python script directly Only (like when running python filename.py on the command line)
if name =='main': You can execute the following processing. And if it is imported from another file, it will not be processed. This description is used, for example, when creating and testing a module by yourself. It is used when you want to prevent unnecessary processing.
Let's take a closer look at this mechanism here. By the way, name is a variable that is automatically defined for each script file. The file name (module name) is automatically stored.
However, when you run the file directly, main is automatically stored in name. Let's check with the following example.
Example) What is output when the following test1.py is executed
test1.py
#Function show()Have been defined
def show():
return __name__
print(__name__)
#Output result
__main__
Because test1.py is running directly main is automatically stored in name, so main is output.
When the Python script is executed directly like this Because main is stored in a variable called name
name =='main becomes True if name =='main': The following processing is executed.
By the way, I just created a very simple app that just displays Hello World !. This time, we will reflect HTML & CSS to make it more like a web application.
The contents are explained in Introduction to HTML & CSS.
mnist.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def hello_world():
return render_template('index.html')
if __name__ == "__main__":
app.run()
You will be working in a local environment.
1, Create a folder with an appropriate name (for example, mnist_app) on the desktop etc.
2, Create mnist.py in the mnist_app folder and copy and paste the above code
3, Create a templates folder in the mnist_app folder and create index.html in it Copy and paste the code of HTML template explanation 1/5 to index.html
4, Create a static folder inside the mnist_app folder Create a stylesheet.css in it (Flask is supposed to look for the html file in the templates folder and the css file in the static folder) Copy and paste the code of CSS template explanation 1/5 into stylesheet.css
5, cd mnist_app / to move to the mnist_app folder
6, Type python mnist.py in the terminal and run
7, Access http://127.0.0.1:5000/
After confirming, press Ctrl + C to end the process.
Let's take a closer look at the code. What's different from the code that lets you run the smallest Flask app
return render_template('index.html')only.
-By passing an html format file as an argument to render_template () You can reflect html on the page of the associated URL. The html file passed to this argument must be in the temlpates folder.
@app.route('/')
def hello_world():
return render_template('index.html')
So far, we have designed the web page side and created a file uploader. However, you can't actually upload the file without adding code on Flask's side.
Here, we receive the image uploaded from the web page and identify it with the trained model. Let's look at the code that displays the result.
Before running the code with this ipynb file Please prepare the trained model model.h5 in the same directory.
mnist.py
import os
from flask import Flask, request, redirect, url_for, render_template, flash
from werkzeug.utils import secure_filename
from keras.models import Sequential, load_model
from keras.preprocessing import image
import tensorflow as tf
import numpy as np
classes = ["0","1","2","3","4","5","6","7","8","9"]
num_classes = len(classes)
image_size = 28
UPLOAD_FOLDER = "uploads"
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])
app = Flask(__name__)
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
model = load_model('./model.h5')#Load the trained model
graph = tf.get_default_graph()
@app.route('/', methods=['GET', 'POST'])
def upload_file():
global graph
with graph.as_default():
if request.method == 'POST':
if 'file' not in request.files:
flash('No file')
return redirect(request.url)
file = request.files['file']
if file.filename == '':
flash('No file')
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(UPLOAD_FOLDER, filename))
filepath = os.path.join(UPLOAD_FOLDER, filename)
#Read the received image and convert it to np format
img = image.load_img(filepath, grayscale=True, target_size=(image_size,image_size))
img = image.img_to_array(img)
data = np.array([img])
#Pass the transformed data to the model for prediction
result = model.predict(data)[0]
predicted = result.argmax()
pred_answer = "this is" + classes[predicted] + "is"
return render_template("index.html",answer=pred_answer)
return render_template("index.html",answer="")
if __name__ == "__main__":
app.run()
Since it cannot be executed on Fastpyter, the following is the work in the local environment.
Replace mnist.py with the above code
Create uploads folder in the same hierarchy as mnist.py
Put model.h5 that saved the model trained earlier in the same hierarchy as mnist.py
Keep the file placement the same as before, type python mnist.py in the terminal and run it
Go to http://127.0.0.1:5000/
Now, let's upload an image of numbers.
After confirming, press Ctrl + C to end the process.
Now let's take a closer look at this code.
First, import the required libraries and modules.
import os
from flask import Flask, request, redirect, url_for, render_template, flash
from werkzeug.utils import secure_filename
from keras.models import Sequential, load_model
from keras.preprocessing import image
import tensorflow as tf
import numpy as np
Next, store the class names you want to classify in the classes list. This time, we will classify the numbers, so set them to 0-9. Pass the size of the image used for training to imaze_size. This time, I used the MNIST dataset, so I set it to 28.
classes = ["0","1","2","3","4","5","6","7","8","9","10"]
num_classes = len(classes)
image_size = 28
Pass the name of the folder to save the uploaded image to UPLOAD_FOLDER. For ALLOWED_EXTENSIONS, specify the extensions that allow uploading.
UPLOAD_FOLDER = "uploads"
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg'])
Create an instance of the Flask class.
app = Flask(__name__)
Defines a function that checks the extension of uploaded files. Returns True if the two conditions before and after and are met.
The first condition'.' In filename is Whether the character. Is present in the variable filename.
The second condition filename.rsplit ('.', 1) [1] .lower () in ALLOWED_EXTENSIONS Whether the string after. In the variable filename corresponds to one of ALLOWED_EXTENSIONS.
rsplit () is basically the same as split (). However, split () was separated from the beginning of the string In rsplit, the order of delimiter is from the end of the character string.
lower () converts the string to lowercase.
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
Load the trained model. graph = tf.get_default_graph () is the code needed for a Keras bug, so don't worry about it.
model = load_model('./model.h5')#Load the trained model
graph = tf.get_default_graph()
Next, we will define the function to be executed when the top page is accessed.
GET and POST are a type of HTTP method.
I will omit the detailed explanation GET fetches resources (pops html file when page is accessed) POST means sending data to the server.
global graph、with graph.as_default():Also
Don't worry, it's needed because of a Keras bug.
request is a function for handling data sent from a form on the web request.method contains the request method It is also explained in Introduction to HTML & CSS. And when request.method =='POST', the code that follows will be executed.
@app.route('/', methods=['GET', 'POST'])
def upload_file():
global graph
with graph.as_default():
if request.method == 'POST':
Here, does the POST request contain file data? It also checks if the file has a filename.
redirect () is a function that redirects to the url given as an argument request.url contains the URL of the page on which the request was made.
That is, if there is no uploaded file or no file name, it will return to the original page.
if 'file' not in request.files:
flash('No file')
return redirect(request.url)
file = request.files['file']
if file.filename == '':
flash('No file')
return redirect(request.url)
Then check the extension of the uploaded file.
Then, secure_filename () disables (sanitizes) any dangerous strings in the filename.
Next, join the path given as an argument by os.path.join () according to os. (Combined with \ on Windows, combined with / on Mac and Linax) Save the uploaded image to that path. Also, the save destination is stored in filepath.
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(UPLOAD_FOLDER, filename))
filepath = os.path.join(UPLOAD_FOLDER, filename)
Finally, we will determine the number of the uploaded image. Here, we use Keras's image.load_img function that can load and resize images at the same time.
In the argument, specify the URL of the image you want to load and the size you want to resize the image.
Further grayscale=By passing True
It can be read in monochrome. image.img_to_array converts the image given in the argument to a Numpy array.
You also need to pass a list of Numpy arrays to model.predict (). Therefore, img is passed as a list to np.array (). And the prediction result is stored in pred_answer.
#Read the received image and convert it to np format
img = image.load_img(filepath, grayscale=True, target_size=(image_size,image_size))
img = image.img_to_array(img)
data = np.array([img])
#Pass the transformed data to the model for prediction
result = model.predict(data)[0]
predicted = result.argmax()
pred_answer = "this is" + classes[predicted] + "is"
By passing answer = pred_answer as an argument of ender_template You can assign pred_answer to the answer written in index.html.
return render_template("index.html",answer=pred_answer)
When no POST request is made (simply accessing the URL) Nothing is displayed in the answer of index.html.
return render_template("index.html",answer="")
Finally, app.run () is executed and the server starts up.
if __name__ == "__main__":
app.run()
Until recently, I used to run web apps only on my own computer. Here you will learn how to deploy a web app to Heroku and publish it to the world.
When deploying a web app, to make the server available externally
host='0.0.0.0'Specify.
port = int(os.environ.get('PORT', 8080))Then
I get the port number that can be used on Heroku and store it in post.
If not set, 8080 will be stored.
At the end of mnist.py
if __name__ == "__main__":
app.run()
Part of
if __name__ == "__main__":
port = int(os.environ.get('PORT', 8080))
app.run(host ='0.0.0.0',port = port)
Please rewrite it with the above code.
Set up Heroku.
Before executing the code Located in the mnist_app directory in the same directory as this ipynb file Please prepare Procfile, requirements.txt, runtime.txt
First, register as a member of Heroku and log in. Then install Heroku.
Please install from the Heroku CLI site. Git will be installed at the same time you install Heroku CLI.
Here's how to deploy to Heroku.
1, Move to the directory containing the app file (cd __)
3, move to Heroku, Enter Create New App-> App name Go to the page of the app that registers the country in United States and move to Setteings Click Add build pack to add Python
Move the three files below to the directory where the app is located (It's in the mnist_app directory, which is in the same directory as this ipynb file.)
Procfile, requirements.txt, runtime.txt
When checking the operation on Heroku, be sure to use the file mnist.py Name it main.py.
Since the Procfile specifies to start a file called main.py, Use main.py this time.
You can start a file with any name by rewriting Procfile.
Also, requirements.txt
In your own app on Heroku by writing the required libraries for
The library will be installed.
runtime.Describe the Python version to be used in txt.
In the directory (folder), main.py, Procfile, requirements.txt, runtime.txt Make sure you have the trained model, templates folder, statics folder, uploads folder,
~ In the hierarchy with the application file of the terminal (command prompt) ~
git init(This is the first time only)
heroku git:remote -a (app name)
git add .
git commit -m “(Write a message about what has changed)”
git push heroku master
Please deploy as.
The deployed app will have the URL https: // app name.herokuapp.com/. You can also enter the command heroku open to go to the URL where the web app is running. If you can confirm the operation, the deployment is successful.
Recommended Posts