1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Python×株式投資: J-Quants API 認証について

Posted at

J-Quants APIを使い始める前にAPI認証されるかどうかを試す

はじめに

先日、財務データの取得の方法に関して、質問がありました。

J-Quants APIは、日本取引所グループ (JPX) が提供する個人投資家向けの金融データAPIサービスです。過去の財務情報や株価データなどを取得できます。

そこで、この記事では、J-Quants APIを使い始めるために必要なIDトークンの取得方法を、実際のサンプルコードと共に解説します。

注意
筆者は現在コロナウイルス感染症に罹患して、意識を朦朧とさせながら記事を執筆中です。いつもよりも大いに生成AIの力に頼っています。内容を鵜呑みにする前に、読者の皆様で、一度冷静にご判断いただくことをお勧めします。また、画面越しに感染のリスクがあるため、画面から十分離れて、一読ください。

必要な準備

1. J-Quantsアカウント

  • J-Quants公式HP でアカウントを作成
  • 筆者はライトプラン(¥1,650/月(税込))以上に加入

2. 環境変数ファイルの作成

プロジェクトのルートディレクトリに J-Quants.env ファイルを作成:

# J-Quants.env
JQUANTS_EMAIL=your_email@example.com
JQUANTS_PASSWORD=your_password

3. 必要なPythonライブラリ

pip install requests python-dotenv

J-Quants APIの動作確認用コードの紹介

目的

J-Quants APIが正常に動作するかをテストするための認証確認スクリプトを紹介します。

具体的な処理内容

  1. 認証テスト: J-Quants APIにログインしてIDトークンを取得
  2. API動作確認: 取得したトークンで実際にAPIリクエストを実行
  3. データ取得テスト: 上場企業一覧を取得してAPIが正常に動作することを確認

サンプルコードの全体構成

作成した jquants_auth_test.py は以下の構成になっています:

jquants_auth_test.py
├── get_jquants_token()      # 認証処理のメイン関数
├── test_api_request()       # APIリクエストのテスト関数
└── main()                   # 全体の実行を制御する関数

実際のコードを使って解説

1. 認証処理の流れ(get_jquants_token関数)

Step 1: 環境変数の読み込み

# 環境変数ファイルから認証情報を読み込み
load_dotenv('J-Quants.env')
JQUANTS_MAIL = os.getenv("JQUANTS_EMAIL")
JQUANTS_PASS = os.getenv("JQUANTS_PASSWORD")

何をしているか:

  • J-Quants.envファイルからメールアドレスとパスワードを読み込む
  • セキュリティのため、パスワードを直接コードに書かない

Step 2: 認証情報の確認

# 認証情報の確認
if not JQUANTS_MAIL or not JQUANTS_PASS:
    print("❌ 環境変数ファイル 'J-Quants.env' に認証情報が設定されていません")
    print("   以下の内容でファイルを作成してください:")
    print("   JQUANTS_EMAIL=your_email@example.com")
    print("   JQUANTS_PASSWORD=your_password")
    return None

何をしているか:

  • メールアドレスとパスワードが正しく設定されているかチェック
  • 設定されていない場合は、具体的な対処法を表示して処理を停止

Step 3: 2段階認証の実行

認証プロセスの概要
このスクリプトが行っている認証は、一般的なWebサービスで採用されている**「トークンベース認証」**という方式です。

単純に毎回メールアドレスとパスワードを送るのではなく、**2種類の「鍵(トークン)」**を使い分けることで、セキュリティが高められています。

リフレッシュトークン (Refresh Token):

  • 目的: 新しい「IDトークン」を発行してもらうための、長期間有効な鍵
  • 取得方法: 最初に一度だけ、メールアドレスとパスワードを使って取得
  • イメージ: 「自動ログインを許可する」にチェックを入れた状態

IDトークン (ID Token):

  • 目的: 実際に株価データなどを取得するAPIリクエストを行うための、短時間だけ有効な鍵
  • 取得方法: 「リフレッシュトークン」を使って取得
  • イメージ: Webサイトにログインした後に発行される、一時的な「セッションID」

この2段階の仕組みにより、毎回パスワードを送信する必要がなくなり、万が一IDトークンが漏洩しても短時間で無効になるため、安全性が向上します。

第1段階:ユーザー認証

# 1. ユーザー認証(リフレッシュトークン取得)
print("   📤 ユーザー認証中...")
auth_data = {"mailaddress": JQUANTS_MAIL, "password": JQUANTS_PASS}
auth_response = session.post(
    "https://api.jquants.com/v1/token/auth_user",
    data=json.dumps(auth_data),
    timeout=30
)
auth_response.raise_for_status()
refresh_token = auth_response.json()["refreshToken"]
print("   ✅ リフレッシュトークン取得完了")

