Hugging Face Access Token取得支援ツール(ソースコードと説明と利用ガイド)

概要

Hugging Face にアクセスするためのAccess Tokenの取得と管理を支援するコマンドライン型のツールである。ブラウザでAccess Token取得ページを開き、利用者が取得したAccess Tokenを画面に表示せずに入力し、環境設定ファイル(.env)へ保存する。Python標準ライブラリだけで動作する。

目次

関連する外部ページ

サイト内の関連情報

第1章 プログラム利用ガイド

1. このプログラムの利用シーン

Hugging Face にアクセスするためのAccess Tokenを取得・管理することを支援するツールである。Hugging Face の学習済みモデルやデータセットを扱うプログラムでは、認証にAccess Tokenが必要になる場合がある。

2. 主な機能

3. 基本的な使い方

4. 便利な機能

第2章 Python開発環境、ライブラリ類

ここでは、最低限の事前準備について説明する。機械学習や深層学習を行う場合は、NVIDIA CUDA、Visual Studio、Cursorなどを追加でインストールすると便利である。これらについては別ページ https://www.kkaneko.jp/cc/dev/aiassist.html で解説している。

第3章 Python 3.12 のインストール

Pythonのインストールを行い、Pythonのプログラムを実行する環境を整える。扱う環境は、Windows搭載パソコンである。金子研究室では、Python 3.12.10を推奨する。

[Windows での Python 3.12 のインストール手順を見るには、ここをクリック]

Windows での Python 3.12 のインストール

以下のいずれかの方法でPython 3.12をインストールする。Pythonがインストール済みの場合、この手順は不要である。

方法 1:winget によるインストール

インストールコマンドの実行方法

管理者権限コマンドプロンプトを起動する(手順:Windowsキーまたはスタートメニュー → cmd と入力 → 右クリック → 「管理者として実行」)。そして、コマンド全体をコマンドプロンプトにコピー&ペーストする。

--scope machine を指定することで、システム全体(全ユーザー向け)にインストールされる。このオプションの実行には管理者権限が必要である。インストール完了後、コマンドプロンプトを再起動するとPATHが反映される。

REM Python 3.12 をシステム領域にインストール
winget install --id Python.Python.3.12 -e --scope machine --silent --accept-source-agreements --accept-package-agreements --override "/quiet InstallAllUsers=1 PrependPath=1 Include_test=0 Include_pip=1 Include_launcher=1 InstallLauncherAllUsers=1 TargetDir=\"C:\Program Files\Python312\""
if not "%ERRORLEVEL%"=="0" ( color 0c & echo Python 3.12 のインストールに失敗しました & ping 127.0.0.1 -n 6 >nul & color )

REM Python と Scripts を PATH 先頭に追加
powershell -NoProfile -Command "$p='C:\Program Files\Python312'; $s=\"$p\Scripts\"; if(Test-Path $p){$k=[Microsoft.Win32.Registry]::LocalMachine.OpenSubKey('SYSTEM\CurrentControlSet\Control\Session Manager\Environment',$true); $c=$k.GetValue('Path','',[Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames); $t=$k.GetValueKind('Path'); $new=$c; if((';'+$new+';') -notlike \"*;$p;*\"){$new=$p+';'+$new}; if((';'+$new+';') -notlike \"*;$s;*\"){$new=$s+';'+$new}; if($new -ne $c){$k.SetValue('Path',$new,$t)}; $k.Close()}"

REM 現在のセッションにも反映(システムPATHを再取得して連結)
for /f "usebackq tokens=2,*" %A in (`reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v Path`) do set "PATH=%B"

REM pip / wheel の更新
python -m pip install --no-user -U pip wheel
if not "%ERRORLEVEL%"=="0" ( color 0c & echo pip / wheel の更新に失敗しました & ping 127.0.0.1 -n 6 >nul & color )

