[PYTHON] Convenient usage summary of Flask

flask is a library for creating web applications with python. Here's a summary of the basics of using flask.

Installation

pip install flask

Introduction

First of all, create an API that returns the simplest "Hello World".

from flask import Flask
app = Flask(__name__)

@app.route('/')
def root():
    return "Hello World!"

if __name__ == "__main__":
    app.run()

--If you decorate with the function @ app.route (url), the function will be executed when you access the url.

python app.py

Run the ʻapp.pycreated above to start the web server. When you accesshttp: // localhost: 5000 /with a browser,Hello World!` Will be displayed on the screen.

Development settings

from flask import Flask
app = Flask(__name__)

@app.route('/')
def root():
    return "Hello World!"

if __name__ == "__main__":
    app.run(debug=True,host='localhost',port=5000)

--Change main as above. --If you pass debug = True (debug mode), it will be loaded automatically when you change ʻapp.pyor the html file described later while the server is running. The initial value ofdebug is False. --host portcan be decided freely. The initial value ofport` is 5000.

Make it accessible from the outside.

from flask import Flask
app = Flask(__name__)

@app.route('/')
def root():
    return "Hello World!"

if __name__ == "__main__":
    app.run(debug=False,host='0.0.0.0',port=5000)

--Change main as above. --When host = localhost, it can only be accessed locally. To make it accessible from the outside, host =" 0.0.0.0 ". --Set debug = False for security reasons.

The browser also starts at the same time

import threading,webbrowser
from flask import Flask
app = Flask(__name__)

@app.route('/')
def root():
    return "Hello World!"

if __name__ == "__main__":
    threading.Timer(1.0, lambda: webbrowser.open('http://localhost:5000') ).start()
    app.run(debug=False)

--Add a command to open the browser with main. --When you execute ʻapp.py, the browser starts up and the page is displayed. --If you pass debug = True to ʻapp.run (), the main will be re-executed every time you change the code, and the browser will open additionally each time. I'm passing debug = False to prevent that.

If you want the browser to open automatically in debug mode (debug = True), main is

if __name__ == "__main__":
    app.run(debug=True)

And then

!/bin/sh
( sleep 2; open http://localhost:5000/ ) &
python app.py

There is a way to execute a shell script like.

Returns an html file

from flask import Flask,render_template
app = Flask(__name__)

@app.route('/')
def main():
    return render_template('index.html')

if __name__ == "__main__":
    app.run()
<html>
<body>
  Hello World!
</body>
</html>

--Use render_template (file) when returning an html file. --For the html file (here, ʻindex.html), create a directory called templates in the same location as ʻapp.py and place it in that directory. --When you access http: // localhost: 5000 / from a browser, ʻindex.html` is rendered, and in this case, "Hellow World!" Is displayed.

CSS / JavaScript files

--Place CSS and JavaScript files in the directory ./static. The image is also placed here. --From the html file, each

<head>
  <script src="/static/script.js"></script>
  <link rel="stylesheet" href="/static/style.css">
</head>

Call like.

GET request

--Here, consider an api that receives a GET request at the address of / get and returns a json object of{"message": "Hello World!"}.

from flask import Flask,request,jsonify,render_template
app = Flask(__name__)

@app.route('/')
def index_html():
    return render_template('index.html')

@app.route('/get',methods=['GET'])
def get():
    return jsonify({'message':'Hello world!'})

if __name__ == '__main__':
    app.run()

--Specify ʻurl and methodsto accept requests with decorator@ app.route (url, methods). -- jsonify ()` is a function that converts an object into a string and produces an appropriate response.

<html>
<body>
  <button onclick='get();'>get</button>

  <script>
    function get(){
      fetch('/get').then(
        response => response.json()
      ).then(
        json => { document.body.innerHTML += JSON.stringify(json); }
      ).catch(
        e => console.error(e)
      );
    }
  </script>
</body>
</html>

-When you press the button, the returned JSON is displayed as a character string.

If you want to do something when fetch wants to succeed, you can do the following.

fetch('/get').then(
  response => (
    if (response.ok){
 //成功時に行ないたい処理
    } else {
        throw new Error()
    }
  ).catch(
    e => console.error(e)
  );

POST request

--Here, consider an api that receives a POST request to the / post address and returns the same JSON as it is.

from flask import Flask,request,jsonify,render_template
app = Flask(__name__)

@app.route('/')
def index_html():
    return render_template('index.html')

@app.route('/post',methods=['POST'])
 def post (): # Returns the sent json as it is.
    req = request.json
    return jsonify(req)

if __name__ == '__main__':
    app.run()

--JSON sent by POST request can be obtained by request.json.

<html>
<body>
<button onclick='post();'>post</button>

<script>
function post(){
  fetch('/post', {
    method: "POST",
    headers: { "Content-Type": "application/json"},
    body: JSON.stringify({"message": "Hello World!!!"})
  }).then(
    response => response.json()
  ).then(
    json => { document.body.innerHTML += JSON.stringify(json); }
  ).catch(
    e => console.error(e)
  );
}
</script>
</body>
</html>

--Here, when you press the button, a POST request with JSON of {'message':'Hello World !!!'} as data is sent. The same JSON will be returned, so display it.

API that returns image data

Think of an API where the server receives the data, creates a graph with matplotlib, and returns the image data. Here, the image data is converted to dataURL and the data is returned. The dataURL is the image data expressed as a url.

from flask import Flask,render_template,jsonify,request

import matplotlib
matplotlib.use('agg')
from matplotlib import pyplot as plt
from matplotlib.backends.backend_agg import FigureCanvasAgg
import io,base64

app = Flask(__name__)

@app.route('/')
def main():
    return render_template('index.html')

@app.route('/image',methods=['POST'])
def image():
    data = request.json
    x = data['x']
    y = data['y']

 #Create a diagram
    plt.figure(figsize=(3,3),dpi=100)
    plt.plot(x,y,'k*-',markersize=10)

 #Change figure to dataURL
    canvas = FigureCanvasAgg(plt.gcf())
    png_output = io.BytesIO()
    canvas.print_png(png_output)
    img_data = base64.b64encode(png_output.getvalue()).decode('utf-8')
    dataurl = 'data:image/png;base64,'+img_data

    return jsonify({'img_data':dataurl})

if __name__ == "__main__":
    app.run()

--First of all, note that the command below is executed at the very beginning of importing the library related to matplotlib because it will draw the figure on the server.

import matplotlib
matplotlib.use('agg')

--In ʻimage ()`, matplotlib creates a graph from data, converts it to dataURL, and returns it.

