【最后203篇系列】028 FastAPI的后臺任務處理

說明

今天偶然在別的文章里看到這個功能,突然覺得正好。

CeleryWorker已經搭好了,但是我一直想在用戶請求時進行額外的處理會比較影響處理時間,用這個正好可以搭配上。
在這里插入圖片描述
在這里插入圖片描述
我設想的一個場景:

  • 1 用戶發起請求
  • 2 接口中進行關鍵信息的日志記錄 logger.info這種,直接記錄在文本文件里
  • 3 影響請求后在后臺進行相關操作:在redis中計數,將數據轉發kafka等

這樣既不會影響請求時間,又可以把需要做的操作,例如在內存中記錄,修改狀態;采樣數據發送做完。

一個比較笨(現在有在用)的方法是在處理時將數據采樣發送到kafka,然后擔心kafka服務出問題,又做了try…except。當然,最壞的情況也還好,因為調用大模型通常都是數秒。

當然,在接口中logging和redis這樣的操作倒是沒關系,因為時間足夠短。某種程度上來說,logging+ logstash可能是更好的方案,redis都還有可能掛。

還有一個相對好一點的方法(準備好了還沒有啟用)。使用WCelery發送任務(甚至可以是復雜任務),并且可以再封裝一層異步(async httpx),這樣也只是多花一個請求時間。

當然這些都不如直接用FastAPI自帶的BackgroundTasks方法,這種服務啟動嵌入的方法應該更可靠。(其實在flask時代,就有before和after request裝飾器)

以下是一個實驗代碼(主要 by deepseek)

server.py

from fastapi import FastAPI, BackgroundTasks, HTTPException
import time
from typing import Optional
import loggingapp = FastAPI()# 配置日志
logging.basicConfig(filename='app.log', level=logging.INFO)# def write_log(message: str):
#     """記錄日志到文件(模擬耗時操作)"""
#     time.sleep(2)  # 模擬耗時操作
#     with open("log.txt", mode="a") as f:
#         f.write(f"{time.ctime()}: {message}\n")
#     logging.info(f"日志已記錄: {message}")import aiofiles  # 需要先安裝: pip3 install aiofiles
import asyncioasync def write_log(message: str):"""真正的異步日志寫入"""await asyncio.sleep(2)  # 正確使用awaitasync with aiofiles.open("log.txt", mode="a") as f:await f.write(f"{time.ctime()}: {message}\n")logging.info(f"日志已記錄: {message}")  # logging默認是同步的
def send_email(to: str, subject: str, body: Optional[str] = None):"""模擬發送郵件(帶錯誤處理)"""try:time.sleep(3)  # 模擬網絡延遲with open("email_logs.txt", "a") as f:content = f"""Time: {time.ctime()}To: {to}Subject: {subject}Body: {body or 'No content'}{'-'*30}"""f.write(content)print(f"郵件已發送給 {to}")except Exception as e:logging.error(f"郵件發送失敗: {str(e)}")def cleanup_temp_files():# aa"""模擬清理臨時文件"""time.sleep(1)print("臨時文件清理完成")from pydantic import BaseModelclass RegisterInput(BaseModel):username: stremail: str@app.post("/register")
async def register_user(user_input:RegisterInput , background_tasks: BackgroundTasks):"""用戶注冊接口(演示多個后臺任務)"""if not user_input.email.endswith("@example.com"):raise HTTPException(400, "僅支持 example.com 域名")# 添加多個后臺任務background_tasks.add_task(write_log,f"新用戶注冊: {user_input.username}, 郵箱: {user_input.email}")background_tasks.add_task(send_email,to=user_input.email,subject="歡迎注冊",body=f"尊敬的 {user_input.username},感謝您的注冊!")background_tasks.add_task(cleanup_temp_files)return {"message": "注冊成功","details": "激活郵件和日志記錄正在后臺處理"}@app.get("/stats")
async def get_stats(background_tasks: BackgroundTasks):"""獲取統計信息(演示快速響應+后臺處理)"""background_tasks.add_task(write_log,"用戶查看了統計信息")# 立即返回的簡單數據return {"active_users": 42,"note": "詳細日志正在后臺記錄"}if __name__ == "__main__":import uvicornuvicorn.run(app, host="0.0.0.0", port=8000)

test.py

resp = httpx.post('http://127.0.0.1:8000/register', json = {'username':'andy', 'email':'andy@example.com'})

對應產生的幾個文件,如log.txt

