FastAPI lifespan
우리가 FastAPI 와 같은 Application 을 만들다보면 요청 전/후로 리소스를 정리하거나 미리 무거운 리소스를 로드하는 등의 작업이 필요하게 된다. FastAPI 에서는 이를 `asynccontextmanager` 를 이용한 lifespan 으로 지원해주는데 오늘은 이를 알아보도록 하자.
## ContextManager
asynccontextmanager 에 관해서 알아보기 전에 우리는 **ContextManager** 에 대한 개념이 필요하다. ContextManager 는 `with` 문과 함께 실행시간에 의존하는 컨텍스트를 생성하게 된다.
따라서 메소드도 `__enter__()` 와 `__exit__()`(이와 같이 파이썬에서 underbar 두개를 붙이면 던더메소드[^1] 라고 한다) 을 가지고 있다. 즉, 컨텍스트에 진입할때 `__enter__()` 가 호출되고 컨텍스트와 관련된 내용을 반환하고, 처리를 마친뒤에는 __exit__() 함수가 호출되게 된다. 아래 코드 예시를 보면 조금 더 쉬울 것 이다.
```python
from contextlib import contextmanager
@contextmanager
def managed_resource(*args, **kwds):
# 자원을 얻는 코드, 예를 들어:
resource = acquire_resource(*args, **kwds)
try:
yield resource
finally:
# 자원을 해제하는 코드, 예를 들어:
release_resource(resource)
```
보면 리소스를 취득한뒤에 리소스(컨텍스트와 연관된)를 반환한 뒤에 받는 쪽에서 호출이 끝난 뒤 **realeas_resource(resource)** 함수가 호출된다. 조금 더 직관적으로 확인하기 위해 코드로 한번 확인해보자.
```python
import asyncio
from contextlib import asynccontextmanager
@asynccontextmanager
async def hello():
print("before executing function")
yield "hello"
print("after executing function")
async def main():
async with hello() as data:
print(data)
asyncio.run(main())
```
---
[^1]: 던더메소드는 객체에 따라 행동이 정해져있는 메소드로 이 객체가 어떤 던더메소드를 가지고 있는지 알기 위해서는 `dir` 함수를 사용하면 된다.