结合fastapi-users与Langserve轻松实现大语言接口用户认证

在做大模型开发的过程中,相信很多小伙伴都是对大模型开发感兴趣,却对 fastapi 这个框架并不熟悉,但是,实际开发的项目确需要用户鉴权,这时候就会很头疼,查阅官方文档发现,官方虽然有例子,但是写的非常简单,只有一个自定义的verify_token函数,函数内容还需要自己实现,如果投入学习成本在 fastapi 的用户认证上就显得得不偿失。而 fastapi 是有现成的用户认证的框架的,比如 fastapi-users。今天,我就带领大家完成一个使用 fastapi-users来实现带有用户认证功能的Langserve接口。

以上是官方的认证鉴权的方法,实现过程需要自己来完成。

实现步骤:

下载fastapi-users

pip install 'fastapi-users[sqlalchemy]'

代码目录结构

创建 langserve 项目的方法我就不再介绍了,感兴趣的同学,可以看我的这篇公众号文章:LangServe全面使用指南

.
├── app
│   ├── db.py
│   ├── __init__.py
│   ├── __pycache__
│   ├── schemas.py
│   ├── server.py
│   └── users.py
├── Dockerfile
├── packages
│   └── README.md
├── poetry.lock
├── pyproject.toml
├── README.md
└── test.db

其中,db.py、users.py、schemas.py都是新建的 python 文件,这个目录结构也是fastapi-users推荐的拆分方式。

代码编写

db.py

from typing import AsyncGeneratorfrom fastapi import Depends
from fastapi_users.db import SQLAlchemyBaseUserTableUUID, SQLAlchemyUserDatabase
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
from sqlalchemy.orm import DeclarativeBaseDATABASE_URL = "sqlite+aiosqlite:///./test.db"class Base(DeclarativeBase):passclass User(SQLAlchemyBaseUserTableUUID, Base):passengine = create_async_engine(DATABASE_URL)
async_session_maker = async_sessionmaker(engine, expire_on_commit=False)async def create_db_and_tables():async with engine.begin() as conn:await conn.run_sync(Base.metadata.create_all)async def get_async_session() -> AsyncGenerator[AsyncSession, None]:async with async_session_maker() as session:yield sessionasync def get_user_db(session: AsyncSession = Depends(get_async_session)):yield SQLAlchemyUserDatabase(session, User)

schemas.py

import uuidfrom fastapi_users import schemasclass UserRead(schemas.BaseUser[uuid.UUID]):passclass UserCreate(schemas.BaseUserCreate):passclass UserUpdate(schemas.BaseUserUpdate):pass

users.py

import uuid
from typing import Optionalfrom fastapi import Depends, Request
from fastapi_users import BaseUserManager, FastAPIUsers, UUIDIDMixin
from fastapi_users.authentication import (AuthenticationBackend,BearerTransport,JWTStrategy,
)
from fastapi_users.db import SQLAlchemyUserDatabasefrom app.db import User, get_user_dbSECRET = "SECRET"class UserManager(UUIDIDMixin, BaseUserManager[User, uuid.UUID]):reset_password_token_secret = SECRETverification_token_secret = SECRETasync def on_after_register(self, user: User, request: Optional[Request] = None):print(f"User {user.id} has registered.")async def on_after_forgot_password(self, user: User, token: str, request: Optional[Request] = None):print(f"User {user.id} has forgot their password. Reset token: {token}")async def on_after_request_verify(self, user: User, token: str, request: Optional[Request] = None):print(f"Verification requested for user {user.id}. Verification token: {token}")async def get_user_manager(user_db: SQLAlchemyUserDatabase = Depends(get_user_db)):yield UserManager(user_db)bearer_transport = BearerTransport(tokenUrl="auth/jwt/login")def get_jwt_strategy() -> JWTStrategy:return JWTStrategy(secret=SECRET, lifetime_seconds=3600)auth_backend = AuthenticationBackend(name="jwt",transport=bearer_transport,get_strategy=get_jwt_strategy,
)fastapi_users = FastAPIUsers[User, uuid.UUID](get_user_manager, [auth_backend])current_active_user = fastapi_users.current_user(active=True)

注意: 这些都是fastapi-users官方用例部分,最主要的是 server.py中的结合部分。

from fastapi import FastAPI, Depends
from fastapi.responses import RedirectResponse
from langserve import add_routesfrom contextlib import asynccontextmanagerfrom app.db import User, create_db_and_tables
from app.schemas import UserCreate, UserRead, UserUpdate
from app.users import auth_backend, current_active_user, fastapi_users
from langchain.chat_models import ChatOpenAI
from langchain_community.chat_models.moonshot import MoonshotChat@asynccontextmanager
async def lifespan(app: FastAPI):# Not needed if you setup a migration system like Alembicawait create_db_and_tables()yieldapp = FastAPI(lifespan=lifespan,#dependencies=[Depends(current_active_user)]
)app.include_router(fastapi_users.get_auth_router(auth_backend), prefix="/auth/jwt", tags=["auth"]
)
app.include_router(fastapi_users.get_register_router(UserRead, UserCreate),prefix="/auth",tags=["auth"],
)
app.include_router(fastapi_users.get_reset_password_router(),prefix="/auth",tags=["auth"],
)
app.include_router(fastapi_users.get_verify_router(UserRead),prefix="/auth",tags=["auth"],
)
app.include_router(fastapi_users.get_users_router(UserRead, UserUpdate),prefix="/users",tags=["users"],
)@app.get("/authenticated-route")
async def authenticated_route(user: User = Depends(current_active_user)):return {"message": f"Hello {user.email}!"}add_routes(app,MoonshotChat(),path="/openai",dependencies=[Depends(current_active_user)],
)@app.get("/")
async def redirect_root_to_docs():return RedirectResponse("/docs")# Edit this to add the chain you want to add
# add_routes(app, NotImplemented)if __name__ == "__main__":import uvicornuvicorn.run(app, host="0.0.0.0", port=8000)

