FastAPI(64)- Settings and Environment Variables 配置项和环境变量(下)

简介: FastAPI(64)- Settings and Environment Variables 配置项和环境变量(下)

命令行执行

> pytest 53_settings_test.py                                                      
============================================================================================================ test session starts ============================================================================================================
platform darwin -- Python 3.9.5, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: /Users/polo/Downloads/FastAPI_project
plugins: anyio-3.3.2
collected 1 item                                                                                                                                                                                                                            
53_settings_test.py .                                                                                                                                                                                                                 [100%]
============================================================================================================= 1 passed in 0.30s =============================================================================================================


使用 .env 文件


背景

如果有会经常变化的设置项,也许在不同的环境中,将它们放在一个文件中,然后从文件中读取它们,就好像它们是环境变量一样

这些环境变量通常放在一个文件 .env 中,该文件称为“dotenv”

 

tips

  • 以点 (.) 开头的文件是类 Unix 系统(如 Linux 和 macOS)中的隐藏文件
  • 但是 dotenv 文件实际上不必具有那个确切的文件名
  • Pydantic 支持使用外部库读取这类型的文件

 

安装第三方库

pip install python-doten

 

.env 文件

ADMIN_EMAIL="xiaopolo@example.com"

APP_NAME="小菠萝"

 

config.py 文件

from pydantic import BaseSettings
class Settings(BaseSettings):
    app_name: str = "Awesome API"
    admin_email: str
    items_per_user: int = 50
    class Config:
        # 设置需要识别的 .env 文件
        env_file = ".env"
        # 设置字符编码
        env_file_encoding = 'utf-8'


第二种调用 .env 的方法

# 创建 Settings 对象的时候指定

settings = Settings(_env_file='.env', _env_file_encoding='utf-8')

 

lru_cache


背景

继上面的栗子,读取 .env 文件可能是一件代价高昂(缓慢)的操作

从性能角度出发,肯定希望只读取一次,后续每个请求可以重复使用同一个 Settings 对象,这样就只会读取一次 .env 文件

def get_settings():

   return Settings()

上述代码,如果作为请求的依赖项,那么每次请求进来,都会创建一个 Settings 对象,然后读取一次 .env 文件,这不是我们希望的

 

@lru_cache

如果加上了 @lru_cache 那么 get_settings 只会在第一次调用的时候执行一次,然后 Settings 对象也只会创建一次,.env 文件也只会读取一次


from functools import lru_cache
from fastapi import Depends, FastAPI
from . import config
app = FastAPI()
@lru_cache()
def get_settings():
    return config.Settings()
@app.get("/info")
async def info(settings: config.Settings = Depends(get_settings)):
    return {
        "app_name": settings.app_name,
        "admin_email": settings.admin_email,
        "items_per_user": settings.items_per_user,
    }


对于后续请求的依赖项中的 get_settings() 的任何后续调用,它不会执行 get_settings() 的内部代码并创建新的 Settings 对象,而是返回与第一次调用时返回的相同对象

 

lru_cache 技术细节

  • @lru_cache() 修改它修饰的函数返回与第一次返回相同的值,而不是再次执行函数内部代码
  • 因此,它下面的函数将针对每个参数组合执行一次
  • 然后,每当使用完全相同的参数组合调用函数时,每个参数组合返回相同的值将一次又一次地使用
  • 在请求依赖项 get_settings() 的情况下,该函数没有参数,所以它总是返回相同的值
  • 这样,它的行为就好像它只是一个全局变量
  • 但是因为它使用了一个依赖函数,所以可以很容易地覆盖它进行测试
  • @lru_cache() 是 functools 的一部分,它是 Python 标准库的一部分
  • 使用 @lru_cache() 可以避免为每个请求一次又一次地读取 .env 文件,同时可以在测试期间覆盖它的值

 

有参数的函数的栗子

@lru_cache()
def say_hi(name: str, salutation: str = "Ms."):
    print(123)
    return f"Hello {salutation} {name}"
print(say_hi(name="Camila"))
print(say_hi(name="Camila"))
print(say_hi(name="Rick", salutation="Mr."))
print(say_hi(name="Rick", salutation="Mr."))
print(say_hi(name="Camila"))
print(say_hi(name="Rick", salutation="Mr."))


运行结果

123
Hello Ms. Camila
Hello Ms. Camila
123
Hello Mr. Rick
Hello Mr. Rick
Hello Ms. Camila
Hello Mr. Rick


使用完全相同的参数调用函数时,直接返回结果而不会执行厘米的代码

 

原理图

微信图片_20220515164913.png



相关文章
|
API 数据库 数据安全/隐私保护
FastAPI(64)- Settings and Environment Variables 配置项和环境变量(上)
FastAPI(64)- Settings and Environment Variables 配置项和环境变量(上)
529 0
FastAPI(64)- Settings and Environment Variables 配置项和环境变量(上)
|
NoSQL Redis 数据库
FastAPI(六十七)实战开发《在线课程学习系统》接口开发--用户登陆接口开发
FastAPI(六十七)实战开发《在线课程学习系统》接口开发--用户登陆接口开发
|
NoSQL 测试技术 Redis
FastAPI(八十四)实战开发《在线课程学习系统》--接口测试(下)
FastAPI(八十四)实战开发《在线课程学习系统》--接口测试(下)
FastAPI(八十四)实战开发《在线课程学习系统》--接口测试(下)
|
存储 测试技术 数据安全/隐私保护
FastAPI(八十三)实战开发《在线课程学习系统》--注册接口单元测试
FastAPI(八十三)实战开发《在线课程学习系统》--注册接口单元测试
FastAPI(八十三)实战开发《在线课程学习系统》--注册接口单元测试
|
测试技术 数据安全/隐私保护
FastAPI(八十四)实战开发《在线课程学习系统》--接口测试(上)
FastAPI(八十四)实战开发《在线课程学习系统》--接口测试(上)
FastAPI(八十二)实战开发《在线课程学习系统》接口开发-- 课程上架下架
FastAPI(八十二)实战开发《在线课程学习系统》接口开发-- 课程上架下架
|
NoSQL Redis 数据库
FastAPI(八十一)实战开发《在线课程学习系统》接口开发-- 推荐课程列表与课程点赞
FastAPI(八十一)实战开发《在线课程学习系统》接口开发-- 推荐课程列表与课程点赞
FastAPI(八十)实战开发《在线课程学习系统》接口开发-- 课程列表
FastAPI(八十)实战开发《在线课程学习系统》接口开发-- 课程列表
FastAPI(七十九)实战开发《在线课程学习系统》接口开发-- 加入课程和退出课程
FastAPI(七十九)实战开发《在线课程学习系统》接口开发-- 加入课程和退出课程
FastAPI(七十八)实战开发《在线课程学习系统》接口开发-- 评论
FastAPI(七十八)实战开发《在线课程学习系统》接口开发-- 评论