LogicGoInfotechSpaces commited on
Commit
1a68f4f
·
verified ·
1 Parent(s): 3eea63f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +105 -56
app.py CHANGED
@@ -51,12 +51,20 @@ DO_SPACES_KEY = os.getenv("DO_SPACES_KEY")
51
  DO_SPACES_SECRET = os.getenv("DO_SPACES_SECRET")
52
  DO_SPACES_BUCKET = os.getenv("DO_SPACES_BUCKET")
53
 
54
- # NEW admin DB
55
  ADMIN_MONGO_URL = os.getenv("ADMIN_MONGO_URL")
56
- admin_client = AsyncIOMotorClient(ADMIN_MONGO_URL)
57
- admin_db = admin_client.adminPanel
58
- subcategories_col = admin_db.subcategories
59
- media_clicks_col = admin_db.media_clicks
 
 
 
 
 
 
 
 
60
 
61
  # OLD logs DB
62
  MONGODB_URL = os.getenv("MONGODB_URL")
@@ -65,67 +73,88 @@ database = None
65
 
66
  # --------------------- Download Models ---------------------
67
  def download_models():
68
- logger.info("Downloading models...")
69
- inswapper_path = hf_hub_download(
70
- repo_id=REPO_ID,
71
- filename="models/inswapper_128.onnx",
72
- repo_type="model",
73
- local_dir=MODELS_DIR,
74
- token=HF_TOKEN
75
- )
76
-
77
- buffalo_files = ["1k3d68.onnx", "2d106det.onnx", "genderage.onnx", "det_10g.onnx", "w600k_r50.onnx"]
78
- for f in buffalo_files:
79
- hf_hub_download(
80
  repo_id=REPO_ID,
81
- filename=f"models/buffalo_l/" + f,
82
  repo_type="model",
83
  local_dir=MODELS_DIR,
84
  token=HF_TOKEN
85
  )
86
 
87
- logger.info("Models downloaded.")
88
- return inswapper_path
89
-
 
 
 
 
 
 
90
 
91
- inswapper_path = download_models()
 
 
 
 
92
 
93
- # --------------------- Face Analysis + Swapper ---------------------
94
- providers = ['CUDAExecutionProvider', 'CPUExecutionProvider']
95
- face_analysis_app = FaceAnalysis(name="buffalo_l", root=MODELS_DIR, providers=providers)
96
- face_analysis_app.prepare(ctx_id=0, det_size=(640, 640))
97
- swapper = insightface.model_zoo.get_model(inswapper_path, providers=providers)
 
 
 
 
 
 
 
 
 
 
98
 
99
  # --------------------- CodeFormer ---------------------
100
  CODEFORMER_PATH = "CodeFormer/inference_codeformer.py"
101
 
102
- # def ensure_codeformer():
103
- # if not os.path.exists("CodeFormer"):
104
- # subprocess.run("git clone https://github.com/sczhou/CodeFormer.git", shell=True, check=True)
105
- # subprocess.run("pip install -r CodeFormer/requirements.txt", shell=True, check=True)
106
- # subprocess.run("python CodeFormer/basicsr/setup.py develop", shell=True, check=True)
107
- # subprocess.run("python CodeFormer/scripts/download_pretrained_models.py facelib", shell=True, check=True)
108
- # subprocess.run("python CodeFormer/scripts/download_pretrained_models.py CodeFormer", shell=True, check=True)
109
  def ensure_codeformer():
110
- if not os.path.exists("CodeFormer"):
111
- subprocess.run("git clone https://github.com/sczhou/CodeFormer.git", shell=True, check=True)
112
- subprocess.run("pip install -r CodeFormer/requirements.txt", shell=True, check=True)
113
-
114
- # Always ensure BasicSR is installed from local directory
115
- # This is needed for Hugging Face Spaces where BasicSR can't be installed from GitHub
116
- if os.path.exists("CodeFormer/basicsr/setup.py"):
117
- subprocess.run("python CodeFormer/basicsr/setup.py develop", shell=True, check=True)
118
-
119
- # Install realesrgan after BasicSR is installed (realesrgan depends on BasicSR)
120
- # This must be done after BasicSR installation to avoid PyPI install issues
121
  try:
