Corin1998's picture
Upload 9 files
86e8ae4 verified
import gradio as gr
import httpx
import json
def build_ui(fastapi_app):
base = "" # 同一プロセスなので相対パスでOK
async def do_summarize(platforms, keywords_csv, brand, limit, language):
keywords = [k.strip() for k in keywords_csv.split(",") if k.strip()]
async with httpx.AsyncClient() as client:
r = await client.post(f"{base}/api/summarize_trends", json={
"platforms": platforms, "keywords": keywords, "brand": brand,
"limit": int(limit), "language": language
})
r.raise_for_status()
data = r.json()
items = data["items"]
summary = data["summary"]
return json.dumps(items, ensure_ascii=False, indent=2), summary
async def do_generate_plan(brand, language, platforms, keywords_csv, start_date, tone, cta, image_style_hint):
keywords = [k.strip() for k in keywords_csv.split(",") if k.strip()]
async with httpx.AsyncClient() as client:
r = await client.post(f"{base}/api/generate_week_plan", json={
"brand": brand, "language": language, "platforms": platforms,
"keywords": keywords, "start_date": (start_date or None),
"tone": tone, "cta": cta, "image_style_hint": image_style_hint
})
r.raise_for_status()
posts = r.json()
return json.dumps(posts, ensure_ascii=False, indent=2)
async def do_list_calendar():
async with httpx.AsyncClient() as client:
r = await client.get(f"{base}/api/calendar")
r.raise_for_status()
return json.dumps(r.json(), ensure_ascii=False, indent=2)
async def do_approve(post_id):
async with httpx.AsyncClient() as client:
r = await client.post(f"{base}/api/approve_post/{int(post_id)}")
r.raise_for_status()
return json.dumps(r.json(), ensure_ascii=False, indent=2)
async def do_schedule(post_id, iso):
async with httpx.AsyncClient() as client:
r = await client.post(f"{base}/api/schedule_post/{int(post_id)}", json={"scheduled_at": iso})
r.raise_for_status()
return json.dumps(r.json(), ensure_ascii=False, indent=2)
async def save_keywords(keywords_csv):
keywords = [k.strip() for k in keywords_csv.split(",") if k.strip()]
async with httpx.AsyncClient() as client:
r = await client.post(f"{base}/api/keywords", json={"keywords": keywords})
r.raise_for_status()
return "保存しました"
async def load_keywords():
async with httpx.AsyncClient() as client:
r = await client.get(f"{base}/api/keywords")
r.raise_for_status()
data = r.json()
return ", ".join(data.get("keywords", []))
with gr.Blocks(title="SNS運用AIライト") as demo:
gr.Markdown("## SNS運用AIライト — 競合/トレンド要約 → 1週間案 → 承認 → 予約投稿")
with gr.Tab("1) トレンド要約"):
platforms = gr.CheckboxGroup(choices=["x","instagram"], value=["x","instagram"], label="対象プラットフォーム")
keywords = gr.Textbox(label="監視キーワード(カンマ区切り)", placeholder="自社名, 競合名, 業界ワード")
brand = gr.Textbox(label="ブランド名(任意)", placeholder="HitC Inc. など")
limit = gr.Slider(5, 50, step=1, value=20, label="取得件数(疑似/本API対応)")
language = gr.Dropdown(["ja","en"], value="ja", label="出力言語")
btn = gr.Button("トレンド要約を実行")
items_json = gr.Code(label="取得結果(JSON)", language="json")
summary = gr.Textbox(label="要約", lines=12)
btn.click(do_summarize, [platforms, keywords, brand, limit, language], [items_json, summary])
with gr.Tab("2) 1週間の投稿案生成"):
brand2 = gr.Textbox(label="ブランド名", placeholder="HitC Inc.")
language2 = gr.Dropdown(["ja","en"], value="ja", label="言語")
platforms2 = gr.CheckboxGroup(choices=["x","instagram"], value=["x","instagram"], label="プラットフォーム")
keywords2 = gr.Textbox(label="キーワード(任意/カンマ区切り)")
start_date = gr.Textbox(label="開始日(ISO, 任意)", placeholder="2025-09-01")
tone = gr.Textbox(label="トーン", value="プロフェッショナルで親しみやすい")
cta = gr.Textbox(label="CTA", value="詳細はこちら")
imgstyle = gr.Textbox(label="画像ラフのスタイルヒント", value="ミニマル、端的なタイポ、ブランドカラー意識")
btn2 = gr.Button("投稿案を生成 & DB保存")
posts_json = gr.Code(label="投稿案(DBにdraft保存)", language="json")
btn2.click(do_generate_plan, [brand2, language2, platforms2, keywords2, start_date, tone, cta, imgstyle], [posts_json])
with gr.Tab("3) 承認・予約・カレンダー"):
gr.Markdown("承認→予約→公開(APScheduler)が動きます。")
post_id = gr.Number(label="Post ID")
approve_btn = gr.Button("承認する")
schedule_iso = gr.Textbox(label="予約日時(ISO, 例: 2025-09-01T09:00:00Z)")
schedule_btn = gr.Button("予約に登録")
out = gr.Code(label="レスポンス", language="json")
approve_btn.click(do_approve, [post_id], [out])
schedule_btn.click(do_schedule, [post_id, schedule_iso], [out])
cal_btn = gr.Button("カレンダー取得")
cal_json = gr.Code(label="カレンダー", language="json")
cal_btn.click(do_list_calendar, [], [cal_json])
with gr.Tab("設定"):
kw_in = gr.Textbox(label="監視キーワード(カンマ区切り)")
load_btn = gr.Button("読み込み")
save_btn = gr.Button("保存")
msg = gr.Textbox(label="メッセージ")
load_btn.click(load_keywords, [], [kw_in])
save_btn.click(save_keywords, [kw_in], [msg])
return demo