add fastapi init
This commit is contained in:
23
chat/api/v1/ai_chat.py
Normal file
23
chat/api/v1/ai_chat.py
Normal file
@@ -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)
|
||||||
12
chat/config.py
Normal file
12
chat/config.py
Normal file
@@ -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"
|
||||||
|
)
|
||||||
13
chat/db/session.py
Normal file
13
chat/db/session.py
Normal file
@@ -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()
|
||||||
21
chat/deps/auth.py
Normal file
21
chat/deps/auth.py
Normal file
@@ -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}
|
||||||
26
chat/main.py
Normal file
26
chat/main.py
Normal file
@@ -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"}
|
||||||
16
chat/models/user.py
Normal file
16
chat/models/user.py
Normal file
@@ -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))
|
||||||
3
chat/requirements.txt
Normal file
3
chat/requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
fastapi
|
||||||
|
uvicorn[standard]
|
||||||
|
langchain-openai
|
||||||
9
chat/schemas/user.py
Normal file
9
chat/schemas/user.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
class UserOut(BaseModel):
|
||||||
|
id: int
|
||||||
|
username: str
|
||||||
|
email: str = None
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
orm_mode = True
|
||||||
15
chat/services/chat_service.py
Normal file
15
chat/services/chat_service.py
Normal file
@@ -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()
|
||||||
1
chat/utils/jwt.py
Normal file
1
chat/utils/jwt.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
# 预留:如需JWT校验可在此实现
|
||||||
16
chat/utils/resp.py
Normal file
16
chat/utils/resp.py
Normal file
@@ -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)
|
||||||
Reference in New Issue
Block a user