122
- import realesrgan
123
- except ImportError:
124
- subprocess.run("pip install --no-cache-dir realesrgan", shell=True, check=True)
125
-
126
- if not os.path.exists("CodeFormer"):
127
- subprocess.run("python CodeFormer/scripts/download_pretrained_models.py facelib", shell=True, check=True)
128
- subprocess.run("python CodeFormer/scripts/download_pretrained_models.py CodeFormer", shell=True, check=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
 
130
  ensure_codeformer()
131
 
@@ -545,10 +574,18 @@ fastapi_app = FastAPI()
545
  @fastapi_app.on_event("startup")
546
  async def startup_db():
547
  global client, database
548
- logger.info("Initializing MongoDB for API logs...")
549
- client = AsyncIOMotorClient(MONGODB_URL)
550
- database = client.FaceSwap
551
- logger.info("MongoDB initialized for API logs")
 
 
 
 
 
 
 
 
552
 
553
  @fastapi_app.on_event("shutdown")
554
  async def shutdown_db():
@@ -660,6 +697,8 @@ def multi_face_swap(src_img, tgt_img):
660
 
661
  for src_face, _ in pairs:
662
  # 🔁 re-detect current target faces
 
 
663
  current_faces = face_analysis_app.get(result_img)
664
  current_faces = sorted(current_faces, key=face_sort_key)
665
 
@@ -670,6 +709,8 @@ def multi_face_swap(src_img, tgt_img):
670
 
671
  target_face = candidates[0]
672
 
 
 
673
  result_img = swapper.get(
674
  result_img,
675
  target_face,
@@ -696,10 +737,14 @@ def face_swap_and_enhance(src_img, tgt_img, temp_dir=None):
696
 
697
  src_faces = face_analysis_app.get(src_bgr)
698
  tgt_faces = face_analysis_app.get(tgt_bgr)
 
 
699
  if not src_faces or not tgt_faces:
700
  return None, None, "❌ Face not detected in one of the images"
701
 
702
  swapped_path = os.path.join(temp_dir, f"swapped_{uuid.uuid4().hex[:8]}.jpg")
 
 
703
  swapped_bgr = swapper.get(tgt_bgr, tgt_faces[0], src_faces[0])
704
  if swapped_bgr is None:
705
  return None, None, "❌ Face swap failed"
@@ -1590,9 +1635,13 @@ async def face_swap_api(
1590
  with swap_lock:
1591
  result_img = tgt_bgr.copy()
1592
  for src_face, _ in pairs:
 
 
1593
  current_faces = sorted(face_analysis_app.get(result_img), key=face_sort_key)
1594
  candidates = [f for f in current_faces if f.gender == src_face.gender] or current_faces
1595
  target_face = candidates[0]
 
 
1596
  result_img = swapper.get(result_img, target_face, src_face, paste_back=True)
1597
 
1598
  result_rgb = cv2.cvtColor(result_img, cv2.COLOR_BGR2RGB)
 
51
  DO_SPACES_SECRET = os.getenv("DO_SPACES_SECRET")
52
  DO_SPACES_BUCKET = os.getenv("DO_SPACES_BUCKET")
53
 
54
+ # NEW admin DB (with error handling for missing env vars)
55
  ADMIN_MONGO_URL = os.getenv("ADMIN_MONGO_URL")
56
+ admin_client = None
57
+ admin_db = None
58
+ subcategories_col = None
59
+ media_clicks_col = None
60
+ if ADMIN_MONGO_URL:
61
+ try:
62
+ admin_client = AsyncIOMotorClient(ADMIN_MONGO_URL)
63
+ admin_db = admin_client.adminPanel
64
+ subcategories_col = admin_db.subcategories
65
+ media_clicks_col = admin_db.media_clicks
66
+ except Exception as e:
67
+ logger.warning(f"MongoDB admin connection failed (optional): {e}")
68
 
69
  # OLD logs DB
70
  MONGODB_URL = os.getenv("MONGODB_URL")
 
73
 
74
  # --------------------- Download Models ---------------------
75
  def download_models():
76
+ try:
77
+ logger.info("Downloading models...")
78
+ inswapper_path = hf_hub_download(
 
 
 
 
 
 
 
 
 
79
  repo_id=REPO_ID,
80
+ filename="models/inswapper_128.onnx",
81
  repo_type="model",
82
  local_dir=MODELS_DIR,
83
  token=HF_TOKEN
84
  )
85
 
86
+ buffalo_files = ["1k3d68.onnx", "2d106det.onnx", "genderage.onnx", "det_10g.onnx", "w600k_r50.onnx"]
87
+ for f in buffalo_files:
88
+ hf_hub_download(
89
+ repo_id=REPO_ID,
90
+ filename=f"models/buffalo_l/" + f,
91
+ repo_type="model",
92
+ local_dir=MODELS_DIR,
93
+ token=HF_TOKEN
94
+ )
95
 
96
+ logger.info("Models downloaded successfully.")
97
+ return inswapper_path
98
+ except Exception as e:
99
+ logger.error(f"Model download failed: {e}")
100
+ raise
101
 
102
+ try:
103
+ inswapper_path = download_models()
104
+
105
+ # --------------------- Face Analysis + Swapper ---------------------
106
+ providers = ['CUDAExecutionProvider', 'CPUExecutionProvider']
107
+ face_analysis_app = FaceAnalysis(name="buffalo_l", root=MODELS_DIR, providers=providers)
108
+ face_analysis_app.prepare(ctx_id=0, det_size=(640, 640))
109
+ swapper = insightface.model_zoo.get_model(inswapper_path, providers=providers)
110
+ logger.info("Face analysis models loaded successfully")
111
+ except Exception as e:
112
+ logger.error(f"Failed to initialize face analysis models: {e}")
113
+ # Set defaults to prevent crash
114
+ inswapper_path = None
115
+ face_analysis_app = None
116
+ swapper = None
117
 
118
  # --------------------- CodeFormer ---------------------
119
  CODEFORMER_PATH = "CodeFormer/inference_codeformer.py"
120
 
 
 
 
 
 
 
 
121
  def ensure_codeformer():
 
 
 
 
 
 
 
 
 
 
 
122
  try:
123
+ if not os.path.exists("CodeFormer"):
124
+ logger.info("CodeFormer not found, cloning repository...")
125
+ subprocess.run("git clone https://github.com/sczhou/CodeFormer.git", shell=True, check=True)
126
+ subprocess.run("pip install -r CodeFormer/requirements.txt", shell=True, check=False) # Non-critical deps
127
+
128
+ # Always ensure BasicSR is installed from local directory
129
+ # This is needed for Hugging Face Spaces where BasicSR can't be installed from GitHub
130
+ if os.path.exists("CodeFormer/basicsr/setup.py"):
131
+ logger.info("Installing BasicSR from local directory...")
132
+ subprocess.run("python CodeFormer/basicsr/setup.py develop", shell=True, check=True)
133
+ logger.info("BasicSR installed successfully")
134
+
135
+ # Install realesrgan after BasicSR is installed (realesrgan depends on BasicSR)
136
+ # This must be done after BasicSR installation to avoid PyPI install issues
137
+ try:
138
+ import realesrgan
139
+ logger.info("RealESRGAN already installed")
140
+ except ImportError:
141
+ logger.info("Installing RealESRGAN...")
142
+ subprocess.run("pip install --no-cache-dir realesrgan", shell=True, check=True)
143
+ logger.info("RealESRGAN installed successfully")
144
+
145
+ # Download models if CodeFormer exists (fixed logic)
146
+ if os.path.exists("CodeFormer"):
147
+ try:
148
+ subprocess.run("python CodeFormer/scripts/download_pretrained_models.py facelib", shell=True, check=False, timeout=300)
149
+ except (subprocess.TimeoutExpired, subprocess.CalledProcessError):
150
+ logger.warning("Failed to download facelib models (optional)")
151
+ try:
152
+ subprocess.run("python CodeFormer/scripts/download_pretrained_models.py CodeFormer", shell=True, check=False, timeout=300)
153
+ except (subprocess.TimeoutExpired, subprocess.CalledProcessError):
154
+ logger.warning("Failed to download CodeFormer models (optional)")
155
+ except Exception as e:
156
+ logger.error(f"CodeFormer setup failed: {e}")
157
+ logger.warning("Continuing without CodeFormer features...")
158
 
159
  ensure_codeformer()
160
 
 
574
  @fastapi_app.on_event("startup")
575
  async def startup_db():
576
  global client, database
577
+ if MONGODB_URL:
578
+ try:
579
+ logger.info("Initializing MongoDB for API logs...")
580
+ client = AsyncIOMotorClient(MONGODB_URL)
581
+ database = client.FaceSwap
582
+ logger.info("MongoDB initialized for API logs")
583
+ except Exception as e:
584
+ logger.warning(f"MongoDB connection failed (optional): {e}")
585
+ client = None
586
+ database = None
587
+ else:
588
+ logger.warning("MONGODB_URL not set, skipping MongoDB initialization")
589
 
590
  @fastapi_app.on_event("shutdown")
591
  async def shutdown_db():
 
697
 
698
  for src_face, _ in pairs:
699
  # 🔁 re-detect current target faces
700
+ if face_analysis_app is None:
701
+ raise ValueError("Face analysis models not initialized. Please ensure models are downloaded.")
702
  current_faces = face_analysis_app.get(result_img)
703
  current_faces = sorted(current_faces, key=face_sort_key)
704
 
 
709
 
710
  target_face = candidates[0]
711
 
712
+ if swapper is None:
713
+ raise ValueError("Face swap models not initialized. Please ensure models are downloaded.")
714
  result_img = swapper.get(
715
  result_img,
716
  target_face,
 
737
 
738
  src_faces = face_analysis_app.get(src_bgr)
739
  tgt_faces = face_analysis_app.get(tgt_bgr)
740
+ if face_analysis_app is None:
741
+ return None, None, "❌ Face analysis models not initialized. Please ensure models are downloaded."
742
  if not src_faces or not tgt_faces:
743
  return None, None, "❌ Face not detected in one of the images"
744
 
745
  swapped_path = os.path.join(temp_dir, f"swapped_{uuid.uuid4().hex[:8]}.jpg")
746
+ if swapper is None:
747
+ return None, None, "❌ Face swap models not initialized. Please ensure models are downloaded."
748
  swapped_bgr = swapper.get(tgt_bgr, tgt_faces[0], src_faces[0])
749
  if swapped_bgr is None:
750
  return None, None, "❌ Face swap failed"
 
1635
  with swap_lock:
1636
  result_img = tgt_bgr.copy()
1637
  for src_face, _ in pairs:
1638
+ if face_analysis_app is None:
1639
+ raise HTTPException(status_code=500, detail="Face analysis models not initialized. Please ensure models are downloaded.")
1640
  current_faces = sorted(face_analysis_app.get(result_img), key=face_sort_key)
1641
  candidates = [f for f in current_faces if f.gender == src_face.gender] or current_faces
1642
  target_face = candidates[0]
1643
+ if swapper is None:
1644
+ raise HTTPException(status_code=500, detail="Face swap models not initialized. Please ensure models are downloaded.")
1645
  result_img = swapper.get(result_img, target_face, src_face, paste_back=True)
1646
 
1647
  result_rgb = cv2.cvtColor(result_img, cv2.COLOR_BGR2RGB)