.gitignore
파일은 링크 대로 설정하겠습니다.
이제 python 가상환경을 만들어보도록 하겠습니다. 저는 python 3.8.9 환경에서 진행해볼게요
python -m venv venv
를 통해서 venv
라는 가상환경을 만들고,
source venv/bin/activate
로 활성화 시킵니다.
pip install -U pip
로 최신 pip로 업데이트 해 줍니다.
이제 fastapi를 설치해볼게요.
pip install fastapi
로 fastapi를 설치하겠습니다.
그리고 main.py
를 생성 하고 아래와 같이 공식페이지에 나온대로 Hello World를 입력해볼게요.
app.get
, app.post
method를 decorator와 함께 사용해서 API를 만드는 방식인데
이는 express나 flask같이 주로 쓰이는 프레임워크와 비슷한 방식이네요.
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def hello_world():
return {"Hello": "World"}
비동기기반 프레임워크다보니 asgi가 필요하고 그 중에서도 uvicorn을 예시로 사용더라구요
아래처럼 uvicorn
을 설치하고 실행해보도록 합시다
--reload
옵션은 개발용으로, uvicorn 서버 실행 중에 소스가 변경될경우 reload를 자동으로 진행해주니 사용해보겠습니다.
실행하면 이렇게 자동으로 포트를 잡아주고 해당 주소 localhost:8000
를 통해 접속해보면..
이렇게 hello world를 json 형식으로 받을 수 있습니다!
그뿐만 아니라 localhost:8000/docs
로 접속해보면...
이렇게 swagger openapi 형식의 문서가 자동으로 생성되는것을 확인할 수 있습니다.
개발 시 swagger openapi를 자주 사용하는 저에게는 정말 좋은 기능이었어요!
그럼 이제 path parameter를 어떻게 받느냐!
main.py
에 아래 코드처럼 API를 하나 추가해봅시다.
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def hello_world():
return {"Hello": "World"}
@app.get("/{id}")
def get_somthing(id):
return {"id": id}
이제 localhost:8000/
뒤에 입력하는 값 그대로 return 해주는 것을 볼 수 있습니다.
{}
을 사용해서 path에 있는 값을 가져올 수 있네요
하지만 이게 다가 아니라는거!
python의 type hinting을 사용해서 입력값의 validation까지 가능합니다.
이렇게 함수의 매개변수선언에 int
로 타입힌팅을 해 봅시다.
이렇게 해서 path parameter로 받을 id
라는 변수는 int
형식이라는 것을 표현해줄 수 있는데요.
해당 타입에 맞지 않는 입력이 들어오는 경우 자동으로 validation 실패에 대해서 response 해 줍니다.
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def hello_world():
return {"Hello": "World"}
@app.get("/{id}")
def get_somthing(id: int):
return {"id": id}
바로 확인해봅시다.
차이점이 느껴지시나요?
아까는 "123"
으로 string
형식이었지만 이번엔 123
으로 integer
형식이 되었습니다.
그럼이제 integer
가 될 수 없는 알파벳을 넣으면..
이렇게~ 자동으로 생성된 에러 메시지를 확인할 수 있습니다~
type hint 기능을 적극적으로 활용한 프레임워크라 간편하네요
Q. 그럼 query parameter는요?
A. path에{}
로 선언하지 않고, 매개변수로 받으면 query parameter 입니다.
바로 보시죠
from fastapi import FastAPI
from fastapi import Query
app = FastAPI()
@app.get("/")
def hello_world():
return {"Hello": "World"}
@app.get("/{id}")
def get_somthing(id: int, q: str = "default"):
return {"id": id, "q": q}
이렇게 q: int
로 query parameter의 type hinting을 해주고,
그 뒤의 = "default"
로 default value를 설정해줄 수 있습니다.
이제 localhost:8000/123
으로 query parameter 없이 요청하면?
이렇게 설정해둔 default 값이 나오죠?
그럼 localhost:8000/123?q=test
로 query parameter q
에 test
값을 줘볼게요
그럼 입력값이 그대로 나오게되죠?
여기서 query parameter의 조건을 좀 더 제한시켜봅시다
이번엔 optional query parameter를typing
내장모듈의 Optional
객체를 사용해서,
validation은 fastapi
의 Query
객체를 사용해 볼게요
from typing import Optional
from fastapi import FastAPI
from fastapi import Query
app = FastAPI()
@app.get("/")
def hello_world():
return {"Hello": "World"}
@app.get("/{id}")
def get_somthing(id: int, q: Optional[str] = Query("default")):
return {"id": id, "q": q}
이렇게 Optional[str]
을 통해서 optional parameter에, str
타입임을 명시해 주고
Query([default])
를 통해서 default value를 설정해줄 수 있습니다.
사실 이렇게만 사용하면 위 방식과 결과가 똑같지만
Query
객체를 사용하는 경우 min_length
(최소 길이), max_length
(최대 길이), regex
(정규표현식) 같이 더욱 제한적인 validation을 쉽게 할 수 있습니다.
아래 두 가지 조건을 적용해볼게요
- 한 자리수 이상
- 세 자리수 이하
from typing import Optional
from fastapi import FastAPI
from fastapi import Query
app = FastAPI()
@app.get("/")
def hello_world():
return {"Hello": "World"}
@app.get("/{id}")
def get_somthing(
id: int, q: Optional[str] = Query("default", min_length=1, max_length=3)
):
return {"id": id, "q": q}
자 간단하죠?
그럼 해당 범위를 벗어나는 request가 들어온다면?
이렇게 어떤 부분이 잘못되었는지 잘 나오는 것을 볼 수 있습니다!
하지만 위 방법을 사용해서 데이터를 제공하려면
역시 데이터를 생성해야겠죠? 😂
다음시간부터는 post
방식과 DB연동을 진행해볼게요~