asimfayaz commited on
Commit
9118fd9
·
1 Parent(s): 1bb9da2

Add stage information to API status responses

Browse files

- Add stage field to JobInfo class to track current processing stage
- Update update_job_status function to include stage parameter
- Add stage tracking at each milestone in process_generation_job
- Include stage in API status response for better client feedback
- Update API documentation with stage values and examples
- Stages: queued, initializing, preprocessing, shape_generation, face_reduction, texture_generation, completed, failed

Files changed (2) hide show
  1. API_README.md +12 -1
  2. gradio_app.py +13 -9
API_README.md CHANGED
@@ -76,6 +76,7 @@ Check the status of a generation job.
76
  {
77
  "status": "completed|processing|queued|failed",
78
  "progress": 0-100,
 
79
  "model_urls": {
80
  "glb": "url_to_glb_file"
81
  }
@@ -88,6 +89,16 @@ Check the status of a generation job.
88
  - `completed`: Job completed successfully
89
  - `failed`: Job failed with an error
90
 
 
 
 
 
 
 
 
 
 
 
91
  ## Usage Examples
92
 
93
  ### Python Example
@@ -124,7 +135,7 @@ while True:
124
  print(f"Generation failed: {data.get('error')}")
125
  break
126
 
127
- print(f"Progress: {data['progress']}%")
128
  time.sleep(5)
129
  ```
130
 
 
76
  {
77
  "status": "completed|processing|queued|failed",
78
  "progress": 0-100,
79
+ "stage": "current_processing_stage",
80
  "model_urls": {
81
  "glb": "url_to_glb_file"
82
  }
 
89
  - `completed`: Job completed successfully
90
  - `failed`: Job failed with an error
91
 
92
+ **Stage Values:**
93
+ - `queued`: Job is waiting to be processed
94
+ - `initializing`: Setting up job and converting images
95
+ - `preprocessing`: Preparing images and options
96
+ - `shape_generation`: Generating 3D mesh from images
97
+ - `face_reduction`: Optimizing mesh geometry
98
+ - `texture_generation`: Creating textures for the 3D model
99
+ - `completed`: Job finished successfully
100
+ - `failed`: Job failed with an error
101
+
102
  ## Usage Examples
103
 
104
  ### Python Example
 
135
  print(f"Generation failed: {data.get('error')}")
136
  break
137
 
138
+ print(f"Progress: {data['progress']}% - Stage: {data['stage']}")
139
  time.sleep(5)
140
  ```
141
 
gradio_app.py CHANGED
@@ -82,6 +82,7 @@ class JobInfo:
82
  self.job_id = job_id
83
  self.status = JobStatus.QUEUED
84
  self.progress = 0
 
85
  self.start_time = time.time()
86
  self.end_time = None
87
  self.error_message = None
@@ -101,12 +102,14 @@ def create_job() -> str:
101
  return job_id
102
 
103
 
104
- def update_job_status(job_id: str, status: JobStatus, progress: int = None, error_message: str = None):
105
  """Update job status and progress."""
106
  if job_id in jobs:
107
  jobs[job_id].status = status
108
  if progress is not None:
109
  jobs[job_id].progress = progress
 
 
110
  if error_message is not None:
111
  jobs[job_id].error_message = error_message
112
  if status in [JobStatus.COMPLETED, JobStatus.FAILED]:
@@ -132,7 +135,7 @@ def process_generation_job(job_id: str, images: Dict[str, str], options: Dict[st
132
  global face_reduce_worker, tex_pipeline, HAS_TEXTUREGEN, SAVE_DIR
133
 
134
  try:
135
- update_job_status(job_id, JobStatus.PROCESSING, progress=10)
136
 
137
  # Convert base64 images to PIL Images
138
  pil_images = {}
@@ -144,7 +147,7 @@ def process_generation_job(job_id: str, images: Dict[str, str], options: Dict[st
144
  should_remesh = options.get("should_remesh", True)
145
  should_texture = options.get("should_texture", True)
146
 
147
- update_job_status(job_id, JobStatus.PROCESSING, progress=20)
148
 
149
  # Generate 3D mesh
150
  # For non-MV mode, use the front image as the main image, or the first available image
@@ -169,7 +172,7 @@ def process_generation_job(job_id: str, images: Dict[str, str], options: Dict[st
169
  randomize_seed=False,
170
  )
171
 
172
- update_job_status(job_id, JobStatus.PROCESSING, progress=50)
173
 
174
  # Export white mesh
175
  white_mesh_path = export_mesh(mesh, save_folder, textured=False, type='obj')
@@ -178,7 +181,7 @@ def process_generation_job(job_id: str, images: Dict[str, str], options: Dict[st
178
  mesh = face_reduce_worker(mesh)
179
  reduced_mesh_path = export_mesh(mesh, save_folder, textured=False, type='obj')
180
 
181
- update_job_status(job_id, JobStatus.PROCESSING, progress=70)
182
 
183
  # Texture generation if enabled
184
  textured_mesh_path = None
@@ -215,7 +218,7 @@ def process_generation_job(job_id: str, images: Dict[str, str], options: Dict[st
215
  # If texture generation fails, we still have the white mesh as fallback
216
  textured_mesh_path = None
217
 
218
- update_job_status(job_id, JobStatus.PROCESSING, progress=90)
219
 
220
  # Prepare model URLs
221
  model_urls = {}
@@ -228,11 +231,11 @@ def process_generation_job(job_id: str, images: Dict[str, str], options: Dict[st
228
 
229
  # Update job with results
230
  jobs[job_id].model_urls = model_urls
231
- update_job_status(job_id, JobStatus.COMPLETED, progress=100)
232
 
233
  except Exception as e:
234
  logger.error(f"Job {job_id} failed: {e}")
235
- update_job_status(job_id, JobStatus.FAILED, error_message=str(e))
236
 
237
 
238
  MAX_SEED = 1e7
@@ -1245,7 +1248,8 @@ if __name__ == '__main__':
1245
 
1246
  response = {
1247
  "status": job.status.value,
1248
- "progress": job.progress
 
1249
  }
1250
 
1251
  if job.status == JobStatus.COMPLETED:
 
82
  self.job_id = job_id
83
  self.status = JobStatus.QUEUED
84
  self.progress = 0
85
+ self.stage = "queued"
86
  self.start_time = time.time()
87
  self.end_time = None
88
  self.error_message = None
 
102
  return job_id
103
 
104
 
105
+ def update_job_status(job_id: str, status: JobStatus, progress: int = None, stage: str = None, error_message: str = None):
106
  """Update job status and progress."""
107
  if job_id in jobs:
108
  jobs[job_id].status = status
109
  if progress is not None:
110
  jobs[job_id].progress = progress
111
+ if stage is not None:
112
+ jobs[job_id].stage = stage
113
  if error_message is not None:
114
  jobs[job_id].error_message = error_message
115
  if status in [JobStatus.COMPLETED, JobStatus.FAILED]:
 
135
  global face_reduce_worker, tex_pipeline, HAS_TEXTUREGEN, SAVE_DIR
136
 
137
  try:
138
+ update_job_status(job_id, JobStatus.PROCESSING, progress=10, stage="initializing")
139
 
140
  # Convert base64 images to PIL Images
141
  pil_images = {}
 
147
  should_remesh = options.get("should_remesh", True)
148
  should_texture = options.get("should_texture", True)
149
 
150
+ update_job_status(job_id, JobStatus.PROCESSING, progress=20, stage="preprocessing")
151
 
152
  # Generate 3D mesh
153
  # For non-MV mode, use the front image as the main image, or the first available image
 
172
  randomize_seed=False,
173
  )
174
 
175
+ update_job_status(job_id, JobStatus.PROCESSING, progress=50, stage="shape_generation")
176
 
177
  # Export white mesh
178
  white_mesh_path = export_mesh(mesh, save_folder, textured=False, type='obj')
 
181
  mesh = face_reduce_worker(mesh)
182
  reduced_mesh_path = export_mesh(mesh, save_folder, textured=False, type='obj')
183
 
184
+ update_job_status(job_id, JobStatus.PROCESSING, progress=70, stage="face_reduction")
185
 
186
  # Texture generation if enabled
187
  textured_mesh_path = None
 
218
  # If texture generation fails, we still have the white mesh as fallback
219
  textured_mesh_path = None
220
 
221
+ update_job_status(job_id, JobStatus.PROCESSING, progress=90, stage="texture_generation")
222
 
223
  # Prepare model URLs
224
  model_urls = {}
 
231
 
232
  # Update job with results
233
  jobs[job_id].model_urls = model_urls
234
+ update_job_status(job_id, JobStatus.COMPLETED, progress=100, stage="completed")
235
 
236
  except Exception as e:
237
  logger.error(f"Job {job_id} failed: {e}")
238
+ update_job_status(job_id, JobStatus.FAILED, stage="failed", error_message=str(e))
239
 
240
 
241
  MAX_SEED = 1e7
 
1248
 
1249
  response = {
1250
  "status": job.status.value,
1251
+ "progress": job.progress,
1252
+ "stage": job.stage
1253
  }
1254
 
1255
  if job.status == JobStatus.COMPLETED: