Spaces:
Running
Running
# app.py | |
import gradio as gr | |
import together | |
import os | |
import base64 | |
from PIL import Image | |
from io import BytesIO | |
import requests # ▼▼▼ 修正箇所: requestsライブラリをインポート ▼▼▼ | |
# --- 1. 設定: APIキーの読み込み --- | |
api_key = os.environ.get("TOGETHER_API_KEY") | |
if api_key: | |
together_client = together.Together(api_key=api_key) | |
else: | |
together_client = None | |
# 使用する画像生成モデル | |
IMAGE_MODEL = "black-forest-labs/FLUX.1-schnell-Free" | |
# --- 2. 中核機能: 画像生成関数 --- | |
def generate_image_from_prompt(prompt: str, history: list): | |
if not together_client: | |
raise gr.Error("TogetherAIのAPIクライアントが設定されていません。環境変数 TOGETHER_API_KEY を確認してください。") | |
if not prompt or not prompt.strip(): | |
raise gr.Error("画像を生成するには、プロンプトを入力してください。") | |
print(f"プロンプトを元に画像を生成中: '{prompt}'") | |
try: | |
response = together_client.images.generate( | |
prompt=prompt, | |
model=IMAGE_MODEL, | |
steps=4, | |
n=4, | |
height=1024, | |
width=1024 | |
) | |
generated_images = [] | |
# ▼▼▼ 修正箇所: URLから画像をダウンロードするロジックに変更 ▼▼▼ | |
for image_data_item in response.data: | |
# APIの応答に 'url' が含まれているかチェック | |
if hasattr(image_data_item, 'url') and image_data_item.url: | |
try: | |
image_url = image_data_item.url | |
print(f"URLから画像をダウンロード中: {image_url}") | |
# URLにアクセスして画像データを取得 | |
image_response = requests.get(image_url) | |
image_response.raise_for_status() # エラーがあれば例外を発生させる | |
# ダウンロードしたバイトデータからPILイメージを作成 | |
image = Image.open(BytesIO(image_response.content)) | |
generated_images.append((image, prompt)) | |
except requests.exceptions.RequestException as e: | |
print(f"画像のダウンロードに失敗しました: {e}") | |
continue # この画像の処理をスキップして次に進む | |
# (参考) b64_jsonが返ってくるモデルのためのフォールバック処理 | |
elif image_data_item.b64_json: | |
image_b64 = image_data_item.b64_json | |
image_data = base64.b64decode(image_b64) | |
image = Image.open(BytesIO(image_data)) | |
generated_images.append((image, prompt)) | |
if not generated_images: | |
raise gr.Error("画像の生成に失敗しました。APIから有効な画像データやURLが返されませんでした。") | |
new_history = generated_images + history | |
print(f"{len(generated_images)}枚の画像の生成が完了しました。") | |
return new_history, new_history | |
except Exception as e: | |
if isinstance(e, gr.Error): | |
raise e | |
print(f"予期せぬエラーが発生しました: {e}") | |
raise gr.Error(f"画像の生成に失敗しました。エラー詳細: {e}") | |
# --- 3. Gradio UIの構築 (変更なし) --- | |
with gr.Blocks(theme=gr.themes.Soft(), css=".gradio-container {max-width: 800px; margin: auto;}") as app: | |
gr.Markdown( | |
""" | |
# 🖼️ TogetherAI 画像生成アプリ (Gradio版) | |
プロンプトを入力して、TogetherAIのAPIで画像を生成します。 | |
最新の画像がギャラリーの先頭に表示されます。 | |
""" | |
) | |
gr.Markdown("---") | |
history_state = gr.State([]) | |
with gr.Column(): | |
prompt_input = gr.Textbox( | |
label="画像生成プロンプト", | |
placeholder="例: 月面にいる、写真のようにリアルな猫の宇宙飛行士", | |
lines=4, | |
interactive=True, | |
) | |
if not together_client: | |
gr.Warning("環境変数 `TOGETHER_API_KEY` が見つかりません。画像生成機能を利用するにはAPIキーを設定してください。") | |
generate_btn = gr.Button("画像生成 ✨ (4枚)", variant="primary", interactive=(together_client is not None)) | |
gr.Markdown("---") | |
gr.Markdown("## 生成された画像") | |
image_gallery = gr.Gallery(label="生成結果", show_label=False, columns=2, height="auto", object_fit="contain", value=None, preview=True) | |
generate_btn.click(fn=generate_image_from_prompt, inputs=[prompt_input, history_state], outputs=[image_gallery, history_state], show_progress="full") | |
gr.Examples( | |
examples=[ | |
"A high-resolution photo of a futuristic city with flying cars", | |
"An oil painting of a serene landscape with a river and mountains", | |
"A cute, fluffy alien creature exploring a vibrant, magical forest", | |
"Logo for a coffee shop named 'The Daily Grind', minimalist, modern" | |
], | |
inputs=prompt_input | |
) | |
if __name__ == "__main__": | |
app.launch(mcp_server=True) |