""" 完全動作版 FastAPI Debug Toolbar - 修正版 StreamingResponse対応バージョン + Hugging Face リポジトリ取得機能 """ from fastapi import FastAPI, Request from fastapi.responses import HTMLResponse, Response from fastapi.middleware.cors import CORSMiddleware import time import json import asyncio from datetime import datetime from starlette.types import Message # Hugging Face クライアントをインポート try: from huggingface_client import HuggingFaceRepoClient HF_CLIENT_AVAILABLE = True except ImportError: HF_CLIENT_AVAILABLE = False app = FastAPI(title="FastAPI Debug Toolbar", description="Laravel風デバッグバー + Hugging Face連携") # CORS設定 app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # デバッグデータ debug_data = {"requests": [], "queries": []} def generate_debug_bar(request_info): """デバッグバーHTML生成""" return f"""
🔧 FastAPI Debug ⏱️ {request_info['response_time']} 📊 {len(debug_data['queries'])} queries 📍 {request_info['method']} {request_info['path']}
Status: {request_info['status']}

📝 Request Info

Method: {request_info['method']}
Path: {request_info['path']}
Time: {request_info['timestamp']}
Response: {request_info['response_time']}

🗄️ Queries ({len(debug_data['queries'])})

{"
".join([f"• {q['query']} ({q['time']})" for q in debug_data['queries'][-3:]]) or "No queries"}
""" @app.middleware("http") async def debug_middleware(request: Request, call_next): start_time = time.time() # レスポンス処理 response = await call_next(request) process_time = time.time() - start_time # リクエスト情報 request_info = { "method": request.method, "path": request.url.path, "timestamp": datetime.now().strftime("%H:%M:%S"), "response_time": f"{process_time:.3f}s", "status": response.status_code } debug_data["requests"].append(request_info) # HTMLResponseの場合のみデバッグバー注入を試行 if isinstance(response, HTMLResponse): try: body = response.body if isinstance(body, bytes): body = body.decode('utf-8') if "" in body: debug_bar = generate_debug_bar(request_info) body = body.replace("", f"{debug_bar}") # 新しいHTMLResponseを作成 new_response = HTMLResponse(content=body, status_code=response.status_code) # ヘッダーをコピー for key, value in response.headers.items(): new_response.headers[key] = value response = new_response except Exception as e: # エラーが発生してもレスポンスは返す print(f"Debug bar injection failed: {e}") # デバッグヘッダー追加(すべてのレスポンスに) response.headers["X-Debug-Time"] = f"{process_time:.3f}s" response.headers["X-Debug-Queries"] = str(len(debug_data["queries"])) response.headers["X-Debug-Method"] = request.method response.headers["X-Debug-Path"] = request.url.path return response def mock_query(sql, delay=0.05): """データベースクエリシミュレート""" time.sleep(delay) debug_data["queries"].append({ "query": sql, "time": f"{delay:.3f}s", "timestamp": datetime.now().isoformat() }) @app.get("/", response_class=HTMLResponse) async def home(): # ホームページのクエリをシミュレート mock_query("SELECT COUNT(*) FROM users", 0.05) return f""" FastAPI Debug Toolbar Demo

🔧 FastAPI Debug Toolbar

Laravel風のデバッグツールバーのデモンストレーション

{len(debug_data["requests"])}
Total Requests
{len(debug_data["queries"])}
Database Queries
1
Active Sessions

✨ 機能

  • 🎯 リクエスト追跡 - HTTPメソッド、パス、レスポンス時間
  • 📊 クエリモニタリング - データベースクエリの実行時間
  • パフォーマンス測定 - リアルタイムの応答速度
  • 🎨 Laravel風デザイン - 親しみやすいダークテーマ

🚀 使用方法

画面下部に表示されるデバッグバーをクリックして展開してください。

各エンドポイントにアクセスしてデバッグ情報を確認できます。

👥 Users API 📊 Debug Dashboard 🗑️ Clear Debug Data 🤗 HF Repository
""" @app.get("/api/users", response_class=HTMLResponse) async def get_users(): # クエリシミュレート mock_query("SELECT * FROM users WHERE active = 1", 0.08) mock_query("SELECT COUNT(*) FROM user_sessions", 0.03) users = [ {"id": 1, "name": "John Doe", "email": "john@example.com"}, {"id": 2, "name": "Jane Smith", "email": "jane@example.com"}, {"id": 3, "name": "Bob Johnson", "email": "bob@example.com"} ] # ユーザーテーブルの行を生成 user_rows = "" for user in users: user_rows += f""" #{user['id']} {user['name']} {user['email']} Active """ # HTML ページとして返す return f""" User Management

👥 User Management

Manage your application users

{len(users)}
Total Users
{len(users)}
Active Users
2
Database Queries
{user_rows}
ID Name Email Status
""" @app.get("/debug/dashboard", response_class=HTMLResponse) async def debug_dashboard(): mock_query("SELECT * FROM debug_info", 0.02) recent_requests = debug_data["requests"][-10:] recent_queries = debug_data["queries"][-10:] return f""" Debug Dashboard

🔧 FastAPI Debug Dashboard

📝 Recent Requests ({len(recent_requests)})

{"".join([f'
{r["timestamp"]} - {r["method"]} {r["path"]} ({r["response_time"]}) - {r["status"]}
' for r in recent_requests])}

🗄️ Recent Queries ({len(recent_queries)})

{"".join([f'
{q["query"]} - {q["time"]}
' for q in recent_queries])}
← Back to Home
""" @app.get("/debug/clear") async def clear_debug_data(): debug_data["requests"].clear() debug_data["queries"].clear() return {"message": "Debug data cleared", "status": "success"} @app.get("/huggingface", response_class=HTMLResponse) async def huggingface_repo_viewer(): """Hugging Face リポジトリ情報表示ページ""" if not HF_CLIENT_AVAILABLE: return """

❌ Hugging Face Client not available

huggingface_client.py が見つかりません

""" mock_query("SELECT * FROM hf_repos", 0.03) client = HuggingFaceRepoClient() repo_id = "kenken999/fastapi_django_main_live" # リポジトリ情報取得 repo_info = client.get_repo_info(repo_id, "space") files = client.list_files(repo_id, "space") commits = client.get_commit_history(repo_id, "space") return f""" Hugging Face Repository Viewer

🤗 Hugging Face Repository Viewer

Repository: {repo_id}

📋 Repository Info

Author:
{repo_info.get('author', 'N/A')}
Created:
{repo_info.get('created_at', 'N/A')[:10] if repo_info.get('created_at') != 'N/A' else 'N/A'}
Modified:
{repo_info.get('last_modified', 'N/A')[:10] if repo_info.get('last_modified') != 'N/A' else 'N/A'}
Downloads:
{repo_info.get('downloads', 0)}
Likes:
{repo_info.get('likes', 0)}
Files:
{len(files)}

📁 Files ({len(files)})

{''.join([f'
📄 {file}
' for file in files[:20]])} {f'
... and {len(files) - 20} more files
' if len(files) > 20 else ''}

📜 Recent Commits

{''.join([f'''
{commit['title']}
{commit['date'][:10] if commit['date'] != 'N/A' else 'N/A'} by {commit['author']}
''' for commit in commits[:5]])}
""" @app.get("/huggingface/file/{file_path:path}") async def view_hf_file(file_path: str): """Hugging Face リポジトリの特定ファイル内容を表示""" if not HF_CLIENT_AVAILABLE: return {"error": "Hugging Face Client not available"} client = HuggingFaceRepoClient() repo_id = "kenken999/fastapi_django_main_live" content = client.read_file_content(repo_id, file_path, "space") return { "repo_id": repo_id, "file_path": file_path, "content": content, "timestamp": datetime.now().isoformat() } if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8003)