Browse Source

临时提交备份

qyl 1 year ago
parent
commit
0adaf517b6
7 changed files with 73 additions and 75 deletions
  1. 18 11
      api/login.py
  2. 0 28
      api/redis.py
  3. 1 1
      config.py
  4. 10 3
      db/user.py
  5. 9 4
      douyin/access_token.py
  6. 2 9
      main.py
  7. 33 19
      待办事项.md

+ 18 - 11
api/login.py

@@ -11,7 +11,7 @@ from fastapi.responses import JSONResponse
 from config import *
 from douyin.access_token import get_access_token
 from douyin.user_info import get_user_info
-from db.user import UserOAuthRepository,UserOAuthToken
+from db.user import UserOAuthRepository,UserInfoRepository
 from api.jwt import verify_jwt_token
 
 login_router = APIRouter()  
@@ -36,13 +36,10 @@ async def login(data: ScanCode):
     
     if data.get("error_code") != 0:
         return data
-    db_manager = UserOAuthRepository()
-    logger.debug(data)
-    db_manager.add_token(data)
     
     # 计算过期时间戳(基于北京时间)  
     expires_in = data.get("expires_in", 0)  # 如果没有 expires_in 键,则默认过期时间为 0  
-    expires_in = 15
+    # expires_in = 15
     expiration_time_utc = datetime.datetime.utcnow() + datetime.timedelta(seconds=expires_in)  
     beijing_timezone_delta = datetime.timedelta(hours=8)  # 北京时间是UTC+8  
     expiration_time_beijing = expiration_time_utc + beijing_timezone_delta  
@@ -50,21 +47,31 @@ async def login(data: ScanCode):
     
     # 生成并返回 token,包含过期时间  
     payload = {  
-        "aud": data["open_id"],
+        "sub": data["open_id"],
         "exp": exp  # 添加过期时间戳(北京时间)到 payload  
     }  
     account_token = jwt.encode(payload, JWT_SECRET_KEY, algorithm="HS256")  
     logger.info(f"login success, expires_time:{datetime.datetime.fromtimestamp(exp).strftime('%Y-%m-%d %H:%M:%S') }, token:{account_token}")
     return {"token": account_token}
 
-
+@login_router.get("/user_info")
+async def user_info(jwt: dict = Depends(verify_jwt_token)):
+    open_id = jwt.get("sub")
+    logger.info(open_id)
+    oauth = UserOAuthRepository().get_by_open_id(open_id)
+    # 没有用户凭证,需要重新登陆
+    if not oauth:
+        return {"error": "need login"}
+    info = await get_user_info(open_id, oauth.access_token)
+    return info
+    
 # 受保护资源示例
 @login_router.get("/account")
-async def read_account(user: dict = Depends(verify_jwt_token)): 
-    open_id = user.get("aud")
+async def read_account(jwt: dict = Depends(verify_jwt_token)): 
+    open_id = jwt.get("aud")
     UserOAuthRepository().display_all_records()
-    logger.info(user.get("aud"))
-    return {"message": "Account information", "open_id": user.get("aud")}
+    logger.info(jwt.get("aud"))
+    return {"message": "Account information", "open_id": jwt.get("aud")}
     # 在这里返回当前用户的信息
     return {"nickname": current_user.username, "avatar": "https://p26.douyinpic.com/aweme/100x100/aweme-avatar/tos-cn-i-0813_66c4e34ae8834399bbf967c3d3c919db.jpeg?from=4010531038"}
 

+ 0 - 28
api/redis.py

@@ -1,28 +0,0 @@
-import aioredis  
-from typing import Any, Optional  
-import time  
-  
-class RedisSession:  
-    def __init__(self, redis_url: str, session_expiry: int = 3600):  
-        self.redis_url = redis_url  
-        self.session_expiry = session_expiry  
-        self.redis = None  
-  
-    async def connect(self):  
-        self.redis = await aioredis.create_redis_pool(self.redis_url)  
-  
-    async def disconnect(self):  
-        if self.redis:  
-            self.redis.close()  
-            await self.redis.wait_closed()  
-  
-    async def get(self, key: str) -> Optional[Any]:  
-        value = await self.redis.get(key)  
-        return value.decode("utf-8") if value else None  
-  
-    async def set(self, key: str, value: Any, expiry: int = None):  
-        expiry = expiry or self.session_expiry  
-        await self.redis.set(key, value, ex=expiry)  
-  
-    async def delete(self, key: str):  
-        await self.redis.delete(key)

