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?

【ChatGPT開発入門】FastAPIとNext.jsで株価データを取得し、グラフを表示する🎵

Last updated at Posted at 2025-02-13

この記事では、PythonのFastAPIを使用してYahoo Financeから株価データを取得し、そのデータをNext.jsを使って表示する方法について解説します。また、実装における工夫点についても詳しく説明します。

プロジェクトの概要

FastAPIを用いてYahoo Financeから株価データを取得し、Next.jsを使ってそのデータを表示するウェブアプリケーションを作成します。以下が今回の実装における主なステップです。

  1. FastAPIサーバーのセットアップ
  2. Next.jsアプリケーションのセットアップ
  3. FastAPIとNext.jsの統合
  4. データのグラフ化

ディレクトリ構成

まず、プロジェクト全体のディレクトリ構成を以下のように整理します。

my-app/
├── back-end/
│   ├── app/
│   │   ├── __init__.py
│   │   ├── main.py
│   └── requirements.txt
├── my-next-app/
│   ├── pages/
│   │   ├── index.js
│   ├── public/
│   ├── styles/
│   ├── .gitignore
│   ├── package.json
│   ├── README.md
│   ├── next.config.js
└── README.md

各ディレクトリとファイルの説明

  • back-end/: FastAPIプロジェクトを含むディレクトリ。
    • app/: FastAPIアプリケーションのコードを格納するディレクトリ。
      • init.py: パッケージとして認識させるための空ファイル。
      • main.py: FastAPIのメインアプリケーションコード。
    • requirements.txt: 必要なPythonパッケージを記載したファイル。
requirements.txt
fastapi
uvicorn
yahoo_fin
  • /: Next.jsプロジェクトを含むディレクトリ。
    • pages/: Next.jsのページコンポーネントを格納するディレクトリ。
      • index.js: メインページのコンポーネント。
    • public/: 静的ファイルを配置するディレクトリ。
    • styles/: CSSファイルを配置するディレクトリ。
    • .gitignore: Gitが無視するファイルやディレクトリを記述したファイル。
    • package.json: Next.jsプロジェクトの設定ファイル。
    • README.md: プロジェクトの説明ファイル。
    • next.config.js: Next.jsの設定ファイル(必要に応じて)。

1. FastAPIサーバーのセットアップ

インストールと初期設定

まず、必要なパッケージをインストールします。

pip install fastapi uvicorn yahoo_fin

次に、FastAPIサーバーのコードを以下のように作成します。

# app/main.py

from fastapi import FastAPI, HTTPException
from yahoo_fin import stock_info as si
from fastapi.middleware.cors import CORSMiddleware
import pandas as pd
import logging

app = FastAPI()

origins = [
    "http://localhost:3000",  # Next.jsのデフォルトのポート
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

@app.get("/stocks/{symbol}")
async def get_stock_data(symbol: str, start: str, end: str):
    try:
        logger.info(f"Fetching data for {symbol} from {start} to {end}")
        data = si.get_data(symbol, start_date=start, end_date=end)
        data = data.reset_index()
        data['date'] = data['index'].astype(str)
        return data.to_dict(orient='records')
    except Exception as e:
        logger.error(f"Error fetching data: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))

工夫した点

  • エラーハンドリング:適切なエラーハンドリングを追加し、エラーが発生した場合に詳細なログを記録するようにしました。
  • データ形式の整形pandasデータフレームのインデックスをリセットし、date 列を作成することで、データが正しい形式で返されるようにしました。

2. Next.jsアプリケーションのセットアップ

インストールと初期設定

Next.jsプロジェクトを作成し、必要なパッケージをインストールします。

npx create-next-app my-next-app
cd my-next-app
npm install chart.js react-chartjs-2

次に、Next.jsアプリケーションのコードを以下のように作成します。

import { useState } from 'react';
import { Line } from 'react-chartjs-2';
import { Chart, registerables } from 'chart.js';

Chart.register(...registerables);

export default function Home() {
  const [data, setData] = useState(null);
  const [symbol, setSymbol] = useState('');
  const [start, setStart] = useState('');
  const [end, setEnd] = useState('');

  const fetchData = async () => {
    try {
      const response = await fetch(`http://localhost:8000/stocks/${symbol}?start=${start}&end=${end}`);
      const result = await response.json();

      // データのコンソール出力
      console.log('Fetched data:', result);

      if (Array.isArray(result)) {
        setData(result);
      } else {
        console.error('Unexpected data format:', result);
        setData([]);
      }
    } catch (error) {
      console.error('Error fetching data:', error);
      setData([]);
    }
  };

  const chartData = {
    labels: data ? data.map(item => item.date) : [],
    datasets: [
      {
        label: `${symbol} Stock Price`,
        data: data ? data.map(item => item.close) : [],
        fill: false,
        backgroundColor: 'rgba(75,192,192,0.4)',
        borderColor: 'rgba(75,192,192,1)',
      },
    ],
  };

  return (
    <div>
      <h1>Stock Data</h1>
      <input placeholder="Symbol" value={symbol} onChange={(e) => setSymbol(e.target.value)} />
      <input type="date" value={start} onChange={(e) => setStart(e.target.value)} />
      <input type="date" value={end} onChange={(e) => setEnd(e.target.value)} />
      <button onClick={fetchData}>Fetch Data</button>
      {data && (
        <Line data={chartData} />
      )}
    </div>
  );
}

工夫した点

  • データの形式確認:データを取得した際に、データが配列形式であることを確認し、想定外のデータ形式が返された場合のエラーハンドリングを追加しました。
  • グラフの表示chart.jsreact-chartjs-2 を使用して、取得したデータをグラフ化しました。

3. FastAPIとNext.jsの統合

FastAPIサーバーを起動し、Next.jsアプリケーションからデータを取得して表示します。

実行

  1. FastAPIサーバーを起動

    uvicorn app.main:app --reload
    
  2. Next.jsアプリケーションを起動

    npm run dev
    

ブラウザで http://localhost:3000 にアクセスすると、Yahoo Financeから取得したデータがグラフとして表示されます。

シンプルな構成が難しかった理由

最初はシンプルな構成で実装を試みましたが、以下の点で難しさがありました。

  • クランブトークンとクッキーの問題: JavaScriptのライブラリを用いる際に、Yahoo Financeのクランブトークンとクッキーの取得や管理が必要でした。一方、Pythonのyahoo_finライブラリではこれらの管理が自動化されており、設定が簡単でした。
  • エラーハンドリングの複雑さ: JavaScript側で発生するエラーのハンドリングが複雑で、エラーの原因を特定しにくかったため、PythonのFastAPIを使用してバックエンドを構築することにしました。

まとめ

この記事では、FastAPIとNext.jsを使ってYahoo Financeから株価データを取得し、そのデータをグラフとして表示する方法を紹介しました。エラーハンドリングやデータの形式確認など、いくつかの工夫点を中心に解説しました。このアプローチを活用して、他のデータソースやグラフ表示にも応用できるでしょう。

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?