GoodML commited on
Commit
67f39b5
·
verified ·
1 Parent(s): 1e79ac5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +132 -46
app.py CHANGED
@@ -220,56 +220,142 @@ def transcribe_audio(wav_file_path):
220
  os.remove(wav_file_path)
221
  print(f"Temporary WAV file deleted: {wav_file_path}")
222
 
 
 
223
 
224
- def query_gemini_api(transcription):
225
  """
226
  Send transcription text to Gemini API and fetch structured recipe information synchronously.
 
 
227
  """
228
- try:
229
- # Define the structured prompt
230
- prompt = (
231
- "Analyze the provided cooking video transcription and extract the following structured information:\n"
232
- "1. Recipe Name: Identify the name of the dish being prepared.\n"
233
- "2. Ingredients List: Extract a detailed list of ingredients with their respective quantities (if mentioned).\n"
234
- "3. Steps for Preparation: Provide a step-by-step breakdown of the recipe's preparation process, organized and numbered sequentially.\n"
235
- "4. Cooking Techniques Used: Highlight the cooking techniques demonstrated in the video, such as searing, blitzing, wrapping, etc.\n"
236
- "5. Equipment Needed: List all tools, appliances, or utensils mentioned, e.g., blender, hot pan, cling film, etc.\n"
237
- "6. Nutritional Information (if inferred): Provide an approximate calorie count or nutritional breakdown based on the ingredients used.\n"
238
- "7. Serving size: In count of people or portion size.\n"
239
- "8. Special Notes or Variations: Include any specific tips, variations, or alternatives mentioned.\n"
240
- "9. Festive or Thematic Relevance: Note if the recipe has any special relevance to holidays, events, or seasons.\n"
241
- f"Text: {transcription}\n"
242
- )
243
-
244
- # Prepare the payload and headers
245
- payload = {
246
- "contents": [
247
- {
248
- "parts": [
249
- {"text": prompt}
250
- ]
251
- }
252
- ]
253
- }
254
- headers = {"Content-Type": "application/json"}
255
-
256
- # Send request to Gemini API synchronously
257
- response = requests.post(
258
- f"{GEMINI_API_ENDPOINT}?key={GEMINI_API_KEY}",
259
- json=payload,
260
- headers=headers,
261
- )
262
-
263
- # Raise error if response code is not 200
264
- response.raise_for_status()
265
-
266
- data = response.json()
267
-
268
- return data.get("candidates", [{}])[0].get("content", {}).get("parts", [{}])[0].get("text", "No result found")
269
-
270
- except requests.exceptions.RequestException as e:
271
- print(f"Error querying Gemini API: {e}")
272
- return {"error": str(e)}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
273
 
274
 
275
  if __name__ == '__main__':
 
220
  os.remove(wav_file_path)
221
  print(f"Temporary WAV file deleted: {wav_file_path}")
222
 
223
+ import time
224
+ import requests
225
 
226
+ def query_gemini_api(transcription, max_retries=3, backoff_factor=2):
227
  """
228
  Send transcription text to Gemini API and fetch structured recipe information synchronously.
229
+ Includes automatic retries with exponential backoff for transient rate-limit errors (HTTP 429).
230
+ If all attempts fail, returns a default structured response.
231
  """
