동기(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에서 실행을 해주었을 때
비동기적으로 실행되는 결과를 볼 수 있다.