FastAPI 學(xué)習(xí) - Redis使用

  • 在配置redis的時(shí)候遇到了一個(gè)神奇的問(wèn)題
    在同一個(gè)請(qǐng)求中 使用redis可以set和get內(nèi)容
    另一個(gè)請(qǐng)求中卻不能get到之前set的內(nèi)容

1. 注冊(cè)redis到app

參考了別人的項(xiàng)目和redis的官方文檔, 在app啟動(dòng)的時(shí)候增加了redis的注冊(cè)

from redis import asyncio

@app.on_event("startup")
async def startup_event():
    app.redis = await asyncio.from_url(REDIS_URL, decode_responses=True, encoding="utf8", )

然后在后續(xù)的項(xiàng)目中通過(guò)request.app.redis.get/set 來(lái)插入和獲得內(nèi)容

2. 增加通用工具方法

在工具類(lèi)中增加了set_cache 和 get_cache del_cache

import json

from datetime import timedelta

from fastapi import Request


async def set_cache(key: str, value, request: Request, ex: timedelta = None) -> bool:
   if not all((key, value)):
       return False

   params = {'name': 'blog.cache.' + key, 'value': value}
   if ex:
       params['ex'] = ex

   if isinstance(value, int | float | str):
       return await request.app.redis.set(**params)
   else:
       try:
           params['value'] = json.dumps(value)
           return await request.app.redis.set(**params)
       except json.JSONDecodeError:
           return False


async def get_cache(key: str, request: Request) -> str:
   return await request.app.redis.get('blog.cache.' + key)


async def del_cache(key: str, request: Request) -> str:
   return await request.app.redis.delete('blog.cache.' + key)

可是在后續(xù)的使用過(guò)程中發(fā)現(xiàn)每次需要調(diào)用緩存的時(shí)候必須要傳入request, 也就是必須從接口進(jìn)入, 非常的不優(yōu)雅

于是發(fā)現(xiàn)redis是注冊(cè)在request.app中, 于是直接引用app, 嘗試使用app.redis.get/set/delete, 發(fā)現(xiàn)是有效的, 只是我目前的項(xiàng)目代碼結(jié)構(gòu)會(huì)導(dǎo)致循環(huán)引用的問(wèn)題, 于是優(yōu)化了項(xiàng)目的代碼結(jié)構(gòu)

3. 改為直接使用app.redis.get/set

現(xiàn)在就方便很多了, 在其他地方使用的時(shí)候也不需要注意傳遞request

import json

from datetime import timedelta

from config.init_blog import app


async def set_cache(key: str, value, ex: timedelta = None) -> bool:
    if not all((key, value)):
        return False

    params = {'name': 'blog.cache.' + key, 'value': value}
    if ex:
        params['ex'] = ex

    if isinstance(value, int | float | str):
        return await app.redis.set(**params)
    else:
        try:
            params['value'] = json.dumps(value)
            return await app.redis.set(**params)
        except json.JSONDecodeError:
            return False


async def get_cache(key: str) -> str:
    return await app.redis.get('blog.cache.' + key)


async def del_cache(key: str) -> str:
    return await app.redis.delete('blog.cache.' + key)

4. 優(yōu)化項(xiàng)目文件結(jié)構(gòu)

之前我的init_blog 文件中的 create_app方法不僅創(chuàng)建了FastAPI的app, 還做了靜態(tài)文件目錄掛載, 允許訪問(wèn)的源配置, CORS中間件的配置, pg數(shù)據(jù)庫(kù)注冊(cè), redis數(shù)據(jù)庫(kù)注冊(cè), 模塊路由的注冊(cè)

在這里面做了很多創(chuàng)建app以外的事情, 這樣非常的不優(yōu)雅, 而且路由注冊(cè)會(huì)引入其他模塊的文件, 導(dǎo)致通用工具包在引入全局app的時(shí)候出現(xiàn)循環(huán)引用

于是把這個(gè)方法進(jìn)行了拆分, create_app的時(shí)候只做app相關(guān)的配置(靜態(tài)文件目錄掛載, 允許訪問(wèn)的源配置, CORS中間件的配置), 其他的注冊(cè)放到其他文件中, 這里建議把路由注冊(cè)的方法放在一個(gè)獨(dú)立的文件里, 因?yàn)檫@個(gè)方法需要導(dǎo)入所有的模塊的router, 跟其他方法放在一起很容易出現(xiàn)循環(huán)引用

5. 添加幾個(gè)測(cè)試api

我在common模塊下的api文件里面都是用來(lái)測(cè)試的, 所以我就直接加到里面

@router.get('/redis/get/{key}')
async def test_redis_get(key: str):
    return await get_cache(key)


@router.get('/redis/set/{key}')
async def test_redis_set(key: str, value: str):
    await set_cache(key, value)
    return await get_cache(key)

然后進(jìn)入到swagger里面進(jìn)行測(cè)試
這里簡(jiǎn)書(shū)一直上傳圖片失敗, 所以就不放圖片了, 大家可以自己測(cè)試


后續(xù)如果有遇到其他問(wèn)題 我會(huì)繼續(xù)更新
歡迎關(guān)注此代碼倉(cāng)庫(kù), 如果覺(jué)得有用請(qǐng)給我一個(gè)??

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末桃煎,一起剝皮案震驚了整個(gè)濱河市花颗,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鬼悠,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件亏娜,死亡現(xiàn)場(chǎng)離奇詭異焕窝,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)维贺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)它掂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人溯泣,你說(shuō)我怎么就攤上這事虐秋。” “怎么了垃沦?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵客给,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我肢簿,道長(zhǎng)靶剑,這世上最難降的妖魔是什么蜻拨? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮桩引,結(jié)果婚禮上官觅,老公的妹妹穿的比我還像新娘。我一直安慰自己阐污,他們只是感情好休涤,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著笛辟,像睡著了一般功氨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上手幢,一...
    開(kāi)封第一講書(shū)人閱讀 48,970評(píng)論 1 284
  • 那天捷凄,我揣著相機(jī)與錄音,去河邊找鬼围来。 笑死跺涤,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的监透。 我是一名探鬼主播桶错,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼胀蛮!你這毒婦竟也來(lái)了院刁?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤粪狼,失蹤者是張志新(化名)和其女友劉穎退腥,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體再榄,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡狡刘,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了困鸥。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嗅蔬。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖窝革,靈堂內(nèi)的尸體忽然破棺而出购城,到底是詐尸還是另有隱情,我是刑警寧澤虐译,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布瘪板,位于F島的核電站,受9級(jí)特大地震影響漆诽,放射性物質(zhì)發(fā)生泄漏侮攀。R本人自食惡果不足惜锣枝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望兰英。 院中可真熱鬧撇叁,春花似錦、人聲如沸畦贸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)薄坏。三九已至趋厉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胶坠,已是汗流浹背君账。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留沈善,地道東北人乡数。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像闻牡,于是被迫代替她去往敵國(guó)和親净赴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容