如何部署FastAPI

环境:

Win10

FastAPI

问题描述:

如何部署FastAPI

解决方案:

FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,使用 Python 3.6 及更高版本。它的设计目的是提供简单且易于使用的接口,同时利用 Python 的类型提示和异步特性来实现高效的性能。以下是 FastAPI 的一些关键特点和优势:

关键特点

  1. 高性能:

    • FastAPI 是基于 Starlette(一个用于构建 Web 应用程序的高性能异步框架)构建的,同时也使用了 Pydantic 进行数据验证,因此其性能接近于 Node.js 和 Go 这样的语言构建的框架。
  2. 简单易用:

    • FastAPI 提供了简单的接口和清晰的文档,使得即使是初学者也能快速上手。通过使用 Python 的类型提示,您可以更容易地定义 API 的输入和输出。
  3. 支持异步编程:

    • FastAPI 支持异步请求处理,这使得它能够高效地处理大量并发请求,尤其适合 I/O 密集型的应用程序(例如,调用外部 API、数据库操作等)。
  4. 自动生成文档:

    • FastAPI 自动生成 OpenAPI(以前称为 Swagger)文档,使得用户可以方便地查看 API 的接口文档。可以通过 /docs 访问交互式文档,或者通过 /redoc 访问另一种风格的文档。
  5. 强类型支持:

    • FastAPI 利用 Python 的类型注释,支持请求体、查询参数和路径参数的类型验证。这有助于减少错误并使代码更加清晰。
  6. 依赖注入:

    • FastAPI 内置了一套简单而强大的依赖注入系统,使得组织代码和管理复杂依赖关系变得简单。
  7. 易于集成和扩展:

    • FastAPI 可以与其他 Python 库和框架无缝集成,例如 SQLAlchemy(数据库 ORM)、Redis,以及其他的第三方库。

使用示例

以下是一个简单的 FastAPI 示例,展示了如何定义一个 API,并处理 GET 和 POST 请求:

from fastapi import FastAPI
from pydantic import BaseModelapp = FastAPI()class Item(BaseModel):name: strprice: float@app.get("/")
async def read_root():return {"Hello": "World"}@app.post("/items/")
async def create_item(item: Item):return {"item_name": item.name, "item_price": item.price}

启动 FastAPI 应用

您可以使用 uvicorn 启动 FastAPI 应用:

uvicorn main:app --reload

其中 main 是包含 FastAPI 应用的 Python 文件名(不带扩展名),app 是 FastAPI 实例的名称。添加 --reload 标志以便在代码更改后自动重新加载服务器。

我这操作已火山api为例

1.安装库

pip install fastapi[all]pip install uvicorn

2.写个py文件

from fastapi import FastAPI, HTTPException
import websockets
import json
import gzip
import uuid
from io import BytesIO
from fastapi.responses import Responseapp = FastAPI()# 火山引擎的配置信息
appid = "9250999999713"  # 替换为您的实际appid
token = "y8suQ999999iQCNuduno"  # 替换为您的实际token
cluster = "volcano_tts"
voice_type = "zh_female_wanwanxiaohe_moon_bigtts"
host = "openspeech.bytedance.com"
api_url = f"wss://openspeech.bytedance.com/api/v1/tts/ws_binary"default_header = bytearray(b'\x11\x10\x11\x00')@app.post("/tts")
async def tts(text: str):if not text:raise HTTPException(status_code=400, detail="No text provided")submit_request_json = {"app": {"appid": appid,"token": token,"cluster": cluster},"user": {"uid": "388808087185088"},"audio": {"voice_type": voice_type,"encoding": "mp3","speed_ratio": 1.0,"volume_ratio": 1.0,"pitch_ratio": 1.0,},"request": {"reqid": str(uuid.uuid4()),"text": text,"text_type": "plain","operation": "submit"}}try:async with websockets.connect(api_url, extra_headers={"Authorization": f"Bearer {token}"}) as ws:payload_bytes = json.dumps(submit_request_json).encode()payload_bytes = gzip.compress(payload_bytes)full_client_request = default_header + len(payload_bytes).to_bytes(4, 'big') + payload_bytesawait ws.send(full_client_request)file_to_save = BytesIO()while True:res = await ws.recv()if res:done = parse_response(res, file_to_save)if done:breakelse:breakexcept websockets.exceptions.WebSocketException as e:raise HTTPException(status_code=500, detail=f"WebSocket connection error: {str(e)}")return Response(content=file_to_save.getvalue(), media_type='audio/mp3')def parse_response(res, file):# 解析响应数据的逻辑与官方示例代码相同# ...if __name__ == "__main__":import uvicornuvicorn.run(app, host="0.0.0.0", port=5100)

