开源模型应用落地-FastAPI-助力模型交互-WebSocket篇(二)

一、前言

    使用 FastAPI 可以帮助我们更简单高效地部署 AI 交互业务。FastAPI 提供了快速构建 API 的能力,开发者可以轻松地定义模型需要的输入和输出格式,并编写好相应的业务逻辑。

    FastAPI 的异步高性能架构,可以有效支持大量并发的预测请求,为用户提供流畅的交互体验。此外,FastAPI 还提供了容器化部署能力,开发者可以轻松打包 AI 模型为 Docker 镜像,实现跨环境的部署和扩展。

    总之,使用 FastAPI 可以大大提高 AI 应用程序的开发效率和用户体验,为 AI 模型的部署和交互提供全方位的支持。

    基础入门:开源模型应用落地-FastAPI-助力模型交互-WebSocket篇(一),本篇学习如何接收认证参数以及处理断开连接


二、术语

2.1.FastAPI

    FastAPI 是一个用于构建 API 的现代、快速(高性能)的 Python Web 框架。它是基于标准 Python 类型注释的 ASGI (Asynchronous Server Gateway Interface) 框架。

FastAPI 具有以下主要特点:

  1. 快速: FastAPI 使用 ASGI 服务器和 Starlette 框架,在性能测试中表现出色。它可以与 Uvicorn 一起使用,提供非常高的性能。

  2. 简单: FastAPI 利用 Python 类型注释,使 API 定义变得简单且直观。开发人员只需要定义输入和输出模型,FastAPI 会自动生成 API 文档。

  3. 现代: FastAPI 支持 OpenAPI 标准,可以自动生成 API 文档和交互式文档。它还支持 JSON Schema 和数据验证。

  4. 全功能: FastAPI 提供了路由、依赖注入、数据验证、安全性、测试等功能,是一个功能齐全的 Web 框架。

  5. 可扩展: FastAPI 被设计为可扩展的。开发人员可以轻松地集成其他库和组件,如数据库、身份验证等。

2.2.WebSocket

    是一种计算机通信协议,它提供了在单个 TCP 连接上进行全双工通信的机制。它是 HTML5 一个重要的组成部分。

WebSocket 协议主要有以下特点:

  1. 全双工通信:WebSocket 允许客户端和服务器之间进行双向实时通信,即数据可以同时在两个方向上流动。这与传统的 HTTP 请求-响应模型不同,HTTP 中数据只能单向流动。

  2. 持久性连接:WebSocket 连接是一种持久性的连接,一旦建立就会一直保持,直到客户端或服务器主动关闭连接。这与 HTTP 的连接是短暂的不同。

  3. 低开销:相比 HTTP 请求-响应模型,WebSocket 在建立连接时需要较少的数据交换,因此网络开销较小。

  4. 实时性:由于 WebSocket 连接是持久性的,且数据可以双向流动,因此 WebSocket 非常适用于需要实时、低延迟数据交互的应用场景,如聊天应用、实时游戏、股票行情等。


三、前置条件

3.1. 创建虚拟环境&安装依赖

conda create -n fastapi_test python=3.10
conda activate fastapi_test
pip install fastapi websockets uvicorn

四、技术实现

4.1. 接收认证参数

    在使用 FastAPI 和 WebSocket 构建 API 接口时,存在一些安全风险需要注意,例如:身份验证和授权:确保API有适当的身份验证和授权机制,以防止未经授权的访问

服务端:

from typing import Annotated
from fastapi import (
    Depends,
    FastAPI,
    WebSocket,
    WebSocketException,
    status,
)
import uvicorn

app = FastAPI()

async def authenticate(
    websocket: WebSocket,
    userid: str,
    secret: str,
):
    if userid is None or secret is None:
        raise WebSocketException(code=status.WS_1008_POLICY_VIOLATION)

    print(f'userid: {userid},secret: {secret}')
    if '12345' == userid and 'xxxxxxxxxxxxxxxxxxxxxxxxxx' == secret:
        return 'pass'
    else:
        return 'fail'



