chawin.chen commited on
Commit
7396c20
·
1 Parent(s): 56daa9f
Files changed (2) hide show
  1. Dockerfile +1 -1
  2. app.py +58 -0
Dockerfile CHANGED
@@ -47,6 +47,7 @@ RUN mkdir -p /opt/data/chinese_celeb_dataset /opt/data/faiss /opt/data/models /
47
  WORKDIR /app
48
  COPY requirements.txt .
49
  COPY *.py /app/
 
50
 
51
  # 安装必要的系统工具和依赖
52
  RUN apt-get update && apt-get install -y --no-install-recommends \
@@ -73,4 +74,3 @@ RUN pip install --upgrade pip
73
  RUN pip install --no-cache-dir -r requirements.txt
74
  EXPOSE 7860
75
  CMD ["uvicorn", "app:app", "--workers", "1", "--loop", "asyncio", "--http", "httptools", "--host", "0.0.0.0", "--port", "7860", "--timeout-keep-alive", "600"]
76
-
 
47
  WORKDIR /app
48
  COPY requirements.txt .
49
  COPY *.py /app/
50
+ COPY facelist-web /app/facelist-web
51
 
52
  # 安装必要的系统工具和依赖
53
  RUN apt-get update && apt-get install -y --no-install-recommends \
 
74
  RUN pip install --no-cache-dir -r requirements.txt
75
  EXPOSE 7860
76
  CMD ["uvicorn", "app:app", "--workers", "1", "--loop", "asyncio", "--http", "httptools", "--host", "0.0.0.0", "--port", "7860", "--timeout-keep-alive", "600"]
 
app.py CHANGED
@@ -2,8 +2,14 @@ import os
2
  import time
3
  from contextlib import asynccontextmanager
4
 
 
 
 
5
  from fastapi import FastAPI
 
6
  from starlette.middleware.cors import CORSMiddleware
 
 
7
 
8
  from cleanup_scheduler import start_cleanup_scheduler, stop_cleanup_scheduler
9
  from config import (
@@ -137,6 +143,58 @@ app.add_middleware(
137
  # 注册路由
138
  app.include_router(api_router)
139
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  # 添加根路径处理
141
  @app.get("/")
142
  async def root():
 
2
  import time
3
  from contextlib import asynccontextmanager
4
 
5
+ import base64
6
+ import secrets
7
+
8
  from fastapi import FastAPI
9
+ from fastapi.staticfiles import StaticFiles
10
  from starlette.middleware.cors import CORSMiddleware
11
+ from starlette.middleware.base import BaseHTTPMiddleware
12
+ from starlette.responses import Response, PlainTextResponse
13
 
14
  from cleanup_scheduler import start_cleanup_scheduler, stop_cleanup_scheduler
15
  from config import (
 
143
  # 注册路由
144
  app.include_router(api_router)
145
 
146
+
147
+ _default_frontend_dir = os.path.abspath(
148
+ os.path.join(os.path.dirname(__file__), "facelist-web")
149
+ )
150
+ FRONTEND_DIR = os.path.abspath(
151
+ os.path.expanduser(os.environ.get("FACELIST_FRONTEND_DIR", _default_frontend_dir))
152
+ )
153
+
154
+ _basic_user = os.environ.get("FACELIST_BASIC_USER", "admin")
155
+ _basic_pass = os.environ.get("FACELIST_BASIC_PASS", "admin")
156
+ _basic_secret = f"{_basic_user}:{_basic_pass}"
157
+ _basic_token = "Basic " + base64.b64encode(_basic_secret.encode()).decode()
158
+
159
+
160
+ class FacelistBasicAuthMiddleware(BaseHTTPMiddleware):
161
+ """仅保护 /facelist 前缀的 Basic Auth"""
162
+
163
+ async def dispatch(self, request, call_next):
164
+ path = request.url.path
165
+ if path.startswith("/facelist"):
166
+ auth = request.headers.get("Authorization", "")
167
+ if not secrets.compare_digest(auth, _basic_token):
168
+ return PlainTextResponse(
169
+ "Unauthorized",
170
+ status_code=401,
171
+ headers={"WWW-Authenticate": 'Basic realm="facelist"'},
172
+ )
173
+ return await call_next(request)
174
+
175
+
176
+ class SPAStaticFiles(StaticFiles):
177
+ """支持SPA路由回退到index.html的静态文件服务"""
178
+
179
+ async def get_response(self, path: str, scope):
180
+ response = await super().get_response(path, scope)
181
+ if response.status_code == 404:
182
+ # 未匹配到具体文件时回退到前端入口
183
+ response = await super().get_response("index.html", scope)
184
+ return response
185
+
186
+ app.add_middleware(FacelistBasicAuthMiddleware)
187
+
188
+ if os.path.isdir(FRONTEND_DIR):
189
+ app.mount(
190
+ "/facelist",
191
+ SPAStaticFiles(directory=FRONTEND_DIR, html=True),
192
+ name="facelist",
193
+ )
194
+ logger.info("前端静态资源已挂载在 /facelist ,目录: %s", FRONTEND_DIR)
195
+ else:
196
+ logger.warning("未找到前端目录 %s ,跳过前端静态资源挂载", FRONTEND_DIR)
197
+
198
  # 添加根路径处理
199
  @app.get("/")
200
  async def root():