何をしているか:

  • J-Quantsの認証サーバー (/token/auth_user) に、読み込んだメールアドレスとパスワードをPOSTリクエストで送信
  • 認証が成功すると、サーバーはJSON形式で**「リフレッシュトークン」**を返してくる
  • このステップ以降、パスワードはもう使わない

第2段階:IDトークン取得

# 2. IDトークン取得
print("   🔄 IDトークン取得中...")
token_response = session.post(
    "https://api.jquants.com/v1/token/auth_refresh",
    params={"refreshtoken": refresh_token},
    timeout=30
)
token_response.raise_for_status()
id_token = token_response.json()["idToken"]
print("   ✅ IDトークン取得完了")

何をしているか:

  • ステップ1で取得したrefresh_tokenを使い、別の認証サーバー (/token/auth_refresh) に「IDトークンをください」とリクエストを送信
  • リフレッシュトークンが有効であれば、サーバーは**「IDトークン」**を返してくる(有効期限は短く設定されている)
  • これが実際のAPIアクセスのための「鍵」となる

Step 4: ヘッダーの設定

# 3. ヘッダー設定
headers = {"Authorization": f"Bearer {id_token}"}
print("🎉 J-QuantsのIDトークン取得完了!")
return headers, session

何をしているか:

  • ステップ2で取得したid_tokenを、APIリクエストの際に「私は認証済みです」と証明するためのHTTPヘッダーを作成
  • 形式: Authorization: Bearer <取得したIDトークン> という形式にするのがルール
  • これ以降、株価情報などを取得する際には、すべてのリクエストにこのheadersを付けて送る必要がある

2. APIリクエストのテスト(test_api_request関数)

Step 1: 認証状態の確認

def test_api_request(headers, session):
    """APIリクエストのテスト"""
    if not headers or not session:
        print("❌ 認証が完了していません")
        return False

何をしているか:

  • 認証が正常に完了しているかチェック
  • 認証が完了していない場合は処理を停止

Step 2: 上場企業一覧の取得

print("\n🧪 APIリクエストのテスト中...")
try:
    # 簡単なテスト:上場企業一覧の取得
    print("   📊 上場企業一覧を取得中...")
    url = "https://api.jquants.com/v1/listed/info"
    response = session.get(url, headers=headers, timeout=30)

何をしているか:

  • 認証が成功したか確認するため、簡単なAPIリクエストを実行
  • 上場企業一覧の取得APIを使用(制限が少ない)
  • 30秒のタイムアウトを設定

Step 3: レスポンスの処理

if response.status_code == 200:
    data = response.json()
    companies = data.get('info', [])
    print(f"   ✅ 取得成功: {len(companies)}社の情報")
    
    # 最初の3社の情報を表示
    print("\n📋 取得した企業情報(最初の3社):")
    for i, company in enumerate(companies[:3]):
        print(f"   {i+1}. {company.get('CompanyName', 'N/A')} ({company.get('Code', 'N/A')})")
    
    return True

何をしているか:

  • HTTPステータスコード200(成功)をチェック
  • JSONレスポンスを解析して企業数を表示
  • 最初の3社の企業名とコードを表示して動作確認

3. 全体の実行制御(main関数)

Step 1: 認証の実行

def main():
    """メイン実行"""
    print("🚀 J-Quants API 認証テスト開始")
    print("=" * 50)
    
    # 1. 認証
    headers, session = get_jquants_token()

何をしているか:

  • プログラムの開始を表示
  • get_jquants_token()関数を呼び出して認証を実行

Step 2: 認証失敗時の処理

if not headers:
    print("\n❌ 認証に失敗しました")
    print("   以下を確認してください:")
    print("   - J-Quants.env ファイルが存在するか")
    print("   - メールアドレスとパスワードが正しいか")
    print("   - J-Quantsアカウントが有効か")
    return

何をしているか:

  • 認証が失敗した場合の具体的な確認項目を表示
  • ユーザーが対処しやすいように詳細な情報を提供

Step 3: APIテストの実行

# 2. APIテスト
success = test_api_request(headers, session)

何をしているか:

  • 認証が成功した場合、APIリクエストのテストを実行
  • 実際にデータを取得できるかテスト

Step 4: 結果の表示

# 3. 結果表示
print("\n" + "=" * 50)
if success:
    print("🎉 認証テスト完了!J-Quants APIが正常に動作しています")
    print("\n📝 次のステップ:")
    print("   1. 財務データの取得")
    print("   2. 株価データの取得")
    print("   3. その他の金融データの取得")
