tomo2chin2 commited on
Commit
60bdc52
·
verified ·
1 Parent(s): af31960

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +120 -55
app.py CHANGED
@@ -28,15 +28,17 @@ logger = logging.getLogger(__name__)
28
  class GeminiRequest(BaseModel):
29
  """Geminiへのリクエストデータモデル"""
30
  text: str
31
- extension_percentage: float = 10.0 # デフォルト値8%
32
- temperature: float = 0.5 # デフォルト値を0.3に下げて創造性を抑制
33
  trim_whitespace: bool = True # 余白トリミングオプション(デフォルト有効)
 
34
 
35
  class ScreenshotRequest(BaseModel):
36
  """スクリーンショットリクエストモデル"""
37
  html_code: str
38
- extension_percentage: float = 10.0 # デフォルト値8%
39
  trim_whitespace: bool = True # 余白トリミングオプション(デフォルト有効)
 
40
 
41
  # HTMLのFont Awesomeレイアウトを改善する関数
42
  def enhance_font_awesome_layout(html_code):
@@ -108,31 +110,74 @@ def enhance_font_awesome_layout(html_code):
108
  # どちらもない場合は先頭に追加
109
  return f'<html><head>{fa_fix_css}</head>' + html_code + '</html>'
110
 
111
- def load_system_instruction():
112
- """HuggingFaceリポジトリからprompt.txtを直接ダウンロードして読み込む"""
 
 
 
 
 
 
 
 
113
  try:
114
- # ファイルを直接ダウンロード
115
- logger.info("HuggingFaceリポジトリからprompt.txtをダウンロード中...")
116
- file_path = hf_hub_download(
117
- repo_id="tomo2chin2/GURAREKOstlyle",
118
- filename="prompt.txt",
119
- repo_type="dataset"
120
- )
121
 
122
- # ファイルを読み込む
123
- with open(file_path, 'r', encoding='utf-8') as file:
124
- instruction = file.read()
 
 
 
125
 
126
- logger.info(f"システムインストラクションを正常に読み込みました: {len(instruction)}バイト")
127
- return instruction
128
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  except Exception as e:
130
- # エラーが発生した場合
131
  error_msg = f"システムインストラクションの読み込みに失敗: {str(e)}"
132
  logger.error(error_msg)
133
  raise ValueError(error_msg)
134
 
135
- def generate_html_from_text(text, temperature=0.3):
136
  """テキストからHTMLを生成する"""
137
  try:
138
  # APIキーの取得と設定
@@ -148,11 +193,11 @@ def generate_html_from_text(text, temperature=0.3):
148
  # Gemini APIの設定
149
  genai.configure(api_key=api_key)
150
 
151
- # HuggingFaceデータセットからシステムインストラクションを読み込む
152
- system_instruction = load_system_instruction()
153
 
154
  # モデル初期化
155
- logger.info(f"Gemini APIにリクエストを送信: テキスト長さ = {len(text)}, 温度 = {temperature}")
156
 
157
  # モデル初期化
158
  model = genai.GenerativeModel(model_name)
