0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

とりあえずFlaskでAPI開発ハンズオン

Posted at

環境

  • macOS:13.6.7
  • Docker:27.3.1
  • VScode

開発環境構築

VScodeを開いて、ターミナルを起動
自分の好きなディレクトリにて開発をしましょう

$ cd /Users/{username}/Desktop/
$ mkdir API_test

{username}は自分のPCのユーザー名を入力
例: /Users/{username}/Desktop/API_test/Users/alice/Desktop/API_test になる

今回は軽量のDockerイメージのalpineを使ってみたいと思いますので、イメージをローカル環境に持ってきます

$ docker pull python:3.8-alpine

API構築

そもそもAPIとは?GPTに聞いてみた

異なるソフトウェアアプリケーションが相互にデータや機能をやりとりできるようにするための「インターフェース(接点)」です

連携の際に使えるデータの取り出し口のようなもの

また、APIを実装していく上でいくつかの用語が出てきますのでざっくり理解

  • エンドポイント
    APIを利用するためのURLパスで、特定のデータや機能を提供するための接続先です。
    例えば、/userエンドポイントはユーザー情報を扱うための接続先になります。

  • メソッド(HTTPメソッド)
    APIがどのようなアクションを実行するかを指定するもので、代表的なものにGET(データ取得)、POST(データ送信)、PUT(データ更新)、DELETE(データ削除)があります。

  • パラメータ
    エンドポイントへのリクエストに付随して送る情報で、必要なデータや条件を指定します。

ステップ1 コピペ実装

では実際にソースコードを書いてみます。
とりあえずコピペしてみて、動くものを見てみましょう!

ディレクトリ構成

API_test/
├── src
    └── app.py
    └── user.json
├── Dockerfile
├── requirements.txt
└── docker-compose.yml

app.pyファイル

app.py
# app.py
from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/')
def home():
    return jsonify(message="Hello!")

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

Dockerfileファイル

# Dockerfile
# ベースイメージにAlpineのPythonを指定
FROM python:3.8-alpine

# 作業ディレクトリを設定
WORKDIR /app

# 必要なパッケージをインストール
RUN apk add --no-cache gcc musl-dev curl

# 依存関係をインストール
COPY requirements.txt .
RUN pip install -r requirements.txt

# Flaskアプリのソースコードをコピー
COPY . .

# Flaskアプリの実行
CMD ["python", "./src/app.py"]

docker-compose.ymlファイル

docker-compose.yml
# docker-compose.yml
version: '3'
services:
  web:
    container_name: api_test
    build: .
    ports:
      - "5000:5000"
    volumes:
      - /Users/{username}/Desktop/API_test:/apps

実行

/Users/{username}/Desktop/API_test配下にて以下を実行

$ docker compose up --build
$ curl localhost:5000 -v

以下のように出力されるはず

*   Trying [::1]:5000...
* Connected to localhost (::1) port 5000
> GET / HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/8.4.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Server: Werkzeug/3.0.6 Python/3.8.20
< Date: Fri, 08 Nov 2024 17:18:52 GMT
< Content-Type: application/json
< Content-Length: 49
< Connection: close
< 
{"message":"Hello!"}
* Closing connection

app.pyにて指定した通り、{"message":"Hello!"}とJSONが返ってきます
今回curl-vオプションで詳細まで表示しています
確認してみるとレスポンスが200でGETが返ってきていることがわかります

ステップ2 GETメソッドのパスを追加してみる

パスを新しく追加してみます
/heartbeatのエンドポイントにリクエストされた場合は「元気です!」とテキストでレスポンスするようにしてみましょう

app.py
...

# 新しいエンドポイント /heartbeat を追加
@app.route('/heartbeat')
def heartbeat():
    return "元気です!"
...

ソースコードを更新したので、コンテナも更新する必要があります

$ docker compose up --build
$ curl localhost:5000/heartbeat

このようにGETメソッドは追加することができます

ステップ3 クエリを指定してGETメソッドしてみよう

