import gradio as gr # ここでgradioをgrとしてインポート import base64 from fastapi import FastAPI, File, UploadFile from fastapi.responses import JSONResponse from fastapi.staticfiles import StaticFiles from fastapi.middleware.cors import CORSMiddleware import uvicorn import os import glob # --- FastAPI アプリケーションの作成 --- app = FastAPI() # --- CORS設定の追加 --- app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # --- 静的ファイルのサービング設定 --- # Gradioのディレクトリを探索してアセットを見つける gradio_dir = os.path.dirname(gr.__file__) # ここを修正: gradio → gr # バージョン情報を表示 print(f"Gradio version: {gr.__version__}") print(f"Gradio directory: {gradio_dir}") # 基本的な静的ファイルディレクトリをマウント static_dir = os.path.join(gradio_dir, "templates", "frontend", "static") if os.path.exists(static_dir): print(f"Mounting static directory: {static_dir}") app.mount("/static", StaticFiles(directory=static_dir), name="static") # _appディレクトリを探す(新しいSvelteKitベースのフロントエンド用) app_dir = os.path.join(gradio_dir, "templates", "frontend", "_app") if os.path.exists(app_dir): print(f"Mounting _app directory: {app_dir}") app.mount("/_app", StaticFiles(directory=app_dir), name="_app") # assetsディレクトリを探す assets_dir = os.path.join(gradio_dir, "templates", "frontend", "assets") if os.path.exists(assets_dir): print(f"Mounting assets directory: {assets_dir}") app.mount("/assets", StaticFiles(directory=assets_dir), name="assets") # cdnディレクトリがあれば追加 cdn_dir = os.path.join(gradio_dir, "templates", "cdn") if os.path.exists(cdn_dir): print(f"Mounting cdn directory: {cdn_dir}") app.mount("/cdn", StaticFiles(directory=cdn_dir), name="cdn") # --- (既存の) Base64 エンコード関数 (async def に修正) --- async def encode_to_base64(file_obj): """ gr.FileまたはUploadFileから受け取ったファイルオブジェクトを処理し、 Base64エンコードされた文字列を返す関数。 """ if file_obj is None: return "ファイルをアップロードしてください。" try: if isinstance(file_obj, UploadFile): # FastAPIのUploadFileの場合 file_bytes = await file_obj.read() else: # GradioのFileの場合 (file_obj.name はファイルパス) file_path = file_obj.name with open(file_path, 'rb') as f: file_bytes = f.read() base64_bytes = base64.b64encode(file_bytes) base64_string = base64_bytes.decode('utf-8') return base64_string except Exception as e: print(f"エラー発生: {e}") return f"ファイルの処理中にエラーが発生しました: {e}" # --- FastAPI エンドポイント --- @app.post("/api/encode_base64") async def api_encode_base64(file: UploadFile = File(...)): """ APIエンドポイント: ファイルを受け取りBase64エンコードしてJSONで返す """ base64_string = await encode_to_base64(file) if "エラー" in base64_string: return JSONResponse(content={"error": base64_string}, status_code=400) return {"base64_string": base64_string} # --- Gradio インターフェース --- input_file = gr.File( label="画像またはPDFファイルを入力", file_types=['image', '.pdf'] ) output_text = gr.Textbox( label="Base64エンコード結果 (Gradio)", lines=10, interactive=True ) # Gradioインターフェースの設定 iface = gr.Interface( fn=encode_to_base64, inputs=input_file, outputs=output_text, title="ファイル ⇨ Base64 エンコーダー (Gradio & API)", description="画像またはPDFファイルをアップロードしてBase64エンコード。\nAPIエンドポイント: `/api/encode_base64` (POST)", allow_flagging='never', theme=gr.themes.Base() # 明示的にテーマを指定 ) # --- アプリケーションの起動 --- app = gr.mount_gradio_app(app, iface, path="/") if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=7860)