@@ -486,11 +531,12 @@ def render_fullpage_screenshot(html_code: str, extension_percentage: float = 6.0
486
  logger.error(f"Error removing temporary file {tmp_path}: {e}")
487
 
488
  # --- Geminiを使った新しい関数 ---
489
- def text_to_screenshot(text: str, extension_percentage: float, temperature: float = 0.3, trim_whitespace: bool = True) -> Image.Image:
 
490
  """テキストをGemini APIでHTMLに変換し、スクリーンショットを生成する統合関数"""
491
  try:
492
- # 1. テキストからHTMLを生成(温度パラメータも渡す)
493
- html_code = generate_html_from_text(text, temperature)
494
 
495
  # 2. HTMLからスクリーンショットを生成
496
  return render_fullpage_screenshot(html_code, extension_percentage, trim_whitespace)
@@ -587,14 +633,17 @@ async def api_text_to_screenshot(request: GeminiRequest):
587
  テキストからHTMLインフォグラフィックを生成してスクリーンショットを返すAPIエンドポイント
588
  """
589
  try:
590
- logger.info(f"テキスト→スクリーンショットAPIリクエスト受信。テキスト長さ: {len(request.text)}, 拡張率: {request.extension_percentage}%, 温度: {request.temperature}")
 
 
591
 
592
- # テキストからHTMLを生成してスクリーンショットを作成(温度パラメータも渡す)
593
  pil_image = text_to_screenshot(
594
  request.text,
595
  request.extension_percentage,
596
  request.temperature,
597
- request.trim_whitespace
 
598
  )
599
 
600
  if pil_image.size == (1, 1):
@@ -615,14 +664,14 @@ async def api_text_to_screenshot(request: GeminiRequest):
615
 
616
  # --- Gradio Interface Definition ---
617
  # 入力モードの選択用Radioコンポーネント
618
- def process_input(input_mode, input_text, extension_percentage, temperature, trim_whitespace):
619
  """入力モードに応じて適切な処理を行う"""
620
  if input_mode == "HTML入力":
621
- # HTMLモードの場合は既存の処理
622
  return render_fullpage_screenshot(input_text, extension_percentage, trim_whitespace)
623
  else:
624
  # テキスト入力モードの場合はGemini APIを使用
625
- return text_to_screenshot(input_text, extension_percentage, temperature, trim_whitespace)
626
 
627
  # Gradio UIの定義
628
  with gr.Blocks(title="Full Page Screenshot (テキスト変換対応)", theme=gr.themes.Base()) as iface:
@@ -644,23 +693,34 @@ with gr.Blocks(title="Full Page Screenshot (テキスト変換対応)", theme=gr
644
  )
645
 
646
  with gr.Row():
647
- extension_percentage = gr.Slider(
648
- minimum=0,
649
- maximum=30,
650
- step=1.0,
651
- value=10, # デフォルト値10%
652
- label="上下高さ拡張率(%)"
653
- )
654
-
655
- # 温度調整スライダー(テキストモード時のみ表示)
656
- temperature = gr.Slider(
657
- minimum=0.0,
658
- maximum=1.0,
659
- step=0.1,
660
- value=0.5, # デフォルト値を0.5に下げて創造性を抑制
661
- label="生成時の温度(低い=一貫性高、高い=創造性高)",
662
- visible=False # 最初は非表示
663
- )
 
 
 
 
 
 
 
 
 
 
 
664
 
665
  # 余白トリミングオプション
666
  trim_whitespace = gr.Checkbox(
@@ -672,21 +732,25 @@ with gr.Blocks(title="Full Page Screenshot (テキスト変換対応)", theme=gr
672
  submit_btn = gr.Button("生成")
673
  output_image = gr.Image(type="pil", label="ページ全体のスクリーンショット")
674
 
675
- # 入力モード変更時のイベント処理(テキストモード時のみ温度スライダーを表示)
676
- def update_temperature_visibility(mode):
677
  # Gradio 4.x用のアップデート方法
678
- return {"visible": mode == "テキスト入力", "__type__": "update"}
 
 
 
 
679
 
680
  input_mode.change(
681
- fn=update_temperature_visibility,
682
  inputs=input_mode,
683
- outputs=temperature
684
  )
685
 
686
  # 生成ボタンクリック時のイベント処理
687
  submit_btn.click(
688
  fn=process_input,
689
- inputs=[input_mode, input_text, extension_percentage, temperature, trim_whitespace],
690
  outputs=output_image
691
  )
692
 
@@ -699,6 +763,7 @@ with gr.Blocks(title="Full Page Screenshot (テキスト変換対応)", theme=gr
699
 
700
  ## 設定情報
701
  - 使用モデル: {gemini_model} (環境変数 GEMINI_MODEL で変更可能)
 
702
  """)
703
 
704
  # --- Mount Gradio App onto FastAPI ---
 
28
  class GeminiRequest(BaseModel):
29
  """Geminiへのリクエストデータモデル"""
30
  text: str
31
+ extension_percentage: float = 10.0 # デフォルト値10%
32
+ temperature: float = 0.5 # デフォルト値を0.5に設定
33
  trim_whitespace: bool = True # 余白トリミングオプション(デフォルト有効)
34
+ style: str = "standard" # デフォルトはstandard
35
 
36
  class ScreenshotRequest(BaseModel):
37
  """スクリーンショットリクエストモデル"""
38
  html_code: str
39
+ extension_percentage: float = 10.0 # デフォルト値10%
40
  trim_whitespace: bool = True # 余白トリミングオプション(デフォルト有効)
41
+ style: str = "standard" # デフォルトはstandard
42
 
43
  # HTMLのFont Awesomeレイアウトを改善する関数
44
  def enhance_font_awesome_layout(html_code):
 
110
  # どちらもない場合は先頭に追加
