Download app.py from WACATW/sayAI: direct link, hf CLI and curl.
- Browser
- Download file 3.01 kB
-
https://huggingface.co/spaces/WACATW/sayAI/resolve/main/app.py
- Command line
-
hf download hf://spaces/WACATW/sayAI/app.py
-
curl -L -o app.py https://huggingface.co/spaces/WACATW/sayAI/resolve/main/app.py
3.01 kB
| 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() | |
| # ── 用户认证 ── | |
| 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"} | |
| 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"} | |
| # ── 文件上传 ── | |
| 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} | |
| def list_files(user: str = Depends(auth.get_current_user)): | |
| return {"files": storage.list_user_files(user)} | |
| # ── AI 识图搜索 ── | |
| 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} | |
| def root(): | |
| return FileResponse("static/index.html") | |
| if __name__ == "__main__": | |
| import uvicorn | |
| uvicorn.run(app, host="0.0.0.0", port=7860) |