본문 바로가기

카테고리 없음

[FastAPI] async def 와 def

동기(Syncronous) : 데이터의 요청과 결과가 한 자리에서 동시에 일어난다. 한 요청이 끝나고 다음 요청 시행

비동기(Asyncronous) : 요청한 결과는 동시에 일어나지 않을 것이다. 한 요청 이후 다른 요청 바로 시작되고 결과도 언제 나올지 모름


FastAPI 에서 await 을 호출하려면 async def 를 사용하고 그게 아니라면 def 를 사용하라고 된다.

두 경우 모두 비동기적으로 작동한다는데 anync def에서 await 가 뭘 하는지 아래서 확인해보자

 

async def 와 def 의 차이점

1.첫번째

async def some_library (num: int, something:str):
    S = 0
    for i in range (num):
        print(" something..: ", something, i) 
        time.sleep(1)
        S += 1 
    return S
app = FastAPI()
@app.post('/")
async def read_results(something:str):
    s1 = await some_library(5, something)
    return {'data' : 'data', 's1':s1}

FastAPI 를 실행하면 somthing 이라는 어떤 값을 가져와서 some_library 를 실행한다. 이때 time.sleep(1) 로 1초씩 멈추며 for 문을 실행한다.

아래 파이썬 코드를 실행하면

req.py

import requests
import random

params={'something':f'{random.randint(0,100)}'}
url = "http://127.0.0.1:8000/async"
res=requests.post(url, params=params)
print(res.status_code)
print(res.json())

랜덤으로 만든 int 를 리턴받고 1 초마다 반복하는 것을 볼 수 있다.

이때 만약 2개의 쉘에서 동시에 python3 req.py 를 실행하면 아래의 결과가 나온다.

첫번째 command 가 모두 끝나고 두번째 command 에서 파이썬이 실행되는 것을 볼 수 있다.

이것은 동기적인 방법이며 async-await 을 time.sleep() 으로 잘못사용했기 때문이다.

 

2. 두번째 올바른 사용

import asyncio
# async def 확인1
async def some_library(num: int, something:str):
    s = 0
    for i in range(num):
        print(" something ... : ", something, i)
        #time.sleep(1)
        await asyncio.sleep(1)
        s+= int(something)
    return s

@app.post("/async")
async def read_results(something:str):
    s1 = await some_library(5, something)
    return {'data' : 'data', 's1':s1}

 

await asyncio.sleep() 을 이용해 2개의 command에서 실행을 해주었을 때

비동기적으로 실행되는 결과를 볼 수 있다.

 

 

참고: https://lsjsj92.tistory.com/649#google_vignette