Skip to content

๐Ÿ”— โฎ๏ธ ๐ŸŒพ

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)

& ๐ŸŒ ๐Ÿ‘ซ ๐Ÿ’ช โš™๏ธ 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)

๐ŸŽ ๐ŸŒŒ, ๐Ÿ‘† ๐Ÿ’ช โœ”๏ธ ๐Ÿ”— โฎ๏ธ yield & return ๐ŸŒ€.

& ๐Ÿ‘† ๐Ÿ’ช โœ”๏ธ ๐Ÿ‘ ๐Ÿ”— ๐Ÿ‘ˆ ๐Ÿšš ๐Ÿ“š ๐ŸŽ ๐Ÿ”— โฎ๏ธ yield, โ™’๏ธ.

๐Ÿ‘† ๐Ÿ’ช โœ”๏ธ ๐Ÿ™† ๐ŸŒ€ ๐Ÿ”— ๐Ÿ‘ˆ ๐Ÿ‘† ๐Ÿ’š.

FastAPI ๐Ÿ”œ โš’ ๐Ÿ’ญ ๐ŸŒ ๐Ÿƒ โ˜‘ โœ”.

๐Ÿ“ก โ„น

๐Ÿ‘‰ ๐Ÿ‘ท ๐Ÿ‘ ๐Ÿ ๐Ÿ”‘ ๐Ÿ‘จโ€๐Ÿ’ผ.

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 ๐Ÿ”œ โšซ๏ธ ๐Ÿ‘† ๐Ÿ”˜.