111
  return f'<html><head>{fa_fix_css}</head>' + html_code + '</html>'
112
 
113
+ def load_system_instruction(style="standard"):
114
+ """
115
+ 指定されたスタイルのシステムインストラクションを読み込む
116
+
117
+ Args:
118
+ style: 使用するスタイル名 (standard, cute, resort, cool, dental)
119
+
120
+ Returns:
121
+ 読み込まれたシステムインストラクション
122
+ """
123
  try:
124
+ # 有効なスタイル一覧
125
+ valid_styles = ["standard", "cute", "resort", "cool", "dental"]
 
 
 
 
 
126
 
127
+ # スタイルの検証
128
+ if style not in valid_styles:
129
+ logger.warning(f"無効なスタイル '{style}' が指定されました。デフォルトの 'standard' を使用します。")
130
+ style = "standard"
131
+
132
+ logger.info(f"スタイル '{style}' のシステムインストラクションを読み込みます")
133
 
134
+ # まず、ローカルのスタイルディレクトリ内のprompt.txtを確認
135
+ local_path = os.path.join(os.path.dirname(__file__), style, "prompt.txt")
136
+
137
+ # ローカルファイルが存在する場合はそれを使用
138
+ if os.path.exists(local_path):
139
+ logger.info(f"ローカルファイルを使用: {local_path}")
140
+ with open(local_path, 'r', encoding='utf-8') as file:
141
+ instruction = file.read()
142
+ return instruction
143
+
144
+ # HuggingFaceリポジトリからのファイル読み込みを試行
145
+ try:
146
+ # スタイル固有のファイルパスを指定
147
+ file_path = hf_hub_download(
148
+ repo_id="tomo2chin2/GURAREKOstlyle",
149
+ filename=f"{style}/prompt.txt",
150
+ repo_type="dataset"
151
+ )
152
+
153
+ logger.info(f"スタイル '{style}' のプロンプトをHuggingFaceから読み込みました: {file_path}")
154
+ with open(file_path, 'r', encoding='utf-8') as file:
155
+ instruction = file.read()
156
+ return instruction
157
+
158
+ except Exception as style_error:
159
+ # スタイル固有ファイルの読み込みに失敗した場合、デフォルトのprompt.txtを使用
160
+ logger.warning(f"スタイル '{style}' のプロンプト読み込みに失敗: {str(style_error)}")
161
+ logger.info("デフォルトのprompt.txtを読み込みます")
162
+
163
+ file_path = hf_hub_download(
164
+ repo_id="tomo2chin2/GURAREKOstlyle",
165
+ filename="prompt.txt",
166
+ repo_type="dataset"
167
+ )
168
+
169
+ with open(file_path, 'r', encoding='utf-8') as file:
170
+ instruction = file.read()
171
+
172
+ logger.info("デフォルトのシステムインストラクションを読み込みました")
173
+ return instruction
174
+
175
  except Exception as e:
 
176
  error_msg = f"システムインストラクションの読み込みに失敗: {str(e)}"
177
  logger.error(error_msg)
178
  raise ValueError(error_msg)
179
 
180
+ def generate_html_from_text(text, temperature=0.3, style="standard"):
181
  """テキストからHTMLを生成する"""
182
  try:
183
  # APIキーの取得と設定
 
193
  # Gemini APIの設定
194
  genai.configure(api_key=api_key)
195
 
196
+ # 指定されたスタイルのシステムインストラクションを読み込む
197
+ system_instruction = load_system_instruction(style)
198
 
199
  # モデル初期化
200
+ logger.info(f"Gemini APIにリクエストを送信: テキスト長さ = {len(text)}, 温度 = {temperature}, スタイル = {style}")
201
 
202
  # モデル初期化
203
  model = genai.GenerativeModel(model_name)
 
531
  logger.error(f"Error removing temporary file {tmp_path}: {e}")
532
 
533
  # --- Geminiを使った新しい関数 ---
534
+ def text_to_screenshot(text: str, extension_percentage: float, temperature: float = 0.3,
535
+ trim_whitespace: bool = True, style: str = "standard") -> Image.Image:
536
  """テキストをGemini APIでHTMLに変換し、スクリーンショットを生成する統合関数"""
537
  try:
538
+ # 1. テキストからHTMLを生成(温度パラメータとスタイルも渡す)
539
+ html_code = generate_html_from_text(text, temperature, style)
540
 
541
  # 2. HTMLからスクリーンショットを生成
