Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
|
@@ -27,9 +27,10 @@ logger = logging.getLogger(__name__)
|
|
| 27 |
class GeminiRequest(BaseModel):
|
| 28 |
"""Geminiへのリクエストデータモデル"""
|
| 29 |
text: str
|
| 30 |
-
extension_percentage: float =
|
|
|
|
| 31 |
|
| 32 |
-
def generate_html_from_text(text):
|
| 33 |
"""テキストからHTMLを生成する"""
|
| 34 |
try:
|
| 35 |
# APIキーの取得と設定
|
|
@@ -144,7 +145,7 @@ def generate_html_from_text(text):
|
|
| 144 |
ーーー<ユーザーが入力(または添付)>ーーー"""
|
| 145 |
|
| 146 |
# モデルを初期化して処理
|
| 147 |
-
logger.info(f"Gemini APIにリクエストを送信: テキスト長さ = {len(text)}")
|
| 148 |
|
| 149 |
# モデル初期化とフォールバック処理
|
| 150 |
try:
|
|
@@ -157,10 +158,10 @@ def generate_html_from_text(text):
|
|
| 157 |
|
| 158 |
# 生成設定
|
| 159 |
generation_config = {
|
| 160 |
-
"temperature":
|
| 161 |
"top_p": 0.95,
|
| 162 |
"top_k": 64,
|
| 163 |
-
"max_output_tokens":
|
| 164 |
}
|
| 165 |
|
| 166 |
# プロンプト構築
|
|
@@ -211,8 +212,8 @@ def render_fullpage_screenshot(html_code: str, extension_percentage: float, is_g
|
|
| 211 |
|
| 212 |
# Gemini生成コンテンツの場合、拡張率を調整
|
| 213 |
if is_gemini_content:
|
| 214 |
-
#
|
| 215 |
-
extension_percentage = max(extension_percentage,
|
| 216 |
logger.info(f"Gemini生成コンテンツ用に拡張率を調整: {extension_percentage}%")
|
| 217 |
|
| 218 |
# 1) Save HTML code to a temporary file
|
|
@@ -398,11 +399,11 @@ def render_fullpage_screenshot(html_code: str, extension_percentage: float, is_g
|
|
| 398 |
logger.error(f"Error removing temporary file {tmp_path}: {e}")
|
| 399 |
|
| 400 |
# --- Geminiを使った新しい関数 ---
|
| 401 |
-
def text_to_screenshot(text: str, extension_percentage: float) -> Image.Image:
|
| 402 |
"""テキストをGemini APIでHTMLに変換し、スクリーンショットを生成する統合関数"""
|
| 403 |
try:
|
| 404 |
-
# 1. テキストからHTML
|
| 405 |
-
html_code = generate_html_from_text(text)
|
| 406 |
|
| 407 |
# 2. HTMLからスクリーンショットを生成(Gemini生成コンテンツとしてフラグをオン)
|
| 408 |
return render_fullpage_screenshot(html_code, extension_percentage, is_gemini_content=True)
|
|
@@ -455,7 +456,7 @@ if os.path.exists(cdn_dir):
|
|
| 455 |
# Pydantic model for API request body validation
|
| 456 |
class ScreenshotRequest(BaseModel):
|
| 457 |
html_code: str
|
| 458 |
-
extension_percentage: float =
|
| 459 |
|
| 460 |
# API Endpoint for screenshot generation
|
| 461 |
@app.post("/api/screenshot",
|
|
@@ -503,12 +504,13 @@ async def api_text_to_screenshot(request: GeminiRequest):
|
|
| 503 |
テキストからHTMLインフォグラフィックを生成してスクリーンショットを返すAPIエンドポイント
|
| 504 |
"""
|
| 505 |
try:
|
| 506 |
-
logger.info(f"テキスト→スクリーンショットAPIリクエスト受信。テキスト長さ: {len(request.text)}, 拡張率: {request.extension_percentage}
|
| 507 |
|
| 508 |
-
# テキストからHTML
|
| 509 |
pil_image = text_to_screenshot(
|
| 510 |
request.text,
|
| 511 |
-
request.extension_percentage
|
|
|
|
| 512 |
)
|
| 513 |
|
| 514 |
if pil_image.size == (1, 1):
|
|
@@ -529,19 +531,19 @@ async def api_text_to_screenshot(request: GeminiRequest):
|
|
| 529 |
|
| 530 |
# --- Gradio Interface Definition ---
|
| 531 |
# 入力モードの選択用Radioコンポーネント
|
| 532 |
-
def process_input(input_mode,
|
| 533 |
"""入力モードに応じて適切な処理を行う"""
|
| 534 |
if input_mode == "HTML入力":
|
| 535 |
# HTMLモードの場合は既存の処理
|
| 536 |
-
return render_fullpage_screenshot(
|
| 537 |
else:
|
| 538 |
# テキスト入力モードの場合はGemini APIを使用
|
| 539 |
-
return text_to_screenshot(
|
| 540 |
|
| 541 |
# Gradio UIの定義
|
| 542 |
with gr.Blocks(title="Full Page Screenshot (テキスト変換対応)", theme=gr.themes.Base()) as iface:
|
| 543 |
gr.Markdown("# HTMLビューア & テキスト→インフォグラフィック変換")
|
| 544 |
-
gr.Markdown("HTML
|
| 545 |
|
| 546 |
with gr.Row():
|
| 547 |
input_mode = gr.Radio(
|
|
@@ -550,35 +552,49 @@ with gr.Blocks(title="Full Page Screenshot (テキスト変換対応)", theme=gr
|
|
| 550 |
value="HTML入力"
|
| 551 |
)
|
| 552 |
|
| 553 |
-
|
| 554 |
-
|
| 555 |
-
|
| 556 |
-
|
| 557 |
-
|
| 558 |
-
placeholder="<!DOCTYPE html>\n<html>\n<head>\n <title>Example</title>\n</head>\n<body>\n <h1>Hello World</h1>\n</body>\n</html>"
|
| 559 |
-
)
|
| 560 |
-
|
| 561 |
-
with gr.TabItem("テキスト入力"):
|
| 562 |
-
text_input = gr.Textbox(
|
| 563 |
-
lines=15,
|
| 564 |
-
label="テキスト入力 (Geminiで変換)",
|
| 565 |
-
placeholder="ここにテキストを入力すると、Gemini APIによってグラフィカルなHTMLに変換されます。"
|
| 566 |
-
)
|
| 567 |
-
|
| 568 |
-
extension_percentage = gr.Slider(
|
| 569 |
-
minimum=0,
|
| 570 |
-
maximum=30, # より高い値を許可
|
| 571 |
-
step=1.0,
|
| 572 |
-
value=8.0, # デフォルト値を増加
|
| 573 |
-
label="上下高さ拡張率(%)"
|
| 574 |
)
|
| 575 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 576 |
submit_btn = gr.Button("生成")
|
| 577 |
output_image = gr.Image(type="pil", label="ページ全体のスクリーンショット")
|
| 578 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 579 |
submit_btn.click(
|
| 580 |
fn=process_input,
|
| 581 |
-
inputs=[input_mode,
|
| 582 |
outputs=output_image
|
| 583 |
)
|
| 584 |
|
|
|
|
| 27 |
class GeminiRequest(BaseModel):
|
| 28 |
"""Geminiへのリクエストデータモデル"""
|
| 29 |
text: str
|
| 30 |
+
extension_percentage: float = 6.0 # ①デフォルト値を6%に変更
|
| 31 |
+
temperature: float = 1.0 # ④デフォルト値1.0の温度パラメータを追加
|
| 32 |
|
| 33 |
+
def generate_html_from_text(text, temperature=1.0):
|
| 34 |
"""テキストからHTMLを生成する"""
|
| 35 |
try:
|
| 36 |
# APIキーの取得と設定
|
|
|
|
| 145 |
ーーー<ユーザーが入力(または添付)>ーーー"""
|
| 146 |
|
| 147 |
# モデルを初期化して処理
|
| 148 |
+
logger.info(f"Gemini APIにリクエストを送信: テキスト長さ = {len(text)}, 温度 = {temperature}")
|
| 149 |
|
| 150 |
# モデル初期化とフォールバック処理
|
| 151 |
try:
|
|
|
|
| 158 |
|
| 159 |
# 生成設定
|
| 160 |
generation_config = {
|
| 161 |
+
"temperature": temperature, # ④パラメータとして受け取った温度を設定
|
| 162 |
"top_p": 0.95,
|
| 163 |
"top_k": 64,
|
| 164 |
+
"max_output_tokens": 8192,
|
| 165 |
}
|
| 166 |
|
| 167 |
# プロンプト構築
|
|
|
|
| 212 |
|
| 213 |
# Gemini生成コンテンツの場合、拡張率を調整
|
| 214 |
if is_gemini_content:
|
| 215 |
+
# ②最低でも5%の拡張を確保(20%から5%に変更)
|
| 216 |
+
extension_percentage = max(extension_percentage, 5.0)
|
| 217 |
logger.info(f"Gemini生成コンテンツ用に拡張率を調整: {extension_percentage}%")
|
| 218 |
|
| 219 |
# 1) Save HTML code to a temporary file
|
|
|
|
| 399 |
logger.error(f"Error removing temporary file {tmp_path}: {e}")
|
| 400 |
|
| 401 |
# --- Geminiを使った新しい関数 ---
|
| 402 |
+
def text_to_screenshot(text: str, extension_percentage: float, temperature: float = 1.0) -> Image.Image:
|
| 403 |
"""テキストをGemini APIでHTMLに変換し、スクリーンショットを生成する統合関数"""
|
| 404 |
try:
|
| 405 |
+
# 1. テキストからHTMLを生成(温度パラメータも渡す)
|
| 406 |
+
html_code = generate_html_from_text(text, temperature)
|
| 407 |
|
| 408 |
# 2. HTMLからスクリーンショットを生成(Gemini生成コンテンツとしてフラグをオン)
|
| 409 |
return render_fullpage_screenshot(html_code, extension_percentage, is_gemini_content=True)
|
|
|
|
| 456 |
# Pydantic model for API request body validation
|
| 457 |
class ScreenshotRequest(BaseModel):
|
| 458 |
html_code: str
|
| 459 |
+
extension_percentage: float = 6.0 # ①デフォルト値を6%に変更
|
| 460 |
|
| 461 |
# API Endpoint for screenshot generation
|
| 462 |
@app.post("/api/screenshot",
|
|
|
|
| 504 |
テキストからHTMLインフォグラフィックを生成してスクリーンショットを返すAPIエンドポイント
|
| 505 |
"""
|
| 506 |
try:
|
| 507 |
+
logger.info(f"テキスト→スクリーンショットAPIリクエスト受信。テキスト長さ: {len(request.text)}, 拡張率: {request.extension_percentage}%, 温度: {request.temperature}")
|
| 508 |
|
| 509 |
+
# テキストからHTMLを生成してスクリーンショットを作成(温度パラメータも渡す)
|
| 510 |
pil_image = text_to_screenshot(
|
| 511 |
request.text,
|
| 512 |
+
request.extension_percentage,
|
| 513 |
+
request.temperature
|
| 514 |
)
|
| 515 |
|
| 516 |
if pil_image.size == (1, 1):
|
|
|
|
| 531 |
|
| 532 |
# --- Gradio Interface Definition ---
|
| 533 |
# 入力モードの選択用Radioコンポーネント
|
| 534 |
+
def process_input(input_mode, input_text, extension_percentage, temperature):
|
| 535 |
"""入力モードに応じて適切な処理を行う"""
|
| 536 |
if input_mode == "HTML入力":
|
| 537 |
# HTMLモードの場合は既存の処理
|
| 538 |
+
return render_fullpage_screenshot(input_text, extension_percentage)
|
| 539 |
else:
|
| 540 |
# テキスト入力モードの場合はGemini APIを使用
|
| 541 |
+
return text_to_screenshot(input_text, extension_percentage, temperature)
|
| 542 |
|
| 543 |
# Gradio UIの定義
|
| 544 |
with gr.Blocks(title="Full Page Screenshot (テキスト変換対応)", theme=gr.themes.Base()) as iface:
|
| 545 |
gr.Markdown("# HTMLビューア & テキスト→インフォグラフィック変換")
|
| 546 |
+
gr.Markdown("HTMLコードをレンダリングするか、テキストをGemini APIでインフォグラフィックに変換して画像として取得します。")
|
| 547 |
|
| 548 |
with gr.Row():
|
| 549 |
input_mode = gr.Radio(
|
|
|
|
| 552 |
value="HTML入力"
|
| 553 |
)
|
| 554 |
|
| 555 |
+
# ③共用のテキストボックス(タブ無し)
|
| 556 |
+
input_text = gr.Textbox(
|
| 557 |
+
lines=15,
|
| 558 |
+
label="入力",
|
| 559 |
+
placeholder="HTMLコードまたはテキストを入力してください。入力モードに応じて処理されます。"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 560 |
)
|
| 561 |
|
| 562 |
+
with gr.Row():
|
| 563 |
+
extension_percentage = gr.Slider(
|
| 564 |
+
minimum=0,
|
| 565 |
+
maximum=30,
|
| 566 |
+
step=1.0,
|
| 567 |
+
value=6, # ①デフォルト値を6%に変更
|
| 568 |
+
label="上下高さ拡張率(%)"
|
| 569 |
+
)
|
| 570 |
+
|
| 571 |
+
# ④温度調整スライダー(テキストモード時のみ表示)
|
| 572 |
+
temperature = gr.Slider(
|
| 573 |
+
minimum=0.0,
|
| 574 |
+
maximum=1.4,
|
| 575 |
+
step=0.1,
|
| 576 |
+
value=1.0, # デフォルト値1.0
|
| 577 |
+
label="生成時の温度(創造性)",
|
| 578 |
+
visible=False # 最初は非表示
|
| 579 |
+
)
|
| 580 |
+
|
| 581 |
submit_btn = gr.Button("生成")
|
| 582 |
output_image = gr.Image(type="pil", label="ページ全体のスクリーンショット")
|
| 583 |
|
| 584 |
+
# 入力モード変更時のイベント処理(テキストモード時のみ温度スライダーを表示)
|
| 585 |
+
def update_temperature_visibility(mode):
|
| 586 |
+
return gr.Slider.update(visible=(mode == "テキスト入力"))
|
| 587 |
+
|
| 588 |
+
input_mode.change(
|
| 589 |
+
fn=update_temperature_visibility,
|
| 590 |
+
inputs=input_mode,
|
| 591 |
+
outputs=temperature
|
| 592 |
+
)
|
| 593 |
+
|
| 594 |
+
# 生成ボタンクリック時のイベント処理
|
| 595 |
submit_btn.click(
|
| 596 |
fn=process_input,
|
| 597 |
+
inputs=[input_mode, input_text, extension_percentage, temperature],
|
| 598 |
outputs=output_image
|
| 599 |
)
|
| 600 |
|