+ 1 - 1
config.py

@@ -16,7 +16,7 @@ DOUYIN_OPEN_API="https://open.douyin.com"
 # HOST = socket.gethostbyname(socket.gethostname())
 # 这个网址 https://open-douyin.magong.site 对应这台服务器的 192.168.1.32:8600 端口,因为这台服务器没有公网ip,所以在本地计算机无法通过  http://192.168.1.32:8600/ 访问到 fastapi 接口,只能通过 https://open-douyin.magong.site/ 访问
 HOST = '::'
-PORT = 8600
+PORT = int(os.environ.get("PORT")) if os.environ.get("PORT") else 8600
 JWT_SECRET_KEY = os.environ["JWT_SECRET_KEY"]
 
 DB_URL=os.environ["DB_URL"]

+ 10 - 3
db/user.py

@@ -7,7 +7,6 @@ sys.path.append(os.path.dirname(os.path.dirname(__file__)))
 from sqlmodel import Field, SQLModel,create_engine,Session,select,func
 import psycopg2
 from config import DB_URL,logger
-from douyin.access_token import get_access_token
 # from db.common import engine
 from sqlalchemy import UniqueConstraint, Index
 from sqlalchemy.dialects.postgresql import insert
@@ -130,13 +129,21 @@ class UserOAuthRepository:
             statement = select(UserOAuthToken)
             user_tokens = session.exec(statement).all()
             return user_tokens
+    
+    # 根据 open_id 获取模型中某一行
+    def get_by_open_id(self, open_id):  
+        with Session(self.engine) as session:  
+            statement = select(UserOAuthToken).where(UserOAuthToken.open_id == open_id)  
+            result = session.exec(statement)  
+            return result.first()  
 
 
 def main():
     db_manager = UserOAuthRepository()
     data = {'access_token': 'act.3.wl8L3DFQ3sj3uKYzQShOSs8HbOgKh0FVvjxKeaTum0ZOEXoyBI8D1N7gTBqGbrY32KP-Pm41EAvcobSheOBi8tvRdhj7m5-5ZVoprZZu_GN5J2KnH2fZ_X9_l7Q6iFyvpPoMkX3Zyom3PCkeRZp4Jg9sE2ZiwuvZVdnvft0A25uBWXvj2IEbWW_0Bf8=', 'captcha': '', 'desc_url': '', 'description': '', 'error_code': 0, 'expires_in': 1296000, 'log_id': '20240129123749239735B0529965BC6D93', 'open_id': '_000QadFMhmU1jNCI3JdPnyVDL6XavC70dFy', 'refresh_expires_in': 2592000, 'refresh_token': 'rft.c29d64456ea3d5e4c932247ee93dd735aq5OhtcYNXNFAD70XHKrdntpE6U0', 'scope': 'user_info,trial.whitelist'}
-    db_manager.add_token(data)
-    res = db_manager.display_all_records()
+    # db_manager.add_token(data)
+    # res = db_manager.display_all_records()
+    res = db_manager.get_from_id("_000QadFMhmU1jNCI3JdPnyVDL6XavC70dFy", "access_token")
     logger.debug(res)
 
 if __name__ == "__main__":

+ 9 - 4
douyin/access_token.py

@@ -5,6 +5,7 @@ import httpx
 from config import logger
 from typing import Optional
 from pydantic import BaseModel
+from db.user import UserOAuthToken,UserOAuthRepository
 
 class DouyinAccessTokenResponse(BaseModel):
     error_code: int
@@ -30,8 +31,12 @@ async def get_access_token(code):
                 "client_secret": client_secret,  
                 "code": code,  
             },  
-        )  
-  
+        )
+        res_json = response.json()
+        if res_json("data").get("error_code") != 0:
+            db_manager = UserOAuthRepository()
+            db_manager.add_token(res_json("data"))
+
     ''' response success:
     {
     "data": {
@@ -62,8 +67,8 @@ async def get_access_token(code):
         }
     }
     '''
