Gaurav vashistha commited on
Commit
8e0ba30
·
1 Parent(s): 924120a

fix: use positional arg only for operations.get(), simplified polling

Browse files
Files changed (1) hide show
  1. agent.py +24 -26
agent.py CHANGED
@@ -37,9 +37,11 @@ def get_or_upload_file(client, filepath):
37
  def analyze_only(path_a, path_c, job_id=None):
38
  update_job_status(job_id, "analyzing", 10, "Director checking file cache...")
39
  client = genai.Client(api_key=Settings.GOOGLE_API_KEY)
 
40
  try:
41
  file_a = get_or_upload_file(client, path_a)
42
  file_c = get_or_upload_file(client, path_c)
 
43
  while file_a.state.name == "PROCESSING" or file_c.state.name == "PROCESSING":
44
  update_job_status(job_id, "analyzing", 20, "Google processing video...")
45
  time.sleep(2)
@@ -58,6 +60,7 @@ def analyze_only(path_a, path_c, job_id=None):
58
  if text.startswith("```json"): text = text[7:]
59
  elif text.startswith("```"): text = text[3:]
60
  if text.endswith("```"): text = text[:-3]
 
61
  try: data = json.loads(text.strip())
62
  except: data = {}
63
  if isinstance(data, list): data = data[0] if len(data) > 0 else {}
