🐍

FlaskでAPI作ってみた

に公開

はじめに

こんにちは、Haruです。
今回は、Flaskを使ってAPIを作ってみます。
とりあえず動かしてみるところから、実践までやってみています。
備忘録なので、誤っている箇所などあれば、教えていただけると幸いです。

APIを作ってみる

とりあえずHello Worldが表示されるAPIを動かしてみる

※Windows11、Python 3.12.0の環境で動かしています。

  1. パッケージをインストールする
pip install flask
  1. server.pyを作成し、コードを書く
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return 'Hello World'


if __name__ == '__main__':
    app.debug = True
    app.run(host='0.0.0.0', port=8000)
  1. python3 server.py またはVSCodeの実行ボタンから実行
  2. localhost:8000でブラウザで起動
  3. 実行される

参考:Flaskで「Hello World」を出力させる #Python - Qiita

APIをアレンジしてみる

localhost:8000/homeでルーティングを指定

@app.route("/home")
def home():
    return "This is Home page."

URLを一部を引数として受け取る

localhost:8000//message/<message>で、<message>に入れた文字列が表示されるようになります。

@app.route('/message/<message>')
def showMessage(message):
    return message

localhost:8000/messageId/<int:messageId>で、messageIdに入れた数字で、変わるようになります。

@app.route('/messageId/<int:messageId>')
def showMessageId(messageId):
    messages = [
        "zero",
        "one",
        "two",
        "three",
    ]
    return messages[messageId]

エラーページのカスタマイズ

404.htmlは、templatesの配下に置きましょう。
404エラーが起きたときのコードを書いています。

@app.errorhandler(404)
def page_not_found(error):
    return render_template('404.html'), 404

参考:[Pythonフレームワーク] Flaskで超簡単に REST API を実装する #Python - Qiita

POSTメソッドを使う

偶数か奇数かを判定するためのコードです。

@app.route("/", methods=["GET", "POST"])
def odd_even():
    if request.method == "GET":
        return """
        下に整数を入力してください。奇数か偶数か判定します
        <form action="/" method="POST">
        <input name="num"></input>
        </form>"""
    else:
        try:
            return """
            {}は{}です!
            <form action="/" method="POST">
            <input name="num"></input>
            </form>""".format(str(request.form["num"]), ["偶数", "奇数"][int(request.form["num"]) % 2])
        except:
            return """
                    有効な数字ではありません!入力しなおしてください。
                    <form action="/" method="POST">
                    <input name="num"></input>
                    </form>"""

参考:はじめての Flask #2 ~POSTを受け取ろう~ #Python - Qiita

画像をアップロードしてみよう

以下のようなディレクトリ構成です。

Sample
├─static
│ └─image
├─templates
│ ├─upload.html
│ └─uploaded_file.html
└─app.py

app.py

@app.route('/upload', methods=['GET', 'POST'])
def upload():
    # URLでhttp://127.0.0.1:5000/uploadを指定したときはGETリクエストとなるのでこっち
    if request.method == 'GET':
        return render_template('upload.html')
    # formでsubmitボタンが押されるとPOSTリクエストとなるのでこっち
    elif request.method == 'POST':
        file = request.files['example']
        upload_folder = './static/image'
        # ディレクトリが存在しない場合は作成する
        if not os.path.exists(upload_folder):
            os.makedirs(upload_folder)
        file.save(os.path.join(upload_folder, file.filename))
        return redirect(url_for('uploaded_file', filename=file.filename))

@app.route('/uploaded_file/<string:filename>')
def uploaded_file(filename):
    return render_template('uploaded_file.html', filename=filename)

もともと、以下のようなupload関数だったが、うまくいかなかったので、上のようなコードに変更しています。
uploaded_file関数は変えていません。

@app.route('/upload', methods=['GET', 'POST'])
def upload():
    # URLでhttp://127.0.0.1:5000/uploadを指定したときはGETリクエストとなるのでこっち
    if request.method == 'GET':
        return render_template('upload.html')
    # formでsubmitボタンが押されるとPOSTリクエストとなるのでこっち
    elif request.method == 'POST':
        file = request.files['example']
        file.save(os.path.join('./static/image', file.filename))
        return redirect(url_for('uploaded_file', filename=file.filename))

upload.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>アップロードページ</title>
</head>
<body>
    <h1>アップロード</h1>
    <form action="{{url_for('upload')}}" method="POST" enctype="multipart/form-data">
        <input type="file" name="example">
        <input type="submit" value="アップロード">
    </form>

</body>
</html>

uploaded_file.html
以下は、もともとのコードに、<img src="{{ url_for('static', filename='image/' + filename) }}" alt="Uploaded Image">を追加して、アップロードした画像が確認できるようにしています。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>アップロード完了</title>
</head>
<body>
    <h1>ファイルアップロード完了</h1>
    <h2>{{ filename }}</h2>
    <img src="{{ url_for('static', filename='image/' + filename) }}" alt="Uploaded Image">
</body>
</html>

参考:Flaskを使って画像データをアップロードする方法 - 学んだことをメモするブログ

終わりに

今回は、Flaskを使って、APIをとりあえず動かしてみるところから、実践まで、私の備忘録も兼ねてやってみました。
ぜひ参考にしていただけると幸いです。

Discussion