232
+ # Define the structured prompt
233
+ prompt = (
234
+ "Analyze the provided cooking video transcription and extract the following structured information:\n"
235
+ "1. Recipe Name: Identify the name of the dish being prepared.\n"
236
+ "2. Ingredients List: Extract a detailed list of ingredients with their respective quantities (if mentioned).\n"
237
+ "3. Steps for Preparation: Provide a step-by-step breakdown of the recipe's preparation process, organized and numbered sequentially.\n"
238
+ "4. Cooking Techniques Used: Highlight the cooking techniques demonstrated in the video, such as searing, blitzing, wrapping, etc.\n"
239
+ "5. Equipment Needed: List all tools, appliances, or utensils mentioned, e.g., blender, hot pan, cling film, etc.\n"
240
+ "6. Nutritional Information (if inferred): Provide an approximate calorie count or nutritional breakdown based on the ingredients used.\n"
241
+ "7. Serving size: In count of people or portion size.\n"
242
+ "8. Special Notes or Variations: Include any specific tips, variations, or alternatives mentioned.\n"
243
+ "9. Festive or Thematic Relevance: Note if the recipe has any special relevance to holidays, events, or seasons.\n"
244
+ f"Text: {transcription}\n"
245
+ )
246
+
247
+ # Prepare the payload and headers
248
+ payload = {
249
+ "contents": [
250
+ {
251
+ "parts": [
252
+ {"text": prompt}
253
+ ]
254
+ }
255
+ ]
256
+ }
257
+ headers = {"Content-Type": "application/json"}
258
+
259
+ # Attempt sending the request with retries
260
+ for attempt in range(max_retries):
261
+ try:
262
+ response = requests.post(
263
+ f"{GEMINI_API_ENDPOINT}?key={GEMINI_API_KEY}",
264
+ json=payload,
265
+ headers=headers,
266
+ )
267
+
268
+ # Check for 429 explicitly and wait before retrying
269
+ if response.status_code == 429:
270
+ if attempt < max_retries - 1:
271
+ wait_time = backoff_factor ** attempt
272
+ print(f"[Gemini] Rate limit reached (429). Retrying in {wait_time} seconds...")
273
+ time.sleep(wait_time)
274
+ continue
275
+ else:
276
+ raise requests.exceptions.RequestException("Rate limit (429) after max retries")
277
+
278
+ response.raise_for_status()
279
+ data = response.json()
280
+ return data.get("candidates", [{}])[0].get("content", {}).get("parts", [{}])[0].get("text", "No result found")
281
+
282
+ except requests.exceptions.RequestException as e:
283
+ print(f"Error querying Gemini API: {e}")
284
+ if attempt < max_retries - 1:
285
+ wait_time = backoff_factor ** attempt
286
+ print(f"Retrying in {wait_time} seconds...")
287
+ time.sleep(wait_time)
288
+ else:
289
+ # If all retries fail, return a default structured response
290
+ default_response = (
291
+ "Recipe Name: none\n"
292
+ "Ingredients List: none\n"
293
+ "Steps for Preparation: none\n"
294
+ "Cooking Techniques Used: none\n"
295
+ "Equipment Needed: none\n"
296
+ "Nutritional Information: none\n"
297
+ "Serving size: none\n"
298
+ "Special Notes or Variations: none\n"
299
+ "Festive or Thematic Relevance: none"
300
+ )
301
+ return default_response
302
+
303
+ # In case the loop finishes without returning, which should not happen
304
+ return {
305
+ "error": "Unexpected error occurred in query_gemini_api."
306
+ }
307
+
308
+
309
+
310
+ # def query_gemini_api(transcription):
311
+ # """
312
+ # Send transcription text to Gemini API and fetch structured recipe information synchronously.
313
+ # """
314
+ # try:
315
+ # # Define the structured prompt
316
+ # prompt = (
317
+ # "Analyze the provided cooking video transcription and extract the following structured information:\n"
318
+ # "1. Recipe Name: Identify the name of the dish being prepared.\n"
319
+ # "2. Ingredients List: Extract a detailed list of ingredients with their respective quantities (if mentioned).\n"
320
+ # "3. Steps for Preparation: Provide a step-by-step breakdown of the recipe's preparation process, organized and numbered sequentially.\n"
321
+ # "4. Cooking Techniques Used: Highlight the cooking techniques demonstrated in the video, such as searing, blitzing, wrapping, etc.\n"
322
+ # "5. Equipment Needed: List all tools, appliances, or utensils mentioned, e.g., blender, hot pan, cling film, etc.\n"
323
+ # "6. Nutritional Information (if inferred): Provide an approximate calorie count or nutritional breakdown based on the ingredients used.\n"
324
+ # "7. Serving size: In count of people or portion size.\n"
325
+ # "8. Special Notes or Variations: Include any specific tips, variations, or alternatives mentioned.\n"
326
+ # "9. Festive or Thematic Relevance: Note if the recipe has any special relevance to holidays, events, or seasons.\n"
327
+ # f"Text: {transcription}\n"
328
+ # )
329
+
330
+ # # Prepare the payload and headers
331
+ # payload = {
332
+ # "contents": [
333
+ # {
334
+ # "parts": [
335
+ # {"text": prompt}
336
+ # ]
337
+ # }
338
+ # ]
339
+ # }
340
+ # headers = {"Content-Type": "application/json"}
341
+
342
+ # # Send request to Gemini API synchronously
343
+ # response = requests.post(
344
+ # f"{GEMINI_API_ENDPOINT}?key={GEMINI_API_KEY}",
345
+ # json=payload,
346
+ # headers=headers,
347
+ # )
348
+
349
+ # # Raise error if response code is not 200
350
+ # response.raise_for_status()
351
+
352
+ # data = response.json()
353
+
354
+ # return data.get("candidates", [{}])[0].get("content", {}).get("parts", [{}])[0].get("text", "No result found")
355
+
356
+ # except requests.exceptions.RequestException as e:
357
+ # print(f"Error querying Gemini API: {e}")
358
+ # return {"error": str(e)}
359
 
360
 
361
  if __name__ == '__main__':