Hugging Face Access Token取得支援ツール(ソースコードと説明と利用ガイド)
プログラム利用ガイド
1. このプログラムの利用シーン
Hugging Face にアクセスするためのAccess Tokenを取得・管理することを支援するツールです。
2. 主な機能
- ブラウザ自動起動: Hugging Face のAccess Token取得ページを自動的にブラウザで開きます。
- セキュアな入力処理: Access Tokenの入力時に文字を画面に表示せず、機密情報を保護します。
- 柔軟な設定オプション: 環境変数名(HF_TOKEN、HUGGINGFACE_HUB_TOKEN等)と保存先ファイル(.env、.env.development等)を選択できます。
- 既存トークン管理: すでにAccess Tokenが設定されている場合、継続使用または上書き更新を選択できます。
3. 基本的な使い方
- プログラム起動: Pythonで本プログラムを実行します。
- 環境変数名の選択: 保存する環境変数名を1〜4の番号で選択するか、カスタム名を入力します。
- 保存先ファイルの選択: .envファイルの保存先を選択します(.env、.env.development、.env.production、またはカスタムパス)。
- ブラウザでのトークン取得: 自動的に開かれるブラウザでHugging Faceにログインし、Access Tokenを生成・コピーします。
- トークン入力: コピーしたAccess Tokenをセキュアに貼り付けます(文字は表示されません)。
- 保存確認: トークンをファイルに保存するかを選択し、処理を完了します。
4. 便利な機能
- 既存設定の確認: すでにAccess Tokenが設定されている場合、内容を確認して継続使用か更新かを選択できます。
- ブラウザ起動モード: 既定モード、新しいタブ、新しいウィンドウから起動方法を選択できます。
- 入力検証機能: 環境変数名の妥当性を自動的にチェックし、不正な場合は適切な名前に修正します。
- 利用ガイド表示: 保存完了後、Pythonコードでの使用例や環境変数設定例を表示します。
Python開発環境,ライブラリ類
ここでは、最低限の事前準備について説明する。機械学習や深層学習を行う場合は、NVIDIA CUDA、Visual Studio、Cursorなどを追加でインストールすると便利である。これらについては別ページ https://www.kkaneko.jp/cc/dev/aiassist.htmlで詳しく解説しているので、必要に応じて参照してください。
Python 3.12 のインストール
インストール済みの場合は実行不要。
管理者権限でコマンドプロンプトを起動(手順:Windowsキーまたはスタートメニュー > cmd と入力 > 右クリック > 「管理者として実行」)し、以下を実行する。管理者権限は、wingetの--scope machineオプションでシステム全体にソフトウェアをインストールするために必要である。
REM Python をシステム領域にインストール
winget install --scope machine --id Python.Python.3.12 -e --silent
REM Python のパス設定
set "PYTHON_PATH=C:\Program Files\Python312"
set "PYTHON_SCRIPTS_PATH=C:\Program Files\Python312\Scripts"
echo "%PATH%" | find /i "%PYTHON_PATH%" >nul
if errorlevel 1 setx PATH "%PATH%;%PYTHON_PATH%" /M >nul
echo "%PATH%" | find /i "%PYTHON_SCRIPTS_PATH%" >nul
if errorlevel 1 setx PATH "%PATH%;%PYTHON_SCRIPTS_PATH%" /M >nul
【関連する外部ページ】
Python の公式ページ: https://www.python.org/
AI エディタ Windsurf のインストール
Pythonプログラムの編集・実行には、AI エディタの利用を推奨する。ここでは,Windsurfのインストールを説明する。
管理者権限でコマンドプロンプトを起動(手順:Windowsキーまたはスタートメニュー > cmd と入力 > 右クリック > 「管理者として実行」)し、以下を実行して、Windsurfをシステム全体にインストールする。管理者権限は、wingetの--scope machineオプションでシステム全体にソフトウェアをインストールするために必要となる。
winget install --scope machine Codeium.Windsurf -e --silent
【関連する外部ページ】
Windsurf の公式ページ: https://windsurf.com/
[1] Python Software Foundation. (2025). webbrowser — Convenient web-browser controller. Python 3.13.7 documentation. https://docs.python.org/3/library/webbrowser.html
[2] Python Software Foundation. (2025). getpass — Portable password input. Python 3.13.7 documentation. https://docs.python.org/3/library/getpass.html
Hugging Face Access Token取得支援プログラム
概要
このプログラムは、Hugging Face Access Tokenの取得と管理を支援するコマンドライン型ツールである。ユーザーがブラウザでHugging Faceのサービスから手動でトークンを取得し、環境設定ファイル(.env)に保存する機能を提供する。
主要技術
webbrowser モジュール
Pythonの標準ライブラリに含まれるクロスプラットフォーム対応のブラウザ制御モジュール[1]。デフォルトブラウザを自動検出して使用する。新しいタブ、新しいウィンドウ、既定のブラウザでのURL表示が可能である。
getpass モジュール
パスワード入力時のエコーを無効化するセキュアな入力機能を提供する標準モジュール[2]。入力された文字が画面に表示されないため機密情報の入力に適している。端末制御によって安全な入力を実現し、クロスプラットフォーム対応である。
実装の特色
入力検証とサニタイゼーション
環境変数名のPOSIX準拠チェックと自動サニタイゼーション機能を実装している。不正な文字の除去を行う。
セキュリティ配慮
トークンの部分マスク表示により、ログやコンソール出力での機密情報漏洩を防止している。
参考文献
[1] Python Software Foundation. (2025). webbrowser — Convenient web-browser controller. Python 3.13.7 documentation. https://docs.python.org/3/library/webbrowser.html
[2] Python Software Foundation. (2025). getpass — Portable password input. Python 3.13.7 documentation. https://docs.python.org/3/library/getpass.html
ソースコード
"""
Hugging Face Access Token取得支援プログラム
特徴技術名: webbrowserモジュール
出典: Python Software Foundation. (2025). webbrowser — Convenient web-browser controller. Python 3.13.5 documentation. https://docs.python.org/3/library/webbrowser.html
特徴機能: プラットフォーム独立のブラウザ制御
webbrowserモジュールは、Unix、Windows、macOSで動作し、各プラットフォームのデフォルトブラウザを自動的に検出して使用する機能を提供する。
学習済みモデル: 使用していない
方式設計:
- 関連利用技術:
- getpassモジュール: パスワード入力時のエコー無効化によるセキュアな入力機能
- pathlibモジュール: オブジェクト指向ファイルパス操作とファイル読み書き機能
- reモジュール: .env内の環境変数行の検出(export有無や空白を許容)
- shutilモジュール: .envのバックアップ作成
- 入力と出力:
入力:
• 環境変数名の選択(HF_TOKEN/HUGGINGFACE_HUB_TOKEN/HUGGINGFACE_API_TOKEN/カスタム)
• 保存先ファイルの選択(.env/.env.development/.env.production/カスタム)
• ブラウザの開き方の選択(既定/新しいタブ/新しいウィンドウ)
• ユーザーによる選択操作(ブラウザでのAccess Token取得、コンソールでのトークン入力)
出力: ブラウザでのHugging Face Access Tokenページ表示、トークンの.envファイル保存、保存後のガイダンス表示
- 処理手順:
1. 環境変数名と保存先ファイルを選択する
2. 既存Access Tokenの確認と選択肢提示
3. ブラウザでHugging Face Access Tokenページを開く
4. ユーザーによる手動でのAccess Token取得
5. getpassを使用したセキュアなトークン入力
6. .envをバックアップし、トークンの.envファイルへの保存
7. 保存後の確認メッセージと利用ガイダンス表示
- 前処理: 既存.envファイルの読み込みとAccess Token存在確認
- 後処理: トークン保存後の確認メッセージ表示
- 追加処理: トークンの部分マスク表示によるセキュリティ配慮、バックアップ作成
- 調整を必要とする設定値:
- var_name: 保存する環境変数名(HF_TOKEN/HUGGINGFACE_HUB_TOKEN/HUGGINGFACE_API_TOKEN/カスタム)
- filename: トークンを保存するファイル名(デフォルト: .env)
- browser_mode: ブラウザ起動モード(既定/新しいタブ/新しいウィンドウ)
将来方策: 既存の.envファイルの読み込みと同一Access Tokenの存在確認は現行実装で対応済み
その他の重要事項:
- getpassモジュールによりAccess Token入力時の画面表示を防止
- バックアップ作成機能により既存ファイルの安全性を確保
- 入力中断処理でユーザビリティを向上
- Hugging Face Access Tokenは通常"hf_"で始まる形式
- 例外処理を強化してプログラムの安定性を向上
- 冗長なコードを統合して保守性を向上
前準備: なし(標準ライブラリのみ使用)
"""
import webbrowser
from pathlib import Path
import getpass
import re
import shutil
import sys
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_API_URL = 'https://huggingface.co/settings/tokens'
def safe_input(prompt, default=None):
"""入力中断時の共通処理"""
try:
return input(prompt)
except (KeyboardInterrupt, EOFError):
if default is not None:
print('\n入力が中断されたため既定値を用いる')
return default
print('\n処理を中断しました。プログラムを終了します。')
sys.exit(1)
def handle_file_operation_error(operation_name, error):
"""ファイル操作エラーの共通処理"""
print(f'{operation_name}でエラー: {error}')
return False
def get_user_choice(title, choices, default_key, custom_prompt=None):
"""ユーザー選択処理の統一関数"""
print(title)
# 既定の選択肢を表示
for i, choice in enumerate(choices, 1):
print(f'{i}. {choice}')
# カスタム選択肢がある場合
if custom_prompt:
print(f'{len(choices) + 1}. {custom_prompt}')
# 入力受付
valid_keys = [str(i) for i in range(1, len(choices) + 1)]
if custom_prompt:
valid_keys.append(str(len(choices) + 1))
prompt = f"選択 ({'/'.join(valid_keys)}, 既定: {default_key}): "
key = safe_input(prompt, default=default_key).strip() or default_key
# 既定選択肢の処理
try:
index = int(key) - 1
if 0 <= index < len(choices):
return choices[index], False # 選択された値, カスタムフラグ
except ValueError:
pass
# カスタム選択の処理
if custom_prompt and key == str(len(choices) + 1):
return None, True # カスタム入力が必要
# デフォルト値の処理
try:
default_index = int(default_key) - 1
if 0 <= default_index < len(choices):
return choices[default_index], False
except ValueError:
pass
return choices[0], False # フォールバック
def wait_enter(prompt):
"""Enterキー待ちの共通処理"""
safe_input(prompt)
def sanitize_var_name(name):
"""環境変数名を検証・サニタイズする。無効な場合は既定名にフォールバックするための情報を返す。"""
n = (name or '').strip()
# 先頭の 'export' を除去(あれば)
lowered = n.lower()
if lowered.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=DEFAULT_ENV_FILE, var_name='HF_TOKEN'):
"""既存のAccess Tokenを確認する"""
file_path = Path(filename)
if not file_path.exists():
return None
try:
content = file_path.read_text(encoding='utf-8')
lines = content.splitlines()
for line in lines:
line = line.strip()
if line.startswith(f'{var_name}='):
access_token = line.split('=', 1)[1].strip()
if access_token:
return access_token
return None
except (OSError, IOError, UnicodeDecodeError, PermissionError) as e:
handle_file_operation_error('ファイル読み込み', e)
return None
def open_token_page(mode='default'):
"""Hugging FaceのAccess Tokenページを開く"""
print('ブラウザでHugging FaceのAccess Tokenページを開きます...')
try:
funcs = {'new_tab': webbrowser.open_new_tab, 'new_window': webbrowser.open_new}
opened = funcs.get(mode, webbrowser.open)(HUGGINGFACE_API_URL)
if not opened:
print('ブラウザを開けなかった可能性がある。URLを手動で開くこと:')
print(HUGGINGFACE_API_URL)
return False
# ブラウザが起動するまで少し待つ
time.sleep(1)
return True
except (webbrowser.Error, OSError) as e:
print(f'ブラウザの起動でエラーが発生: {e}')
print(f'URLを手動で開いてください: {HUGGINGFACE_API_URL}')
return False
def get_access_token():
"""ユーザーからAccess Tokenを取得"""
print('コピーしたAccess Tokenを貼り付けてください')
try:
access_token = getpass.getpass('Access Token: ')
return access_token.strip()
except KeyboardInterrupt:
print('\n入力がキャンセルされました')
return None
except EOFError:
print('\n入力がキャンセルされました')
return None
except Exception as e:
print(f'入力でエラーが発生: {e}')
return None
def save_access_token(access_token, filename=DEFAULT_ENV_FILE, var_name='HF_TOKEN'):
"""Access Tokenをファイルに保存(上書きモード)"""
try:
file_path = Path(filename)
# バックアップ作成
if file_path.exists():
backup_path = Path(str(file_path) + '.bak')
try:
shutil.copyfile(str(file_path), str(backup_path))
print(f'バックアップを作成しました: {backup_path}')
except (shutil.SameFileError, IsADirectoryError, PermissionError,
FileNotFoundError, OSError) as e:
handle_file_operation_error('バックアップ作成', e)
print('バックアップの作成に失敗しましたが、処理を続行します')
existing_lines = []
if file_path.exists():
try:
content = file_path.read_text(encoding='utf-8')
for line in content.splitlines():
if not line.strip().startswith(f'{var_name}='):
existing_lines.append(line + '\n')
except (OSError, IOError, UnicodeDecodeError, PermissionError) as e:
handle_file_operation_error('既存ファイルの読み込み', e)
return False
# 新しいAccess Tokenを追加
content = ''.join(existing_lines)
if content and not content.endswith('\n'):
content += '\n'
content += f'{var_name}={access_token}\n'
# 親ディレクトリがない場合は作成
try:
file_path.parent.mkdir(parents=True, exist_ok=True)
except (FileExistsError, PermissionError, OSError) as e:
handle_file_operation_error('ディレクトリ作成', e)
return False
try:
file_path.write_text(content, encoding='utf-8', newline='\n')
print(f'Access Tokenを {file_path.resolve()} に保存しました')
return True
except (OSError, IOError, PermissionError) as e:
handle_file_operation_error('ファイル保存', e)
return False
except Exception as e:
print(f'予期しないエラー: {e}')
return False
def choose_env_file():
"""保存先のenvファイルを選択する"""
result, is_custom = get_user_choice(
'保存先ファイルを選択する',
DEFAULT_ENV_CHOICES,
'1',
'カスタムパスを指定する'
)
if is_custom:
custom = safe_input('保存先ファイル名を入力: ', default=DEFAULT_ENV_FILE).strip()
return custom or DEFAULT_ENV_FILE
return result
def choose_var_name():
"""保存する環境変数名を選択する"""
result, is_custom = get_user_choice(
'保存する環境変数名を選択する',
DEFAULT_KEY_CHOICES,
'1',
'カスタム名を指定する'
)
if is_custom:
custom = safe_input('変数名を入力(例: HF_TOKEN): ',
default=DEFAULT_KEY_CHOICES[0]).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,
'1'
)
# 選択された表示名に対応するモードを返す
try:
index = choices.index(result)
return modes[index]
except ValueError:
return 'default'
def main():
print('=== Hugging Face Access Token取得支援ツール ===\n')
try:
# 変数名と保存先ファイルを選択
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 = safe_input('選択 (1/2, 既定: 1): ', default='1').strip() or '1'
if choice == '1':
print('既存のAccess Tokenを使用します')
print('\n処理を終了します')
return
elif choice != '2':
print('無効な選択です')
print('\n処理を終了します')
return
# ブラウザを開く
mode = choose_browser_mode()
wait_enter('Enterキーを押すとブラウザが開きます...')
browser_opened = open_token_page(mode)
if not browser_opened:
choice = safe_input('ブラウザの起動に失敗しました。処理を続行しますか? (y/n, 既定: y): ',
default='y').strip().lower()
if choice not in ('y', ''):
print('処理を中止します')
return
# 手動操作の指示を表示
print('\n=== 手動操作の手順 ===')
print('1. ブラウザでHugging Faceアカウントにログインしてください')
print(' ※ アカウントがない場合は先にhttps://huggingface.co/joinで作成してください')
print('2. メール確認が済んでいない場合は先にメール認証を完了してください')
print("3. 'New token'ボタンをクリック")
print('4. トークンの名前を入力(例:MyProject)')
print('5. ロール(Role)を選択(通常はreadで十分)')
print("6. 'Generate a token'ボタンをクリック")
print('7. 表示されたAccess Token(hf_で始まる文字列)をコピーしてください')
print(' ※ このトークンは一度しか表示されません!')
print('=======================================\n')
# Access Token取得の確認
wait_enter('Access TokenをコピーしたらEnterキーを押してください...')
# Access Tokenを取得
access_token = get_access_token()
if access_token:
print(f'\n取得したAccess Token: {access_token[:8]}...{access_token[-4:]}')
# ファイルに保存
save_choice = safe_input('\nファイルに保存しますか? (y/n, 既定: y): ',
default='y').strip().lower()
if save_choice in ('y', ''):
saved = save_access_token(access_token, env_file, var_name)
if saved:
# 保存後の参考情報を表示
print('\n=== 利用の参考情報 ===')
resolved = str(Path(env_file).resolve())
print(f'保存パス: {resolved}')
print(f'環境変数名: {var_name}')
print('- Pythonでの使用例:')
print(f' from huggingface_hub import login')
print(f' login(token="{var_name}")')
print('- 環境変数での使用例:')
print(f' export $(grep -v "^#" {env_file} | xargs)')
print('======================\n')
else:
print('ファイルの保存に失敗しました')
else:
print('Access Tokenが入力されませんでした')
except Exception as e:
print(f'予期しないエラーが発生しました: {e}')
print('プログラムを終了します')
print('\n処理を終了します')
if __name__ == '__main__':
try:
main()
except (KeyboardInterrupt, EOFError):
print('\n処理を中断しました。プログラムを終了します。')
except Exception as e:
print(f'\n致命的なエラーが発生しました: {e}')
print('プログラムを終了します。')