HariLogicgo commited on
Commit
eb78ab5
·
1 Parent(s): b80a82c

modifief app.py for private repo

Browse files
Files changed (1) hide show
  1. app.py +36 -70
app.py CHANGED
@@ -12,8 +12,9 @@ import insightface
12
  from insightface.app import FaceAnalysis
13
  from huggingface_hub import hf_hub_download
14
 
15
- from fastapi import FastAPI, UploadFile, File, HTTPException, Request, Response
16
  from fastapi.responses import RedirectResponse
 
17
  from pydantic import BaseModel
18
  from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorGridFSBucket
19
  from bson import ObjectId
@@ -22,15 +23,11 @@ import uvicorn
22
  import gradio as gr
23
  from gradio import mount_gradio_app
24
 
25
- # -------------------------------------------------
26
- # Logging
27
- # -------------------------------------------------
28
  logging.basicConfig(level=logging.INFO)
29
  logger = logging.getLogger(__name__)
30
 
31
- # -------------------------------------------------
32
- # Paths
33
- # -------------------------------------------------
34
  REPO_ID = "HariLogicgo/face_swap_models"
35
  BASE_DIR = "./workspace"
36
  UPLOAD_DIR = os.path.join(BASE_DIR, "uploads")
@@ -41,17 +38,21 @@ os.makedirs(UPLOAD_DIR, exist_ok=True)
41
  os.makedirs(RESULT_DIR, exist_ok=True)
42
  os.makedirs(MODELS_DIR, exist_ok=True)
43
 
44
- # -------------------------------------------------
45
- # Download models
46
- # -------------------------------------------------
 
 
47
  def download_models():
48
- logger.info("Downloading models...")
49
  inswapper_path = hf_hub_download(
50
  repo_id=REPO_ID,
51
  filename="models/inswapper_128.onnx",
52
  repo_type="model",
53
- local_dir=MODELS_DIR
 
54
  )
 
55
  buffalo_files = [
56
  "1k3d68.onnx",
57
  "2d106det.onnx",
@@ -64,24 +65,21 @@ def download_models():
64
  repo_id=REPO_ID,
65
  filename=f"models/buffalo_l/{f}",
66
  repo_type="model",
67
- local_dir=MODELS_DIR
 
68
  )
69
  logger.info("Models downloaded successfully")
70
  return inswapper_path
71
 
72
  inswapper_path = download_models()
73
 
74
- # -------------------------------------------------
75
- # Face Analysis + Swapper
76
- # -------------------------------------------------
77
  providers = ['CUDAExecutionProvider', 'CPUExecutionProvider']
78
  face_analysis_app = FaceAnalysis(name="buffalo_l", root=MODELS_DIR, providers=providers)
79
  face_analysis_app.prepare(ctx_id=0, det_size=(640, 640))
80
  swapper = insightface.model_zoo.get_model(inswapper_path, providers=providers)
81
 
82
- # -------------------------------------------------
83
- # CodeFormer setup
84
- # -------------------------------------------------
85
  CODEFORMER_PATH = "CodeFormer/inference_codeformer.py"
86
 
87
  def ensure_codeformer():
@@ -94,9 +92,7 @@ def ensure_codeformer():
94
 
95
  ensure_codeformer()
96
 
