tomo2chin2 commited on
Commit
3d00718
·
verified ·
1 Parent(s): 0ddcaea

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +100 -33
app.py CHANGED
@@ -1,64 +1,131 @@
1
  import gradio as gr
2
  import base64
3
- import os # ファイルパスのデバッグ用に念のためインポート
 
 
 
 
4
 
5
- def encode_to_base64(file_obj):
 
6
  """
7
- gr.Fileから受け取ったファイルオブジェクトを読み込み、
8
- Base64エンコードされた文字列を返す関数。
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  """
10
  if file_obj is None:
11
  return "ファイルをアップロードしてください。"
12
 
13
  try:
14
- # GradioのFileコンポーネントは一時ファイルオブジェクトを提供し、
15
- # その .name 属性に一時ファイルのパスが含まれている
16
  file_path = file_obj.name
17
- print(f"処理中のファイル: {file_path}") # デバッグ用ログ
18
 
19
- # ファイルをバイナリ読み込みモードで開く
20
  with open(file_path, 'rb') as f:
21
- # ファイルの内容全体をバイト列として読み込む
22
  file_bytes = f.read()
23
 
24
- # バイト列をBase64にエンコードする (結果もバイト列)
25
- base64_bytes = base64.b64encode(file_bytes)
26
-
27
- # Base64のバイト列をUTF-8文字列にデコードする
28
- base64_string = base64_bytes.decode('utf-8')
29
-
30
  return base64_string
31
 
32
  except Exception as e:
33
- print(f"エラー発生: {e}") # デバッグ用ログ
 
34
  return f"ファイルの処理中にエラーが発生しました: {e}"
35
 
36
- # --- Gradioインターフェースの定義 ---
 
 
 
 
37
 
