โ & ๐ ๐ข¶
๐ ๐ผ ๐ ๐ธ ๐ช ๐ช ๐ข โ โ๏ธ ๐ณ, ๐ผ ใ ๐, ๐ฝ ๐, ๐ ๐ง ๐โ๐ฆบ, โ๏ธ.
๐ ๐ซ โ ๐ข (๐ช ๐), ๐ ๐ฝ ๐. & ๐ ๐ช ๐ฟ, ๐ ใ.
๐ ๐ค โซ๏ธ โ ๐ ๐ซ ๐ ๐ข ๐ โ ๐ธ.
๐ ๐ข¶
Tip
๐ฅ ๐ โช ๐ญ โซ๏ธโ "๐ ๐ข" & โ โ๏ธ ๐ซ, ๐ญ ๐ ๐ถ โญ ๐ ๐.
๐ ๐ข (๐ญ "๐จ๐ป {") ๐ข ๐ ๐ ๐ ๐ ๐, ๐โโ โ๏ธ, & ๐ช โ ๐ ๐ ๐ (โ๏ธ ๐ ๐ ๐).
๐ ๐ช โ & โ๏ธ ๐ ๐ข ๐, ๐ต ๐โโ ๐:
// You could create an env var MY_NAME with
$ export MY_NAME="Wade Wilson"
// Then you could use it with other programs, like
$ echo "Hello $MY_NAME"
Hello Wade Wilson
// Create an env var MY_NAME
$ $Env:MY_NAME = "Wade Wilson"
// Use it with other programs, like
$ echo "Hello $Env:MY_NAME"
Hello Wade Wilson
โ ๐จ๐ป {๐¶
๐ ๐ช โ ๐ ๐ข ๐ ๐, ๐ถ (โ๏ธ โฎ๏ธ ๐ ๐ ๐ฉโ๐ฌ), & โคด๏ธ โ ๐ซ ๐.
๐ผ ๐ ๐ช โ๏ธ ๐ main.py
โฎ๏ธ:
import os
name = os.getenv("MY_NAME", "World")
print(f"Hello {name} from Python")
Tip
๐ฅ โ os.getenv()
๐ข ๐ฒ ๐จ.
๐ฅ ๐ซ ๐, โซ๏ธ None
๐ข, ๐ฅ ๐ฅ ๐ "World"
๐ข ๐ฒ โ๏ธ.
โคด๏ธ ๐ ๐ช ๐ค ๐ ๐ ๐:
// Here we don't set the env var yet
$ python main.py
// As we didn't set the env var, we get the default value
Hello World from Python
// But if we create an environment variable first
$ export MY_NAME="Wade Wilson"
// And then call the program again
$ python main.py
// Now it can read the environment variable
Hello Wade Wilson from Python
๐ ๐ข ๐ช โ ๐ ๐, โ๏ธ ๐ช โ ๐, & ๐ซ โ๏ธ ๐ช (๐ git
) โฎ๏ธ ๐ ๐, โซ๏ธ โ โ๏ธ ๐ซ ๐ณ โ๏ธ โ.
๐ ๐ช โ ๐ ๐ข ๐ด ๐ฏ ๐ ๐ผ, ๐ ๐ด ๐ช ๐ ๐, & ๐ด ๐ฎ ๐.
๐, โ โซ๏ธ โถ๏ธ๏ธ โญ ๐ โซ๏ธ, ๐ ๐ โธ:
// Create an env var MY_NAME in line for this program call
$ MY_NAME="Wade Wilson" python main.py
// Now it can read the environment variable
Hello Wade Wilson from Python
// The env var no longer exists afterwards
$ python main.py
Hello World from Python
Tip
๐ ๐ช โ ๐ ๐ โซ๏ธ 1๏ธโฃ2๏ธโฃ-โ ๐ฑ: ๐.
๐ & ๐ฌ¶
๐ซ ๐ ๐ข ๐ช ๐ด ๐ต โ ๐ป, ๐ซ ๐ข ๐ & โ๏ธ ๐ โฎ๏ธ ๐ ๐ & ๐ โ๏ธ (& โฎ๏ธ ๐ ๐โโ โ๏ธ, ๐พ, ๐ช, ๐ธ๐ป).
๐ โ ๐ ๐ ๐ฒ โ ๐ โช๏ธโก๏ธ ๐ ๐ข ๐ str
, & ๐ ๐ ๏ธ ๐ ๐ โ๏ธ ๐ฌ โ๏ธ ๐จ ๐.
Pydantic Settings
¶
๐, Pydantic ๐ ๐ ๐ ๐ต ๐ซ โ ๐ โช๏ธโก๏ธ ๐ ๐ข โฎ๏ธ Pydantic: โ ๐งพ.
โ Settings
๐¶
๐ BaseSettings
โช๏ธโก๏ธ Pydantic & โ ๐ง-๐, ๐ถ ๐
๐ โฎ๏ธ Pydantic ๐ท.
๐ ๐ โฎ๏ธ Pydantic ๐ท, ๐ ๐ฃ ๐ ๐ข โฎ๏ธ ๐ โ, & ๐ฒ ๐ข ๐ฒ.
๐ ๐ช โ๏ธ ๐ ๐ ๐ฌ โ & ๐งฐ ๐ โ๏ธ Pydantic ๐ท, ๐ ๐ ๐ ๐ & ๐ ๐ฌ โฎ๏ธ Field()
.
from fastapi import FastAPI
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
app_name: str = "Awesome API"
admin_email: str
items_per_user: int = 50
settings = Settings()
app = FastAPI()
@app.get("/info")
async def info():
return {
"app_name": settings.app_name,
"admin_email": settings.admin_email,
"items_per_user": settings.items_per_user,
}
Tip
๐ฅ ๐ ๐ ๐ณ โฉ ๐ & ๐, ๐ซ โ๏ธ ๐ ๐ผ, โ๏ธ ๐ 1๏ธโฃ ๐.
โคด๏ธ, ๐โ ๐ โ ๐ ๐ Settings
๐ (๐ ๐ผ, settings
๐), Pydantic ๐ โ ๐ ๐ข ๐ผ-๐ ๐,, โ-๐ผ ๐ข APP_NAME
๐ โ ๐ข app_name
.
โญ โซ๏ธ ๐ ๐ & โ ๐ฝ. , ๐โ ๐ โ๏ธ ๐ settings
๐, ๐ ๐ โ๏ธ ๐ ๐ ๐ ๐ฃ (โ
items_per_user
๐ int
).
โ๏ธ settings
¶
โคด๏ธ ๐ ๐ช โ๏ธ ๐ settings
๐ ๐ ๐ธ:
from fastapi import FastAPI
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
app_name: str = "Awesome API"
admin_email: str
items_per_user: int = 50
settings = Settings()
app = FastAPI()
@app.get("/info")
async def info():
return {
"app_name": settings.app_name,
"admin_email": settings.admin_email,
"items_per_user": settings.items_per_user,
}
๐ ๐ฝ¶
โญ, ๐ ๐ ๐ ๐ฝ ๐ถโโ๏ธ ๐ณ ๐ ๐ข, ๐ผ ๐ ๐ช โ ADMIN_EMAIL
& APP_NAME
โฎ๏ธ:
$ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" uvicorn main:app
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
Tip
โ ๐ ๐จ๐ป {๐ ๐ ๐ ๐ซ โฎ๏ธ ๐, & ๐ฎ ๐ซ ๐ โญ ๐.
& โคด๏ธ admin_email
โ ๐ โ "deadpool@example.com"
.
app_name
๐ "ChimichangApp"
.
& items_per_user
๐ ๐ง ๐ฎ ๐ข ๐ฒ 50
.
โ โ1๏ธโฃ ๐น¶
๐ ๐ช ๐ฎ ๐ โ โ1๏ธโฃ ๐น ๐ ๐ ๐ ๐ฆ ๐ธ - ๐ ๐.
๐ผ, ๐ ๐ช โ๏ธ ๐ config.py
โฎ๏ธ:
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
app_name: str = "Awesome API"
admin_email: str
items_per_user: int = 50
settings = Settings()
& โคด๏ธ โ๏ธ โซ๏ธ ๐ main.py
:
from fastapi import FastAPI
from .config import settings
app = FastAPI()
@app.get("/info")
async def info():
return {
"app_name": settings.app_name,
"admin_email": settings.admin_email,
"items_per_user": settings.items_per_user,
}
Tip
๐ ๐ ๐ช ๐ __init__.py
๐ ๐ ๐ ๐ฆ ๐ธ - ๐ ๐.
โ ๐¶
๐พ โซ๏ธ 5๏ธโฃ๐ โ ๐ โ โช๏ธโก๏ธ ๐, โฉ๏ธ โ๏ธ ๐ ๐ โฎ๏ธ settings
๐ โ๏ธ ๐.
๐ ๐ช โด๏ธ โ โฎ๏ธ ๐ฌ, โซ๏ธ ๐ถ โฉ ๐ ๐ โฎ๏ธ ๐ ๐ ๐ โ.
๐ ๐¶
๐ โช๏ธโก๏ธ โฎ๏ธ ๐ผ, ๐ config.py
๐ ๐ช ๐ ๐:
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
app_name: str = "Awesome API"
admin_email: str
items_per_user: int = 50
๐ ๐ ๐ ๐ฅ ๐ซ โ ๐ข ๐ settings = Settings()
.
๐ ๐ฑ ๐¶
๐ ๐ฅ โ ๐ ๐ ๐จ ๐ config.Settings()
.
from functools import lru_cache
from fastapi import Depends, FastAPI
from .config import Settings
app = FastAPI()
@lru_cache()
def get_settings():
return Settings()
@app.get("/info")
async def info(settings: Settings = Depends(get_settings)):
return {
"app_name": settings.app_name,
"admin_email": settings.admin_email,
"items_per_user": settings.items_per_user,
}
Tip
๐ฅ ๐ ๐ฌ @lru_cache()
๐.
๐ ๐ ๐ช ๐ค get_settings()
๐ ๐ข.
& โคด๏ธ ๐ฅ ๐ช ๐ โซ๏ธ โช๏ธโก๏ธ โก ๐ ๏ธ ๐ข ๐ & โ๏ธ โซ๏ธ ๐ ๐ฅ ๐ช โซ๏ธ.
from functools import lru_cache
from fastapi import Depends, FastAPI
from .config import Settings
app = FastAPI()
@lru_cache()
def get_settings():
return Settings()
@app.get("/info")
async def info(settings: Settings = Depends(get_settings)):
return {
"app_name": settings.app_name,
"admin_email": settings.admin_email,
"items_per_user": settings.items_per_user,
}
โ & ๐ฌ¶
โคด๏ธ โซ๏ธ ๐ ๐ถ โฉ ๐ ๐ โ ๐ โฎ๏ธ ๐ฌ ๐ ๐ ๐ get_settings
:
from fastapi.testclient import TestClient
from .config import Settings
from .main import app, get_settings
client = TestClient(app)
def get_settings_override():
return Settings(admin_email="testing_admin@example.com")
app.dependency_overrides[get_settings] = get_settings_override
def test_app():
response = client.get("/info")
data = response.json()
assert data == {
"app_name": "Awesome API",
"admin_email": "testing_admin@example.com",
"items_per_user": 50,
}
๐ ๐ ๐ฅ โ ๐ ๐ฒ admin_email
๐โ ๐ ๐ Settings
๐, & โคด๏ธ ๐ฅ ๐จ ๐ ๐ ๐.
โคด๏ธ ๐ฅ ๐ช ๐ฏ ๐ โซ๏ธ โ๏ธ.
๐ .env
๐¶
๐ฅ ๐ โ๏ธ ๐ โ ๐ ๐ฒ ๐ ๐, ๐ฒ ๐ ๐, โซ๏ธ 5๏ธโฃ๐ โ ๐ฎ ๐ซ ๐ ๐ & โคด๏ธ โ ๐ซ โช๏ธโก๏ธ โซ๏ธ ๐ฅ ๐ซ ๐ ๐ข.
๐ ๐ก โ ๐ฅ ๐ โซ๏ธ โ๏ธ ๐, ๐ซ ๐ ๐ข ๐ ๐ฅ ๐ .env
, & ๐ ๐ค "๐จ๐ป".
Tip
๐ โถ๏ธ โฎ๏ธ โฃ (.
) ๐ตโโ ๐ ๐ฅ-๐ โ๏ธ, ๐ ๐พ & ๐ธ๐ป.
โ๏ธ ๐จ๐ป ๐ ๐ซ ๐ค โ๏ธ โ๏ธ ๐ โ ๐.
Pydantic โ๏ธ ๐โ๐ฆบ ๐ โช๏ธโก๏ธ ๐ ๐ ๐ โ๏ธ ๐ข ๐. ๐ ๐ช โ ๐ Pydantic โ: ๐จ๐ป (.๐จ๐ป) ๐โ๐ฆบ.
Tip
๐ ๐ท, ๐ ๐ช pip install python-dotenv
.
.env
๐¶
๐ ๐ช โ๏ธ .env
๐ โฎ๏ธ:
ADMIN_EMAIL="deadpool@example.com"
APP_NAME="ChimichangApp"
โ โ โช๏ธโก๏ธ .env
¶
& โคด๏ธ โน ๐ config.py
โฎ๏ธ:
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
app_name: str = "Awesome API"
admin_email: str
items_per_user: int = 50
class Config:
env_file = ".env"
๐ฅ ๐ฅ โ ๐ Config
๐ ๐ Pydantic Settings
๐, & โ env_file
๐ โฎ๏ธ ๐จ๐ป ๐ ๐ฅ ๐ โ๏ธ.
Tip
Config
๐ โ๏ธ Pydantic ๐ณ. ๐ ๐ช โ ๐ Pydantic ๐ท ๐
๐ Settings
๐ด ๐ โฎ๏ธ lru_cache
¶
๐ ๐ โช๏ธโก๏ธ ๐พ ๐ โ (๐) ๐ ๏ธ, ๐ ๐ฒ ๐ โซ๏ธ ๐ด ๐ & โคด๏ธ ๐ค-โ๏ธ ๐ โ ๐, โฉ๏ธ ๐ โซ๏ธ ๐ ๐จ.
โ๏ธ ๐ ๐ฐ ๐ฅ:
Settings()
๐ Settings
๐ ๐ โ, & ๐ โซ๏ธ ๐ โ .env
๐ ๐.
๐ฅ ๐ ๐ข ๐:
def get_settings():
return Settings()
๐ฅ ๐ โ ๐ ๐ ๐ ๐จ, & ๐ฅ ๐ ๐ .env
๐ ๐ ๐จ. ๐ถ ๐ถ
โ๏ธ ๐ฅ โ๏ธ @lru_cache()
๐จโ๐จ ๐ ๐, Settings
๐ ๐ โ ๐ด ๐, ๐ฅ ๐ฐ โซ๏ธ ๐ค. ๐ถ ๐ถ
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()
๐ ๐ข โซ๏ธ ๐ ๐จ ๐ ๐ฒ ๐ ๐จ ๐ฅ ๐ฐ, โฉ๏ธ ๐ป โซ๏ธ ๐, ๐ ๏ธ ๐ ๐ข ๐ ๐ฐ.
, ๐ข ๐ โซ๏ธ ๐ ๐ ๏ธ ๐ ๐ ๐ โ. & โคด๏ธ ๐ฒ ๐จ ๐ ๐ ๐ โ ๐ โ๏ธ ๐ & ๐ ๐โ ๐ข ๐ค โฎ๏ธ โซ๏ธโ ๐ ๐ โ.
๐ผ, ๐ฅ ๐ โ๏ธ ๐ข:
@lru_cache()
def say_hi(name: str, salutation: str = "Ms."):
return f"Hello {salutation} {name}"
๐ ๐ ๐ช ๐ ๏ธ ๐ ๐:
sequenceDiagram
participant code as Code
participant function as say_hi()
participant execute as Execute function
rect rgba(0, 255, 0, .1)
code ->> function: say_hi(name="Camila")
function ->> execute: execute function code
execute ->> code: return the result
end
rect rgba(0, 255, 255, .1)
code ->> function: say_hi(name="Camila")
function ->> code: return stored result
end
rect rgba(0, 255, 0, .1)
code ->> function: say_hi(name="Rick")
function ->> execute: execute function code
execute ->> code: return the result
end
rect rgba(0, 255, 0, .1)
code ->> function: say_hi(name="Rick", salutation="Mr.")
function ->> execute: execute function code
execute ->> code: return the result
end
rect rgba(0, 255, 255, .1)
code ->> function: say_hi(name="Rick")
function ->> code: return stored result
end
rect rgba(0, 255, 255, .1)
code ->> function: say_hi(name="Camila")
function ->> code: return stored result
end
๐ผ ๐ ๐ get_settings()
, ๐ข ๐ซ โ ๐ โ, โซ๏ธ ๐ง ๐จ ๐ ๐ฒ.
๐ ๐, โซ๏ธ ๐ญ ๐ ๐ฅ โซ๏ธ ๐ ๐ข. โ๏ธ โซ๏ธ โ๏ธ ๐ ๐ข, โคด๏ธ ๐ฅ ๐ช ๐ โซ๏ธ ๐ช ๐ฌ.
@lru_cache()
๐ functools
โ ๐ ๐ ๐ฉ ๐, ๐ ๐ช โ ๐
๐ โซ๏ธ ๐ ๐ฉบ @lru_cache()
.
๐¶
๐ ๐ช โ๏ธ Pydantic โ ๐ต โ โ๏ธ ๐ณ ๐ ๐ธ, โฎ๏ธ ๐ ๐๏ธ Pydantic ๐ท.
- โ๏ธ ๐ ๐ ๐ช ๐ ๐ฌ.
- ๐ ๐ช โ๏ธ
.env
๐ โฎ๏ธ โซ๏ธ. - โ๏ธ
@lru_cache()
โก๏ธ ๐ โ ๐ ๐จ๐ป ๐ ๐ & ๐ ๐ ๐จ, โช ๐ค ๐ ๐ โซ๏ธ โฎ๏ธ ๐ฌ.