Fri Apr 18 23:27:02 2025: 新用戶注冊: andy, 郵箱: andy@example.com
Fri Apr 18 23:28:08 2025: 新用戶注冊: andy, 郵箱: andy@example.com
Fri Apr 18 23:29:52 2025: 新用戶注冊: andy, 郵箱: andy@example.com
Fri Apr 18 23:30:33 2025: 新用戶注冊: andy, 郵箱: andy@example.com
Fri Apr 18 23:39:40 2025: 新用戶注冊: andy001, 郵箱: andy001@example.com

實驗成功,感覺還挺好的。

原文有一些錯誤,說background_tasks只能執行同步任務,事實證明是錯誤的。某種程度上說,異步的才符合FastAPI的特點。

在這里插入圖片描述
另外,如果有些同步操作時間特別短是可以不用異步的。例如redis操作。
在這里插入圖片描述
以上對我有用,希望對你也有用。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/79479.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/79479.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/79479.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

uboot下讀取ubifs分區的方法

在uboot 的defconfig中增加以下內容: CONFIG_MTDIDS_DEFAULT"nand0nand0" CONFIG_MTDPARTS_DEFAULT"mtdpartsnand0:1M(boot1),1M(boot2),1M(hwinfo),6M(kernel1),6M(kernel2),56M(rootfs1),56M(rootfs2),-(ubi2)" CONFIG_CMD_UBIy 其中&#x…

圖+文+語音一體化:多模態合成數據集構建的實戰與方法論

