File size: 3,013 Bytes
d7cfbb9 89336c2 d7cfbb9 89336c2 d7cfbb9 6a5c583 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | from fastapi import FastAPI, UploadFile, File, Form, Depends, HTTPException
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
import os
import auth, storage, ai_search
app = FastAPI(title="云学习平台")
# ── 自动创建 static 目录,避免启动崩溃 ──
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
STATIC_DIR = os.path.join(BASE_DIR, "static")
os.makedirs(STATIC_DIR, exist_ok=True)
INDEX_PATH = os.path.join(STATIC_DIR, "index.html")
if not os.path.exists(INDEX_PATH):
with open(INDEX_PATH, "w", encoding="utf-8") as f:
f.write("<h1>云学习平台已启动</h1><p>请访问 <a href='/docs'>/docs</a></p>")
app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static")
def startup():
auth.init_db()
storage.ensure_bucket()
# ── 用户认证 ──
@app.post("/auth/register")
def register(username: str = Form(...), password: str = Form(...)):
conn = auth.sqlite3.connect(auth.DB_PATH)
try:
conn.execute(
"INSERT INTO users (username, password_hash, created_at) VALUES (?,?,?)",
(username, auth.hash_password(password), auth.datetime.now().isoformat())
)
conn.commit()
except auth.sqlite3.IntegrityError:
raise HTTPException(400, "用户名已存在")
finally:
conn.close()
token = auth.create_access_token({"sub": username})
return {"access_token": token, "token_type": "bearer"}
@app.post("/auth/login")
def login(username: str = Form(...), password: str = Form(...)):
conn = auth.sqlite3.connect(auth.DB_PATH)
row = conn.execute("SELECT password_hash FROM users WHERE username=?", (username,)).fetchone()
conn.close()
if not row or not auth.verify_password(password, row[0]):
raise HTTPException(401, "用户名或密码错误")
token = auth.create_access_token({"sub": username})
return {"access_token": token, "token_type": "bearer"}
# ── 文件上传 ──
@app.post("/files/upload")
async def upload(file: UploadFile = File(...), user: str = Depends(auth.get_current_user)):
content = await file.read()
path = storage.upload_file(content, file.filename, user, file.content_type or "application/octet-stream")
return {"path": path, "filename": file.filename}
@app.get("/files/list")
def list_files(user: str = Depends(auth.get_current_user)):
return {"files": storage.list_user_files(user)}
# ── AI 识图搜索 ──
@app.post("/ai/search-by-image")
async def search_by_image(file: UploadFile = File(...), user: str = Depends(auth.get_current_user)):
image_bytes = await file.read()
description = await ai_search.analyze_image(image_bytes)
results = await ai_search.search_in_library(description, user, storage)
return {"ai_description": description, "results": results}
@app.get("/")
def root():
return FileResponse("static/index.html")
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=7860) |