[PYTHON] Create a simple app that incorporates the Fetch API of Ajax requests in Flask and explain it quickly

Introduction

・ For those who have started studying Flask and JavaScript -Use TheCatAPI.com: Beta to create an app that retrieves images of cats with Ajax requests.

Create a Flask app to get images of cats with the Fetch API

Prepare Flask. If you're still not sure about Flask, check out the article below. [Probably the second most popular web application framework in Python] Summarize the basics of Flask in an easy-to-understand manner

The configuration is as follows.

app.py
templates
└─hello.html

app.py


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

@app.route('/')
def hello_world():
    return render_template('hello.html')

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

hello.html


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>hello</title>
    <h1>hello</h1>
</head>
<body>
    
</body>
</html>

When you start Flask above, the following screen will appear on your browser. image.png

The version that hits the API in JavaScript

Now, let's display the image of the cat with the Fetch API. Click the button to display the image of the cat.

The entire HTML code is below

.html


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>hello</title>
    <style>
        .w300 {
            width: 300px;
        }
    </style>
</head>
<body>
    <form id="form">
        <div id="image"></div>
        <button id="lookCatButton" type="button">See cat</button>
    </form>
    <script>
        const url = 'https://api.thecatapi.com/v1/images/search?size=full';
        const options = {
            method: 'GET'
        }

        function getCatImage(url, options){
            return fetch(url, options)
            .then( response => response.json() );
        }
        async function getImage(url, options){
            const response = await getCatImage(url, options);
            const imageDiv = document.getElementById("image");
            const imageElement = document.createElement("img");
            imageElement.src = response[0].url;
            imageElement.className = "w300";
            imageDiv.appendChild(imageElement);
        }
        document.getElementById("lookCatButton")
        .addEventListener("click", () =>{
            getImage(url, options)
        })
    </script>
</body>
</html>

Description

With the Fetch API, you can set the request destination ** URL ** and the second ** options ** as the first argument. This time, define the URL and options as follows.

.js


const url = 'https://api.thecatapi.com/v1/images/search?size=full';
const options = {method: 'GET'};

In options, specify GET as the request method. If you want to know more about options, please refer to the following. https://developer.mozilla.org/ja/docs/Web/API/Fetch_API/Using_Fetch https://developer.mozilla.org/ja/docs/Web/API/WindowOrWorkerGlobalScope/fetch

Since the return value of fetch is returned by promise, you can use the **. Then () ** method. I will. And since the callback function can be used in **. Then () **, omit () because there is one ** argument in ** arrow function **, and omit {} because it is the only statement return. **.

.js


fetch(url, options)
.then( response => response.json() );

If you write it with an arrow function that is not omitted, it will be as follows.

.js


fetch(url, options)
.then( (response) => {
    return response.json()
});

When using fetch, the code written after it may be executed before the request is sent and the response is returned. Therefore, I use ** asyn / await ** to execute fetch and execute the subsequent code after the response is returned.

Define a ** async function ** and add ** await ** to the function that uses fetch in it and put it in a variable. It is the following part

.js