3.运行脚本
在这里插入图片描述
4.打开web页面
在这里插入图片描述

http api接口 火山

import os
import sys
from fastapi import FastAPI, HTTPException, Depends, Query, Depends
from fastapi.responses import StreamingResponse, JSONResponse
from pydantic import BaseModel
from typing import Optional
import io
import asyncio
import base64
import uuid
import logging
import httpx
import argparse
from pydub import AudioSegment# 设置日志配置
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)app = FastAPI()class TTSSettings:def __init__(self, token: str, app_id: str, cluster_id: str, user_id: str):self.token = tokenself.app_id = app_idself.cluster_id = cluster_idself.user_id = user_id# 初始化火山引擎 TTS 设置 (请根据实际情况调整这些值)
tts_settings = TTSSettings(token="y8uduno",  # 确保这里使用的是有效的令牌app_id="9713",cluster_id="volcano_tts",user_id="your_user_id"
)class TTSRequest(BaseModel):text: str  # 只需要提供文本字段async def request_tts(text: str) -> bytes:url = "https://openspeech.bytedance.com/api/v1/tts"headers = {"Authorization": f"Bearer;{tts_settings.token}",  # 注意这里的分号"Content-Type": "application/json"}data = {"app": {"appid": tts_settings.app_id,"token": tts_settings.token,"cluster": tts_settings.cluster_id},"user": {"uid": tts_settings.user_id},"audio": {"voice_type": "zh_female_wanwanxiaohe_moon_bigtts",  # 使用适当的音色类型"encoding": "mp3","speed_ratio": 1.0},"request": {"reqid": str(uuid.uuid4()),  # 每次调用都生成新的唯一 reqid"text": text,"operation": "query"}}logger.debug(f"Sending TTS request with text: {text}")async with httpx.AsyncClient() as client:try:response = await client.post(url, json=data, headers=headers)response.raise_for_status()  # 如果响应状态码不是 2xx,则抛出异常except httpx.HTTPStatusError as exc:logger.error(f"HTTP error occurred while requesting TTS: {exc.response.status_code}, {exc.response.text}")raise HTTPException(status_code=exc.response.status_code, detail=exc.response.text)result = response.json()code = result.get('code')message = result.get('message')logger.debug(f"TTS response received: {result}")if code == 3000:  # 请求成功audio_base64 = result.get('data')if audio_base64:logger.info("Successfully received MP3 audio data.")return base64.b64decode(audio_base64)else:raise Exception("No audio data in the response.")else:raise Exception(f"TTS request failed: {message}")def mp3_to_wav_stream(mp3_data: bytes) -> io.BytesIO:"""Convert MP3 data to WAV format."""logger.debug("Converting MP3 to WAV...")audio_segment = AudioSegment.from_file(io.BytesIO(mp3_data), format="mp3")wav_io = io.BytesIO()audio_segment.export(wav_io, format="wav")wav_io.seek(0)logger.debug("MP3 to WAV conversion completed.")return wav_ioasync def generate_tts_audio(text: str, media_type: str = "wav") -> io.BytesIO:try:mp3_data = await request_tts(text)if mp3_data is not None:output_io = io.BytesIO()if media_type.lower() != "mp3":# 使用 pydub 和 ffmpeg 转换为指定格式wav_stream = mp3_to_wav_stream(mp3_data)audio_segment = AudioSegment.from_file(wav_stream, format="wav")audio_segment.export(output_io, format=media_type)else:# 如果请求的是 MP3 格式,则直接返回原始数据output_io.write(mp3_data)output_io.seek(0)return output_ioelse:raise Exception("Failed to generate TTS audio.")except Exception as e:logger.error(f"Error during TTS generation: {e}")raise@app.post("/tts")
async def process_tts_request(request_data: TTSRequest):try:fixed_media_type = "wav"  # 固定其他参数audio_io = await generate_tts_audio(text=request_data.text,media_type=fixed_media_type)# 定义保存文件的路径和文件名output_dir = "output_audios"  # 输出目录if not os.path.exists(output_dir):os.makedirs(output_dir)  # 如果目录不存在,则创建# 使用 UUID 生成唯一的文件名,避免文件名冲突file_name = f"{uuid.uuid4()}.{fixed_media_type}"file_path = os.path.join(output_dir, file_name)# 将 BytesIO 内容写入文件with open(file_path, 'wb') as f:f.write(audio_io.getvalue())logger.info(f"Audio saved to {file_path}.")return StreamingResponse(audio_io, media_type=f"audio/{fixed_media_type}")except Exception as e:logger.error(f"TTS request failed: {e}")raise HTTPException(status_code=400, detail=str(e))@app.get("/")
async def read_root():"""根路径简单响应"""return {"message": "Welcome to the TTS API"}@app.get("/control")
async def control(command: str = Query(..., description="Command to execute")):if command == "restart":os.execl(sys.executable, sys.executable, *sys.argv)elif command == "exit":os.kill(os.getpid(), signal.SIGTERM)return JSONResponse(content={"message": "Service terminated"}, status_code=200)else:raise HTTPException(status_code=400, detail="Invalid command")if __name__ == "__main__":import uvicornparser = argparse.ArgumentParser(description="VolcanoTTS API")parser.add_argument("-a", "--bind_addr", type=str, default="127.0.0.1", help="Bind address, default: 127.0.0.1")parser.add_argument("-p", "--port", type=int, default=9881, help="Port number, default: 9881")args = parser.parse_args()uvicorn.run(app, host=args.bind_addr, port=args.port)

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

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