/helloエンドポイントで、クエリパラメータからusernameを受け取り、「[username]さん、こんにちは!」と返すように修正してみましょう

app.py
from flask import Flask, jsonify,request

...

# /helloエンドポイントでusernameを受け取り、挨拶を返す
@app.route('/hello')
def hello():
    username = request.args.get('username', 'ゲスト')
    return f"{username}さん、こんにちは!"

...
$ docker compose up --build
$ curl localhost:5000/hello?username=raha

どうですか?出力されましたか?

ステップ3 POST&PUTを試す

ユーザーとその年齢を登録するようにしてみましょう
少し難しくなります...

まず、ユーザー情報を管理するjsonファイルを用意しましょう

$ touch ./src/user.json

それではソースコードを変更していきます

app.py
# app.py
import json
from flask import Flask, request, jsonify

app = Flask(__name__)

# ユーザー情報を保存するファイルパス
USER_FILE = 'user.json'

# user.jsonファイルを読み込んで辞書として返す
def load_users():
    try:
        with open(USER_FILE, 'r') as file:
            return json.load(file)
    except (FileNotFoundError, json.JSONDecodeError):
        return {}

# usersをuser.jsonファイルに保存する
def save_users(users):
    with open(USER_FILE, 'w') as file:
        json.dump(users, file, indent=4)

# POST /user エンドポイント:新しいユーザーを追加
@app.route('/user', methods=['POST'])
def add_user():
    users = load_users()
    data = request.get_json()
    username = data.get('username')
    age = data.get('age')

    if not username or not age:
        return "usernameとageを指定してください", 400

    # ユーザーが既に存在するかチェック
    if username in users:
        return f"{username}は既に存在します", 400

    # 新しいユーザーを追加してファイルに保存
    users[username] = age
    save_users(users)
    return jsonify(message=f"{username}が追加されました", user={username: age}), 201

# PUT /user/<username> エンドポイント:ユーザーの年齢を更新
@app.route('/user/<username>', methods=['PUT'])
def update_user(username):
    users = load_users()

    if username not in users:
        return f"{username}は存在しません", 404

    data = request.get_json()
    age = data.get('age')

    if not age:
        return "ageを指定してください", 400

    # ユーザーの年齢を更新してファイルに保存
    users[username] = age
    save_users(users)
    return jsonify(message=f"{username}の年齢が更新されました", user={username: age}), 200

# GET /user/<username> エンドポイント:ユーザー情報を取得
@app.route('/user/<username>', methods=['GET'])
def get_user(username):
    users = load_users()

    if username not in users:
        return f"{username}は存在しません", 404

    # ユーザー情報を返す
    return jsonify(username=username, age=users[username])

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

ではリクエストしてみましょう
POSTはGETと違うcurlの叩き方をします

$ docker compose up --build
$ curl -X POST -H "Content-Type: application/json" -d '{"username": "raha", "age": 15}' http://localhost:5000/user

では、情報が登録されたかGETリクエストしてみましょう

次に、年齢が嘘なので、更新をしてみます

$ curl -X PUT -H "Content-Type: application/json" -d '{"age": 20}' http://localhost:5000/user/raha

こちらもGETリクエストで確認してみましょう

ステップ4 ユーザー削除してみる

...

# DELETE /user エンドポイント:クエリパラメータで指定されたユーザー情報を削除
@app.route('/user', methods=['DELETE'])
def delete_user():
    username = request.args.get('username')
    if not username:
        return "usernameをクエリパラメータで指定してください", 400

    users = load_users()

    if username not in users:
        return f"{username}は存在しません", 404

    # ユーザー情報を削除してファイルに保存
    del users[username]
    save_users(users)
    return jsonify(message=f"{username}が削除されました"), 200

...

削除の際のリクエストは以下です

$ curl -X DELETE "http://localhost:5000/user?username=taro"

では、ユーザー情報を取得してみましょう
適当な存在しないユーザー情報を取得しようとするとどうなるでしょう

おわり

APIサーバーの開発ハンズオンは以上です

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?