@@ -83,63 +86,57 @@ def generate_only(prompt, path_a, path_c, job_id, style, audio, neg, guidance, m
83
  if Settings.GCP_PROJECT_ID:
84
  client = genai.Client(vertexai=True, project=Settings.GCP_PROJECT_ID, location=Settings.GCP_LOCATION)
85
 
 
86
  op = client.models.generate_videos(
87
  model='veo-3.1-generate-preview',
88
  prompt=full_prompt,
89
  config=types.GenerateVideosConfig(number_of_videos=1)
90
  )
91
 
92
- # --- DEBUG LOGGING ---
93
- logger.info(f"DEBUG: OP Type: {type(op)}")
94
- if hasattr(client, 'operations'):
95
- logger.info(f"DEBUG: Client Ops Dir: {dir(client.operations)}")
96
-
97
  op_name = str(op)
98
  if hasattr(op, 'name'): op_name = op.name
99
  elif isinstance(op, dict) and 'name' in op: op_name = op['name']
100
 
101
  logger.info(f"Tracking ID: {op_name}")
102
 
 
103
  start_time = time.time()
104
  while True:
105
- if time.time() - start_time > 300: raise Exception("Generation timed out.")
106
-
107
- current_op = None
108
 
109
- # Strategy 1: Try keyword argument (Standard)
110
  try:
111
- current_op = client.operations.get(name=op_name)
112
- except Exception as e1:
113
- # Strategy 2: Try positional argument (Fallback)
114
- try:
115
- current_op = client.operations.get(op_name)
116
- except Exception as e2:
117
- logger.warning(f"Refresh failed S1: {e1} | S2: {e2}")
118
 
119
  # Check Status
120
  is_done = False
121
- if current_op:
122
- if hasattr(current_op, 'done'): is_done = current_op.done
123
- elif isinstance(current_op, dict): is_done = current_op.get('done')
124
 
125
  if is_done:
126
  logger.info("Job DONE.")
127
- op = current_op # Update op for result extraction
128
  break
129
 
130
- logger.info("Waiting...")
131
  time.sleep(10)
132
 
133
- # Result Extraction (Safe)
134
  result = None
135
  if hasattr(op, 'result'):
136
- # Try accessing as property first, then method
137
  try:
138
  res_val = op.result
139
  if callable(res_val): result = res_val()
140
  else: result = res_val
141
  except: pass
142
- elif isinstance(op, dict): result = op.get('result')
 
143
 
144
  generated_videos = None
145
  if result:
@@ -163,6 +160,7 @@ def generate_only(prompt, path_a, path_c, job_id, style, audio, neg, guidance, m
163
  update_job_status(job_id, "stitching", 85, "Stitching...", video_url=bridge_path)
164
  final_cut = os.path.join("outputs", f"{job_id}_merged_temp.mp4")
165
  merged_path = stitch_videos(path_a, bridge_path, path_c, final_cut)
 
166
  msg = "Done! (Merged)" if merged_path else "Done! (Bridge Only)"
167
  update_job_status(job_id, "completed", 100, msg, video_url=bridge_path, merged_video_url=merged_path)
168
  return
@@ -172,7 +170,7 @@ def generate_only(prompt, path_a, path_c, job_id, style, audio, neg, guidance, m
172
  raise Exception("GCP_PROJECT_ID not set.")
173
 
174
  except Exception as e:
175
- logger.error(f"Fatal: {e}")
176
  update_job_status(job_id, "error", 0, f"Error: {e}")
177
  job_failed = True
178
  finally:
@@ -180,5 +178,5 @@ def generate_only(prompt, path_a, path_c, job_id, style, audio, neg, guidance, m
180
  try:
181
  with open(f"outputs/{job_id}.json", "r") as f:
182
  if json.load(f).get("status") not in ["completed", "error"]:
183
- update_job_status(job_id, "error", 0, "Terminated.")
184
  except: pass
 
37
  def analyze_only(path_a, path_c, job_id=None):
38
  update_job_status(job_id, "analyzing", 10, "Director checking file cache...")
39
  client = genai.Client(api_key=Settings.GOOGLE_API_KEY)
40
+
41
  try:
42
  file_a = get_or_upload_file(client, path_a)
43
  file_c = get_or_upload_file(client, path_c)
44
+
45
  while file_a.state.name == "PROCESSING" or file_c.state.name == "PROCESSING":
46
  update_job_status(job_id, "analyzing", 20, "Google processing video...")
47
  time.sleep(2)
 
60
  if text.startswith("```json"): text = text[7:]
61
  elif text.startswith("```"): text = text[3:]
62
  if text.endswith("```"): text = text[:-3]
63
+
64
  try: data = json.loads(text.strip())
65
  except: data = {}
66
  if isinstance(data, list): data = data[0] if len(data) > 0 else {}
 
86
  if Settings.GCP_PROJECT_ID:
87
  client = genai.Client(vertexai=True, project=Settings.GCP_PROJECT_ID, location=Settings.GCP_LOCATION)
88
 
89
+ # 1. Start Job
90
  op = client.models.generate_videos(
91
  model='veo-3.1-generate-preview',
92
  prompt=full_prompt,
93
  config=types.GenerateVideosConfig(number_of_videos=1)
94
  )
95
 
96
+ # 2. Extract ID String
 
 
 
 
97
  op_name = str(op)
98
  if hasattr(op, 'name'): op_name = op.name
99
  elif isinstance(op, dict) and 'name' in op: op_name = op['name']
100
 
101
  logger.info(f"Tracking ID: {op_name}")
102
 
103
+ # 3. Poll for Completion
104
  start_time = time.time()
105
  while True:
106
+ if time.time() - start_time > 300:
107
+ raise Exception("Generation timed out.")
 
108
 
 
109
  try:
110
+ # FIX: Use positional argument for get()
111
+ current_op = client.operations.get(op_name)
112
+ except Exception as e:
113
+ logger.warning(f"Refresh failed: {e}")
114
+ time.sleep(10)
115
+ continue
 
116
 
117
  # Check Status
118
  is_done = False
119
+ if hasattr(current_op, 'done'): is_done = current_op.done
120
+ elif isinstance(current_op, dict): is_done = current_op.get('done')
 
121
 
122
  if is_done:
123
  logger.info("Job DONE.")
124
+ op = current_op
125
  break
126
 
127
+ logger.info("Waiting for Veo...")
128
  time.sleep(10)
129
 
130
+ # 4. Get Result
131
  result = None
132
  if hasattr(op, 'result'):
 
133
  try:
134
  res_val = op.result
135
  if callable(res_val): result = res_val()
136
  else: result = res_val
137
  except: pass
138
+ elif isinstance(op, dict):
139
+ result = op.get('result')
140
 
141
  generated_videos = None
142
  if result:
 
160
  update_job_status(job_id, "stitching", 85, "Stitching...", video_url=bridge_path)
161
  final_cut = os.path.join("outputs", f"{job_id}_merged_temp.mp4")
162
  merged_path = stitch_videos(path_a, bridge_path, path_c, final_cut)
163
+
164
  msg = "Done! (Merged)" if merged_path else "Done! (Bridge Only)"
165
  update_job_status(job_id, "completed", 100, msg, video_url=bridge_path, merged_video_url=merged_path)
166
  return
 
170
  raise Exception("GCP_PROJECT_ID not set.")
171
 
172
  except Exception as e:
173
+ logger.error(f"Gen Fatal: {e}")
174
  update_job_status(job_id, "error", 0, f"Error: {e}")
175
  job_failed = True
176
  finally:
 
178
  try:
179
  with open(f"outputs/{job_id}.json", "r") as f:
180
  if json.load(f).get("status") not in ["completed", "error"]:
181
+ update_job_status(job_id, "error", 0, "Job timed out.")
182
  except: pass