30. Dependencies with yield
1. Dependencies with yield
- FastAPI는 함수의 종료 후 몇 가지 추가 단계를 수행하는 dependencies를 지원한다.
- 이를 위해서는
return
대신yield
를 사용하고 이후에 추가 단계를 작성한다.
Note
yield
는 한 번만 사용하는 게 좋다.
2. A database dependency with yield
- 다음의 예제는
yield
를 사용하여 데이터베이스 세션을 만들고, 종료한 후 닫을 수 있는 예제이다.
- 다음과 같이 작성하면, response를 보내기 전
yield
문까지 실행된다.
- 다음과 같이 yield된 값은 path operations 및 다른 dependencies에 주입되는 값이다.
- yield 문 다음의 코드는 response가 전달된 후 실행된다.
3. A dependency with yield
and try
yield
가 있는 dependency에서try
블록을 사용하는 경우 dependency를 사용할 때 throw된 모든 예외를 수신한다.- 예를 들어, 다른 dependency 또는 path operation에 있는 일부 코드가 데이터베이스 트랜잭션 "rollback"을 하거나 다른 에러를 생성하는 경우 dependency에서 예외를 수신한다.
- 따라서
except SomeException
으로 dependency 내부에서 특정 예외를 찾을 수 있다.
- 또한 다음과 같이
finally
블록을 사용하여 예외가 있는지 여부에 관계없이 닫을 수 있다.
4. Sub-dependencies with yield
- 어떠한 sub-dependencies 내부에서도
yield
를 사용할 수 있다.
- 다음의 예제는 sub-dependencies 내부에서
yield
를 사용하는 예제이다.
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)
- 위의 예제의 경우,
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)
Note
yield
뿐만 아니라return
또한 같이 사용될 수 있다.
5. Context Managers
1) What are "Context Managers"
- "Context Managers"란,
with
문에서 사용할 수 있는 Python 객체이다.
- 예를 들어, 다음과 같이 파일을 읽는 데 사용하는 것이다.
- 위의 예제에서
open("./somefile.txt")
는 "Context Manager"라는 객체를 생성한다. with
블록이 종료되면 예외가 있더라도 파일을 닫게 된다.yield
를 사용하여 dependency를 생성하면, FastAPI가 내부적으로 이를 context manager로 변환하고 다른 관련 도구와 결합한다.
2) Using context managers in dependencies with yield
- Python에서는 클래스 내부에
__enter__()
및__exit__()
이라는 두 가지 메서드를 사용하여 context manager를 만들 수 있다.
- 다음과 같이 dependency 함수 내에서
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