🔗 ⏮️ 🌾¶
FastAPI 🐕🦺 🔗 👈 ➕ 🔁 ⏮️ 🏁.
👉, ⚙️ yield
↩️ return
, & ✍ ➕ 🔁 ⏮️.
Tip
⚒ 💭 ⚙️ yield
1️⃣ 👁 🕰.
📡 ℹ
🙆 🔢 👈 ☑ ⚙️ ⏮️:
🔜 ☑ ⚙️ FastAPI 🔗.
👐, FastAPI ⚙️ 📚 2️⃣ 👨🎨 🔘.
💽 🔗 ⏮️ yield
¶
🖼, 👆 💪 ⚙️ 👉 ✍ 💽 🎉 & 🔐 ⚫️ ⏮️ 🏁.
🕴 📟 ⏭ & 🔌 yield
📄 🛠️ ⏭ 📨 📨:
async def get_db():
db = DBSession()
try:
yield db
finally:
db.close()
🌾 💲 ⚫️❔ 💉 🔘 ➡ 🛠️ & 🎏 🔗:
async def get_db():
db = DBSession()
try:
yield db
finally:
db.close()
📟 📄 yield
📄 🛠️ ⏮️ 📨 ✔️ 🚚:
async def get_db():
db = DBSession()
try:
yield db
finally:
db.close()
Tip
👆 💪 ⚙️ async
⚖️ 😐 🔢.
FastAPI 🔜 ▶️️ 👜 ⏮️ 🔠, 🎏 ⏮️ 😐 🔗.
🔗 ⏮️ yield
& try
¶
🚥 👆 ⚙️ try
🍫 🔗 ⏮️ yield
, 👆 🔜 📨 🙆 ⚠ 👈 🚮 🕐❔ ⚙️ 🔗.
🖼, 🚥 📟 ☝ 🖕, ➕1️⃣ 🔗 ⚖️ ➡ 🛠️, ⚒ 💽 💵 "💾" ⚖️ ✍ 🙆 🎏 ❌, 👆 🔜 📨 ⚠ 👆 🔗.
, 👆 💪 👀 👈 🎯 ⚠ 🔘 🔗 ⏮️ except SomeException
.
🎏 🌌, 👆 💪 ⚙️ finally
⚒ 💭 🚪 📶 🛠️, 🙅♂ 🤔 🚥 📤 ⚠ ⚖️ 🚫.
async def get_db():
db = DBSession()
try:
yield db
finally:
db.close()
🎧-🔗 ⏮️ yield
¶
👆 💪 ✔️ 🎧-🔗 & "🌲" 🎧-🔗 🙆 📐 & 💠, & 🙆 ⚖️ 🌐 👫 💪 ⚙️ yield
.
FastAPI 🔜 ⚒ 💭 👈 "🚪 📟" 🔠 🔗 ⏮️ yield
🏃 ☑ ✔.
🖼, dependency_c
💪 ✔️ 🔗 🔛 dependency_b
, & dependency_b
🔛 dependency_a
:
from fastapi import Depends
async def dependency_a():
dep_a = generate_dep_a()
try:
yield dep_a
finally:
dep_a.close()
async def dependency_b(dep_a=Depends(dependency_a)):
dep_b = generate_dep_b()
try:
yield dep_b
finally:
dep_b.close(dep_a)
async def dependency_c(dep_b=Depends(dependency_b)):
dep_c = generate_dep_c()
try:
yield dep_c
finally:
dep_c.close(dep_b)
🤓 Other versions and variants
from typing import Annotated
from fastapi import Depends
async def dependency_a():
dep_a = generate_dep_a()
try:
yield dep_a
finally:
dep_a.close()
async def dependency_b(dep_a: Annotated[DepA, Depends(dependency_a)]):
dep_b = generate_dep_b()
try:
yield dep_b
finally:
dep_b.close(dep_a)
async def dependency_c(dep_b: Annotated[DepB, Depends(dependency_b)]):
dep_c = generate_dep_c()
try:
yield dep_c
finally:
dep_c.close(dep_b)
from fastapi import Depends
from typing_extensions import Annotated
async def dependency_a():
dep_a = generate_dep_a()
try:
yield dep_a
finally:
dep_a.close()
async def dependency_b(dep_a: Annotated[DepA, Depends(dependency_a)]):
dep_b = generate_dep_b()
try:
yield dep_b
finally:
dep_b.close(dep_a)
async def dependency_c(dep_b: Annotated[DepB, Depends(dependency_b)]):
dep_c = generate_dep_c()
try:
yield dep_c
finally:
dep_c.close(dep_b)
& 🌐 👫 💪 ⚙️ yield
.
👉 💼 dependency_c
, 🛠️ 🚮 🚪 📟, 💪 💲 ⚪️➡️ dependency_b
(📥 📛 dep_b
) 💪.
& , 🔄, dependency_b
💪 💲 ⚪️➡️ dependency_a
(📥 📛 dep_a
) 💪 🚮 🚪 📟.
from fastapi import Depends
async def dependency_a():
dep_a = generate_dep_a()
try:
yield dep_a
finally:
dep_a.close()
async def dependency_b(dep_a=Depends(dependency_a)):
dep_b = generate_dep_b()
try:
yield dep_b
finally:
dep_b.close(dep_a)
async def dependency_c(dep_b=Depends(dependency_b)):
dep_c = generate_dep_c()
try:
yield dep_c
finally:
dep_c.close(dep_b)
🤓 Other versions and variants
from typing import Annotated
from fastapi import Depends
async def dependency_a():
dep_a = generate_dep_a()
try:
yield dep_a
finally:
dep_a.close()
async def dependency_b(dep_a: Annotated[DepA, Depends(dependency_a)]):
dep_b = generate_dep_b()
try:
yield dep_b
finally:
dep_b.close(dep_a)
async def dependency_c(dep_b: Annotated[DepB, Depends(dependency_b)]):
dep_c = generate_dep_c()
try:
yield dep_c
finally:
dep_c.close(dep_b)
from fastapi import Depends
from typing_extensions import Annotated
async def dependency_a():
dep_a = generate_dep_a()
try:
yield dep_a
finally:
dep_a.close()
async def dependency_b(dep_a: Annotated[DepA, Depends(dependency_a)]):
dep_b = generate_dep_b()
try:
yield dep_b
finally:
dep_b.close(dep_a)
async def dependency_c(dep_b: Annotated[DepB, Depends(dependency_b)]):
dep_c = generate_dep_c()
try:
yield dep_c
finally:
dep_c.close(dep_b)
🎏 🌌, 👆 💪 ✔️ 🔗 ⏮️ yield
& return
🌀.
& 👆 💪 ✔️ 👁 🔗 👈 🚚 📚 🎏 🔗 ⏮️ yield
, ♒️.
👆 💪 ✔️ 🙆 🌀 🔗 👈 👆 💚.
FastAPI 🔜 ⚒ 💭 🌐 🏃 ☑ ✔.
🔗 ⏮️ yield
& HTTPException
¶
👆 👀 👈 👆 💪 ⚙️ 🔗 ⏮️ yield
& ✔️ try
🍫 👈 ✊ ⚠.
⚫️ 5️⃣📆 😋 🤚 HTTPException
⚖️ 🎏 🚪 📟, ⏮️ yield
. ✋️ ⚫️ 🏆 🚫 👷.
🚪 📟 🔗 ⏮️ yield
🛠️ ⏮️ 📨 📨, ⚠ 🐕🦺 🔜 ✔️ ⏪ 🏃. 📤 🕳 😽 ⚠ 🚮 👆 🔗 🚪 📟 (⏮️ yield
).
, 🚥 👆 🤚 HTTPException
⏮️ yield
, 🔢 (⚖️ 🙆 🛃) ⚠ 🐕🦺 👈 ✊ HTTPException
Ⓜ & 📨 🇺🇸🔍 4️⃣0️⃣0️⃣ 📨 🏆 🚫 📤 ✊ 👈 ⚠ 🚫🔜.
👉 ⚫️❔ ✔ 🕳 ⚒ 🔗 (✅ 💽 🎉), 🖼, ⚙️ 🖥 📋.
🖥 📋 🏃 ⏮️ 📨 ✔️ 📨. 📤 🙅♂ 🌌 🤚 HTTPException
↩️ 📤 🚫 🌌 🔀 📨 👈 ⏪ 📨.
✋️ 🚥 🖥 📋 ✍ 💽 ❌, 🌘 👆 💪 💾 ⚖️ 😬 🔐 🎉 🔗 ⏮️ yield
, & 🎲 🕹 ❌ ⚖️ 📄 ⚫️ 🛰 🕵 ⚙️.
🚥 👆 ✔️ 📟 👈 👆 💭 💪 🤚 ⚠, 🏆 😐/"🙃" 👜 & 🚮 try
🍫 👈 📄 📟.
🚥 👆 ✔️ 🛃 ⚠ 👈 👆 🔜 💖 🍵 ⏭ 🛬 📨 & 🎲 ❎ 📨, 🎲 🙋♀ HTTPException
, ✍ 🛃 ⚠ 🐕🦺.
Tip
👆 💪 🤚 ⚠ 🔌 HTTPException
⏭ yield
. ✋️ 🚫 ⏮️.
🔁 🛠️ 🌅 ⚖️ 🌘 💖 👉 📊. 🕰 💧 ⚪️➡️ 🔝 🔝. & 🔠 🏓 1️⃣ 🍕 🔗 ⚖️ 🛠️ 📟.
sequenceDiagram
participant client as Client
participant handler as Exception handler
participant dep as Dep with yield
participant operation as Path Operation
participant tasks as Background tasks
Note over client,tasks: Can raise exception for dependency, handled after response is sent
Note over client,operation: Can raise HTTPException and can change the response
client ->> dep: Start request
Note over dep: Run code up to yield
opt raise
dep -->> handler: Raise HTTPException
handler -->> client: HTTP error response
dep -->> dep: Raise other exception
end
dep ->> operation: Run dependency, e.g. DB session
opt raise
operation -->> dep: Raise HTTPException
dep -->> handler: Auto forward exception
handler -->> client: HTTP error response
operation -->> dep: Raise other exception
dep -->> handler: Auto forward exception
end
operation ->> client: Return response to client
Note over client,operation: Response is already sent, can't change it anymore
opt Tasks
operation -->> tasks: Send background tasks
end
opt Raise other exception
tasks -->> dep: Raise other exception
end
Note over dep: After yield
opt Handle other exception
dep -->> dep: Handle exception, can't change response. E.g. close DB session.
end
Info
🕴 1️⃣ 📨 🔜 📨 👩💻. ⚫️ 💪 1️⃣ ❌ 📨 ⚖️ ⚫️ 🔜 📨 ⚪️➡️ ➡ 🛠️.
⏮️ 1️⃣ 📚 📨 📨, 🙅♂ 🎏 📨 💪 📨.
Tip
👉 📊 🎦 HTTPException
, ✋️ 👆 💪 🤚 🙆 🎏 ⚠ ❔ 👆 ✍ 🛃 ⚠ 🐕🦺.
🚥 👆 🤚 🙆 ⚠, ⚫️ 🔜 🚶♀️ 🔗 ⏮️ 🌾, 🔌 HTTPException
, & ⤴️ 🔄 ⚠ 🐕🦺. 🚥 📤 🙅♂ ⚠ 🐕🦺 👈 ⚠, ⚫️ 🔜 ⤴️ 🍵 🔢 🔗 ServerErrorMiddleware
, 🛬 5️⃣0️⃣0️⃣ 🇺🇸🔍 👔 📟, ➡️ 👩💻 💭 👈 📤 ❌ 💽.
🔑 👨💼¶
⚫️❔ "🔑 👨💼"¶
"🔑 👨💼" 🙆 👈 🐍 🎚 👈 👆 💪 ⚙️ with
📄.
🖼, 👆 💪 ⚙️ with
✍ 📁:
with open("./somefile.txt") as f:
contents = f.read()
print(contents)
🔘, open("./somefile.txt")
✍ 🎚 👈 🤙 "🔑 👨💼".
🕐❔ with
🍫 🏁, ⚫️ ⚒ 💭 🔐 📁, 🚥 📤 ⚠.
🕐❔ 👆 ✍ 🔗 ⏮️ yield
, FastAPI 🔜 🔘 🗜 ⚫️ 🔑 👨💼, & 🌀 ⚫️ ⏮️ 🎏 🔗 🧰.
⚙️ 🔑 👨💼 🔗 ⏮️ yield
¶
Warning
👉, 🌅 ⚖️ 🌘, "🏧" 💭.
🚥 👆 ▶️ ⏮️ FastAPI 👆 💪 💚 🚶 ⚫️ 🔜.
🐍, 👆 💪 ✍ 🔑 👨💼 🏗 🎓 ⏮️ 2️⃣ 👩🔬: __enter__()
& __exit__()
.
👆 💪 ⚙️ 👫 🔘 FastAPI 🔗 ⏮️ yield
⚙️
with
⚖️ async with
📄 🔘 🔗 🔢:
class MySuperContextManager:
def __init__(self):
self.db = DBSession()
def __enter__(self):
return self.db
def __exit__(self, exc_type, exc_value, traceback):
self.db.close()
async def get_db():
with MySuperContextManager() as db:
yield db
Tip
➕1️⃣ 🌌 ✍ 🔑 👨💼 ⏮️:
⚙️ 👫 🎀 🔢 ⏮️ 👁 yield
.
👈 ⚫️❔ FastAPI ⚙️ 🔘 🔗 ⏮️ yield
.
✋️ 👆 🚫 ✔️ ⚙️ 👨🎨 FastAPI 🔗 (& 👆 🚫🔜 🚫).
FastAPI 🔜 ⚫️ 👆 🔘.