tomo2chin2 commited on
Commit
df45e87
·
verified ·
1 Parent(s): 9ee433b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +72 -59
app.py CHANGED
@@ -18,11 +18,7 @@ import logging
18
  from huggingface_hub import hf_hub_download # 追加: HuggingFace Hubからファイルを直接ダウンロード
19
 
20
  # 正しいGemini関連のインポート
21
- #import google.generativeai as genai
22
- # --- ここだけ差し替え ---
23
- from google import genai # 新 SDK の推奨 import​:contentReference[oaicite:2]{index=2}
24
- from google.genai import types # ThinkingConfig 等を使うための追加​:contentReference[oaicite:3]{index=3}
25
-
26
 
27
  # ロギング設定
28
  logging.basicConfig(level=logging.INFO)
@@ -182,77 +178,94 @@ def load_system_instruction(style="standard"):
182
  raise ValueError(error_msg)
183
 
184
  def generate_html_from_text(text, temperature=0.3, style="standard"):
185
- """
186
- テキスト → Gemini で HTML 生成
187
- - gemini‑2.5‑flash‑preview‑04‑17 のときは thinking_budget=0 を強制
188
- - それ以外のモデルは従来どおり
189
- """
190
  try:
191
- # --- 共通前処理 --------------------------------------------------
192
  api_key = os.environ.get("GEMINI_API_KEY")
193
  if not api_key:
194
- raise ValueError("環境変数 GEMINI_API_KEY が設定されていません")
 
195
 
 
196
  model_name = os.environ.get("GEMINI_MODEL", "gemini-1.5-pro")
 
 
 
197
  genai.configure(api_key=api_key)
 
 
198
  system_instruction = load_system_instruction(style)
199
- prompt = f"{system_instruction}\n\n{text}"
200
 