async function getImage(url, options){
    const response = await getCatImage(url, options);

After that, the image URL of the cat is displayed as appendChild.

Since the series of processes is executed after clicking the button, it is executed when ** click ** is done with ** addEventListener **.

.js


document.getElementById("lookCatButton")
.addEventListener("click", () =>{
    getImage(url, options)
})

Now, every time you press the button, the image of the cat will be displayed. image.png

Dare to hit the API on the python side

As mentioned above, fetch requires the URL to send the request to the first argument, so ** create the URL of the request destination by Flask routing **. Therefore, the code to get the data of Neko-chan API and ** return ** with jsonify to dump with json when returning as a response.

I made the following code. ** / get_data ** is added.

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


@app.route('/get_data')
def get_data():
    url = 'https://api.thecatapi.com/v1/images/search?size=full' #Cat API
    response = requests.get(url)
    cat_img_url = eval(response.text)[0]['url'] #Get the image URL here
    response_data = {
        'cat_img_url' : cat_img_url
    }
    return jsonify(response_data) #Return to js side with jsonify


@app.route('/')
def hello_world():
    return render_template('hello.html')

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

On the JavaScript side, change the URL of the request destination to **. / Get_data ** of the routing destination you set earlier.

.js


const url = './get_data';

Since the dumped value is entered in json from python, get the "cat_img_url" set on the python side.

.js


imageElement.src = response.cat_img_url;

Everything else is the same, and the overall code is as follows.

.html


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .w300 {
            width: 300px;
        }
    </style>
</head>
<body>
    <form id="form">
        <div id="image"></div>
        <button id="lookCat" type="button">See cat</button>
    </form>
    <script>
        const url = './get_data';
        const options = {
            method: 'GET'
        }

        function getCatImage(url, options){
            return fetch(url, options)
            .then( response => response.json() );
        }
        async function getImage(url, options){
            const response = await getCatImage(url, options);
            const imageDiv = document.getElementById("image");
            const imageElement = document.createElement("img");
            imageElement.src = response.cat_img_url;
            imageElement.className = "w300";
            imageDiv.appendChild(imageElement);
        }
        document.getElementById("lookCat")
        .addEventListener("click", () =>{
            getImage(url, options)
        })
    </script>
</body>
</html>

Now, when you click the button, you can get the image and display it on the python side.

image.png

By the way, if you directly access the routing destination added this time, the following contents will be displayed. image.png

in conclusion

This time, I tried fetch request and response with two patterns, one requesting on the python side and the other requesting on the JavaScript side, which was very good for organizing my head.

References

Notes on the latest Ajax request communication and Fetch API [Probably the second most popular web application framework in Python] Summarize the basics of Flask in an easy-to-understand manner MDN web docs - Fetch API MDN web docs-Using Fetch MDN web docs --Callback function MDN web docs --Arrow Functions MDN web docs - async function

Recommended Posts

Create a simple app that incorporates the Fetch API of Ajax requests in Flask and explain it quickly
A simple mock server that simply embeds the HTTP request header in the body of the response and returns it.
Create a simple GUI app in Python
Create a simple web app with flask
Create a REST API using the model learned in Lobe and TensorFlow Serving.
Create a web app that converts PDF to text using Flask and PyPDF2
Create a filter to get an Access Token in the Graph API (Flask)
If you define a method in a Ruby class and define a method in it, it becomes a method of the original class.
The result of making a map album of Italy honeymoon in Python and sharing it
Create a simple API just to input and output JSON files ~ Python / Flask edition ~
A simple cache of values in the property decorator. Read only. Note that it keeps caching until the object is deleted.
A server that returns the number of people in front of the camera with bottle.py and OpenCV
Parse the Researchmap API in Python and automatically create a Word file for the achievement list
Steps to set up Pipenv, create a CRUD app with Flask, and containerize it with Docker
Get the trading price of virtual currency and create a chart with API of Zaif exchange
A program that receives the servo command of the radio control, interrupts the Raspberry Pi and logs it
[Python] The role of the asterisk in front of the variable. Divide the input value and assign it to a variable
A simple reason why the return value of round (2.675,2) is 2.67 in python (it should be 2.68 in reality ...)
I made a LINE bot that tells me the type and strength of Pokemon in the Galar region with Heroku + Flask + PostgreSQL (Heroku Postgres)
pandas Fetch the name of a column that contains a specific character
[Python / Django] Create a web API that responds in JSON format
A function that measures the processing time of a method in python
Dig the directory and create a list of directory paths + file names
Create a function to get the contents of the database in Go
Note that I understand the algorithm of the machine learning naive Bayes classifier. And I wrote it in Python.
[Rails 6] Embed Google Map in the app and add a marker to the entered address. [Confirmation of details]
[Python / Jupyter] Translate the comment of the program copied to the clipboard and insert it in a new cell
I made a POST script to create an issue on Github and register it in the Project
Create a bot that posts the number of people positive for the new coronavirus in Tokyo to Slack
[CleanArchitecture with Python] Apply CleanArchitecture step by step to a simple API and try to understand "what kind of change is strong" in the code base.