542
  return render_fullpage_screenshot(html_code, extension_percentage, trim_whitespace)
 
633
  テキストからHTMLインフォグラフィックを生成してスクリーンショットを返すAPIエンドポイント
634
  """
635
  try:
636
+ logger.info(f"テキスト→スクリーンショットAPIリクエスト受信。テキスト長さ: {len(request.text)}, "
637
+ f"拡張率: {request.extension_percentage}%, 温度: {request.temperature}, "
638
+ f"スタイル: {request.style}")
639
 
640
+ # テキストからHTMLを生成してスクリーンショットを作成(温度パラメータとスタイルも渡す)
641
  pil_image = text_to_screenshot(
642
  request.text,
643
  request.extension_percentage,
644
  request.temperature,
645
+ request.trim_whitespace,
646
+ request.style
647
  )
648
 
649
  if pil_image.size == (1, 1):
 
664
 
665
  # --- Gradio Interface Definition ---
666
  # 入力モードの選択用Radioコンポーネント
667
+ def process_input(input_mode, input_text, extension_percentage, temperature, trim_whitespace, style):
668
  """入力モードに応じて適切な処理を行う"""
669
  if input_mode == "HTML入力":
670
+ # HTMLモードの場合は既存の処理(スタイルは使わない)
671
  return render_fullpage_screenshot(input_text, extension_percentage, trim_whitespace)
672
  else:
673
  # テキスト入力モードの場合はGemini APIを使用
674
+ return text_to_screenshot(input_text, extension_percentage, temperature, trim_whitespace, style)
675
 
676
  # Gradio UIの定義
677
  with gr.Blocks(title="Full Page Screenshot (テキスト変換対応)", theme=gr.themes.Base()) as iface:
 
693
  )
694
 
695
  with gr.Row():
696
+ with gr.Column(scale=1):
697
+ # スタイル選択ドロップダウン
698
+ style_dropdown = gr.Dropdown(
699
+ choices=["standard", "cute", "resort", "cool", "dental"],
700
+ value="standard",
701
+ label="デザインスタイル",
702
+ info="テキスト→HTML変換時のデザインテーマを選択します",
703
+ visible=False # テキスト入力モードの時だけ表示
704
+ )
705
+
706
+ with gr.Column(scale=2):
707
+ extension_percentage = gr.Slider(
708
+ minimum=0,
709
+ maximum=30,
710
+ step=1.0,
711
+ value=10, # デフォルト値10%
712
+ label="上下高さ拡張率(%)"
713
+ )
714
+
715
+ # 温度調整スライダー(テキストモード時のみ表示)
716
+ temperature = gr.Slider(
717
+ minimum=0.0,
718
+ maximum=1.0,
719
+ step=0.1,
720
+ value=0.5, # デフォルト値を0.5に設定
721
+ label="生成時の温度(低い=一貫性高、高い=創造性高)",
722
+ visible=False # 最初は非表示
723
+ )
724
 
725
  # 余白トリミングオプション
726
  trim_whitespace = gr.Checkbox(
 
732
  submit_btn = gr.Button("生成")
733
  output_image = gr.Image(type="pil", label="ページ全体のスクリーンショット")
734
 
735
+ # 入力モード変更時のイベント処理(テキストモード時のみ温度スライダーとスタイルドロップダウンを表示)
736
+ def update_controls_visibility(mode):
737
  # Gradio 4.x用のアップデート方法
738
+ is_text_mode = mode == "テキスト入力"
739
+ return [
740
+ {"visible": is_text_mode, "__type__": "update"}, # temperature
741
+ {"visible": is_text_mode, "__type__": "update"}, # style_dropdown
742
+ ]
743
 
744
  input_mode.change(
745
+ fn=update_controls_visibility,
746
  inputs=input_mode,
747
+ outputs=[temperature, style_dropdown]
748
  )
749
 
750
  # 生成ボタンクリック時のイベント処理
751
  submit_btn.click(
752
  fn=process_input,
753
+ inputs=[input_mode, input_text, extension_percentage, temperature, trim_whitespace, style_dropdown],
754
  outputs=output_image
755
  )
756
 
 
763
 
764
  ## 設定情報
765
  - 使用モデル: {gemini_model} (環境変数 GEMINI_MODEL で変更可能)
766
+ - 対応スタイル: standard, cute, resort, cool, dental
767
  """)
768
 
769
  # --- Mount Gradio App onto FastAPI ---