Programming Language/Python

FastAPI - async with 구문

hustle_D 2025. 9. 10. 14:58
반응형

일반적인 with구문은 파일 열기/닫기 처럼 동기적인 작업을 자동으로 처리해주는 것 처럼, async with는 비동기적인 작업을 시작하고 끝내는 과정을 안전하게 관리해준다.

 

비동기 프로그래밍에서는 리소스 관리를 위한 특별한 문법으로 일반적인 with 구분이 파일을 핸들링 하기 위해서 혹은 데이터베이스 커넥션을 위해서 동기적인 리소스를 안전하게 열고 닫는 역할을 하듯이 async with는 await이 필요한 비동기적인 리소스를 안전하게 관리해준다.

 

async with 구분은 내부적으로 __aenther__와 __aexit__을 호출한다

 

__aenther__

__aenther__는 async with 블록이 시작될때 호출된다.

리소스를 설정하고 필요하다면 await을 사용해서 비동기적으로 준비한다

 

__aexit__

__aexit__은 async with 블록이 끝날 때 호출된다

리소스를 정리하고 예외 발생 여부와는 관계 없이 마무리 작업을 안전하게 처리해준다

이 메서드 또한 await을 사용할 수 있어 비동기적인 정리를 할 수 있다.

 

예시로 비동기 파일 읽기를 만들어보자.

 

먼저 비동기로 파일을 읽어오는 I/O라이브러리인 aiofiles를 import 해주고 

 

파일을 읽어주는 함수 하나를 비동기로 생성해주자.

이제 async with를 열어주고

aiofiles을 통해서 open을 호출해주고 내부에 path와 모드를 r로 열어주자.

이제 열린 파일객체인 f를 사용해서 내용을 read()를 사용해서 읽어 변수에 저장하도록 하자

이때 f.read()는 파일의 I/O에 관여된 부분이기에 대기하지 않도록 await을 넣어주자.

그리고 받은 content를 반환해주자.

 

이제 메인함수를 비동기로 생성해주고 

호출할 만한 간단한 텍스트 파일을 생성해주고 read_file 함수를 통해서 그 경로를 전달하도록 하자

이때 해당 함수도 결국 I/O에 해당되기에 await을 붙여 기다리지 않게 만들어주도록 하자 .

그리고 이제 내부 내용을 출력할 수 있도록 print문에 content를 출력하도록 하고 

메인을 호출 할 수 있도록 asyncio라이브러리의 run함수를 사용해서 main()을 이벤트 루프에 태워주면서 실행하도록 해주고

물론 asyncio를 import해줘야함

이제 실행해보면

이렇게 출력 되는 것을 볼 수 있다.

 

여기서

해당부분이 호출되면서 내부적으로는 

f = await aiofiles.open(filepath, mode="r").__aenter__()

이런식으로 실행되게 된다.

 

그리고 내부에 로직들이 모두 실행되고 종료되거나 예외가 발생하는 경우 파이썬에서는 자동으로 

await f.__aexit__(exc_type, exc_value, traceback)

위 코드를 실행한다.


이러면 사용자가 궂이 .close()와 같은 구문을 사용하지 않더라도 자동으로 파이썬에서 닫아주기에 좀 더 안전하게 사용이 가능하다.

 

해당 구문은 I/O 작업인 파일을 읽고 쓰거네트워크를 통해서 데이터를 주고 받거데이터베이스에 접근하는 경우 등에서 자주 사용된다.

반응형