这里,我用的是kimi的api接口,最主要的改变是在add_routes中增加了dependencies参数,引入了fastapi-users封装好的current_active_user。

add_routes(app,MoonshotChat(),path="/openai",dependencies=[Depends(current_active_user)], #这句代码是关键
)

最后,看下实际调用 invoke 接口后的效果吧!只需要在调用的接口的 header 中加入Authorization即可,对应的值是bearer加 token。这个 token 是调用 login 接口后返回的。

调用login接口获取 token

headers 中加入token

调用 invoke 后的效果

总结

怎么样?是不是很简单?如果有不理解的地方或者需要本代码的,欢迎与我联系。

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

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

相关文章

2023年下半年系统架构设计师下午论文真题

试题一 论边缘计算及其应用 边缘计算是在靠近物或数据源头的网络边缘侧,融合网络、计算、存储、应用核心能力的分布式开放平台(架构),就近提供边缘智能服务。边缘计算与云计算各有所长,云计算擅长全局性、非实时、长周期的大数据处理与分析&…

行云堡垒国密算法应用与信创支持

一、 国密算法和信创的介绍 1.1 什么是国密算法 国密算法是国家密码管理局制定颁布的一系列的密码标准,即已经被国家密码局认定的国产密码算法,又称商用密码(是指能够实现商用密码算法的加密,解密和认证等功能的技术)…

uniapp 小程序获取WiFi列表

<template><view ><button click"getWifiList">获取WiFi列表</button><scroll-view:scroll-top"scrollTop"scroll-yclass"content-pop"><viewclass"itemInfo"v-for"(item, index) in wifiList&…

JetBrains RubyMine 2024.1 发布 - 最智能的 Ruby 与 Rails IDE

JetBrains RubyMine 2024.1 发布 - 最智能的 Ruby 与 Rails IDE 请访问原文链接&#xff1a;JetBrains RubyMine 2024.1 (macOS, Linux, Windows) - 最智能的 Ruby 与 Rails IDE&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org…

Excel·VBA二维数组S形排列

与之前的文章《ExcelVBA螺旋数组函数》将一维数组转为二维螺旋数组 本文将数组转为S形排列的二维数组&#xff0c;类似考场座位S形顺序 Function S形排列(ByVal arr, ByVal num_rows&, ByVal num_cols&, Optional ByVal mode$ "row")将数组arr转为num_rows…

跟TED演讲学英文:The inside story of ChatGPT‘s astonishing potential by Greg Brockman

The inside story of ChatGPT’s astonishing potential Link: https://www.ted.com/talks/greg_brockman_the_inside_story_of_chatgpt_s_astonishing_potential Speaker: Greg Brockman Date:April 2023 文章目录 The inside story of ChatGPTs astonishing potentialIntro…

Linux/October

October Enumeration Nmap 扫描发现对外开放了22和80端口&#xff0c;使用nmap详细扫描这两个端口 ┌──(kali㉿kali)-[~/vegetable/HTB/October] └─$ nmap -sC -sV -p 22,80 -oA nmap 10.10.10.16 Starting Nmap 7.…

Unity Shader之数学篇

一、坐标系 1、二维笛卡尔坐标系 屏幕坐标系是二维笛卡尔坐标系&#xff0c;OpenGL的屏幕坐标系原点在左下角&#xff0c;DirectX的屏幕坐标系原点在左上角。 2、三维笛卡尔坐标系 三维笛卡尔坐标系要区分是左手坐标系还是右手坐标系。 左手坐标系&#xff1a;举起你的左手…

ELK日志

​​​​​​​

2024年租用阿里云服务器多少钱?最新价格表

阿里云服务器租用价格表2024年最新&#xff0c;云服务器ECS经济型e实例2核2G、3M固定带宽99元一年&#xff0c;轻量应用服务器2核2G3M带宽轻量服务器一年61元&#xff0c;ECS u1服务器2核4G5M固定带宽199元一年&#xff0c;2核4G4M带宽轻量服务器一年165元12个月&#xff0c;2核…

物联网实战--驱动篇之(七)RTC时钟(DS1302)

目录 一、RTC简介 二、DS1302介绍 三、初始化 四、字节读写 五、功能函数 一、RTC简介 实时时钟&#xff0c;简称RTC&#xff0c;这个在STM32的外设里也有&#xff0c;不过STM32F1系列的RTC实际上只有一个计数器功能&#xff0c;如果需要年月日要自己写软件计算 &#xff…

转行项目经理,考软考还是PMP?

这两者择其一&#xff0c;或者有条件的两个都可以考虑一下&#xff0c;因为国内对这两个证书的需求都很大。 从企业环境来看 PMP适用于各行各业&#xff0c;在外企更受欢迎。 软考适用于计算机领域&#xff0c;而且在国企和政府部门比较受欢迎。 因此&#xff0c;可以综合考…