前回は、検索条件・銘柄一覧・銘柄詳細を並べた株アプリの画面を作りました。
ただし、画面に表示していたトヨタ自動車やソニーグループなどは、コードに直接書いた仮のデータです。
今回はJ-Quants APIから銘柄一覧を取得し、その中から国内の普通株だけに絞り込みます。
▼今回の動画
今回やりたいこと
今回のゴールは、次の3つです。
- FastAPIからJ-Quants APIへリクエストを送る
- 銘柄コードや会社名などの銘柄一覧を取得する
- 取得した一覧から普通株だけを取り出す
今回はデータベースへの保存までは行いません。まずは、J-Quantsから必要な銘柄情報を受け取れるところまで進めます。
データ取得の流れ
株アプリは、フロントエンド・バックエンド・外部API・データベースという構成で作っています。
- Next.jsで作ったフロントエンドからFastAPIへリクエストを送る
- FastAPIからJ-Quants APIへリクエストを送る
- J-Quantsから銘柄一覧が返ってくる
- FastAPIで必要なデータだけに絞る
- 将来的には、絞ったデータをデータベースへ保存する
今回は、このうちFastAPIとJ-Quants間のやり取りが中心です。
最初に仮データで接続を確認する
いきなりJ-Quantsへ接続する前に、FastAPIから仮の銘柄データを返せるか確認しました。
from fastapi import FastAPI
app = FastAPI()
@app.get("/stocks")
def get_stocks():
return [
{"Code": "7203", "CoName": "トヨタ自動車"},
{"Code": "6758", "CoName": "ソニーグループ"},
]
/stocksへアクセスすると、会社コードと会社名をJSON形式で返します。
Next.js側では、受け取ったデータをuseStateで保持し、mapを使って1件ずつ表示しました。まず仮データを使うことで、フロントエンドとバックエンドの接続を分けて確認できます。
CORSを設定する
フロントエンドはlocalhost:3000、バックエンドはlocalhost:8000で動かしています。ポート番号が異なるため、FastAPI側でフロントエンドからのアクセスを許可します。
from fastapi.middleware.cors import CORSMiddleware
origins = [
"http://localhost:3000",
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
この設定によって、Next.jsからFastAPIへアクセスできるようになりました。
APIキーを.envファイルから読み込む
J-Quants APIを利用するにはAPIキーが必要です。APIキーをPythonファイルへ直接書くと、GitHubなどへコードを公開したときに漏れてしまう可能性があります。
そこで、APIキーは.envファイルに保存します。
JQUANTS_API_KEY=ここに自分のAPIキーを入力
FastAPI側では、load_dotenv()で.envを読み込みます。
import os
from dotenv import load_dotenv
load_dotenv()
api_key = os.getenv("JQUANTS_API_KEY")
os.getenv()を使うと、.envに保存した値をPython側で取得できます。
実際のAPIキーは、動画・ブログ・GitHubへ載せないように注意が必要です。
J-Quantsから銘柄一覧を取得する
準備ができたので、FastAPIからJ-Quantsの銘柄一覧APIへGETリクエストを送ります。
import requests
from fastapi import HTTPException
@app.get("/jquants/companies")
def get_jquants_companies():
url = "J-Quantsの銘柄一覧APIのURL"
headers = {
"x-api-key": api_key,
}
response = requests.get(
url,
headers=headers,
timeout=30,
)
try:
response.raise_for_status()
except requests.RequestException as error:
raise HTTPException(
status_code=502,
detail="J-Quantsから銘柄一覧を取得できませんでした",
) from error
response_data = response.json()
companies = response_data["info"]
return companies
requests.get()でJ-Quantsへリクエストを送り、返ってきたレスポンスをresponseへ入れます。
raise_for_status()は、通信エラーなどが発生していないかを確認する処理です。問題がなければ、response.json()でJSON形式のデータをPythonから扱える形に変換します。
取得したデータには、銘柄コード、会社名、英語名、業種区分などが含まれていました。
普通株だけに絞り込む
J-Quantsから取得した一覧には、普通株だけでなくREIT、ETF、外国株なども含まれています。
今回の株アプリで扱いたいのは、まず国内の普通株です。そこで、商品区分を表すProdCatが011の銘柄だけを残します。
common_stocks = [
company
for company in companies
if company.get("ProdCat") == "011"
]
このリスト内包表記では、companiesから銘柄を1件ずつ取り出し、ProdCatが011のデータだけをcommon_stocksへ入れています。
絞り込み前後の件数も確認しました。
return {
"before_count": len(companies),
"after_count": len(common_stocks),
"companies": common_stocks,
}
結果は次のようになりました。
- 絞り込み前:4,446件
- 絞り込み後:3,899件
件数が減っているため、普通株だけに絞り込めたことが確認できます。
今回つまずいたところ
APIキーを読み込めているか確認する途中で、アクセス先がNot Foundになりました。
原因は、確認に使わない別のコードをコメントアウトできていなかったことでした。必要な処理だけを残して実行し直すと、APIキーが読み込まれていることを確認できました。
また、フロントエンド・バックエンド・外部APIの処理がつながるため、説明しながら「分かったつもりだったけれど、まだ曖昧だった部分」にも気づきました。
今回理解できたこと
- Next.jsとFastAPIは別の場所で動いているため、CORSの設定が必要になる
- APIキーは
.envへ保存し、コードへ直接書かない - FastAPIからJ-Quantsへリクエストを送ると、JSON形式で銘柄一覧を受け取れる
ProdCatを確認すると、普通株だけに絞り込める
今回は、コードへ直接書いた仮データではなく、J-Quantsから取得した銘柄一覧を扱えるところまで進みました。
まとめと次回予告
今回はJ-Quants APIから4,446件の銘柄情報を取得し、その中から普通株3,899件へ絞り込みました。
次回は、取得した銘柄データをデータベースへ保存します。外部APIから受け取ったデータを、株アプリで使いやすい形へ少しずつ整えていきます。
▼動画でも実際の開発の様子を公開しています

コメント