else:
    print("⚠️  認証は成功しましたが、APIリクエストでエラーが発生しました")
    print("   ネットワーク環境やAPI制限を確認してください")

何をしているか:

  • 認証テストの結果を表示
  • 成功時は次のステップの案内を表示
  • エラー時は対処法を提示

エラーハンドリングの仕組み

1. ネットワークエラーの処理

except requests.exceptions.RequestException as e:
    print(f"❌ ネットワークエラー: {e}")
    return None, None

何をしているか:

  • インターネット接続の問題やサーバー障害を検出
  • エラーメッセージを表示して処理を停止

2. JSON解析エラーの処理

except json.JSONDecodeError as e:
    print(f"❌ JSON解析エラー: {e}")
    return None, None

何をしているか:

  • APIレスポンスがJSON形式でない場合を検出
  • サーバーからの応答が不正な場合の処理

3. その他のエラーの処理

except Exception as e:
    print(f"❌ 認証に失敗しました: {e}")
    return None, None

何をしているか:

  • 予期しないエラーが発生した場合の処理
  • 認証情報が間違っている場合など

実行方法と実際の出力

実行コマンド

python jquants_auth_test.py

正常な出力例

🚀 J-Quants API 認証テスト開始
==================================================
🔐 J-QuantsのIDトークンを取得中...
📧 メールアドレス: your_email@example.com
🔑 パスワード: ********
   📤 ユーザー認証中...
   ✅ リフレッシュトークン取得完了
   🔄 IDトークン取得中...
   ✅ IDトークン取得完了
🎉 J-QuantsのIDトークン取得完了!

🧪 APIリクエストのテスト中...
   📊 上場企業一覧を取得中...
   ✅ 取得成功: 3,847社の情報

📋 取得した企業情報(最初の3社):
   1. 極洋 (1301)
   2. 日本水産 (1332)
   3. マルハニチロ (1333)

==================================================
🎉 認証テスト完了!J-Quants APIが正常に動作しています

📝 次のステップ:
   1. 財務データの取得
   2. 株価データの取得
   3. その他の金融データの取得

エラー時の出力例

🚀 J-Quants API 認証テスト開始
==================================================
🔐 J-QuantsのIDトークンを取得中...
❌ 環境変数ファイル 'J-Quants.env' に認証情報が設定されていません
   以下の内容でファイルを作成してください:
   JQUANTS_EMAIL=your_email@example.com
   JQUANTS_PASSWORD=your_password

❌ 認証に失敗しました
   以下を確認してください:
   - J-Quants.env ファイルが存在するか
   - メールアドレスとパスワードが正しいか
   - J-Quantsアカウントが有効か

このコードの重要なポイント

1. セキュリティ

  • パスワードを直接コードに書かない
  • 環境変数ファイル(.env)で認証情報を管理

2. エラーハンドリング

  • 各段階でエラーが発生した場合の適切な処理
  • ユーザーが対処しやすいエラーメッセージ

3. 段階的な処理

  • 認証 → APIテスト → 結果表示の順で実行
  • 各段階で問題があれば早期に処理を停止

4. 実際のAPI動作確認

  • 認証だけでなく、実際にデータを取得できるかテスト
  • 上場企業一覧を取得してAPIの動作を確認

次のステップ

認証が成功したら、以下のようなAPIリクエストが可能になります:

財務データの取得

url = "https://api.jquants.com/v1/fins/statements?code=13010"
response = session.get(url, headers=headers)

株価データの取得

url = "https://api.jquants.com/v1/prices/daily_quotes?code=13010&from=2024-01-01&to=2024-12-31"
response = session.get(url, headers=headers)

まとめ

このコードの役割

  • 認証テスト: J-Quants APIへのログインが正常に動作するか確認
  • API動作確認: 取得したトークンで実際にデータを取得できるかテスト
  • 基礎構築: 株価データや財務データを取得するための土台作り

重要なポイント

  • このコードは認証とAPIの動作確認が目的
  • 株価データ自体は取得していない
  • 認証成功後に、別のAPIエンドポイントで実際のデータを取得可能

J-Quants APIを使い始めるには

  1. アカウント作成・プラン加入
  2. .envファイルで認証情報設定
  3. 2段階認証でIDトークン取得
  4. 取得したトークンでAPIリクエスト

次回予告

今回は、このような、内容の薄い記事をお送りしてしまい申し訳ございません。
体調が良くなれば、東証プライム全銘柄の財務データを取得して、統合データセット作る方法紹介します。

##サンプルコード

"""
J-Quants API 認証テスト用スクリプト
IDトークンの取得と簡単なAPIリクエストをテストします
"""

