anvilinteractiv commited on
Commit
cd0663c
·
verified ·
1 Parent(s): 6aa6a22

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +118 -111
app.py CHANGED
@@ -15,6 +15,7 @@ from fastapi import FastAPI, HTTPException, Depends, File, UploadFile
15
  from fastapi.security import APIKeyHeader
16
  from fastapi.staticfiles import StaticFiles
17
  from pydantic import BaseModel
 
18
 
19
  # Install additional dependencies
20
  subprocess.run("pip install spandrel==0.4.1 --no-deps", shell=True, check=True)
@@ -58,7 +59,7 @@ app.mount("/files", StaticFiles(directory=TMP_DIR), name="files")
58
 
59
  # API key authentication
60
  api_key_header = APIKeyHeader(name="X-API-Key")
61
- VALID_API_KEY = os.getenv("POLYGENIX_API_KEY", "your-secret-api-key")
62
 
63
  async def verify_api_key(api_key: str = Depends(api_key_header)):
64
  if api_key != VALID_API_KEY:
@@ -73,10 +74,88 @@ class GenerateRequest(BaseModel):
73
  simplify: bool = True
74
  target_face_num: int = DEFAULT_FACE_NUMBER
75
 
76
- # Test endpoint
77
- @app.get("/api/test")
78
- async def test_endpoint():
79
- return {"message": "FastAPI is running"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
 
81
  # triposg
82
  from image_process import prepare_image
@@ -105,8 +184,9 @@ mv_adapter_pipe = prepare_pipeline(
105
  dtype=torch.float16,
106
  )
107
  birefnet = AutoModelForImageSegmentation.from_pretrained(
108
- "ZhengPeng7/BiRefNet", trust_remote_code=True
109
- ).to(DEVICE)
 
110
  transform_image = transforms.Compose(
111
  [
112
  transforms.Resize((1024, 1024)),
@@ -121,13 +201,27 @@ if not os.path.exists("checkpoints/RealESRGAN_x2plus.pth"):
121
  if not os.path.exists("checkpoints/big-lama.pt"):
122
  subprocess.run("wget -P checkpoints/ https://github.com/Sanster/models/releases/download/add_big_lama/big-lama.pt", shell=True, check=True)
123
 
 
 
 
 
 
 
 
 
 
124
  def get_random_hex():
125
  random_bytes = os.urandom(8)
126
  random_hex = random_bytes.hex()
127
  return random_hex
128
 
 
 
 
 
 
129
  @spaces.GPU(duration=180)
130
- def run_full(image: str, req=None):
131
  seed = 0
132
  num_inference_steps = 50
133
  guidance_scale = 7.5
@@ -159,6 +253,7 @@ def run_full(image: str, req=None):
159
  torch.cuda.empty_cache()
160
 
161
  height, width = 768, 768
 
162
  cameras = get_orthogonal_camera(
163
  elevation_deg=[0, 0, 0, 0, 89.99, -89.99],
164
  distance=[1.8] * NUM_VIEWS,
@@ -267,20 +362,6 @@ async def generate_3d_model(request: GenerateRequest, image: UploadFile = File(.
267
  if os.path.exists(save_dir):
268
  shutil.rmtree(save_dir)
269
 
270
- def start_session(req: gr.Request):
271
- save_dir = os.path.join(TMP_DIR, str(req.session_hash))
272
- os.makedirs(save_dir, exist_ok=True)
273
- print("start session, mkdir", save_dir)
274
-
275
- def end_session(req: gr.Request):
276
- save_dir = os.path.join(TMP_DIR, str(req.session_hash))
277
- shutil.rmtree(save_dir)
278
-
279
- def get_random_seed(randomize_seed, seed):
280
- if randomize_seed:
281
- seed = random.randint(0, MAX_SEED)
282
- return seed
283
-
284
  @spaces.GPU()
285
  @torch.no_grad()
286
  def run_segmentation(image: str):
@@ -325,6 +406,7 @@ def image_to_3d(
325
  @torch.no_grad()
326
  def run_texture(image: Image, mesh_path: str, seed: int, req: gr.Request):
327
  height, width = 768, 768
 
328
  cameras = get_orthogonal_camera(
329
  elevation_deg=[0, 0, 0, 0, 89.99, -89.99],
330
  distance=[1.8] * NUM_VIEWS,
@@ -385,6 +467,7 @@ def run_texture(image: Image, mesh_path: str, seed: int, req: gr.Request):
385
 
386
  torch.cuda.empty_cache()
387
 
 
388
  mv_image_path = os.path.join(save_dir, f"polygenixai_mv_{get_random_hex()}.png")
389
  make_image_grid(images, rows=1).save(mv_image_path)
390
 
@@ -408,92 +491,14 @@ def run_texture(image: Image, mesh_path: str, seed: int, req: gr.Request):
408
 
409
  return textured_glb_path
410
 
411
- HEADER = """
412
- # 🌌 PolyGenixAI: Craft 3D Worlds with Cosmic Precision
413
- ## Unleash Infinite Creativity with AI-Powered 3D Generation by AnvilInteractive Solutions
414
- <p style="font-size: 1.1em; color: #A78BFA;">By <a href="https://www.anvilinteractive.com/" style="color: #A78BFA; text-decoration: none; font-weight: bold;">AnvilInteractive Solutions</a></p>
415
- ## 🚀 Launch Your Creation:
416
- 1. **Upload an Image** (clear, single-object images shine brightest)
417
- 2. **Choose a Style Filter** to infuse your unique vision
418
- 3. Click **Generate 3D Model** to sculpt your mesh
419
- 4. Click **Apply Texture** to bring your model to life
420
- 5. **Download GLB** to share your masterpiece
421
- <p style="font-size: 0.9em; margin-top: 10px; color: #D1D5DB;">Powered by cutting-edge AI and multi-view technology from AnvilInteractive Solutions. Join our <a href="https://www.anvilinteractive.com/community" style="color: #A78BFA; text-decoration: none;">PolyGenixAI Community</a> to connect with creators and spark inspiration.</p>
422
- <style>
423
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');
424
- body {
425
- background-color: #1A1A1A !important;
426
- font-family: 'Inter', sans-serif !important;
427
- color: #D1D5DB !important;
428
- }
429
- .gr-panel {
430
- background-color: #2D2D2D !important;
431
- border: 1px solid #7C3AED !important;
432
- border-radius: 12px !important;
433
- padding: 20px !important;
434
- box-shadow: 0 4px 10px rgba(124, 58, 237, 0.2) !important;
435
- }
436
- .gr-button-primary {
437
- background: linear-gradient(45deg, #7C3AED, #A78BFA) !important;
438
- color: white !important;
439
- border: none !important;
440
- border-radius: 8px !important;
441
- padding: 12px 24px !important;
442
- font-weight: 600 !important;
443
- transition: transform 0.2s, box-shadow 0.2s !important;
444
- }
445
- .gr-button-primary:hover {
446
- transform: translateY(-2px) !important;
447
- box-shadow: 0 4px 12px rgba(124, 58, 237, 0.5) !important;
448
- }
449
- .gr-button-secondary {
450
- background-color: #4B4B4B !important;
451
- color: #D1D5DB !important;
452
- border: 1px solid #A78BFA !important;
453
- border-radius: 8px !important;
454
- padding: 10px 20px !important;
455
- transition: transform 0.2s !important;
456
- }
457
- .gr-button-secondary:hover {
458
- transform: translateY(-1px) !important;
459
- background-color: #6B6B6B !important;
460
- }
461
- .gr-accordion {
462
- background-color: #2D2D2D !important;
463
- border-radius: 8px !important;
464
- border: 1px solid #7C3AED !important;
465
- }
466
- .gr-tab {
467
- background-color: #2D2D2D !important;
468
- color: #A78BFA !important;
469
- border: 1px solid #7C3AED !important;
470
- border-radius: 8px !important;
471
- margin: 5px !important;
472
- }
473
- .gr-tab:hover, .gr-tab-selected {
474
- background: linear-gradient(45deg, #7C3AED, #A78BFA) !important;
475
- color: white !important;
476
- }
477
- .gr-slider input[type=range]::-webkit-slider-thumb {
478
- background-color: #7C3AED !important;
479
- border: 2px solid #A78BFA !important;
480
- }
481
- .gr-dropdown {
482
- background-color: #2D2D2D !important;
483
- color: #D1D5DB !important;
484
- border: 1px solid #A78BFA !important;
485
- border-radius: 8px !important;
486
- }
487
- h1, h3 {
488
- color: #A78BFA !important;
489
- text-shadow: 0 0 10px rgba(124, 58, 237, 0.5) !important;
490
- }
491
- </style>
492
- """
493
-
494
- # Gradio interface
495
  with gr.Blocks(title="PolyGenixAI", css="body { background-color: #1A1A1A; } .gr-panel { background-color: #2D2D2D; }") as demo:
496
  gr.Markdown(HEADER)
 
 
 
 
 
497
  with gr.Tabs(elem_classes="gr-tab"):
498
  with gr.Tab("Create 3D Model"):
499
  with gr.Row():
@@ -546,10 +551,12 @@ with gr.Blocks(title="PolyGenixAI", css="body { background-color: #1A1A1A; } .gr
546
  )
547
  gen_button = gr.Button("Generate 3D Model", variant="primary", elem_classes="gr-button-primary")
548
  gen_texture_button = gr.Button("Apply Texture", variant="secondary", interactive=False, elem_classes="gr-button-secondary")
 
549
  with gr.Column(scale=1):
550
  model_output = gr.Model3D(label="3D Model Preview", interactive=False, height=400, elem_classes="gr-panel")
551
  textured_model_output = gr.Model3D(label="Textured 3D Model", interactive=False, height=400, elem_classes="gr-panel")
552
  download_button = gr.Button("Download GLB", variant="secondary", elem_classes="gr-button-secondary")
 
553
  with gr.Tab("Cosmic Gallery"):
554
  gr.Markdown("### Discover Stellar Creations")
555
  gr.Examples(
@@ -563,6 +570,7 @@ with gr.Blocks(title="PolyGenixAI", css="body { background-color: #1A1A1A; } .gr
563
  cache_examples=True,
564
  )
565
  gr.Markdown("Connect with creators in our <a href='https://www.anvilinteractive.com/community' style='color: #A78BFA; text-decoration: none;'>PolyGenixAI Cosmic Community</a>!")
 
566
  gen_button.click(
567
  run_segmentation,
568
  inputs=[image_prompts],
@@ -583,17 +591,16 @@ with gr.Blocks(title="PolyGenixAI", css="body { background-color: #1A1A1A; } .gr
583
  ],
584
  outputs=[model_output]
585
  ).then(lambda: gr.Button(interactive=True), outputs=[gen_texture_button])
 
586
  gen_texture_button.click(
587
  run_texture,
588
  inputs=[image_prompts, model_output, seed],
589
  outputs=[textured_model_output]
590
  )
 
591
  demo.load(start_session)
592
  demo.unload(end_session)
593
 
594
- # Mount Gradio to FastAPI
595
- app = gr.mount_gradio_app(app, demo, path="/")
596
-
597
  if __name__ == "__main__":
598
- import uvicorn
599
- uvicorn.run(app, host="0.0.0.0", port=7860)
 
15
  from fastapi.security import APIKeyHeader
16
  from fastapi.staticfiles import StaticFiles
17
  from pydantic import BaseModel
18
+ import uvicorn
19
 
20
  # Install additional dependencies
21
  subprocess.run("pip install spandrel==0.4.1 --no-deps", shell=True, check=True)
 
59
 
60
  # API key authentication
61
  api_key_header = APIKeyHeader(name="X-API-Key")
62
+ VALID_API_KEY = os.getenv("POLYGENIX_API_KEY", "your-secret-api-key") # Set in Hugging Face Space secrets
63
 
64
  async def verify_api_key(api_key: str = Depends(api_key_header)):
65
  if api_key != VALID_API_KEY:
 
74
  simplify: bool = True
75
  target_face_num: int = DEFAULT_FACE_NUMBER
76
 
77
+ HEADER = """
78
+ # 🌌 PolyGenixAI: Craft 3D Worlds with Cosmic Precision
79
+ ## Unleash Infinite Creativity with AI-Powered 3D Generation by AnvilInteractive Solutions
80
+ <p style="font-size: 1.1em; color: #A78BFA;">By <a href="https://www.anvilinteractive.com/" style="color: #A78BFA; text-decoration: none; font-weight: bold;">AnvilInteractive Solutions</a></p>
81
+ ## 🚀 Launch Your Creation:
82
+ 1. **Upload an Image** (clear, single-object images shine brightest)
83
+ 2. **Choose a Style Filter** to infuse your unique vision
84
+ 3. Click **Generate 3D Model** to sculpt your mesh
85
+ 4. Click **Apply Texture** to bring your model to life
86
+ 5. **Download GLB** to share your masterpiece
87
+ <p style="font-size: 0.9em; margin-top: 10px; color: #D1D5DB;">Powered by cutting-edge AI and multi-view technology from AnvilInteractive Solutions. Join our <a href="https://www.anvilinteractive.com/community" style="color: #A78BFA; text-decoration: none;">PolyGenixAI Community</a> to connect with creators and spark inspiration.</p>
88
+ <style>
89
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');
90
+ body {
91
+ background-color: #1A1A1A !important;
92
+ font-family: 'Inter', sans-serif !important;
93
+ color: #D1D5DB !important;
94
+ }
95
+ .gr-panel {
96
+ background-color: #2D2D2D !important;
97
+ border: 1px solid #7C3AED !important;
98
+ border-radius: 12px !important;
99
+ padding: 20px !important;
100
+ box-shadow: 0 4px 10px rgba(124, 58, 237, 0.2) !important;
101
+ }
102
+ .gr-button-primary {
103
+ background: linear-gradient(45deg, #7C3AED, #A78BFA) !important;
104
+ color: white !important;
105
+ border: none !important;
106
+ border-radius: 8px !important;
107
+ padding: 12px 24px !important;
108
+ font-weight: 600 !important;
109
+ transition: transform 0.2s, box-shadow 0.2s !important;
110
+ }
111
+ .gr-button-primary:hover {
112
+ transform: translateY(-2px) !important;
113
+ box-shadow: 0 4px 12px rgba(124, 58, 237, 0.5) !important;
114
+ }
115
+ .gr-button-secondary {
116
+ background-color: #4B4B4B !important;
117
+ color: #D1D5DB !important;
118
+ border: 1px solid #A78BFA !important;
119
+ border-radius: 8px !important;
120
+ padding: 10px 20px !important;
121
+ transition: transform 0.2s !important;
122
+ }
123
+ .gr-button-secondary:hover {
124
+ transform: translateY(-1px) !important;
125
+ background-color: #6B6B6B !important;
126
+ }
127
+ .gr-accordion {
128
+ background-color: #2D2D2D !important;
129
+ border-radius: 8px !important;
130
+ border: 1px solid #7C3AED !important;
131
+ }
132
+ .gr-tab {
133
+ background-color: #2D2D2D !important;
134
+ color: #A78BFA !important;
135
+ border: 1px solid #7C3AED !important;
136
+ border-radius: 8px !important;
137
+ margin: 5px !important;
138
+ }
139
+ .gr-tab:hover, .gr-tab-selected {
140
+ background: linear-gradient(45deg, #7C3AED, #A78BFA) !important;
141
+ color: white !important;
142
+ }
143
+ .gr-slider input[type=range]::-webkit-slider-thumb {
144
+ background-color: #7C3AED !important;
145
+ border: 2px solid #A78BFA !important;
146
+ }
147
+ .gr-dropdown {
148
+ background-color: #2D2D2D !important;
149
+ color: #D1D5DB !important;
150
+ border: 1px solid #A78BFA !important;
151
+ border-radius: 8px !important;
152
+ }
153
+ h1, h3 {
154
+ color: #A78BFA !important;
155
+ text-shadow: 0 0 10px rgba(124, 58, 237, 0.5) !important;
156
+ }
157
+ </style>
158
+ """
159
 
160
  # triposg
161
  from image_process import prepare_image
 
184
  dtype=torch.float16,
185
  )
186
  birefnet = AutoModelForImageSegmentation.from_pretrained(
187
+ "ZhengPeng7/BiRefNet", trust_remote_code=True
188
+ )
189
+ birefnet.to(DEVICE)
190
  transform_image = transforms.Compose(
191
  [
192
  transforms.Resize((1024, 1024)),
 
201
  if not os.path.exists("checkpoints/big-lama.pt"):
202
  subprocess.run("wget -P checkpoints/ https://github.com/Sanster/models/releases/download/add_big_lama/big-lama.pt", shell=True, check=True)
203
 
204
+ def start_session(req: gr.Request):
205
+ save_dir = os.path.join(TMP_DIR, str(req.session_hash))
206
+ os.makedirs(save_dir, exist_ok=True)
207
+ print("start session, mkdir", save_dir)
208
+
209
+ def end_session(req: gr.Request):
210
+ save_dir = os.path.join(TMP_DIR, str(req.session_hash))
211
+ shutil.rmtree(save_dir)
212
+
213
  def get_random_hex():
214
  random_bytes = os.urandom(8)
215
  random_hex = random_bytes.hex()
216
  return random_hex
217
 
218
+ def get_random_seed(randomize_seed, seed):
219
+ if randomize_seed:
220
+ seed = random.randint(0, MAX_SEED)
221
+ return seed
222
+
223
  @spaces.GPU(duration=180)
224
+ def run_full(image: str, req: gr.Request):
225
  seed = 0
226
  num_inference_steps = 50
227
  guidance_scale = 7.5
 
253
  torch.cuda.empty_cache()
254
 
255
  height, width = 768, 768
256
+ # Prepare cameras
257
  cameras = get_orthogonal_camera(
258
  elevation_deg=[0, 0, 0, 0, 89.99, -89.99],
259
  distance=[1.8] * NUM_VIEWS,
 
362
  if os.path.exists(save_dir):
363
  shutil.rmtree(save_dir)
364
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
365
  @spaces.GPU()
366
  @torch.no_grad()
367
  def run_segmentation(image: str):
 
406
  @torch.no_grad()
407
  def run_texture(image: Image, mesh_path: str, seed: int, req: gr.Request):
408
  height, width = 768, 768
409
+ # Prepare cameras
410
  cameras = get_orthogonal_camera(
411
  elevation_deg=[0, 0, 0, 0, 89.99, -89.99],
412
  distance=[1.8] * NUM_VIEWS,
 
467
 
468
  torch.cuda.empty_cache()
469
 
470
+ save_dir = os.path.join(TMP_DIR, str(req.session_hash))
471
  mv_image_path = os.path.join(save_dir, f"polygenixai_mv_{get_random_hex()}.png")
472
  make_image_grid(images, rows=1).save(mv_image_path)
473
 
 
491
 
492
  return textured_glb_path
493
 
494
+ # Gradio interface (unchanged)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
495
  with gr.Blocks(title="PolyGenixAI", css="body { background-color: #1A1A1A; } .gr-panel { background-color: #2D2D2D; }") as demo:
496
  gr.Markdown(HEADER)
497
+
498
+ @app.get("/api/test")
499
+ async def test_endpoint():
500
+ return {"message": "FastAPI is running"}
501
+
502
  with gr.Tabs(elem_classes="gr-tab"):
503
  with gr.Tab("Create 3D Model"):
504
  with gr.Row():
 
551
  )
552
  gen_button = gr.Button("Generate 3D Model", variant="primary", elem_classes="gr-button-primary")
553
  gen_texture_button = gr.Button("Apply Texture", variant="secondary", interactive=False, elem_classes="gr-button-secondary")
554
+
555
  with gr.Column(scale=1):
556
  model_output = gr.Model3D(label="3D Model Preview", interactive=False, height=400, elem_classes="gr-panel")
557
  textured_model_output = gr.Model3D(label="Textured 3D Model", interactive=False, height=400, elem_classes="gr-panel")
558
  download_button = gr.Button("Download GLB", variant="secondary", elem_classes="gr-button-secondary")
559
+
560
  with gr.Tab("Cosmic Gallery"):
561
  gr.Markdown("### Discover Stellar Creations")
562
  gr.Examples(
 
570
  cache_examples=True,
571
  )
572
  gr.Markdown("Connect with creators in our <a href='https://www.anvilinteractive.com/community' style='color: #A78BFA; text-decoration: none;'>PolyGenixAI Cosmic Community</a>!")
573
+
574
  gen_button.click(
575
  run_segmentation,
576
  inputs=[image_prompts],
 
591
  ],
592
  outputs=[model_output]
593
  ).then(lambda: gr.Button(interactive=True), outputs=[gen_texture_button])
594
+
595
  gen_texture_button.click(
596
  run_texture,
597
  inputs=[image_prompts, model_output, seed],
598
  outputs=[textured_model_output]
599
  )
600
+
601
  demo.load(start_session)
602
  demo.unload(end_session)
603
 
604
+ # Run both Gradio and FastAPI
 
 
605
  if __name__ == "__main__":
606
+ demo.launch(server_name="0.0.0.0", server_port=7860)