@app.websocket("/ws")
async def websocket_endpoint(*,websocket: WebSocket,userid: str,permission: Annotated[str, Depends(authenticate)],):
    await websocket.accept()
    while True:
        text = await websocket.receive_text()

        if 'fail' == permission:
            await websocket.send_text(
                f"authentication failed"
            )
        else:
            await websocket.send_text(f"receive message from: {userid}, text was: {text}")

if __name__ == '__main__':
    uvicorn.run(app, host='0.0.0.0',port=7777)

客户端:

<!DOCTYPE html>
<html>
    <head>
        <title>Chat</title>
    </head>
    <body>
        <h1>WebSocket Chat</h1>
        <form action="" onsubmit="sendMessage(event)">
            <label>USERID: <input type="text" id="userid" autocomplete="off" value="12345"/></label>
            <label>SECRET: <input type="text" id="secret" autocomplete="off" value="xxxxxxxxxxxxxxxxxxxxxxxxxx"/></label>
            <br/>
            <button onclick="connect(event)">Connect</button>
            <hr>
            <label>Message: <input type="text" id="messageText" autocomplete="off"/></label>
            <button>Send</button>
        </form>
        <ul id='messages'>
        </ul>
        <script>
            var ws = null;
            function connect(event) {
                var userid = document.getElementById("userid")
                var secret = document.getElementById("secret")
                ws = new WebSocket("ws://localhost:7777/ws?userid="+userid.value+"&secret=" + secret.value);
                ws.onmessage = function(event) {
                    var messages = document.getElementById('messages')
                    var message = document.createElement('li')
                    var content = document.createTextNode(event.data)
                    message.appendChild(content)
                    messages.appendChild(message)
                };
                event.preventDefault()
            }
            function sendMessage(event) {
                var input = document.getElementById("messageText")
                ws.send(input.value)
                input.value = ''
                event.preventDefault()
            }
        </script>
    </body>
</html>

调用结果:

输入正确的userid和secret

输入错误的userid和secret

4.2. 处理断开连接

在4.1.接收认证参数的代码基础上,进行修改

from typing import Annotated
from fastapi import (
    Depends,
    FastAPI,
    WebSocket,
    WebSocketException,
    WebSocketDisconnect,
    status,
)
import uvicorn


class ConnectionManager:
    def __init__(self):
        self.active_connections: list[WebSocket] = []

    async def connect(self, websocket: WebSocket):
        await websocket.accept()
        self.active_connections.append(websocket)

    def disconnect(self, websocket: WebSocket):
        self.active_connections.remove(websocket)

    async def send_personal_message(self, message: str, websocket: WebSocket):
        await websocket.send_text(message)

    async def broadcast(self, message: str):
        for connection in self.active_connections:
            await connection.send_text(message)

manager = ConnectionManager()

app = FastAPI()

async def authenticate(
    websocket: WebSocket,
    userid: str,
    secret: str,
):
    if userid is None or secret is None:
        raise WebSocketException(code=status.WS_1008_POLICY_VIOLATION)

    print(f'userid: {userid},secret: {secret}')
    if '12345' == userid and 'xxxxxxxxxxxxxxxxxxxxxxxxxx' == secret:
        return 'pass'
    else:
        return 'fail'



@app.websocket("/ws")
async def websocket_endpoint(*,websocket: WebSocket,userid: str,permission: Annotated[str, Depends(authenticate)],):
    await manager.connect(websocket)
    try:
        while True:
            text = await websocket.receive_text()

            if 'fail' == permission:
                await manager.send_personal_message(
                    f"authentication failed", websocket
                )
            else:
                await manager.send_personal_message(f"receive message from: {userid}, text was: {text}", websocket)

    except WebSocketDisconnect:
        manager.disconnect(websocket)
        print(f"Client #{userid} left the chat")
        await manager.broadcast(f"Client #{userid} left the chat")

if __name__ == '__main__':
    uvicorn.run(app, host='0.0.0.0',port=7777)

调用结果:

1. 打开会话一:

2. 打开会话二:

3.关闭其中一个会话


五、附带说明