import os
import requests
import json
from dotenv import load_dotenv

def get_jquants_token():
    """J-QuantsのIDトークンを取得する"""
    print("🔐 J-QuantsのIDトークンを取得中...")
    
    # 環境変数ファイルから認証情報を読み込み
    load_dotenv('J-Quants.env')
    JQUANTS_MAIL = os.getenv("JQUANTS_EMAIL")
    JQUANTS_PASS = os.getenv("JQUANTS_PASSWORD")
    
    # 認証情報の確認
    if not JQUANTS_MAIL or not JQUANTS_PASS:
        print("❌ 環境変数ファイル 'J-Quants.env' に認証情報が設定されていません")
        print("   以下の内容でファイルを作成してください:")
        print("   JQUANTS_EMAIL=your_email@example.com")
        print("   JQUANTS_PASSWORD=your_password")
        return None
    
    print(f"📧 メールアドレス: {JQUANTS_MAIL}")
    print(f"🔑 パスワード: {'*' * len(JQUANTS_PASS)}")
    
    session = requests.Session()
    
    try:
        # 1. ユーザー認証(リフレッシュトークン取得)
        print("   📤 ユーザー認証中...")
        auth_data = {"mailaddress": JQUANTS_MAIL, "password": JQUANTS_PASS}
        auth_response = session.post(
            "https://api.jquants.com/v1/token/auth_user",
            data=json.dumps(auth_data),
            timeout=30
        )
        auth_response.raise_for_status()
        refresh_token = auth_response.json()["refreshToken"]
        print("   ✅ リフレッシュトークン取得完了")
        
        # 2. IDトークン取得
        print("   🔄 IDトークン取得中...")
        token_response = session.post(
            "https://api.jquants.com/v1/token/auth_refresh",
            params={"refreshtoken": refresh_token},
            timeout=30
        )
        token_response.raise_for_status()
        id_token = token_response.json()["idToken"]
        print("   ✅ IDトークン取得完了")
        
        # 3. ヘッダー設定
        headers = {"Authorization": f"Bearer {id_token}"}
        
        print("🎉 J-QuantsのIDトークン取得完了!")
        return headers, session
        
    except requests.exceptions.RequestException as e:
        print(f"❌ ネットワークエラー: {e}")
        return None, None
    except json.JSONDecodeError as e:
        print(f"❌ JSON解析エラー: {e}")
        return None, None
    except Exception as e:
        print(f"❌ 認証に失敗しました: {e}")
        return None, None

def test_api_request(headers, session):
    """APIリクエストのテスト"""
    if not headers or not session:
        print("❌ 認証が完了していません")
        return False
    
    print("\n🧪 APIリクエストのテスト中...")
    
    try:
        # 簡単なテスト:上場企業一覧の取得
        print("   📊 上場企業一覧を取得中...")
        url = "https://api.jquants.com/v1/listed/info"
        response = session.get(url, headers=headers, timeout=30)
        
        if response.status_code == 200:
            data = response.json()
            companies = data.get('info', [])
            print(f"   ✅ 取得成功: {len(companies)}社の情報")
            
            # 最初の3社の情報を表示
            print("\n📋 取得した企業情報(最初の3社):")
            for i, company in enumerate(companies[:3]):
                print(f"   {i+1}. {company.get('CompanyName', 'N/A')} ({company.get('Code', 'N/A')})")
            
            return True
        else:
            print(f"   ❌ APIエラー: {response.status_code}")
            print(f"   レスポンス: {response.text}")
            return False
            
    except Exception as e:
        print(f"   ❌ APIリクエストエラー: {e}")
        return False

def main():
    """メイン実行"""
    print("🚀 J-Quants API 認証テスト開始")
    print("=" * 50)
    
    # 1. 認証
    headers, session = get_jquants_token()
    
    if not headers:
        print("\n❌ 認証に失敗しました")
        print("   以下を確認してください:")
        print("   - J-Quants.env ファイルが存在するか")
        print("   - メールアドレスとパスワードが正しいか")
        print("   - J-Quantsアカウントが有効か")
        return
    
    # 2. APIテスト
    success = test_api_request(headers, session)
    
    # 3. 結果表示
    print("\n" + "=" * 50)
    if success:
        print("🎉 認証テスト完了!J-Quants APIが正常に動作しています")
        print("\n📝 次のステップ:")
        print("   1. 財務データの取得")
        print("   2. 株価データの取得")
        print("   3. その他の金融データの取得")
    else:
        print("⚠️  認証は成功しましたが、APIリクエストでエラーが発生しました")
        print("   ネットワーク環境やAPI制限を確認してください")

if __name__ == "__main__":
    main()
1
2
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
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?