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?

APIの仕組みを理解する(自分用)

Posted at

はじめに

本記事は、APIの仕組みを自分の手で実装しながら理解することを目的としています。
主に以下の技術を使いながら、FastAPIとStreamlitの連携についてまとめる。

FastAPI(エンドポイントの構築)
Streamlit(UIの構築とデータの表示)
JSONファイル(データの保存と表示)

ディレクトリ構造と各ファイルの内容

sample/
├── main.py         # streamlitでのUI構築
├── test_api.py      # fastapiによるAPIエンドポイント
├── module.py       # 処理用関数やモデルの定義
├── sample.json     # APIで読み書きするJSONファイル
main.py
import module
import streamlit as st

URL = "http://localhost:8000/"
FILE_PATH="sample.json"

# StreamlitのUI
st.title("データ登録とAPIの呼び出し")

if st.button(label="APIからデータ取得する"):
    res = module.request_json(URL)
    if isinstance(res, dict) and "error" in res:
        st.error(res["error"])  # エラーメッセージをStreamlitで表示
    else:
        for item in res:
            for index in item.items():
                st.write(index)
                
col_1,col_2=st.columns(2)
with col_1:
    name = st.text_input("名前")
with col_2:
    age = st.number_input("年齢", min_value=0, step=1)

if st.button("APIへデータを追加する"):
    file_path = FILE_PATH  
    reg = module.Registration(file_path=file_path, name=name, age=int(age))
    module.regist_data(reg)
    
test_api.py
from fastapi import FastAPI
import json

app=FastAPI()

RESPONSE_JSON="sample.json"

@app.get("/")
async def response_json():
  with open(RESPONSE_JSON,"r",encoding="utf-8") as f:
    data=json.load(f)
    
    return data
    
module.py
import requests
from dataclasses import dataclass
import os
import json
import streamlit as st

@dataclass
class Registration:
    file_path: str | int
    name: str
    age: int

def request_json(url):
    try:
        response = requests.get(url, timeout=5)
        response.raise_for_status()  # HTTPエラー時に例外発生
        return response.json()
    except requests.exceptions.HTTPError as e:
        return {"error": f"HTTPエラー: {e.response.status_code}"}
    except requests.exceptions.ConnectionError:
        return {"error": "サーバーに接続できません"}
    except requests.exceptions.Timeout:
        return {"error": "タイムアウトしました"}
    except Exception as e:
        return {"error": f"予期しないエラー: {str(e)}"}
    
def regist_data(registration: Registration):
    # JSONファイルの読み込みまたは新規作成
    file_path = str(registration.file_path)
    data = []
    if os.path.exists(file_path):
        with open(file_path, "r", encoding="utf-8") as f:
            try:
                data = json.load(f)
            except json.JSONDecodeError:
                data = []
    # 新しいデータを追加
    data.append({"name": registration.name, "age": registration.age})
    # ファイルに書き込み
    with open(file_path, "w", encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=2)
    st.write(f"登録完了しました。, 名前={registration.name}, 年齢={registration.age}")
    
sample.json
[
  {
    "name": "Alice",
    "age": 28
  },
  {
    "name": "Bob",
    "age": 34
  },
  {
    "name": "Charlie",
    "age": 22
  }
]

uvicornでFastAPIの起動方法

testapi.py内でFastAPIアプリをapp = FastAPI()として定義していることが前提です。

bash
uvicorn testapi:app --reload

Streamlitの起動と基本構成

StreamlitのUIからエンドポイントにアクセスし、データを取得・表示する流れを構築します。

bash
streamlit run main.py

APIエンドポイントへアクセスしてデータを取得・描画

Streamlitアプリ上で、FastAPIのエンドポイントにリクエストを送り、JSON形式でレスポンスを受け取り、画面に表示します。
(下記のように、ブラウザからエンドポイントへ直接アクセスすることも可能)

URL(エンドポイント)
http://localhost:8000/

# 結果
[{"name":"Alice","age":28},{"name":"Bob","age":34},{"name":"Charlie","age":22}]

APIの仕組みに関する総括

FastAPIは軽量かつ直感的にAPIエンドポイントを構築できる
StreamlitはUIの構築に強く、データ表示や操作を素早く実装できる
JSONファイルを簡易的なDBとして扱うことで、API入門には十分な学習素材になる

おわりに

この記事は、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?