38
- # 入力コンポーネント: ファイルアップロード
39
- # file_typesで使用可能なファイル種別をユーザーに示す(画像全般とPDFを指定)
40
- input_file = gr.File(
41
- label="画像またはPDFファイルを入力",
42
- file_types=['image', '.pdf'] # 'image'は一般的な画像形式をカバー, '.pdf'でPDFを指定
 
43
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
- # 出力コンポーネント: テキストボックス
46
- # linesで高さを調整し、interactive=Trueでコピー可能にする
47
- output_text = gr.Textbox(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  label="Base64エンコード結果",
49
  lines=10,
50
- interactive=True # 結果をコピーできるようにする
51
  )
52
 
53
  # Gradioインターフェースを作成
54
  iface = gr.Interface(
55
- fn=encode_to_base64, # 実行する関数
56
- inputs=input_file, # 入力コンポーネント
57
- outputs=output_text, # 出力コンポーネント
58
- title="ファイル ⇨ Base64 エンコーダー",
59
  description="画像 (JPG, PNG, GIF等) または PDF ファイルをアップロードすると、その Base64 エンコードされた文字列が表示されます。",
60
- allow_flagging='never' # Flagging機能が不要な場合は無効化
61
  )
62
 
63
- # アプリを起動
64
- iface.launch(share=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
  import base64
3
+ import os
4
+ import io
5
+ from fastapi import FastAPI, File, UploadFile, HTTPException
6
+ from fastapi.responses import JSONResponse
7
+ import uvicorn # ローカル実行用にインポート
8
 
9
+ # --- Base64 エンコード処理 (共通ロジック) ---
10
+ def encode_bytes_to_base64(file_bytes: bytes) -> str:
11
  """
12
+ バイト列を受け取り、Base64エンコードされた文字列を返す。
13
+ エラーが発生した場合は例外を送出する。
14
+ """
15
+ try:
16
+ base64_bytes = base64.b64encode(file_bytes)
17
+ base64_string = base64_bytes.decode('utf-8')
18
+ return base64_string
19
+ except Exception as e:
20
+ print(f"Base64エンコードエラー: {e}")
21
+ # エラーを呼び出し元に伝えるために再度raiseする
22
+ raise ValueError(f"Base64エンコード中にエラーが発生しました: {e}")
23
+
24
+ # --- Gradio用 関数 ---
25
+ def gradio_encode_handler(file_obj):
26
+ """
27
+ GradioのFileコンポーネントから受け取ったファイルを処理する関数。
28
  """
29
  if file_obj is None:
30
  return "ファイルをアップロードしてください。"
31
 
32
  try:
 
 
33
  file_path = file_obj.name
34
+ print(f"Gradio処理中のファイル: {file_path}") # デバッグ用ログ
35
 
 
36
  with open(file_path, 'rb') as f:
 
37
  file_bytes = f.read()
38
 
39
+ # 共通のエンコード関数を呼び出す
40
+ base64_string = encode_bytes_to_base64(file_bytes)
 
 
 
 
41
  return base64_string
42
 
43
  except Exception as e:
44
+ print(f"Gradioファイル処理エラー: {e}") # デバッグ用ログ
45
+ # Gradioではエラーメッセージを文字列として返す
46
  return f"ファイルの処理中にエラーが発生しました: {e}"
47
 
48
+ # --- FastAPI アプリケーションの初期化 ---
49
+ app = FastAPI(
50
+ title="File to Base64 API & Gradio UI",
51
+ description="ファイルを受け取りBase64にエンコードするAPIとGradio UIを提供します。"
52
+ )
53
 
54
+ # --- FastAPI エンドポイントの定義 ---
55
+ @app.post(
56
+ "/encode/",
57
+ summary="ファイルをBase64エンコード",
58
+ description="アップロードされたファイルを読み込み、Base64エンコードされた文字列をJSON形式で返します。",
59
+ response_description="ファイル名とBase64エンコードされた文字列を含むJSONオブジェクト"
60
  )
61
+ async def api_encode_file(file: UploadFile = File(..., description="Base64エンコードする画像またはPDFファイル")):
62
+ """
63
+ FastAPIのエンドポイント。
64
+ POSTリクエストでファイルを受け取り、Base64エンコードしてJSONで返す。
65
+ """
66
+ print(f"API処理中のファイル: {file.filename}, Content-Type: {file.content_type}")
67
+
68
+ # ファイルの内容を非同期で読み込む
69
+ contents = await file.read()
70
+
71
+ # ファイルが空でないかチェック
72
+ if not contents:
73
+ raise HTTPException(status_code=400, detail="空のファイルは処理できません。")
74
 
75
+ try:
76
+ # 共通のエンコード関数を呼び出す
77
+ base64_string = encode_bytes_to_base64(contents)
78
+ # 成功したらJSONレスポンスを返す
79
+ return JSONResponse(
80
+ content={
81
+ "filename": file.filename,
82
+ "content_type": file.content_type,
83
+ "base64_string": base64_string
84
+ }
85
+ )
86
+ except ValueError as e: # Base64エンコード中のエラーを捕捉
87
+ print(f"APIエンコード処理エラー: {e}")
88
+ raise HTTPException(status_code=500, detail=str(e))
89
+ except Exception as e: # その他の予期せぬエラー
90
+ print(f"API予期せぬエラー: {e}")
91
+ raise HTTPException(status_code=500, detail=f"ファイルの処理中に予期せぬエラーが発生しました: {e}")
92
+ finally:
93
+ # アップロードされたファイルを閉じる (重要)
94
+ await file.close()
95
+
96
+ # --- Gradio インターフェースの定義 ---
97
+ input_file_gr = gr.File(
98
+ label="画像またはPDFファイルを入力",
99
+ file_types=['image', '.pdf'] # 画像全般とPDFを許可
100
+ )
101
+ output_text_gr = gr.Textbox(
102
  label="Base64エンコード結果",
103
  lines=10,
104
+ interactive=True # 結果をコピー可能にする
105
  )
106
 
107
  # Gradioインターフェースを作成
108
  iface = gr.Interface(
109
+ fn=gradio_encode_handler,
110
+ inputs=input_file_gr,
111
+ outputs=output_text_gr,
112
+ title="ファイル ⇨ Base64 エンコーダー (Gradio UI)",
113
  description="画像 (JPG, PNG, GIF等) または PDF ファイルをアップロードすると、その Base64 エンコードされた文字列が表示されます。",
114
+ allow_flagging='never'
115
  )
116
 
117
+ # --- GradioアプリをFastAPIにマウント ---
118
+ # Gradio UI をルートパス ("/") にマウントします
119
+ app = gr.mount_gradio_app(app, iface, path="/")
120
+
121
+ # --- ローカルでの実行用 (Hugging Face Spacesでは通常不要) ---
122
+ # このブロックは `python app.py` で直接実行した場合のみ動作します。
123
+ # Hugging Face Spaces環境では、Spacesがuvicornを起動してくれるため、この部分は実行されません。
124
+ if __name__ == "__main__":
125
+ print("ローカルサーバーを起動します (http://127.0.0.1:8000)")
126
+ print("Gradio UI: http://127.0.0.1:8000/")
127
+ print("FastAPI エンドポイント (POST): http://127.0.0.1:8000/encode/")
128
+ print("API ドキュメント (Swagger UI): http://127.0.0.1:8000/docs")
129
+ print("API ドキュメント (ReDoc): http://127.0.0.1:8000/redoc")
130
+ # host="0.0.0.0" でローカルネットワーク内の他のデバイスからもアクセス可能に
131
+ uvicorn.run(app, host="0.0.0.0", port=8000)