97
- # -------------------------------------------------
98
- # MongoDB + GridFS setup
99
- # -------------------------------------------------
100
  MONGODB_URL = os.getenv(
101
  "MONGODB_URL",
102
  "mongodb+srv://harilogicgo_db_user:[email protected]/?retryWrites=true&w=majority&appName=Cluster0"
@@ -106,9 +102,7 @@ client: AsyncIOMotorClient = None
106
  database = None
107
  fs_bucket: AsyncIOMotorGridFSBucket = None
108
 
109
- # -------------------------------------------------
110
- # FastAPI App
111
- # -------------------------------------------------
112
  fastapi_app = FastAPI()
113
 
114
  @fastapi_app.on_event("startup")
@@ -127,39 +121,17 @@ async def shutdown_db():
127
  client.close()
128
  logger.info("MongoDB connection closed")
129
 
130
- # -------------------------------------------------
131
- # 🔐 Global Auth Middleware
132
- # -------------------------------------------------
133
- PUBLIC_PATHS = ["/health"]
134
-
135
- API_SECRET_TOKEN = os.getenv("API_SECRET_TOKEN")
136
- if not API_SECRET_TOKEN:
137
- raise RuntimeError("❌ API_SECRET_TOKEN not set in environment!")
138
-
139
- @fastapi_app.middleware("http")
140
- async def auth_middleware(request: Request, call_next):
141
- path = request.url.path
142
- if path in PUBLIC_PATHS: # exact match
143
- return await call_next(request)
144
-
145
- auth_header = request.headers.get("Authorization")
146
- if not auth_header or not auth_header.startswith("Bearer "):
147
- return Response(content="Missing Bearer token", status_code=401)
148
-
149
- token = auth_header.split("Bearer ")[1]
150
- if token != API_SECRET_TOKEN:
151
- return Response(content="Invalid token", status_code=403)
152
 
153
- return await call_next(request)
 
 
 
154
 
155
- # -------------------------------------------------
156
- # Lock for face swap
157
- # -------------------------------------------------
158
  swap_lock = threading.Lock()
159
 
160
- # -------------------------------------------------
161
- # Pipeline Function
162
- # -------------------------------------------------
163
  def face_swap_and_enhance(src_img, tgt_img):
164
  try:
165
  with swap_lock:
@@ -201,9 +173,7 @@ def face_swap_and_enhance(src_img, tgt_img):
201
  except Exception as e:
202
  return None, None, f"❌ Error: {str(e)}"
203
 
204
- # -------------------------------------------------
205
- # Gradio UI
206
- # -------------------------------------------------
207
  with gr.Blocks() as demo:
208
  gr.Markdown("Face Swap")
209
 
@@ -222,24 +192,22 @@ with gr.Blocks() as demo:
222
 
223
  btn.click(process, [src_input, tgt_input], [output_img, download, error_box])
224
 
225
- # -------------------------------------------------
226
- # API Endpoints
227
- # -------------------------------------------------
228
  @fastapi_app.get("/")
229
  def root():
230
  return RedirectResponse("/gradio")
231
 
232
- @fastapi_app.get("/health")
233
  async def health():
234
  return {"status": "healthy"}
235
 
236
- @fastapi_app.post("/source")
237
  async def upload_source(image: UploadFile = File(...)):
238
  contents = await image.read()
239
  file_id = await fs_bucket.upload_from_stream(image.filename, contents, metadata={"type": "source"})
240
  return {"source_id": str(file_id)}
241
 
242
- @fastapi_app.get("/targets")
243
  async def list_targets():
244
  files = []
245
  async for file in database.fs.files.find({"metadata.type": "target", "metadata.predefined": True}):
@@ -249,7 +217,7 @@ async def list_targets():
249
  })
250
  return {"targets": files}
251
 
252
- @fastapi_app.post("/target")
253
  async def upload_target(image: UploadFile = File(...)):
254
  contents = await image.read()
255
  file_id = await fs_bucket.upload_from_stream(image.filename, contents, metadata={"type": "target"})
@@ -259,7 +227,7 @@ class FaceSwapRequest(BaseModel):
259
  source_id: str
260
  target_id: str
261
 
262
- @fastapi_app.post("/faceswap")
263
  async def perform_faceswap(request: FaceSwapRequest):
264
  try:
265
  src_stream = await fs_bucket.open_download_stream(ObjectId(request.source_id))
@@ -290,7 +258,7 @@ async def perform_faceswap(request: FaceSwapRequest):
290
  result_id = await fs_bucket.upload_from_stream("enhanced.png", final_bytes, metadata={"type": "result"})