5.1. FastAPI框架中Depends关键字的作用

  1. 依赖管理:定义函数之间的依赖关系,将一个函数的输出作为另一个函数的输入。

  2. 授权和认证:检查用户的身份和权限,确保只有授权的用户才能访问特定的路由或执行特定的操作。

  3. 数据校验:对输入数据进行校验,确保输入数据满足特定的格式或约束条件。

  4. 依赖注入:实现依赖注入,将依赖项注入到函数中,而不是在函数内部创建依赖项。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Leetcode Hot100之矩阵

1. 矩阵置零 题目描述 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 解题思路 题目要求进行原地更改&#xff0c;也就是不能使用额外的空间&#xff0c;因此我们可以使用第一行的元素来记录对应的…

【软件下载】Folx详细安装教程视频-Folx软件最新版下载

根据大数据调查表明Acceleration PRO下载&#xff1a;抽出多达10个流的故障能够显着提高下载速度。根据行业数据显示与iTunes PRO集成&#xff1a;通过将Folx集成到iTunes来下载歌曲和视频&#xff0c;能够在下载后立即自动添加到iTunes库。实际上我们可以这样讲通过代理下载&a…

Git 冲突处理指南:恢复 Git Reset

⭐️我叫忆_恒心&#xff0c;一名喜欢书写博客的研究生&#x1f468;‍&#x1f393;。 如果觉得本文能帮到您&#xff0c;麻烦点个赞&#x1f44d;呗&#xff01; 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧&#xff0c;喜欢的小伙伴给个三连支…

10个AI高考上岸朋友圈文案设计

高考是人生中的一个重要时刻&#xff0c;上岸后分享朋友圈的文案可以既表达喜悦&#xff0c;也可以展现对未来的期待。以下是10个不同风格的高考上岸朋友圈文案&#xff0c;供你参考&#xff1a; 1. **梦想成真版**&#xff1a; "十年磨一剑&#xff0c;今朝试锋芒。高…

After Effects 2024 mac/win版:创意视效,梦想起航

After Effects 2024是一款引领视效革命的专业软件&#xff0c;汇聚了创意与技术的精华。作为Adobe推出的全新版本&#xff0c;它以其强大的视频处理和动画创作能力&#xff0c;成为从事设计和视频特技的机构&#xff0c;如电视台、动画制作公司、个人后期制作工作室以及多媒体工…

【Linux】进程信号_2

文章目录 八、进程信号1. 信号 未完待续 八、进程信号 1. 信号 除了可以使用 kill 命令和键盘来生成信号&#xff0c;我们也可以使用系统调用来生成信号。 kill函数可以对指定进程发送指定信号。 使用方法&#xff1a; int main(int argc, char *argv[]) {if (argc ! 3) {c…

利用viztracer进行性能分析和优化

上一篇文章&#xff0c;我们详细讲解了scalene这个性能分析和优化工具的使用流程&#xff1b;今天&#xff0c;我们将深入探讨另一个性能分析和优化工具——viztracer。 什么是viztracer&#xff1f; viztracer是一个非常强大的分析器&#xff0c;可以生成详细的性能报告和可…

信号与系统实验-实验五 离散时间系统的时域分析

一、实验目的 1、理解离散信号的定义与时域特征&#xff0c;掌握在时域求解信号的各种变换运算&#xff1b; 2、掌握离散系统的单位响应及其 MATLAB 实现的方法&#xff1b; 3、掌握离散时间序列卷积及其 MATLAB 实现的方法&#xff1b; 4、掌握利用 MATLAB 求解微分方程&a…

国内有哪些比较优秀的wordpress主题?

WordPress作为全球最受欢迎的开源内容管理系统之一&#xff0c;拥有众多优质的主题供用户选择。那么国内有哪些比较优秀的wordpress主题呢&#xff1f;下面小编就和大家分享国内功能比较完善比较受欢迎的wordpress主题。 wordpress主题合集&#xff1a;WP主题-办公人导航https:…

力扣1541. 平衡括号字符串的最少插入次数

Problem: 1541. 平衡括号字符串的最少插入次数 文章目录 题目描述思路及解法复杂度Code 题目描述 思路及解法 Problem: 力扣921. 使括号有效的最少添加 类似于上述题目&#xff0c;不过此时一个左括号要和两个右括号配对 1.同理上述题目&#xff0c;遍历字符串时若遇见一个左括…

