ASGI: Python 웹을 위한 비동기 프로토콜
Wenhao Wang
Dev Intern · Leapcell

FastAPI 개발에서 ASGI 및 Uvicorn 이해하기
FastAPI로 개발할 때 Uvicorn 서버를 사용해야 합니다. 초보자는 그 이유가 궁금할 수 있습니다. 오늘 우리는 이 질문에 답할 것입니다.
Uvicorn
HTTP를 사용하여 간단한 HTTP 요청을 구현해 보겠습니다.
import json # 헤더의 바이트를 문자열로 변환하는 도우미 함수 정의 def convert_bytes_to_str(data): if isinstance(data, bytes): return data.decode('utf-8') if isinstance(data, tuple): return tuple(convert_bytes_to_str(item) for item in data) if isinstance(data, list): return [convert_bytes_to_str(item) for item in data] if isinstance(data, dict): return {key: convert_bytes_to_str(value) for key, value in data.items()} return data async def app(scope, receive, send): # print(scope) data = convert_bytes_to_str(scope) print(json.dumps(data, indent=4)) # 요청 유형 확인 if scope['type'] == 'http': # HTTP 요청 본문 대기 event = await receive() # 응답 내용 response_body = json.dumps({"message": "Hello, ASGI!"}).encode('utf-8') # HTTP 응답 헤더 보내기 await send({ 'type': 'http.response.start', 'status': 200, 'headers': [ (b'content-type', b'application/json'), ], }) # HTTP 응답 본문 보내기 await send({ 'type': 'http.response.body', 'body': response_body, })
scope
필드에는 바이너리 문자열이 포함되어 있으므로 변환 함수 convert_bytes_to_str
가 필요합니다. 간단히 분석해 보겠습니다. 요청 경로 및 메서드와 관련된 정보는 scope
에 있습니다. scope
는 HTTP 이외의 항목도 지원하므로 type
을 사용하여 현재 프로토콜의 유형을 결정해야 합니다. 그런 다음 receive
함수를 사용하여 요청 본문을 수신합니다. 다음으로 json.dumps
를 사용하여 응답 본문을 만들고 encode
로 인코딩합니다. 마지막으로 요청 헤더와 요청 본문을 보냅니다.
여기서 데이터를 두 번 보냅니다. 이 설계는 비동기 프로그래밍의 요구 사항을 충족하고 다양한 애플리케이션 시나리오(스트리밍 응답)에 대한 처리 능력을 향상시킵니다. 실제 프로젝트에 대한 이해를 바탕으로 이제 이론적 기반에서 ASGI를 이해할 수 있습니다.
ASGI
ASGI(Asynchronous Server Gateway Interface)는 비동기 웹 애플리케이션을 구축하기 위한 Python 프로토콜입니다.
ASGI의 주요 기능
- 비동기 지원: 비동기 프로그래밍을 지원합니다.
- 다중 프로토콜 지원: WebSocket 및 Long-Polling과 같은 프로토콜을 지원하므로 HTTP/HTTPS/WebSocket을 지원합니다.
- 동시성 지원: 여러 요청을 동시에 처리할 수 있습니다.
- 통신: 애플리케이션과 서버는 물론 애플리케이션의 여러 부분도 메시지를 주고받으며 상호 작용합니다.
ASGI 프로토콜의 구성
- 애플리케이션 인터페이스
- ASGI 애플리케이션 인터페이스는 애플리케이션이 ASGI 서버와 상호 작용하는 방식을 정의합니다. ASGI 애플리케이션은 일반적으로 비동기 함수인 호출 가능한 객체이며 두 개의 매개변수
scope
와receive
를 허용하고send
비동기 생성기를 반환합니다.- scope: 요청 유형(HTTP 또는 WebSocket), 경로, 쿼리 문자열, 서버 정보 등과 같은 요청에 대한 정보가 포함된 사전입니다.
- receive: ASGI 서버에서 이벤트를 수신하는 데 사용되는 비동기 호출입니다.
- send: ASGI 서버로 이벤트를 다시 보내는 데 사용되는 비동기 생성기입니다.
- ASGI 애플리케이션 인터페이스는 애플리케이션이 ASGI 서버와 상호 작용하는 방식을 정의합니다. ASGI 애플리케이션은 일반적으로 비동기 함수인 호출 가능한 객체이며 두 개의 매개변수
- 서버 인터페이스
- 서버 인터페이스의 주요 책임은 다음과 같습니다.
- 클라이언트로부터 연결을 수락합니다.
- 각 연결에 대한
scope
를 만듭니다. - 애플리케이션의
receive
및send
메서드를 호출하여 이벤트를 전달합니다. - 네트워크 예외를 처리하고 연결을 닫습니다.
- 서버 인터페이스의 주요 책임은 다음과 같습니다.
- 이벤트 루프 인터페이스
- 이벤트 루프 인터페이스는 ASGI 프로토콜의 암시적 부분입니다. ASGI 프로토콜에 의해 직접 정의되는 것이 아니라 ASGI 서버에 의해 관리됩니다.
- 이벤트 루프는 비동기 작업을 예약하고 실행하는 역할을 하며, 이는 비동기 프로그래밍의 핵심입니다. 주요 기능은 다음과 같습니다.
- 비동기 작업을 실행하고 예약합니다.
- 네트워크 요청과 같은 비동기 I/O 작업을 관리합니다.
- 콜백 함수와 비동기 생성기를 처리합니다.
- ASGI에서 이벤트 루프는 일반적으로 다음 Python 라이브러리에서 제공합니다.
- asyncio: Python 표준 라이브러리의 비동기 I/O 프레임워크입니다.
- uvloop:
libuv
를 기반으로 하는 비동기 이벤트 루프이며 Uvicorn 서버와 함께 자주 사용됩니다.
ASGI 서버 및 애플리케이션은 이벤트 루프에 의존하여 비동기 작업을 수행하므로 많은 수의 동시 연결을 효율적으로 처리할 수 있습니다.
ASGI 이벤트
ASGI 이벤트 기반 모델은 수명 주기 관리(시작 및 종료), HTTP 요청 처리 및 WebSocket 연결 관리를 처리합니다. 개발자는 다양한 유형의 이벤트를 통해 연결 및 데이터 흐름을 정확하게 제어하여 비동기 및 동시 처리를 달성할 수 있습니다.
- 수명 주기 이벤트
- 수명 주기 이벤트는 ASGI 애플리케이션의 시작 및 종료 주기와 관련이 있습니다. 일반적으로 초기화 및 정리 작업을 수행하는 데 사용됩니다.
- lifespan.startup
- lifespan.shutdown
- 수명 주기 이벤트는 ASGI 애플리케이션의 시작 및 종료 주기와 관련이 있습니다. 일반적으로 초기화 및 정리 작업을 수행하는 데 사용됩니다.
- HTTP 이벤트
- HTTP 요청에 대한 ASGI의 처리는 여러 이벤트로 나뉘며, 각 HTTP 요청의 세부 정보를 관리할 수 있습니다.
- http.request
- http.response.start
- http.response.body
- http.disconnect
- websocket.send
- HTTP 요청에 대한 ASGI의 처리는 여러 이벤트로 나뉘며, 각 HTTP 요청의 세부 정보를 관리할 수 있습니다.
- WebSocket 이벤트
- ASGI는 WebSocket 연결을 지원하여 양방향 통신을 가능하게 합니다.
- websocket.connect
- websocket.receive
- ASGI는 WebSocket 연결을 지원하여 양방향 통신을 가능하게 합니다.
ASGI 수명 주기
ASGI 애플리케이션 수명 주기는 애플리케이션이 시작 및 종료 중에 거치는 단계를 나타냅니다. 수명 주기 이벤트 채널에 의해 관리됩니다.
scope['type']: lifespan
message['type']
: 시작 및 종료 메시지:lifespan.startup/lifespan.shutdown
- 전송 유형:
{'type': 'lifespan.shutdown.complete'}
ASGI 수명 주기는 애플리케이션의 시작 및 종료와 요청의 설정, 처리, 응답 및 종료의 두 부분으로 나뉩니다.
Uvicorn 및 애플리케이션 계층
앞에서 언급했듯이 Uvicorn은 ASGI 서버 계층을 구현합니다. 그러나 너무 낮은 수준이므로 애플리케이션 계층에서는 그다지 사용자 친화적이지 않습니다. 따라서 다음과 같은 여러 상위 수준 프레임워크가 등장했습니다.
- Starlette: 고성능 웹 서비스를 구축하기 위한 경량 ASGI 프레임워크/툴킷입니다. FastAPI의 기본 구성 요소이며 독립적으로 사용하여 간단한 웹 애플리케이션을 만들 수도 있습니다.
- FastAPI: Python 3.6+ 유형 힌트와 함께 사용되는 API 구축을 위한 최신 고속(고성능) 웹 프레임워크입니다. Starlette 및 표준 Python 유형 힌트를 기반으로 하며 자동 데이터 유효성 검사 및 직렬화는 물론 대화형 API 문서 생성을 제공합니다.
다른 측면에 대해서는 자세히 설명할 필요가 없습니다. 정보가 너무 많으면 압도적일 수 있습니다. Uvicorn에는 app
이 필요하므로 이 두 프레임워크의 경우 인스턴스화된 객체는 app
입니다. 그런 다음 Uvicorn CLI를 사용하여 애플리케이션을 시작합니다.
uvicorn main:app --reload
요약
이 기사에서는 Uvicorn을 통해 Python 웹 ASGI 프로토콜을 주로 살펴봅니다. ASGI는 Python의 비동기 서버 게이트웨이 인터페이스로, 최신 Python 웹 프로그램의 비동기, 동시성 및 다중 프로토콜 기능을 통합합니다.
Leapcell: Python 웹 호스팅, 비동기 작업 및 Redis를 위한 최고의 서버리스 플랫폼
마지막으로, Python 프로젝트를 배포하는 데 가장 적합한 플랫폼인 Leapcell을 추천합니다.
1. 다국어 지원
- JavaScript, Python, Go 또는 Rust로 개발하십시오.
2. 무제한 프로젝트를 무료로 배포
- 사용량에 대해서만 지불하십시오. 요청도 없고 요금도 없습니다.
3. 최고의 비용 효율성
- 유휴 요금 없이 사용한 만큼만 지불하십시오.
- 예: $25는 평균 응답 시간 60ms에서 694만 건의 요청을 지원합니다.
4. 간소화된 개발자 경험
- 간편한 설정을 위한 직관적인 UI.
- 완전 자동화된 CI/CD 파이프라인 및 GitOps 통합.
- 실행 가능한 통찰력을 위한 실시간 메트릭 및 로깅.
5. 손쉬운 확장성 및 고성능
- 쉬운 동시성 처리를 위한 자동 확장.
- 운영 오버헤드가 없으므로 구축에만 집중하십시오.
Leapcell Twitter: https://x.com/LeapcellHQ