目錄 圖文語音一體化:多模態合成數據集構建的實戰與方法論 一、多模態合成數據的核心價值 二、系統架構概覽 三、核心模塊與實現建議 ? 1. 文→圖:圖像合成(Text-to-Image) ? 2. 圖→文:自動描述(I…

linux驅動之poll

驅動中 poll 實現 在用戶空間實現事件操作的一個主要實現是調用 select/poll/epoll 函數。那么在驅動中怎么來實現 poll 的底層呢? 其實在內核的 struct file_operations 結構體中有一個 poll 成員,其就是底層實現的接口函數。 驅動中 poll 函數實現原…

第八篇:系統分析師第三遍——3、4章

目錄 一、目標二、計劃三、完成情況四、意外之喜(最少2點)1.計劃內的明確認知和思想的提升標志2.計劃外的具體事情提升內容和標志 五、總結 一、目標 通過參加考試,訓練學習能力,而非單純以拿證為目的。 1.在復習過程中,訓練快速閱讀能力、掌…

C++17 新特性簡解

C17 新特性簡解 一、核心語言特性 1. 結構化綁定&#xff08;Structured Bindings&#xff09; 用途&#xff1a;解構復合類型&#xff08;如元組、結構體&#xff09;為獨立變量 示例&#xff1a; #include <iostream> #include <tuple>int main() {// 解構 st…

PHP使用pandoc把markdown文件轉為word

文章目錄 首先安裝pandocPHP處理 服務器操作系統是Linux&#xff0c;centos 首先安裝pandoc yum install -y pandoc安裝完成后輸入如下代碼&#xff0c;檢查安裝是否成功 pandoc --versionPHP處理 我把markdown內容存到了數據庫里&#xff0c;所以要從數據庫讀取內容。對內容…

【Python學習筆記】Pandas實現Excel質檢記錄表初審、復核及質檢統計

背景&#xff1a; 我有這樣一個需要審核的飛書題目表&#xff0c;按日期分成多個sheet&#xff0c;有初審——復核——質檢三個環節&#xff0c;這三個環節是不同的同學在作業&#xff0c;并且領到同一個題目的人選是隨機的&#xff0c;也就是說&#xff0c;完成一道題的三個人…

守護進程編程、GDB調試以及外網連接樹莓派

目錄 一、什么是守護進程以及如何創建守護進程1. 什么是守護進程&#xff1f;2. 如何創建守護進程&#xff1f; 二、什么是GDB調試以及如何用GDB命令調試C程序1. 什么是GDB&#xff1f;2. 如何用GDB命令調試C程序&#xff1f; 三、外網訪問樹莓派 一、什么是守護進程以及如何創…

Logisim數字邏輯實訓——計數器設計與應用

4位遞增計數器 六進制計數器 十進制計數器 六十進制計數器 二十四進制計數器 計時器

發現“橫”字手寫有難度,對比兩個“橫”字

我發現手寫體“橫”字“好看”程度&#xff0c;難以比得上印刷體&#xff1a; 兩個從方正簡體啟體來的“橫”字&#xff1a; 哪個更好看&#xff1f;我是傾向于左邊一點。 <div style"transform: rotate(180deg); display: inline-block;"> 左邊是我從方正簡…

ubuntu 向右拖動窗口后消失了、找不到了

這是目前單顯示器的設置&#xff0c;因為實際只有1個顯示器&#xff0c;之前的設置如下圖所示&#xff0c;有2個顯示器&#xff0c;一個主顯示器&#xff0c;一個23寸的顯示器 ubuntu 22.04 系統 今天在操作窗口時&#xff0c;向右一滑&#xff0c;發現這個窗口再也不顯示了、找…

專精特新政策推動,B端UI設計如何賦能中小企業創新發展?

在當前數字化轉型浪潮下&#xff0c;專精特新政策為中小企業提供了強大的支持&#xff0c;助力其在細分領域實現專業化、精細化、特色化和創新化發展。B端UI設計作為提升企業數字化產品用戶體驗和工作效率的重要手段&#xff0c;能夠有效賦能中小企業創新發展。本文將探討專精特…

梯度下降代碼

整體流程 數據預處理:標準化->加一列全為1的偏置項 訓練:梯度下降,將數學公式轉換成代碼 預測 模型代碼 import numpy as np# 標準化函數&#xff1a;對特征做均值-方差標準化 # 返回標準化后的特征、新數據的均值和標準差&#xff0c;用于后續預測def standard(feats…

RAG 實戰|用 StarRocks + DeepSeek 構建智能問答與企業知識庫

文章作者&#xff1a; 石強&#xff0c;鏡舟科技解決方案架構師 趙恒&#xff0c;StarRocks TSC Member &#x1f449; 加入 StarRocks x AI 技術討論社區 https://mp.weixin.qq.com/s/61WKxjHiB-pIwdItbRPnPA RAG 和向量索引簡介 RAG&#xff08;Retrieval-Augmented Gen…

從零開始學A2A一:A2A 協議的高級應用與優化

A2A 協議的高級應用與優化 學習目標 掌握 A2A 高級功能 理解多用戶支持機制掌握長期任務管理方法學習服務性能優化技巧 理解與 MCP 的差異 分析多智能體場景下的優勢掌握不同場景的選擇策略 第一部分&#xff1a;多用戶支持機制 1. 用戶隔離架構 #mermaid-svg-Awx5UVYtqOF…

【C++】入門基礎【上】

目錄 一、C的發展歷史二、C學習書籍推薦三、C的第一個程序1、命名空間namespace2、命名空間的使用3、頭文件<iostream>是干什么的&#xff1f; 個人主頁<—請點擊 C專欄<—請點擊 一、C的發展歷史 C的起源可以追溯到1979年&#xff0c;當時Bjarne Stroustrup(本…

1panel第三方應用商店(本地商店)配置和使用

文章目錄 引言資源網站實戰操作說明 引言 1Panel 提供了一個應用提交開發環境&#xff0c;開發者可以通過提交應用的方式將自己的應用推送到 1Panel 的應用商店中&#xff0c;供其他用戶使用。由此衍生了一種本地應用商店的概念&#xff0c;用戶可以自行編寫應用配置并上傳到自…

Evidential Deep Learning和證據理論教材的區別(主要是概念)

最近終于徹底搞懂了Evidential Deep Learning&#xff0c;之前有很多看不是特別明白的地方&#xff0c;原來是和證據理論教材&#xff08;是的&#xff0c;不只是國內老師寫的&#xff0c;和國外的老師寫的教材出入也比較大&#xff09;的說法有很多不一樣&#xff0c;所以特地…

text-decoration: underline;不生效

必須得紀念一下&#xff0c;在給文本加下劃線時&#xff0c;發現在win電腦不生效&#xff0c;部分mac也不生效&#xff0c;只有個別的mac生效了&#xff0c;思考了以下幾種方面&#xff1a; 1.兼容性問題&#xff1f; 因為是electron項目&#xff0c;不存在瀏覽器兼容性問題&…

VUE SSR(服務端渲染)

&#x1f916; 作者簡介&#xff1a;水煮白菜王&#xff0c;一位前端勸退師 &#x1f47b; &#x1f440; 文章專欄&#xff1a; 前端專欄 &#xff0c;記錄一下平時在博客寫作中&#xff0c;總結出的一些開發技巧和知識歸納總結?。 感謝支持&#x1f495;&#x1f495;&#…