2. Hello World와 Path, Query parameter

jw·2021년 5월 25일
0

fastapi 경험해보기

목록 보기
2/4
post-thumbnail
post-custom-banner

.gitignore 파일은 링크 대로 설정하겠습니다.

이제 python 가상환경을 만들어보도록 하겠습니다. 저는 python 3.8.9 환경에서 진행해볼게요

가상환경 생성

python -m venv venv 를 통해서 venv 라는 가상환경을 만들고,
source venv/bin/activate 로 활성화 시킵니다.

pip install -U pip로 최신 pip로 업데이트 해 줍니다.

fastapi 설치, hello world

이제 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

이렇게 hello world를 json 형식으로 받을 수 있습니다!

그뿐만 아니라 localhost:8000/docs 로 접속해보면...
open api이렇게 swagger openapi 형식의 문서가 자동으로 생성되는것을 확인할 수 있습니다.

개발 시 swagger openapi를 자주 사용하는 저에게는 정말 좋은 기능이었어요!

Path parameter

그럼 이제 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에 있는 값을 가져올 수 있네요
path parameter

하지만 이게 다가 아니라는거!
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}

바로 확인해봅시다.

path parameter with type hint
차이점이 느껴지시나요?

아까는 "123" 으로 string 형식이었지만 이번엔 123으로 integer 형식이 되었습니다.
그럼이제 integer가 될 수 없는 알파벳을 넣으면..

path parameter with type hint error

이렇게~ 자동으로 생성된 에러 메시지를 확인할 수 있습니다~
type hint 기능을 적극적으로 활용한 프레임워크라 간편하네요

Query parameter

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 없이 요청하면?
path parameter with query parameter

이렇게 설정해둔 default 값이 나오죠?
그럼 localhost:8000/123?q=test로 query parameter qtest 값을 줘볼게요

path parameter with query parameter 2

그럼 입력값이 그대로 나오게되죠?

여기서 query parameter의 조건을 좀 더 제한시켜봅시다

이번엔 optional query parameter를typing 내장모듈의 Optional 객체를 사용해서,
validation은 fastapiQuery 객체를 사용해 볼게요

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을 쉽게 할 수 있습니다.

아래 두 가지 조건을 적용해볼게요

  1. 한 자리수 이상
  2. 세 자리수 이하
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가 들어온다면?

query parameter validation error
이렇게 어떤 부분이 잘못되었는지 잘 나오는 것을 볼 수 있습니다!

마무리

하지만 위 방법을 사용해서 데이터를 제공하려면
역시 데이터를 생성해야겠죠? 😂

다음시간부터는 post 방식과 DB연동을 진행해볼게요~

profile
개발 공부중입니다!
post-custom-banner

0개의 댓글