-    logger.debug(response.json()) 
-    return response.json().get("data")
+    logger.debug(res_json) 
+    return res_json.get("data")
 
 # 单元测试
 def main():

+ 2 - 9
main.py

@@ -13,10 +13,7 @@ import os
 # from db.user import UserOAuthToken
 from config import *
 from fastapi.middleware.cors import CORSMiddleware 
-from db.user import DatabaseManager
 from api.login import login_router
-from api.redis import RedisSession
-from starlette.middleware.sessions import SessionMiddleware
 from contextlib import asynccontextmanager
 
 app = FastAPI()  
@@ -30,17 +27,13 @@ app.add_middleware(
 ) 
 app.include_router(login_router)  
 
-# 使用 Redis 会话  
-redis_session = RedisSession("redis://localhost:8001")  
-app.add_middleware(SessionMiddleware, secret_key=JWT_SECRET_KEY)  
-
 @asynccontextmanager
 async def lifespan(app: FastAPI):
     # 在应用启动前运行的代码
-    await redis_session.connect()  
+    pass
     yield
     # 在应用关闭后运行的代码
-    await redis_session.disconnect()
+    pass
 
 def get_session(request: Request):  
     return request.session  

+ 33 - 19
待办事项.md

@@ -1,36 +1,50 @@
 # qyl
+- [ ] **接入 LangChain (代补充)**
+  - [ ] 将一个 pdf 或 doc 文档进行本地向量存储。示例代码(URL文档转向量) m2_vector_store.py  目录: /home/user/code/LangChain
+  - [ ] 向量数据库是否能按文档进行分类?例如我指定查询 1.doc 文档,在另一个场景中,指定查询 2.doc 和 3.doc 两个文档一起查找。
+  - [ ] 评估大模型记忆框架 MemoryBank https://zhuanlan.zhihu.com/p/674220905?utm_campaign=shareopn&utm_medium=social&utm_oi=766444166291935232&utm_psn=1730836140159057920&utm_source=wechat_session
+
+## finish
 - [x] 试一下内网穿透、修改SSH本地配置文件、本地 proxy
 - [ ] **了解数据库**
   - [x] 数据库模型 sqlmodel ,官方文档: https://github.com/tiangolo/sqlmodel  
   - [x] 数据库软件 PostgreSQL 。 2023 最流行的开源数据库,超越 MySQL 。官网: https://github.com/postgres/postgres ,github 地址:https://github.com/postgres/postgres
   - [x] 根据 sqlmodel 的方式编写代码,定义数据库模型,连接至 PostgreSQL ,代码存放在 db/ 目录中(调试了sqlmodel连接PostgreSQL服务器,往数据库中写入数据)
   - [x] 添加、删除、显示记录