<html>
<body>

<button onclick="image();">img</button>
<div id='img'></div>

<script>

function image(){
  fetch('/image', {
    method: "POST",
    headers: { "Content-Type": "application/json"},
    body: JSON.stringify({"x":[0,1,2,3,4,5], "y":[5,2,4,0,3,8]})
  }).then(
    response => response.json()
  ).then(
    json => { document.getElementById('img').innerHTML = `<img src="${json['img_data']}">`; }
  ).catch(
    e => console.error(e)
  );
}

</script>

</body>
</html>

--Click the img button to send the data x = [0,1,2,3,4,5], y = [5,2,4,0,3,8] to the server. --When the response is returned, put the dataURL in the src of the img tag and the image will be displayed.

Cross Origin Request (COR): Access from another domain

By default, access from another domain is restricted. Use the flask-cors package to allow this.

pip install flask-cors
from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route('/')
def root():
    return "Hello World!"

if __name__ == "__main__":
    app.run()

--Simply apply CORS to ʻapp` and you're good to go.

User authentication (digest authentication)

Use the flask-httpauth package for authentication.

pip install flask-httpauth
from flask import Flask
from flask_httpauth import HTTPDigestAuth

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret key here'
auth = HTTPDigestAuth()

users = {
    'Michael': 'pw_m',
    'Smith': 'pw_s'
}

@auth.get_password
def get_pw(username):
    if username in users:
        return users.get(username)
    return None

@app.route('/')
@auth.login_required
def root():
    return "Hello World!"

if __name__ == "__main__":
    app.run()

--Create a function (get_pw) that returns the user's password if the user exists, or None if the user does not exist, given the user name, and then @auth Decorate with .get_password. --Here, it is assumed that there are two users,'Michael' and'Smith', and the passwords are'pw_m'and'pw_s', respectively. --Decorate functions that require authentication with @ auth.login_required. --When you access, the authentication screen appears first, and when you enter the correct user name and password, "Hello World" is displayed.

Recommended Posts

Convenient usage summary of Flask
Summary of pyenv usage
Basic usage of Pandas Summary
pytest usage summary
Installation of Python3 and Flask [Environment construction summary]
Convenient use of ipython
Numerical summary of data
Summary of Tensorflow / Keras
Basic usage of Jinja2
Usage of Python locals ()
Basic usage of SQLAlchemy
Summary of string operations
Flask article summary page
Summary of Python arguments
Summary of logrotate software logrotate
Summary of test method
Python --Explanation and usage summary of the top 24 packages
Summary of things that were convenient when using pandas
pandas Matplotlib Summary by usage
Super basic usage of pytest
Summary of python file operations
Summary of Python3 list operations
2017.3.6 ~ 3.12 Summary of what we did
Convenient library of Tensorflow TF-Slim
Convenient diff command usage notes
Summary of Linux distribution types
Pipenv usage summary (for myself)
(Minimal) usage of django logger
Sample usage of Python pickle
Basic usage of Python f-string
A brief summary of Linux
[Python] Correct usage of join
Index of certain pandas usage
Summary of Proxy connection settings
Summary of how to use pandas.DataFrame.loc
Summary of basic knowledge of PyPy Part 1
Summary of basic implementation by PyTorch
Summary of scraping relations (selenium, pyautogui)
A brief summary of Python collections
H29.2.27 ~ 3.5 Summary of what I did
Summary of Stack Overflow Developer Survey 2020
Easy usage memo of Anaconda (conda)
Machine learning ③ Summary of decision tree
Summary of various operations in Tensorflow
[Python Queue] Convenient use of Deque
A rough summary of OS history
A brief summary of qubits (beginners)
Summary of go json conversion behavior
Installation and easy usage of pytest
A Tour of Go Learning Summary
[python] Correct usage of if statement
Summary of "nl command Advent Calendar 2020"
[Anaconda3] Summary of frequently used commands
Summary of how to use csvkit
[For competition professionals] Summary of doubling
Summary of Python indexes and slices
Summary of multi-process processing of script language
Summary of restrictions by file system
[OpenCV; Python] Summary of findcontours function