201
- safety_settings = [ # 既存設定をそのまま使用
202
- {"category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_MEDIUM_AND_ABOVE"},
203
- {"category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "BLOCK_MEDIUM_AND_ABOVE"},
204
- {"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT", "threshold": "BLOCK_MEDIUM_AND_ABOVE"},
205
- {"category": "HARM_CATEGORY_DANGEROUS_CONTENT", "threshold": "BLOCK_MEDIUM_AND_ABOVE"},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
  ]
207
 
208
- # --- モデル分岐 --------------------------------------------------
209
- if model_name == "gemini-2.5-flash-preview-04-17": # Thinking モデル​:contentReference[oaicite:4]{index=4}
210
- client = genai.Client(api_key=api_key)
211
- gen_cfg = types.GenerateContentConfig( # pydantic Config クラスを使用​:contentReference[oaicite:5]{index=5}
212
- temperature=temperature,
213
- top_p=0.7,
214
- top_k=20,
215
- max_output_tokens=8192,
216
- candidate_count=1,
217
- thinking_config=types.ThinkingConfig(thinking_budget=0) # ← thinking OFF​:contentReference[oaicite:6]{index=6}
218
- )
219
- response = client.models.generate_content(
220
- model=model_name,
221
- contents=prompt,
222
- config=gen_cfg,
223
- safety_settings=safety_settings
224
- )
225
- raw_response = response.text
226
- else:
227
- # 非 Thinking モデルは旧 API と互換のまま
228
- model = genai.GenerativeModel(model_name)
229
- gen_cfg = {
230
- "temperature": temperature,
231
- "top_p": 0.7,
232
- "top_k": 20,
233
- "max_output_tokens": 8192,
234
- "candidate_count": 1,
235
- }
236
- response = model.generate_content(
237
- prompt,
238
- generation_config=gen_cfg,
239
- safety_settings=safety_settings
240
- )
241
- raw_response = response.text
242
 
243
- # --- 後処理(HTML 抽出 & Font Awesome レイアウト補正)------------
 
 
 
244
  html_start = raw_response.find("```html")
245
- html_end = raw_response.rfind("```")
 
246
  if html_start != -1 and html_end != -1 and html_start < html_end:
247
- html_code = raw_response[html_start + 7:html_end].strip()
248
- return enhance_font_awesome_layout(html_code)
 
 
 
 
 
 
 
249
  else:
250
- logger.warning("```html``` ブロックが見つからず、全文を返します")
 
251
  return raw_response
252
 
253
  except Exception as e:
254
- logger.error(f"Gemini HTML 生成エラー: {e}", exc_info=True)
255
- raise
256
 
257
  # 画像から余分な空白領域をトリミングする関数
258
  def trim_image_whitespace(image, threshold=250, padding=10):
 
18
  from huggingface_hub import hf_hub_download # 追加: HuggingFace Hubからファイルを直接ダウンロード
19
 
20
  # 正しいGemini関連のインポート
21
+ import google.generativeai as genai
 
 
 
 
22
 
23
  # ロギング設定
24
  logging.basicConfig(level=logging.INFO)
 
178
  raise ValueError(error_msg)
179
 
180
  def generate_html_from_text(text, temperature=0.3, style="standard"):
181
+ """テキストからHTMLを生成する"""
 
 
 
 
182
  try:
183
+ # APIキーの取得と設定
184
  api_key = os.environ.get("GEMINI_API_KEY")
185
  if not api_key:
186
+ logger.error("GEMINI_API_KEY 環境変数が設定されていません")
187
+ raise ValueError("GEMINI_API_KEY 環境変数が設定されていません")
188
 
189
+ # モデル名の取得(環境変数から、なければデフォルト値)
190
  model_name = os.environ.get("GEMINI_MODEL", "gemini-1.5-pro")
191
+ logger.info(f"使用するGeminiモデル: {model_name}")
192
+
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)
204
+
205
+ # 生成設定 - ばらつきを減らすために設定を調整
206
+ generation_config = {
207
+ "temperature": temperature, # より低い温度を設定
208
+ "top_p": 0.7, # 0.95から0.7に下げて出力の多様性を制限
209
+ "top_k": 20, # 64から20に下げて候補を絞る
210
+ "max_output_tokens": 8192,
211
+ "candidate_count": 1 # 候補は1つだけ生成
212
+ }
213
+
214
+ # 安全設定 - デフォルトの安全設定を使用
215
+ safety_settings = [
216
+ {
217
+ "category": "HARM_CATEGORY_HARASSMENT",
218
+ "threshold": "BLOCK_MEDIUM_AND_ABOVE"
219
+ },
220
+ {
221
+ "category": "HARM_CATEGORY_HATE_SPEECH",
222
+ "threshold": "BLOCK_MEDIUM_AND_ABOVE"
223
+ },
224
+ {
225
+ "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
226
+ "threshold": "BLOCK_MEDIUM_AND_ABOVE"
227
+ },
228
+ {
229
+ "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
230
+ "threshold": "BLOCK_MEDIUM_AND_ABOVE"
231
+ }
232
  ]
233
 
234
+ # プロンプト構築
235
+ prompt = f"{system_instruction}\n\n{text}"
236
+
237
+ # コンテンツ生成
238
+ response = model.generate_content(
239
+ prompt,
240
+ generation_config=generation_config,
241
+ safety_settings=safety_settings
242
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
 
244
+ # レスポンスからHTMLを抽出
245
+ raw_response = response.text
246
+
247
+ # HTMLタグ部分だけを抽出(```html と ``` の間)
248
  html_start = raw_response.find("```html")
249
+ html_end = raw_response.rfind("```")
250
+
251
  if html_start != -1 and html_end != -1 and html_start < html_end:
252
+ html_start += 7 # "```html" の長さ分進める
253
+ html_code = raw_response[html_start:html_end].strip()
254
+ logger.info(f"HTMLの生成に成功: 長さ = {len(html_code)}")
255
+
256
+ # Font Awesomeのレイアウト改善
257
+ html_code = enhance_font_awesome_layout(html_code)
258
+ logger.info("Font Awesomeレイアウトの最適化を適用しました")
259
+
260
+ return html_code
261
  else:
262
+ # HTMLタグが見つからない場合、レスポンス全体を返す
263
+ logger.warning("レスポンスから ```html ``` タグが見つかりませんでした。全テキストを返します。")
264
  return raw_response
265
 
266
  except Exception as e:
267
+ logger.error(f"HTML生成中にエラーが発生: {e}", exc_info=True)
268
+ raise Exception(f"Gemini APIでのHTML生成に失敗しました: {e}")
269
 
270
  # 画像から余分な空白領域をトリミングする関数
271
  def trim_image_whitespace(image, threshold=250, padding=10):