相关文章

day10性能测试(2)——Jmeter安装环境+线程组+Jmeter参数化

【没有所谓的运气🍬,只有绝对的努力✊】 目录 1、LoadRunner vs Jmeter 1.1 LoadRunner 1.2 Jmeter 1.3 对比小结 2、Jmeter 环境安装 2.1 安装jdk 2.2 安装Jmeter 2.3 小结 3、Jmeter 文件目录结构 4、Jmeter默认配置修改 5、Jmeter元件、组…

Android显示系统(08)- OpenGL ES - 图片拉伸

Android显示系统(02)- OpenGL ES - 概述 Android显示系统(03)- OpenGL ES - GLSurfaceView的使用 Android显示系统(04)- OpenGL ES - Shader绘制三角形 Android显示系统(05)- OpenGL…

【工业机器视觉】基于深度学习的水表盘读数识别(4-训练与预测)

【工业机器视觉】基于深度学习的仪表盘识读(读数识别)(3)-CSDN博客 训练与预测 Ultralytics YOLO指的是由Ultralytics公司开发的一系列基于YOLO(You Only Look Once)架构的目标检测算法。YOLO是一种实时目标检测系统,它…

C语言——上下弹跳的小球

//上下弹跳的小球 #include<stdio.h> #include<stdlib.h> #include<windows.h> int main() {int i,j;int x5;int y10;int height20;int velocity1; //记录速度的变量while(1) {xxvelocity;system("cls"); //清屏函数for(i0;i<x;i) {printf…

河工oj第七周补题题解2024

A.GO LecturesⅠ—— Victory GO LecturesⅠ—— Victory - 问题 - 软件学院OJ 代码 统计 #include<bits/stdc.h> using namespace std;double b, w;int main() {for(int i 1; i < 19; i ) {for(int j 1; j < 19; j ) {char ch; cin >> ch;if(ch B) b …

如何利用DBeaver配置连接MongoDB和人大金仓数据库

最近根据国产化要求&#xff0c;需要使用国产数据库&#xff0c;但习惯使用DBeaver连接各种成熟的商业或开源数据库。因此&#xff0c;就想着如何继续基于该工具&#xff0c;连接MongoDB和人大金仓数据库&#xff0c;查了半天很多地方说法不统一&#xff0c;所以自己就简单整理…

esp32 OTA学习笔记

csv分区表中ota-0和ota-1存放程序 不超过1600kb的程序可以ota&#xff08;可手动划分&#xff09; 分区表中有 ota0和ota1两个数据分区。 ota是指先下载固件到ota1然后下次从ota1启动&#xff0c;回滚就是回到ota0 启动。 关于固件&#xff1a; bin文件可以用arduino生成也可以…

获得日志记录之外的新视角:应用程序性能监控简介(APM)

作者&#xff1a;来自 Elastic David Hope 日志记录领域即将发生改变。在这篇文章中&#xff0c;我们将概述从单纯的日志记录到包含日志、跟踪和 APM 的完全集成解决方案的推荐流程。 通过 APM 和跟踪优先考虑客户体验 企业软件开发和运营已成为一个有趣的领域。我们拥有一些非…

【Python网络爬虫 常见问题汇总】

