fastapi-langgraph

news/2025/9/21 21:33:52/文章来源:https://www.cnblogs.com/lightsong/p/19104219

fastapi-langgraph

https://github.com/fanqingsong/fastapi-langgraph

FastAPI LangGraph Agent Template

A production-ready FastAPI template for building AI agent applications with LangGraph integration. This template provides a robust foundation for building scalable, secure, and maintainable AI agent services.

🌟 Features

  • Production-Ready Architecture

    • FastAPI for high-performance async API endpoints
    • LangGraph integration for AI agent workflows
    • Langfuse for LLM observability and monitoring
    • Structured logging with environment-specific formatting
    • Rate limiting with configurable rules
    • PostgreSQL for data persistence
    • Docker and Docker Compose support
    • Prometheus metrics and Grafana dashboards for monitoring
  • Security

    • JWT-based authentication
    • Session management
    • Input sanitization
    • CORS configuration
    • Rate limiting protection
  • Developer Experience

    • Environment-specific configuration
    • Comprehensive logging system
    • Clear project structure
    • Type hints throughout
    • Easy local development setup
  • Model Evaluation Framework

    • Automated metric-based evaluation of model outputs
    • Integration with Langfuse for trace analysis
    • Detailed JSON reports with success/failure metrics
    • Interactive command-line interface
    • Customizable evaluation metrics

 

 

 

"""Chatbot API endpoints for handling chat interactions.This module provides endpoints for chat interactions, including regular chat,
streaming chat, message history management, and chat history clearing.
"""import json
from typing import Listfrom fastapi import (APIRouter,Depends,HTTPException,Request,
)
from fastapi.responses import StreamingResponsefrom app.api.v1.auth import get_current_session
from app.core.config import settings
from app.core.langgraph.graph import LangGraphAgent
from app.core.limiter import limiter
from app.core.logging import logger
from app.models.session import Session
from app.schemas.chat import (ChatRequest,ChatResponse,Message,StreamResponse,
)router = APIRouter()
agent = LangGraphAgent()@router.post("/chat", response_model=ChatResponse)
@limiter.limit(settings.RATE_LIMIT_ENDPOINTS["chat"][0])
async def chat(request: Request,chat_request: ChatRequest,session: Session = Depends(get_current_session),
):"""Process a chat request using LangGraph.Args:request: The FastAPI request object for rate limiting.chat_request: The chat request containing messages.session: The current session from the auth token.Returns:ChatResponse: The processed chat response.Raises:HTTPException: If there's an error processing the request."""try:logger.info("chat_request_received",session_id=session.id,message_count=len(chat_request.messages),)# Process the request through the LangGraphresult = await agent.get_response(chat_request.messages, session.id, user_id=session.user_id)logger.info("chat_request_processed", session_id=session.id)return ChatResponse(messages=result)except Exception as e:logger.error("chat_request_failed", session_id=session.id, error=str(e), exc_info=True)raise HTTPException(status_code=500, detail=str(e))@router.post("/chat/stream")
@limiter.limit(settings.RATE_LIMIT_ENDPOINTS["chat_stream"][0])
async def chat_stream(request: Request,chat_request: ChatRequest,session: Session = Depends(get_current_session),
):"""Process a chat request using LangGraph with streaming response.Args:request: The FastAPI request object for rate limiting.chat_request: The chat request containing messages.session: The current session from the auth token.Returns:StreamingResponse: A streaming response of the chat completion.Raises:HTTPException: If there's an error processing the request."""try:logger.info("stream_chat_request_received",session_id=session.id,message_count=len(chat_request.messages),)async def event_generator():"""Generate streaming events.Yields:str: Server-sent events in JSON format.Raises:Exception: If there's an error during streaming."""try:full_response = ""async for chunk in agent.get_stream_response(chat_request.messages, session.id, user_id=session.user_id):full_response += chunkresponse = StreamResponse(content=chunk, done=False)yield f"data: {json.dumps(response.model_dump())}\n\n"# Send final message indicating completionfinal_response = StreamResponse(content="", done=True)yield f"data: {json.dumps(final_response.model_dump())}\n\n"except Exception as e:logger.error("stream_chat_request_failed",session_id=session.id,error=str(e),exc_info=True,)error_response = StreamResponse(content=str(e), done=True)yield f"data: {json.dumps(error_response.model_dump())}\n\n"return StreamingResponse(event_generator(), media_type="text/event-stream")except Exception as e:logger.error("stream_chat_request_failed",session_id=session.id,error=str(e),exc_info=True,)raise HTTPException(status_code=500, detail=str(e))@router.get("/messages", response_model=ChatResponse)
@limiter.limit(settings.RATE_LIMIT_ENDPOINTS["messages"][0])
async def get_session_messages(request: Request,session: Session = Depends(get_current_session),
):"""Get all messages for a session.Args:request: The FastAPI request object for rate limiting.session: The current session from the auth token.Returns:ChatResponse: All messages in the session.Raises:HTTPException: If there's an error retrieving the messages."""try:messages = await agent.get_chat_history(session.id)return ChatResponse(messages=messages)except Exception as e:logger.error("get_messages_failed", session_id=session.id, error=str(e), exc_info=True)raise HTTPException(status_code=500, detail=str(e))@router.delete("/messages")
@limiter.limit(settings.RATE_LIMIT_ENDPOINTS["messages"][0])
async def clear_chat_history(request: Request,session: Session = Depends(get_current_session),
):"""Clear all messages for a session.Args:request: The FastAPI request object for rate limiting.session: The current session from the auth token.Returns:dict: A message indicating the chat history was cleared."""try:await agent.clear_chat_history(session.id)return {"message": "Chat history cleared successfully"}except Exception as e:logger.error("clear_chat_history_failed", session_id=session.id, error=str(e), exc_info=True)raise HTTPException(status_code=500, detail=str(e))

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/909069.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学python的第7天