291
  return {"result_id": str(result_id)}
292
 
293
- @fastapi_app.get("/download/{result_id}")
294
  async def download_result(result_id: str):
295
  try:
296
  stream = await fs_bucket.open_download_stream(ObjectId(result_id))
@@ -304,10 +272,8 @@ async def download_result(result_id: str):
304
  headers={"Content-Disposition": "attachment; filename=result.png"}
305
  )
306
 
307
- # -------------------------------------------------
308
- # Mount Gradio (last, without overwriting app)
309
- # -------------------------------------------------
310
- mount_gradio_app(fastapi_app, demo, path="/gradio")
311
 
312
  if __name__ == "__main__":
313
  uvicorn.run(fastapi_app, host="0.0.0.0", port=7860)
 
12
  from insightface.app import FaceAnalysis
13
  from huggingface_hub import hf_hub_download
14
 
15
+ from fastapi import FastAPI, UploadFile, File, HTTPException, Response, Depends, Security
16
  from fastapi.responses import RedirectResponse
17
+ from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
18
  from pydantic import BaseModel
19
  from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorGridFSBucket
20
  from bson import ObjectId
 
23
  import gradio as gr
24
  from gradio import mount_gradio_app
25
 
26
+ # --------------------- Logging ---------------------
 
 
27
  logging.basicConfig(level=logging.INFO)
28
  logger = logging.getLogger(__name__)
29
 
30
+ # --------------------- Paths -----------------------
 
 
31
  REPO_ID = "HariLogicgo/face_swap_models"
32
  BASE_DIR = "./workspace"
33
  UPLOAD_DIR = os.path.join(BASE_DIR, "uploads")
 
38
  os.makedirs(RESULT_DIR, exist_ok=True)
39
  os.makedirs(MODELS_DIR, exist_ok=True)
40
 
41
+ # --------------------- Secrets ---------------------
42
+ HF_TOKEN = os.getenv("HF_TOKEN") # Hugging Face private repo token
43
+ API_SECRET_TOKEN = os.getenv("API_SECRET_TOKEN") # Bearer token for API
44
+
45
+ # --------------------- Download Models ---------------------
46
  def download_models():
47
+ logger.info("Downloading models from private HF repo...")
48
  inswapper_path = hf_hub_download(
49
  repo_id=REPO_ID,
50
  filename="models/inswapper_128.onnx",
51
  repo_type="model",
52
+ local_dir=MODELS_DIR,
53
+ token=HF_TOKEN
54
  )
55
+
56
  buffalo_files = [
57
  "1k3d68.onnx",
58
  "2d106det.onnx",
 
65
  repo_id=REPO_ID,
66
  filename=f"models/buffalo_l/{f}",
67
  repo_type="model",
68
+ local_dir=MODELS_DIR,
69
+ token=HF_TOKEN
70
  )
71
  logger.info("Models downloaded successfully")
72
  return inswapper_path
73
 
74
  inswapper_path = download_models()
75
 
76
+ # --------------------- Face Analysis + Swapper ---------------------
 
 
77
  providers = ['CUDAExecutionProvider', 'CPUExecutionProvider']
78
  face_analysis_app = FaceAnalysis(name="buffalo_l", root=MODELS_DIR, providers=providers)
79
  face_analysis_app.prepare(ctx_id=0, det_size=(640, 640))
80
  swapper = insightface.model_zoo.get_model(inswapper_path, providers=providers)
81
 
82
+ # --------------------- CodeFormer ---------------------
 
 
83
  CODEFORMER_PATH = "CodeFormer/inference_codeformer.py"
84
 
85
  def ensure_codeformer():
 
92
 
93
  ensure_codeformer()
94
 
95
+ # --------------------- MongoDB ---------------------
 
 
96
  MONGODB_URL = os.getenv(
97
  "MONGODB_URL",
98
  "mongodb+srv://harilogicgo_db_user:[email protected]/?retryWrites=true&w=majority&appName=Cluster0"
 
102
  database = None
103
  fs_bucket: AsyncIOMotorGridFSBucket = None
104
 
105
+ # --------------------- FastAPI ---------------------
 
 
106
  fastapi_app = FastAPI()
107
 
108
  @fastapi_app.on_event("startup")
 
121
  client.close()
122
  logger.info("MongoDB connection closed")
123
 
124
+ # --------------------- Auth ---------------------
125
+ security = HTTPBearer()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
 
127
+ def verify_token(credentials: HTTPAuthorizationCredentials = Security(security)):
128
+ if credentials.credentials != API_SECRET_TOKEN:
129
+ raise HTTPException(status_code=401, detail="Invalid or missing token")
130
+ return credentials.credentials
131
 
132
+ # --------------------- Face Swap Pipeline ---------------------
 
 
133
  swap_lock = threading.Lock()
134
 
 
 
 
135
  def face_swap_and_enhance(src_img, tgt_img):
136
  try:
137
  with swap_lock:
 
173
  except Exception as e:
174
  return None, None, f"❌ Error: {str(e)}"
175
 
176
+ # --------------------- Gradio ---------------------
 
 
177
  with gr.Blocks() as demo:
178
  gr.Markdown("Face Swap")
179
 
 
192
 
193
  btn.click(process, [src_input, tgt_input], [output_img, download, error_box])
194
 
195
+ # --------------------- API Endpoints ---------------------
 
 
196
  @fastapi_app.get("/")
197
  def root():
198
  return RedirectResponse("/gradio")
199
 
200
+ @fastapi_app.get("/health", dependencies=[Depends(verify_token)])
201
  async def health():
202
  return {"status": "healthy"}
203
 
204
+ @fastapi_app.post("/source", dependencies=[Depends(verify_token)])
205
  async def upload_source(image: UploadFile = File(...)):
206
  contents = await image.read()
207
  file_id = await fs_bucket.upload_from_stream(image.filename, contents, metadata={"type": "source"})
208
  return {"source_id": str(file_id)}
209
 
210
+ @fastapi_app.get("/targets", dependencies=[Depends(verify_token)])
211
  async def list_targets():
212
  files = []
213
  async for file in database.fs.files.find({"metadata.type": "target", "metadata.predefined": True}):
 
217
  })
218
  return {"targets": files}
219
 
220
+ @fastapi_app.post("/target", dependencies=[Depends(verify_token)])
221
  async def upload_target(image: UploadFile = File(...)):
222
  contents = await image.read()
223
  file_id = await fs_bucket.upload_from_stream(image.filename, contents, metadata={"type": "target"})
 
227
  source_id: str
228
  target_id: str
229
 
230
+ @fastapi_app.post("/faceswap", dependencies=[Depends(verify_token)])
231
  async def perform_faceswap(request: FaceSwapRequest):
232
  try:
233
  src_stream = await fs_bucket.open_download_stream(ObjectId(request.source_id))
 
258
  result_id = await fs_bucket.upload_from_stream("enhanced.png", final_bytes, metadata={"type": "result"})
259
  return {"result_id": str(result_id)}
260
 
261
+ @fastapi_app.get("/download/{result_id}", dependencies=[Depends(verify_token)])
262
  async def download_result(result_id: str):
263
  try:
264
  stream = await fs_bucket.open_download_stream(ObjectId(result_id))
 
272
  headers={"Content-Disposition": "attachment; filename=result.png"}
273
  )
274
 
275
+ # --------------------- Mount Gradio ---------------------
276
+ fastapi_app = mount_gradio_app(fastapi_app, demo, path="/gradio")
 
 
277
 
278
  if __name__ == "__main__":
279
  uvicorn.run(fastapi_app, host="0.0.0.0", port=7860)