探索小众爱好:打造个人韧性与特色之路

在这个信息爆炸的时代&#xff0c;我们很容易陷入“千篇一律”的漩涡中&#xff0c;无论是生活方式还是兴趣爱好&#xff0c;似乎都趋向于某种“流行”或“热门”。然而&#xff0c;真正的个性与魅力&#xff0c;往往来源于那些不为大众所知的小众爱好。今天&#xff0c;我想和…

电脑硬盘数据恢复,4个方法,轻松恢复数据

在数字化时代的浪潮中&#xff0c;电脑硬盘不仅是存储数据的仓库&#xff0c;更是我们生活、工作、学习的记忆宫殿。然而&#xff0c;当这个宫殿中的一部分珍贵记忆突然消失&#xff0c;仿佛历史的片段被无情地抹去&#xff0c;我们不禁会感到焦虑和恐慌。此时&#xff0c;电脑…

环球赛乐科技有限公司与北京城市学院共建实习“绿色通道”

环球赛乐&#xff08;北京&#xff09;科技有限公司&#xff08;简称“赛氪网”&#xff09;与北京城市学院近日宣布&#xff0c;双方将合作开通顶岗实习“绿色通道”&#xff0c;旨在为实习生提供高质量的实践机会和就业平台。此次合作不仅体现了校企合作的深度融合&#xff0…

【数据结构】带头双向循环链表的实现及链表顺序表的区别

目录 一、带头双向循环链表接口实现 连接关系&#xff1a; 创建哨兵位&#xff08;表头&#xff09;&#xff1a; 头插——头删&#xff1a; 尾插——尾删&#xff1a; 查找——打印&#xff1a; 指定位置pos前插入&#xff0c;删除pos位置&#xff1a; 链表销毁&#x…

39 - 电影评分(高频 SQL 50 题基础版)

39 - 电影评分 (selectu.name as results fromMovieRating m left join Users u on m.user_idu.user_id GROUP BYm.user_id order by count(*) desc,u.name asc limit 1) union all (selectm1.title as results fromMovieRating m left join Movies m1 on m.movie_idm1.movie…

SQL实现UUIDv7

当我们选择数据库的主键类型时&#xff0c;通常会考虑自增数字或者 UUID。但是这两种类型都有优缺点&#xff0c;自增字段简单有序&#xff0c;性能良好&#xff0c;最大的问题是无法保证全局唯一性&#xff0c;分布式场景受限&#xff1b;UUID 具有全局唯一性&#xff0c;适合…

fastadmin框架修改前端时间戳格式的时区

一、上传文件 将 moment-timezone-with-data.js 和 moment-timezone-with-data.min.js 文件上传到项目的 \public\assets\libs\moment\ 文件夹中。 二、配置中引入文件 在 \public\assets\js\require-backend.js 文件中增加所引入文件的配置: moment-timezone-with-data: …

ITSG、COST-G、Tongji和WHU Level-2数据产品读取绘图(Matlab)

数据介绍&#xff1a; ICGEM International Center for Global Gravity Field Models (gfz-potsdam.de) ITSG 2018&#xff1a;Institute of Geodesy at Graz University of Technolog&#xff08;格拉茨理工大学大地测量研究所&#xff09; 2018版本&#xff0c;最高60阶球谐…

深度之眼(二十六)——神经网络基础知识(一)

文章目录 一、前言二、神经网络与多层感知机2.1 人工神经元2.2 人工神经网络2.3 多层感知机2.4 激活函数 一、前言 看了下课程安排&#xff0c;自己还是没安排好&#xff0c;刚刚捋清了一下思路。 基础&#xff1a;python、数理 认识&#xff1a;神经网络基础、opencv基础、py…

加速科技Flash存储测试解决方案 全面保障数据存储可靠性

Flash存储芯片 现代电子设备的核心数据存储守护者 Flash存储芯片是一种关键的非易失性存储器&#xff0c;作为现代电子设备中不可或缺的核心组件&#xff0c;承载着数据的存取重任。这种小巧而强大的芯片&#xff0c;以其低功耗、可靠性、高速的读写能力和巨大的存储容量&…