学python的第7天列表类型的内置方法 1.用途:多个装备、多个爱好、多门课程,甚至是多个女朋友 2.定义:[]内可以有多个任意类型的值,逗号分隔元素 # my_girl_friend = list([jason,tank,sean]) my_girl_friend = [ja…

Revit二次开发环境配置

# 文章概述 你是否刚接触 Revit 二次开发,面对复杂的开发环境无从下手? 你是否想快速实现一个带交互对话框的插件,却不知从何调用 TaskDialog? 你是否部署插件时频频失败,搞不清 .addin 文件怎么写、插件为何不加…

CF1016G Appropriate Team

首先一个结论是:只有在 \(Y \bmod X =0\) 时,才有答案。 证明显然,因为 \(\gcd\) 和 \(\operatorname{lcm}\) 的性质,\(a_i\) 和 \(v\) 是 \(X\) 的倍数,\(a_j\) 和 \(v\) 是 \(Y\) 的因数。 那么接下来,因为 \(…

CF494C Helping People

CF494C Helping People 看到保证区间不会交错,没想出来这个性质是干什么的,看了题解才知道,这说明区间之间只会互相包含。 那么我们就可以为每个区间指定一个 \(fa\) 区间来代表最小的包含它的区间,不难发现这构成…

深入解析:Extract Chart Data Directly to Excel

深入解析:Extract Chart Data Directly to Excelpre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas",…

AOSP Android12 Source 下载同步

获取Repo工具并配置镜像地址 curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo > ~/bin/repo chmod a+x ~/bin/repo export REPO_URL=https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/初始化仓库并指定…

02020404 EF Core基础04-自增主键、Guid主键、混合自增、Hi/Lo算法、Migration深入、数据库其它迁移命令

02020404 EF Core基础04-自增主键、Guid主键、混合自增、Hi/Lo算法、Migration深入、数据库其它迁移命令 1. 主键无小事(视频3-6) 1.1 自增主键 1、EF Core支持多种主键生成策略:自动增长;Guid;Hi/Lo算法等。 2、…

02020403 EF Core基础03-Fluent API、Data Annotation、两种配置的选择

02020403 EF Core基础03-Fluent API、Data Annotation、两种配置的选择 1. FluentAPI哪些不该用(视频3-4) 1.1 约定配置 主要规则: 1:表名采用DbContext中的对应的DbSet的属性名。 2:数据表列的名字采用实体类属性…

深入解析:Python(1)|| 超基础语法(格式,输入输出,变量,字符串,运算符)

深入解析:Python(1)|| 超基础语法(格式,输入输出,变量,字符串,运算符)2025-09-21 21:23 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflo…

深入解析:STM32-FreeRTOS操作系统-任务管理

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Java中异步任务的执行方式有几种?

在Java中,异步任务的执行方式有多种,每种方式适用于不同的场景和需求。以下是常见的几种实现方式:Thread类 最基础的方式是直接使用Thread类创建线程执行任务:new Thread(() -> {// 异步执行的任务System.out.p…

mysql数据库自增ID为int类型超过范围

mysql数据库自增ID为int类型超过范围mysql数据的自增加的id(int)类型,超过范围:数据自增加ID,为int类型,超过范围,就插入数据库失败;怎么解决? 由于数据比较大, 1.第一个简单粗暴:把int变为(BIGINT)不用迁…

202508_浙江省网络安全测试职业职工技能竞赛_misc-1

流量分析,RE,XORTags:流量分析,RE,XOR 0x00. 题目 你是一名资深的网络安全分析取证师,受命调查一家IT公司近期遭遇的一起严重网络安全事件。 该公司主要业务是为中小型企业提供定制化管理系统和数据分析服务。 由…

python爬虫测试

python爬虫测试0.背景:要下合适自己的驱动,不然都是报错!!你需要完成以下两步:检查你的 Chrome 浏览器版本。打开 Chrome,在地址栏输入 chrome://settings/help。 你会看到你的 Chrome 版本号,例如 版本 120.0.…

广二联考题解补全计划:

第十七套: T1:取模性质,倍增 T2: DP优化,状态优化 T3:容斥原理,数位DP T1: 首先先提一个关于取模的性质,一个数对一个比它小的数取模,大小一定减半,考虑对 $ \frac {n}{2}$ 分治即可。 我们先预处理出来每个数…

如何在 C# 中将文本转换为 Word 以及将 Word 转换为文本 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Chapter 8 Contour / Shape Detection

def getContours(img):contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)for cnt in contours:area = cv2.contourArea(cnt)print(area)if area > 500:# -1 代表所有的轮廓c…

【左程云算法笔记016】双端队列-双链表和固定数组实现 - 教程

【左程云算法笔记016】双端队列-双链表和固定数组实现 - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Cons…

LeetCode 几道 Promises 和 Time 的题目 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …