MakiAi's picture
Update app.py
77fc837 verified
# app.py
import os
import requests
import gradio as gr
from typing import Optional
SESSION = requests.Session()
SESSION.headers.update({
"Accept": "application/vnd.github+json",
"X-GitHub-Api-Version": "2022-11-28",
"User-Agent": "gradio-mcp-github-issue"
})
def create_issue(
owner_repo: str,
title: str,
body: str,
github_token: Optional[str] = None,
request: gr.Request = None
) -> str:
"""
Create a GitHub Issue as the authenticated user.
Args:
owner_repo (str): 対象リポジトリ。形式は `owner/repo`。
title (str): 作成する Issue のタイトル。
body (str): Issue 本文(任意)。
github_token (str, optional): UI から渡す GitHub Token。デフォルトは空。
request (gr.Request, optional): HTTP リクエスト。Authorization ヘッダを含む。
Returns:
str: 作成した Issue の URL。失敗時はエラーメッセージを返す。
"""
# 1) Authorization ヘッダ
auth = ""
if request and request.headers.get("authorization"):
auth = request.headers.get("authorization").strip()
# 2) UI入力
token = ""
if auth:
token = auth.split(" ", 1)[1] if auth.lower().startswith("bearer ") else auth
elif github_token:
token = github_token.strip()
elif os.getenv("GITHUB_TOKEN"):
token = os.getenv("GITHUB_TOKEN").strip()
if not token:
raise gr.Error("Missing GITHUB_TOKEN. Authorization ヘッダ、UI入力、または環境変数で指定してください。")
# --- ここから下は既存の GitHub API 呼び出し処理 ---
url = f"https://api.github.com/repos/{owner_repo}/issues"
headers = {"Authorization": f"Bearer {token}"}
payload = {"title": title.strip(), "body": (body or "")}
resp = SESSION.post(url, headers=headers, json=payload, timeout=20)
if resp.status_code == 201:
data = resp.json()
return f"✅ Issue created: #{data.get('number')}\n{data.get('html_url')}"
else:
try:
err = resp.json()
except Exception:
err = {"message": resp.text}
if resp.status_code == 401:
raise gr.Error("401 Unauthorized: トークンが無効か権限が不足しています。repo スコープ等を確認してください。")
if resp.status_code == 404:
raise gr.Error("404 Not Found: リポジトリが存在しない、または権限がありません。")
raise gr.Error(f"GitHub API Error {resp.status_code}: {err.get('message', err)}")
# --- Gradio UI(開発・検証用) ---
examples = [
["octocat/Hello-World", "Test from Gradio MCP", "Created via demo server.", ""],
["owner/repo", "日本語タイトルの例", "本文に改行もOK\n- bullet 1\n- bullet 2", ""],
["owner/repo", "Token from UI", "UI のトークン欄で渡すテスト", "ghp_xxx_or_fine_grained_token"],
]
with gr.Blocks() as demo:
gr.Markdown("### GitHub Issue Creator (Gradio MCP)")
with gr.Row():
owner_repo = gr.Textbox(label="owner/repo", placeholder="octocat/Hello-World")
title = gr.Textbox(label="title", placeholder="Issue title")
body = gr.Textbox(label="body (optional)", lines=6, placeholder="Issue body (markdown supported)")
github_token = gr.Textbox(
label="GITHUB_TOKEN (optional – for UI testing)",
type="password",
placeholder="例: ghp_xxx もしくは Fine-grained token"
)
out = gr.Textbox(label="Result", lines=3, show_copy_button=True)
run = gr.Button("Create Issue")
run.click(
create_issue,
inputs=[owner_repo, title, body, github_token],
outputs=[out]
)
gr.Examples(
examples=examples,
inputs=[owner_repo, title, body, github_token],
outputs=[out],
fn=create_issue,
cache_examples=False,
)
# MCP サーバを同時起動(Streamable HTTP を使用)
demo.launch(
mcp_server=True, # ← これで MCP エンドポイントが有効化されます
server_name="0.0.0.0",
server_port=int(os.getenv("PORT", "7860")),
)