From 682e3805ebc459ba4c4695b6aeda131ddeba1a42 Mon Sep 17 00:00:00 2001 From: XIE7654 <765462425@qq.com> Date: Wed, 16 Jul 2025 21:14:02 +0800 Subject: [PATCH] add fastapi init --- chat/api/v1/ai_chat.py | 23 +++++++++++++++++++++++ chat/config.py | 12 ++++++++++++ chat/db/session.py | 13 +++++++++++++ chat/deps/auth.py | 21 +++++++++++++++++++++ chat/main.py | 26 ++++++++++++++++++++++++++ chat/models/user.py | 16 ++++++++++++++++ chat/requirements.txt | 3 +++ chat/schemas/user.py | 9 +++++++++ chat/services/chat_service.py | 15 +++++++++++++++ chat/utils/jwt.py | 1 + chat/utils/resp.py | 16 ++++++++++++++++ 11 files changed, 155 insertions(+) create mode 100644 chat/api/v1/ai_chat.py create mode 100644 chat/config.py create mode 100644 chat/db/session.py create mode 100644 chat/deps/auth.py create mode 100644 chat/main.py create mode 100644 chat/models/user.py create mode 100644 chat/requirements.txt create mode 100644 chat/schemas/user.py create mode 100644 chat/services/chat_service.py create mode 100644 chat/utils/jwt.py create mode 100644 chat/utils/resp.py diff --git a/chat/api/v1/ai_chat.py b/chat/api/v1/ai_chat.py new file mode 100644 index 0000000..6dc5e16 --- /dev/null +++ b/chat/api/v1/ai_chat.py @@ -0,0 +1,23 @@ +from fastapi import APIRouter, Depends, Request +from pydantic import BaseModel + +from deps.auth import get_current_user +from services.chat_service import chat_service +from utils.resp import resp_success + +router = APIRouter() + +class ChatRequest(BaseModel): + prompt: str + + + +@router.post("/") +def chat_api(data: ChatRequest, user=Depends(get_current_user)): + # return {"msg": "pong"} + return resp_success(data="dasds") + + # reply = chat_service.chat(data.prompt) + # return {"msg": "pong"} + + # return ChatResponse(response=reply) \ No newline at end of file diff --git a/chat/config.py b/chat/config.py new file mode 100644 index 0000000..5308341 --- /dev/null +++ b/chat/config.py @@ -0,0 +1,12 @@ +import os + +# 数据库配置 +MYSQL_USER = os.getenv('DB_USER', 'root') +MYSQL_PASSWORD = os.getenv('DB_PASSWORD', 'my-secret-pw') +MYSQL_HOST = os.getenv('DB_HOST', 'localhost') +MYSQL_PORT = os.getenv('DB_PORT', '3306') +MYSQL_DB = os.getenv('DB_NAME', 'django_vue') + +SQLALCHEMY_DATABASE_URL = ( + f"mysql+pymysql://{MYSQL_USER}:{MYSQL_PASSWORD}@{MYSQL_HOST}:{MYSQL_PORT}/{MYSQL_DB}?charset=utf8mb4" +) diff --git a/chat/db/session.py b/chat/db/session.py new file mode 100644 index 0000000..242ba08 --- /dev/null +++ b/chat/db/session.py @@ -0,0 +1,13 @@ +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker +from config import SQLALCHEMY_DATABASE_URL + +engine = create_engine(SQLALCHEMY_DATABASE_URL, pool_pre_ping=True) +SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) + +def get_db(): + db = SessionLocal() + try: + yield db + finally: + db.close() \ No newline at end of file diff --git a/chat/deps/auth.py b/chat/deps/auth.py new file mode 100644 index 0000000..35717a8 --- /dev/null +++ b/chat/deps/auth.py @@ -0,0 +1,21 @@ +from fastapi import Depends, HTTPException, status, Request +from sqlalchemy.orm import Session + +from db.session import get_db +from models.user import AuthToken, DjangoUser + + +def get_current_user(request: Request, db: Session = Depends(get_db)): + auth = request.headers.get('Authorization') + if not auth or not auth.startswith('Bearer '): + raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='未登录') + + token = auth.split(' ', 1)[1] + token_obj = db.query(AuthToken).filter(AuthToken.key == token).first() + if not token_obj: + raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='Token无效或已过期') + + user = db.query(DjangoUser).filter(DjangoUser.id == token_obj.user_id).first() + if not user: + raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='用户不存在') + return {"user_id": user.id, "username": user.username, "email": user.email} \ No newline at end of file diff --git a/chat/main.py b/chat/main.py new file mode 100644 index 0000000..41989f4 --- /dev/null +++ b/chat/main.py @@ -0,0 +1,26 @@ +from fastapi import FastAPI +from api.v1 import ai_chat +from fastapi.middleware.cors import CORSMiddleware + +app = FastAPI() + +origins = [ + "http://localhost", + "http://localhost:8010", +] + +app.add_middleware( + CORSMiddleware, + allow_origins=origins, + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + +# 注册路由 +app.include_router(ai_chat.router, prefix="/chat/api/v1", tags=["chat"]) + +# 健康检查 +@app.get("/ping") +def ping(): + return {"msg": "pong"} diff --git a/chat/models/user.py b/chat/models/user.py new file mode 100644 index 0000000..ffcfaf3 --- /dev/null +++ b/chat/models/user.py @@ -0,0 +1,16 @@ +from sqlalchemy import Column, Integer, String, DateTime +from sqlalchemy.ext.declarative import declarative_base + +Base = declarative_base() + +class AuthToken(Base): + __tablename__ = 'authtoken_token' + key = Column(String(40), primary_key=True) + user_id = Column(Integer, nullable=False) + created = Column(DateTime) + +class DjangoUser(Base): + __tablename__ = 'system_users' + id = Column(Integer, primary_key=True) + username = Column(String(150), nullable=False) + email = Column(String(254)) \ No newline at end of file diff --git a/chat/requirements.txt b/chat/requirements.txt new file mode 100644 index 0000000..4050ff9 --- /dev/null +++ b/chat/requirements.txt @@ -0,0 +1,3 @@ +fastapi +uvicorn[standard] +langchain-openai \ No newline at end of file diff --git a/chat/schemas/user.py b/chat/schemas/user.py new file mode 100644 index 0000000..9906b3b --- /dev/null +++ b/chat/schemas/user.py @@ -0,0 +1,9 @@ +from pydantic import BaseModel + +class UserOut(BaseModel): + id: int + username: str + email: str = None + + class Config: + orm_mode = True \ No newline at end of file diff --git a/chat/services/chat_service.py b/chat/services/chat_service.py new file mode 100644 index 0000000..3c16094 --- /dev/null +++ b/chat/services/chat_service.py @@ -0,0 +1,15 @@ +# LangChain集成示例 +from langchain_openai import OpenAI +from dotenv import load_dotenv +load_dotenv() + +class ChatService: + def __init__(self): + # 这里以OpenAI为例,实际可根据需要配置 + self.llm = OpenAI(temperature=0.7, api_key='sssss') + + def chat(self, prompt: str) -> str: + # 简单调用LLM + return self.llm(prompt) + +chat_service = ChatService() \ No newline at end of file diff --git a/chat/utils/jwt.py b/chat/utils/jwt.py new file mode 100644 index 0000000..cf9f2b6 --- /dev/null +++ b/chat/utils/jwt.py @@ -0,0 +1 @@ +# 预留:如需JWT校验可在此实现 \ No newline at end of file diff --git a/chat/utils/resp.py b/chat/utils/resp.py new file mode 100644 index 0000000..607bd21 --- /dev/null +++ b/chat/utils/resp.py @@ -0,0 +1,16 @@ +from typing import Any, Optional +from pydantic import BaseModel + +class CommonResponse(BaseModel): + code: int = 0 + message: str = "success" + data: Any = None + error: Optional[Any] = None + + +def resp_success(data=None, message="success"): + return CommonResponse(code=0, message=message, data=data, error=None) + + +def resp_error(message="error", code=1, error=None): + return CommonResponse(code=code, message=message, data=None, error=error) \ No newline at end of file