目录 1. 爬取图片出现403解决办法&#xff1a;设置请求头中的Referer字段 2.关于干坏事的问题后续不定期更新 欢迎共同探讨学习进步 1. 爬取图片出现403 问题出自案例9&#xff0c;已解决。 【Python网络爬虫笔记】9- 抓取优美图库高清壁纸 当在爬取图库图片时遇到 403 错误…

Redis 数据结构(一)—字符串、哈希表、列表

Redis&#xff08;版本7.0&#xff09;的数据结构主要包括字符串&#xff08;String&#xff09;、哈希表&#xff08;Hash&#xff09;、列表&#xff08;List&#xff09;、集合&#xff08;Set&#xff09;、有序集合&#xff08;Sorted Set&#xff09;、超日志&#xff08…

Docker 安装 Jenkins:2.346.3

准备&#xff1a;已安装Docker&#xff0c;已配置服务器安全组规则 1581 1、拉取镜像 [rootTseng ~]# docker pull jenkins/jenkins:2.346.3 2.346.3: Pulling from jenkins/jenkins 001c52e26ad5: Pull complete 6b8dd635df38: Pull complete 2ba4c74fd680: Pull complet…

学者观察 | Web 3.0生态治理及其安全——北京交通大学副教授李超

导语 李超教授认为Web 3.0中无论是链上治理还是链下治理都有其优劣。链下治理机制更侧重于社区广泛参与和讨论&#xff0c;过程较为繁琐&#xff0c;但能够形成广泛的社区支持和参与&#xff0c;增强决策的合法性和接受度&#xff1b;链上治理机制通过直接在区块链上执行决策&…

RPC设计--应用层缓冲区,TcpBuffer

为什么需要应用层的buffer 为了方便数据处理&#xff0c;从fd上直接读写然后做包的组装、拆解不够方便方便异步发送&#xff0c;将数据写到应用层buffer后即可返回&#xff0c;让epoll即event_loop去异步发送。提高发送效率&#xff0c;多个小包可合并发送 buffer 设计 可以…

QT实战--带行号的支持高亮的编辑器实现(2)

本文主要介绍了第二种实现带行号的支持高亮的编辑器的方式,基于QTextEdit实现的,支持自定义边框,背景,颜色,以及滚动条样式,支持输入变色,复制文本到里面变色,支持替换,是一个纯专业项目使用的编辑器 先上效果图: 1.头文件ContentTextEdit.h #ifndef CONTENT_TEXT_…

Cursor 提示 Too many free trial accounts used on this machine,继续使用方法

Cursor 一直用免费账户&#xff0c;今天使用的时候突然提示&#xff1a; 解决方法&#xff1a; 找到 设备ID 进行重置解决。 位置 $HOME/Library/Application Support/Cursor/User/globalStorage/storage.json 写一个重置脚本&#xff1a; #!/bin/bashgenerate_hex() {loca…

【中间件开发】Redis基础命令详解及概念介绍

文章目录 前言一、Redis相关命令详解及原理1.1 string、set、zset、list、hash1.1.1 string1.1.2 list1.1.3 hash1.1.4 set1.1.5 zset 1.2 分布式锁的实现1.3 lua脚本解决ACID原子性1.4 Redis事务的ACID性质分析 二、Redis协议与异步方式2.1 Redis协议解析2.1.1 redis pipeline…

【WRF理论第十三期】详细介绍 Registry 的作用、结构和内容

目录 1. Introduction&#xff1a;介绍 Registry 的作用和功能。2. Registry Contents&#xff1a;详细描述 Registry 的结构和内容&#xff0c;包括各个部分的条目类型。2.1. DIMSPEC ENTRIES&#xff08;维度规格条目&#xff09;2.2. STATE ENTRIES&#xff08;状态变量条目…

计算机键盘简史 | 键盘按键功能和指法

注&#xff1a;本篇为 “计算机键盘简史 | 键盘按键功能和指法” 相关文章合辑。 英文部分机翻未校。 The Evolution of Keyboards: From Typewriters to Tech Marvels 键盘的演变&#xff1a;从打字机到技术奇迹 Introduction 介绍 The keyboard has journeyed from a humb…

Java版-图论-拓扑排序与有向无环图

拓扑排序 拓扑排序说明 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边<u,v>∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列…

LeetCode 0935.骑士拨号器:动态规划(DP)

【LetMeFly】935.骑士拨号器&#xff1a;动态规划(DP) 力扣题目链接&#xff1a;https://leetcode.cn/problems/knight-dialer/ 象棋骑士有一个独特的移动方式&#xff0c;它可以垂直移动两个方格&#xff0c;水平移动一个方格&#xff0c;或者水平移动两个方格&#xff0c;垂…