方法 2:インストーラーによるインストール

  1. Python公式サイト(https://www.python.org/downloads/)にアクセスし、「Download Python 3.x.x」ボタンからWindows用インストーラーをダウンロードする。
  2. ダウンロードしたインストーラーを実行する。
  3. 初期画面の下部に表示される「Add python.exe to PATH」にチェックを入れてから「Customize installation」を選択する。このチェックを入れ忘れると、コマンドプロンプトから python コマンドを実行できない。
  4. 「Install Python 3.xx for all users」にチェックを入れ、「Install」をクリックする。

インストールの確認

コマンドプロンプトで以下を実行する。

python --version

バージョン番号(例:Python 3.12.x)が表示されればインストール成功である。「'python' は、内部コマンドまたは外部コマンドとして認識されていません。」と表示される場合は、インストールが正常に完了していない。

第4章 Python の開発環境 Visual Studio Code のインストールと Python 用の設定

Python の開発環境Visual Studio Code(プログラムを編集するソフトウェア。以下、VS Code)を整える。

[Windows での Visual Studio Code のインストールと Python 用の設定手順を見るには、ここをクリック]

Windows での Visual Studio Code のインストールと Python 用の設定手順

1. VS Code と拡張機能のインストール

以下のコマンドにより,既存の VS Code を削除し,全ユーザー共有の設定で再インストールしたうえで,拡張機能(VS Code に機能を追加するソフトウェア)をまとめて導入する.

インストールコマンドの実行方法

管理者権限コマンドプロンプトを起動する(手順:Windows キーまたはスタートメニュー → cmd と入力 → 右クリック → 「管理者として実行」)。そして,コマンド全体をコマンドプロンプトにコピー&ペーストする。

インストールコマンド


REM ============================================================
REM Microsoft Visual Studio Code
REM ============================================================
REM Build Tools + Desktop development with C++(VCTools)+ 追加コンポーネント(一括)
REM 未インストール時: winget で新規インストール
REM インストール済み時: setup.exe modify でコンポーネント追加(バージョンは変更しない)
winget list --id Microsoft.VisualStudio.BuildTools 2>nul | findstr /i "BuildTools" >nul 2>&1
if %ERRORLEVEL% EQU 0 (
    for /f "usebackq delims=" %P in (`"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -products Microsoft.VisualStudio.Product.BuildTools -property installationPath`) do start /wait "" "C:\Program Files (x86)\Microsoft Visual Studio\Installer\setup.exe" modify --installPath "%P" --add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Workload.MSBuildTools --add Microsoft.VisualStudio.Component.VC.CMake.Project --add Microsoft.VisualStudio.Component.VC.Llvm.Clang --add Microsoft.VisualStudio.Component.VC.Llvm.ClangToolset --add Microsoft.VisualStudio.Component.Windows11SDK.26100 --add Microsoft.VisualStudio.Component.VC.v143.x86.x64 --includeRecommended --quiet --norestart --nocache
    if not "%ERRORLEVEL%"=="0" ( color 0c & echo Build Tools のコンポーネント追加に失敗しました & ping 127.0.0.1 -n 6 >nul & color )
) else (
    winget install --scope machine --id Microsoft.VisualStudio.BuildTools -e --silent --disable-interactivity --force --accept-source-agreements --accept-package-agreements --override "--quiet --wait --norestart --nocache --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended --add Microsoft.VisualStudio.Workload.MSBuildTools --add Microsoft.VisualStudio.Component.VC.CMake.Project --add Microsoft.VisualStudio.Component.VC.Llvm.Clang --add Microsoft.VisualStudio.Component.VC.Llvm.ClangToolset --add Microsoft.VisualStudio.Component.Windows11SDK.26100 --add Microsoft.VisualStudio.Component.VC.v143.x86.x64"
    if not "%ERRORLEVEL%"=="0" ( color 0c & echo Build Tools のインストールに失敗しました & ping 127.0.0.1 -n 6 >nul & color )
)

REM 全ユーザー共有の拡張機能フォルダ
if not exist "C:\ProgramData\vscode-extensions" mkdir "C:\ProgramData\vscode-extensions"
icacls "C:\ProgramData\vscode-extensions" /grant "Everyone:(OI)(CI)M" /T

REM スタートメニューのショートカットを --extensions-dir 付きで再作成
if exist "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio Code" rmdir /s /q "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio Code"
if exist "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio Code.lnk" del "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio Code.lnk"
powershell -NoProfile -Command "$s=New-Object -ComObject WScript.Shell; $lnk=$s.CreateShortcut('C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio Code.lnk'); $lnk.TargetPath='C:\Program Files\Microsoft VS Code\Code.exe'; $lnk.Arguments='--extensions-dir \"C:\ProgramData\vscode-extensions\"'; $lnk.Save()"
REM ショートカットの検証
powershell -NoProfile -Command "$s=New-Object -ComObject WScript.Shell; $lnk=$s.CreateShortcut('C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio Code.lnk'); Write-Host 'TargetPath:' $lnk.TargetPath; Write-Host 'Arguments:' $lnk.Arguments"

REM ファイル / フォルダ右クリックの「Code で開く」を登録
reg add "HKLM\SOFTWARE\Classes\*\shell\VSCode\command" /ve /d "\"C:\Program Files\Microsoft VS Code\Code.exe\" --extensions-dir \"C:\ProgramData\vscode-extensions\" \"%1\"" /f
reg add "HKLM\SOFTWARE\Classes\Directory\shell\VSCode\command" /ve /d "\"C:\Program Files\Microsoft VS Code\Code.exe\" --extensions-dir \"C:\ProgramData\vscode-extensions\" \"%1\"" /f
reg add "HKLM\SOFTWARE\Classes\Directory\Background\shell\VSCode\command" /ve /d "\"C:\Program Files\Microsoft VS Code\Code.exe\" --extensions-dir \"C:\ProgramData\vscode-extensions\" \"%V\"" /f

REM --extensions-dir 付きで起動する code.cmd ラッパを作成
REM (%* を echo で書くと対話的 cmd で失われるため、PowerShell で [char]37+'*' を書き出す)
powershell -NoProfile -Command "$pct=[char]37; $q=[char]34; $c='@echo off'+[char]13+[char]10+$q+'C:\Program Files\Microsoft VS Code\bin\code.cmd'+$q+' --extensions-dir '+$q+'C:\ProgramData\vscode-extensions'+$q+' '+$pct+'*'+[char]13+[char]10; [IO.File]::WriteAllText('C:\ProgramData\vscode-extensions\vscode.cmd',$c,[Text.Encoding]::ASCII)"

REM 拡張機能のインストール
set "CODE=C:\Program Files\Microsoft VS Code\bin\code.cmd"
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --uninstall-extension GitHub.copilot
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --uninstall-extension GitHub.copilot-chat
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension ms-python.python
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension ms-python.vscode-pylance
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension ms-python.debugpy
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension MS-CEINTL.vscode-language-pack-ja
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension saoudrizwan.claude-dev
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension rust-lang.rust-analyzer
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension tamasfe.even-better-toml
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension anthropic.claude-code
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension almenon.arepl
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --list-extensions --show-versions

REM settings.json を作成(自動更新オフ、Python、Claude Code 設定)
if not exist "%APPDATA%\Code\User" mkdir "%APPDATA%\Code\User"
python -c "import json,os;data={'update.mode':'none','update.enableWindowsBackgroundUpdates':False,'extensions.autoUpdate':False,'python.defaultInterpreterPath':r'C:\Program Files\Python312\python.exe','claudeCode.environmentVariables':[{'name':'ANTHROPIC_API_KEY','value':'not-needed'},{'name':'ANTHROPIC_AUTH_TOKEN','value':'ollama'},{'name':'ANTHROPIC_BASE_URL','value':'http://localhost:11434'},{'name':'ANTHROPIC_MODEL','value':'glm-4.7-flash'},{'name':'CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC','value':'1'}]};p=os.path.join(os.environ['APPDATA'],'Code','User','settings.json');open(p,'w',encoding='utf-8').write(json.dumps(data,indent=4));print('Done:',p)"

REM 自動更新の抑止ポリシー(settings.json に加えて、レジストリ側でも明示的にオフ)
reg add "HKLM\SOFTWARE\Policies\Microsoft\VSCode" /v "UpdateMode" /t REG_SZ /d "none" /f
echo === セットアップ完了 ===

2. Python インタプリタの選択

同一マシンに複数の Python がインストールされている場合,VS Code で使用する Python 本体(インタプリタ:Python プログラムを解釈・実行するソフトウェア)を選択する必要がある.

  1. コマンドパレット(コマンド名で機能を呼び出す VS Code の入力欄)を開く(Ctrl+Shift+P
  2. Python: Select Interpreter と入力する
  3. 表示される一覧から,使用する Python(例:C:\Program Files\Python312\python.exe)を選択する.

必要なライブラリ

このプログラムはPython標準ライブラリだけで動作するため、追加のインストールは不要である。保存したAccess Tokenを実際に使う場面では huggingface_hub が必要になる。その場合は、管理者権限コマンドプロンプトを起動する (手順:Windowsキーまたはスタートメニュー → cmd と入力 → 右クリック → 「管理者として実行」)。

起動したコマンドプロンプトで次を実行する。--no-user は、ユーザ領域ではなくシステム領域へインストールするためのオプションである。

pip install -U --no-user huggingface_hub

第5章 Hugging Face Access Token取得支援プログラム

1. 概要

このプログラムは、Hugging Face Access Tokenの取得と管理を支援するコマンドライン型ツールである。利用者がブラウザでHugging Faceから手動でAccess Tokenを取得し、環境設定ファイル(.env)に保存する機能を提供する。

2. 主要技術

webbrowser モジュール

Pythonの標準ライブラリに含まれる、プラットフォームに依存しないブラウザ制御モジュールである[1]。既定のブラウザを自動的に選んでURLを表示する。新しいタブ、新しいウィンドウ、既定のブラウザでの表示を選べる。

getpass モジュール

入力した文字を画面に表示しない入力機能を提供する標準ライブラリである[2]。入力中の文字が画面に残らないため、機密情報の入力に適している。

3. 実装の特色

環境変数名の検証

環境変数名がPOSIXの慣用(先頭は英字またはアンダースコア、以降は英数字とアンダースコア)に沿っているかを確認する。沿っていない場合は既定名を用いる。

機密情報の取り扱い

取得したAccess Tokenは、画面表示の際に先頭8文字と末尾4文字だけを表示し、全体は表示しない。

Access Tokenの権限

Hugging Face のAccess Tokenには fine-grainedreadwrite の3種類がある[3]。モデルやデータセットのダウンロードだけであれば read で足りる。

4. 参考文献

[1] Python Software Foundation. webbrowser — Convenient web-browser controller. Python 3.12 documentation. https://docs.python.org/3.12/library/webbrowser.html

[2] Python Software Foundation. getpass — Portable password input. Python 3.12 documentation. https://docs.python.org/3.12/library/getpass.html

[3] Hugging Face. User access tokens. https://huggingface.co/docs/hub/security-tokens

5. ソースコード

"""
プログラム名: Hugging Face Access Token取得支援プログラム
特徴技術名: webbrowserモジュール
出典: Python Software Foundation. webbrowser — Convenient web-browser controller. Python 3.12 documentation. https://docs.python.org/3.12/library/webbrowser.html

特徴機能: プラットフォームに依存しないブラウザ制御
webbrowserモジュールは、Unix、Windows、macOSで動作し、各プラットフォームの既定のブラウザを自動的に選んでURLを表示する機能を提供する。

学習済みモデル: 使用していない

方式設計:
- 関連利用技術:
  - getpassモジュール: 入力文字を画面に表示しないAccess Token入力
  - pathlibモジュール: オブジェクト指向のファイルパス操作とファイル読み書き
  - reモジュール: 環境変数名の妥当性検査
  - shutilモジュール: .envのバックアップ作成
- 入力と出力:
  入力:
  ・環境変数名の選択(HF_TOKEN/HUGGINGFACE_HUB_TOKEN/HUGGINGFACE_API_TOKEN/カスタム)
  ・保存先ファイルの選択(.env/.env.development/.env.production/カスタム)
  ・ブラウザの開き方の選択(既定/新しいタブ/新しいウィンドウ)
  ・利用者による操作(ブラウザでのAccess Token取得、コンソールでのAccess Token入力)
  出力: ブラウザでのHugging Face Access Tokenページ表示、Access Tokenの.envファイル保存、保存後のガイダンス表示
- 処理手順:
  1. 環境変数名と保存先ファイルを選択する
  2. 既存Access Tokenの確認と選択肢提示
  3. ブラウザでHugging Face Access Tokenページを開く
  4. 利用者が手動でAccess Tokenを取得する
  5. getpassを使用したAccess Token入力
  6. .envをバックアップし、Access Tokenを.envファイルへ保存する
  7. 保存後の確認メッセージと利用ガイダンス表示
- 前処理: 既存.envファイルの読み込みとAccess Token存在確認
- 後処理: Access Token保存後の確認メッセージ表示
- 追加処理: Access Tokenの部分マスク表示、バックアップ作成
- 調整を必要とする設定値:
  - var_name: 保存する環境変数名(HF_TOKEN/HUGGINGFACE_HUB_TOKEN/HUGGINGFACE_API_TOKEN/カスタム)
  - filename: Access Tokenを保存するファイル名(既定: .env)
  - browser_mode: ブラウザ起動モード(既定/新しいタブ/新しいウィンドウ)

将来方策: 既存の.envファイルの読み込みと同一Access Tokenの存在確認は現行実装で対応済み

その他の重要事項:
- getpassモジュールによりAccess Token入力時の画面表示を防止する
- バックアップ作成機能により既存ファイルの安全性を確保する
- Hugging Face Access Tokenは通常 hf_ で始まる形式である
- huggingface_hub は環境変数 HF_TOKEN を参照する

前準備: なし(標準ライブラリのみ使用)
"""

import webbrowser
from pathlib import Path
import getpass
import re
import shutil
import time

# 設定定数
DEFAULT_ENV_FILE = '.env'
DEFAULT_ENV_CHOICES = ['.env', '.env.development', '.env.production']
DEFAULT_KEY_CHOICES = ['HF_TOKEN', 'HUGGINGFACE_HUB_TOKEN', 'HUGGINGFACE_API_TOKEN']
HUGGINGFACE_TOKEN_URL = 'https://huggingface.co/settings/tokens'


def get_user_choice(title, choices, custom_prompt=None):
    """番号による選択を受け付ける。カスタムを選んだ場合は (None, True) を返す"""
    print(title)

    for i, choice in enumerate(choices, 1):
        print(f'{i}. {choice}')
    if custom_prompt:
        print(f'{len(choices) + 1}. {custom_prompt}')

    key = input('選択 (既定: 1): ').strip() or '1'

    if custom_prompt and key == str(len(choices) + 1):
        return None, True
    if key.isdigit() and 1 <= int(key) <= len(choices):
        return choices[int(key) - 1], False
    return choices[0], False


def sanitize_var_name(name):
    """環境変数名を検証する。不正な場合は既定名と理由を返す"""
    n = (name or '').strip()

    # 先頭の 'export' を除去(あれば)
    if n.lower().startswith('export'):
        parts = n.split(None, 1)
        n = parts[1] if len(parts) == 2 else ''

    # '=' を含む名称は不正(Windows仕様)
    if '=' in n:
        return DEFAULT_KEY_CHOICES[0], True, "変数名に'='は使用できない"

    # POSIX慣用: 先頭は英字またはアンダースコア、その後は英数字とアンダースコアのみ
    if not re.match(r'^[A-Za-z_][A-Za-z0-9_]*$', n):
        if n == '':
            return DEFAULT_KEY_CHOICES[0], True, '空の変数名'
        return DEFAULT_KEY_CHOICES[0], True, '許可文字は英字・数字・アンダースコア。先頭は英字またはアンダースコア'

    return n, False, ''


def check_access_token(filename, var_name):
    """既存のAccess Tokenを確認する"""
    file_path = Path(filename)
    if not file_path.exists():
        return None

    for line in file_path.read_text(encoding='utf-8').splitlines():
        line = line.strip()
        if line.startswith(f'{var_name}='):
            access_token = line.split('=', 1)[1].strip()
            if access_token:
                return access_token

    return None


def open_token_page(mode):
    """Hugging FaceのAccess Tokenページを開く"""
    print('ブラウザでHugging FaceのAccess Tokenページを開きます...')

    funcs = {'new_tab': webbrowser.open_new_tab, 'new_window': webbrowser.open_new}
    funcs.get(mode, webbrowser.open)(HUGGINGFACE_TOKEN_URL)

    # ブラウザが起動するまで少し待つ
    time.sleep(1)


def get_access_token():
    """利用者からAccess Tokenを取得する"""
    print('コピーしたAccess Tokenを貼り付けてください')
    return getpass.getpass('Access Token: ').strip()


def save_access_token(access_token, filename, var_name):
    """Access Tokenをファイルに保存する(同名の行は置き換える)"""
    file_path = Path(filename)
    existing_lines = []

    if file_path.exists():
        backup_path = Path(str(file_path) + '.bak')
        shutil.copyfile(str(file_path), str(backup_path))
        print(f'バックアップを作成しました: {backup_path}')

        for line in file_path.read_text(encoding='utf-8').splitlines():
            if not line.strip().startswith(f'{var_name}='):
                existing_lines.append(line + '\n')

    content = ''.join(existing_lines)
    if content and not content.endswith('\n'):
        content += '\n'
    content += f'{var_name}={access_token}\n'

    file_path.parent.mkdir(parents=True, exist_ok=True)
    file_path.write_text(content, encoding='utf-8', newline='\n')
    print(f'Access Tokenを {file_path.resolve()} に保存しました')


def choose_env_file():
    """保存先のenvファイルを選択する"""
    result, is_custom = get_user_choice(
        '保存先ファイルを選択する',
        DEFAULT_ENV_CHOICES,
        'カスタムパスを指定する'
    )

    if is_custom:
        return input('保存先ファイル名を入力: ').strip() or DEFAULT_ENV_FILE

    return result


def choose_var_name():
    """保存する環境変数名を選択する"""
    result, is_custom = get_user_choice(
        '保存する環境変数名を選択する',
        DEFAULT_KEY_CHOICES,
        'カスタム名を指定する'
    )

    if is_custom:
        custom = input('変数名を入力(例: HF_TOKEN): ').strip()
        var_name, is_fallback, reason = sanitize_var_name(custom)
        if is_fallback:
            print(f"無効な環境変数名のため既定名を使用します: 入力='{custom}' "
                  f"理由={reason} → 使用名='{var_name}'")
        return var_name

    return result


def choose_browser_mode():
    """ブラウザの開き方を選択する"""
    choices = ['既定モードで開く', '新しいタブで開く', '新しいウィンドウで開く']
    modes = ['default', 'new_tab', 'new_window']

    result, _ = get_user_choice('ブラウザの開き方を選択する', choices)

    return modes[choices.index(result)]


def main():
    print('=== Hugging Face Access Token取得支援ツール ===\n')

    # 変数名と保存先ファイルを選択
    var_name = choose_var_name()
    env_file = choose_env_file()

    # 既存のAccess Tokenを確認
    existing_token = check_access_token(env_file, var_name)

    if existing_token:
        print(f'既存のAccess Tokenが見つかりました: {existing_token[:8]}...{existing_token[-4:]}')
        print('1. 既存のAccess Tokenを使用する')
        print('2. 新しいAccess Tokenで上書きする')

        choice = input('選択 (1/2, 既定: 1): ').strip() or '1'

        if choice != '2':
            print('既存のAccess Tokenを使用します')
            print('\n処理を終了します')
            return

    # ブラウザを開く
    mode = choose_browser_mode()
    input('Enterキーを押すとブラウザが開きます...')
    open_token_page(mode)

    # 手動操作の指示を表示
    print('\n=== 手動操作の手順 ===')
    print('1. ブラウザでHugging Faceアカウントにログインしてください')
    print('   ※ アカウントがない場合は先に https://huggingface.co/join で作成してください')
    print('2. メール確認が済んでいない場合は先にメール認証を完了してください')
    print("3. 'Create new token' ボタンをクリック")
    print('4. Token type(fine-grained / read / write)を選択(ダウンロードだけなら read で十分)')
    print('5. Token name を入力(例:MyProject)')
    print("6. 'Create token' ボタンをクリック")
    print('7. 表示されたAccess Token(hf_で始まる文字列)をコピーしてください')
    print('   ※ このAccess Tokenは一度しか表示されません')
    print('=======================================\n')

    # Access Token取得の確認
    input('Access TokenをコピーしたらEnterキーを押してください...')

    # Access Tokenを取得
    access_token = get_access_token()

    if not access_token:
        print('Access Tokenが入力されませんでした')
        print('\n処理を終了します')
        return

    print(f'\n取得したAccess Token: {access_token[:8]}...{access_token[-4:]}')

    # ファイルに保存
    save_choice = input('\nファイルに保存しますか? (y/n, 既定: y): ').strip().lower()
    if save_choice in ('y', ''):
        save_access_token(access_token, env_file, var_name)

        # 保存後の参考情報を表示
        print('\n=== 利用の参考情報 ===')
        print(f'保存パス: {Path(env_file).resolve()}')
        print(f'環境変数名: {var_name}')
        print('- Pythonでの使用例:')
        print('  import os')
        print('  from huggingface_hub import login')
        print(f'  login(token=os.environ["{var_name}"])')
        print('- 環境変数での使用例(コマンドプロンプト):')
        print(f'  set {var_name}=保存したAccess Token')
        print('======================\n')

    print('\n処理を終了します')


if __name__ == '__main__':
    main()