-- [ ] **获取抖音用户信息**
-  - [ ] 详见 [api](./api/readme.md#获取抖音用户信息)
-  - [ ] 参考文档 https://developer.open-douyin.com/docs/resource/zh-CN/dop/develop/sdk/web-app/web/permission
-  - [ ] 后端管理框架参考: https://github.com/amisadmin/fastapi-amis-admin
-  - [ ] 将 code 解析出来。获取用户 access-token 、 expires_in、open_id、refresh_expires_in、refresh_token。参考文档 https://developer.open-douyin.com/docs/resource/zh-CN/dop/develop/openapi/account-permission/get-access-token
-  - [ ] 利用 access-token 获取用户公开信息。
+
+
+# mrh
+- [ ] **登录页**
+  - [ ] 从数据库获取用户数据,展示到用户登录页中。保存到本地 localstore
+  - [ ] 实现文档上传、下载、更新、删除
+  - [ ] 文档预览
+- [ ] **负载均衡 / 内网穿透**
+  - 💡 必要性:一个应用程序/网站有许多微服务,子请求到不同的后端主机,负载均衡,数据库,文件服务器,对象存储,大文件、音视频流点对点传输,用户没有ipv6,方便协作开发,等等
+  - [x] 评估 FRP 穿透打洞可行性,方便API动态增删改查隧道 (不可行,打洞仍需要中继公网服务器)
+  - [ ] natter 搭建一个 API 增删改查隧道。natter + Vmess 探究
+  - [ ] 优选ip
+    - [ ] https://github.com/libbyliu2020/CloudflareScannerOnBrowser
+    - [ ] https://zhuanlan.zhihu.com/p/640446906  
+    - [ ] https://zhuanlan.zhihu.com/p/104311719
+    - [ ] https://zhuanlan.zhihu.com/p/129838721
 - [ ] **接入 LangChain (代补充)**
   - [ ] 向量数据库服务器部署
   - [ ] 评估大模型记忆框架 MemoryBank https://zhuanlan.zhihu.com/p/674220905?utm_campaign=shareopn&utm_medium=social&utm_oi=766444166291935232&utm_psn=1730836140159057920&utm_source=wechat_session
 
-# mrh
+## finish
 - [x] **了解数据库**
   - [x] 数据库模型 sqlmodel ,官方文档: https://github.com/tiangolo/sqlmodel  
   - [x] 数据库软件 PostgreSQL 。 2023 最流行的开源数据库,超越 MySQL 。官网: https://github.com/postgres/postgres ,github 地址:https://github.com/postgres/postgres
   - [x] 部署数据库服务器 PostgreSQL ,确定分布式数据库可行性 https://blog.csdn.net/qq_23934063/article/details/120267886。微软Citus 11 for Postgres分布式架构 https://github.com/citusdata/citus
   - [x] 已完成部署,[使用教程](./db/readme.md)
-- [ ] **编写前端代码**
+- [x] **获取抖音用户信息**
+  - [x] 详见 [api](./api/readme.md#获取抖音用户信息)
+  - [x] 参考文档 https://developer.open-douyin.com/docs/resource/zh-CN/dop/develop/sdk/web-app/web/permission
+  - [x] 后端管理框架参考: https://github.com/amisadmin/fastapi-amis-admin
+  - [x] 将 code 解析出来。获取用户 access-token 、 expires_in、open_id、refresh_expires_in、refresh_token。参考文档 https://developer.open-douyin.com/docs/resource/zh-CN/dop/develop/openapi/account-permission/get-access-token
+  - [x] 利用 access-token 获取用户公开信息。
+
+- [x] **扫码登录**
   - [x] 扫码登录,页面跳转(1月26日)。
-    - [ ] 前端项目:[vue-pure-admin](https://mp.weixin.qq.com/s/iJPJizHKhbXe9iHpclU3FA) 基于 Vue3、Vite、Element-Plus 和 TypeScript 编写的后台管理系统。github链接:https://github.com/xiaoxian521/vue-pure-admin
-  - [ ] 了解用户鉴权, element-plus-admin + Fastapi + Oauth2
-  - [ ] 从数据库获取用户数据,展示到用户登录页中
-  - [ ] 文档上传、下载、更新、删除
-- [ ] **内网穿透**
-  - 💡 必要性:一个应用程序/网站有许多微服务,子请求到不同的后端主机,负载均衡,数据库,文件服务器,对象存储,大文件、音视频流点对点传输,用户没有ipv6,方便协作开发,等等
-  - [x] 评估 FRP 穿透打洞可行性,方便API动态增删改查隧道 (不可行,打洞仍需要中继公网服务器)
-  - [ ] natter 搭建一个 API 增删改查隧道。natter + Vmess 探究
-- [ ] **接入 LangChain (代补充)**
-  - [ ] 向量数据库服务器部署
-  - [ ] 评估大模型记忆框架 MemoryBank https://zhuanlan.zhihu.com/p/674220905?utm_campaign=shareopn&utm_medium=social&utm_oi=766444166291935232&utm_psn=1730836140159057920&utm_source=wechat_session
+    - [x] 前端项目:[vue-pure-admin](https://mp.weixin.qq.com/s/iJPJizHKhbXe9iHpclU3FA) 基于 Vue3、Vite、Element-Plus 和 TypeScript 编写的后台管理系统。github链接:https://github.com/xiaoxian521/vue-pure-admin
+  - [x] 了解用户鉴权, element-plus-admin + Fastapi + Oauth2