어제에 이어 라우트에 대해 마저 다뤄 보겠습니다.
프론트로부터 parameter 를 이용해 정보를 전달받을 수 있는데요,
공식 튜토리얼에서는 Path parameter 와 Query parameter 크게 가지로 나눠서 소개합니다.
Path parameter 먼저 빠르게 설명하자면
파이썬 포맷 문자열이 사용하는 동일한 문법으로 "매개변수" 또는 "변수"를 경로에 선언할 수 있습니다.
쉽게 말해 http://127.0.0.1:8000/items/3
과 같이 path parameter 를 백엔드로 전달하는 방법이지요.
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id):
return {"item_id": item_id}
Result:
{"item_id":"foo"}
우리의 목적은 Google Translate 클론 코딩이므로
구글번역은 어떻게 서버로 번역 요청이 전달되는지 확인해 보니 다음과 같네요.
https://translate.google.com/?sl=ko&tl=en&text=<입력문장>&op=translate
저도 똑같이 Query parameter 로 한번 구현해 보겠습니다.
공식 튜토리얼에서는 이렇게 설명하고 있어요.
http://127.0.0.1:8000/items/?skip=0&limit=10
Query parameter 를 하나씩 NMT 특성에 맞춰서 소개하고, 좀더 적합한 query 로 바꾸어 보겠습니다.
NMT 즉 기계번역의 기본 원리는 문장 : 문장 = 1 : 1 번역입니다.
예를 들어 NMT 는 한국어 문장 '나는 다이너마이트처럼 빛나' 를
영어 문장 'I'm a light it up like dynamite' 로 번역하도록 모델을 학습시키고 번역해 주지요.
이 때 한국어에 해당하는 출발 언어를 'Source' 라고 하고
영어에 해당하는 도착 언어를 'Target' 이라고 해요.
다시 구글번역으로 돌아오면,
https://translate.google.com/?sl=ko&tl=en&text=<입력문장>&op=translate
구글번역의 query 중 sl, tl은 아마도 Source Language, Target Language 의 줄임말인 것 같네요.
서버로 전송되는 입력 문장은 text 인 것 같고요.
op 는 작업을 지정하는 것 같은데, 제 클론코딩에서는 번역 태스크만 수행하므로 구현하지 않겠습니다.
기계번역에 대한 자세한 설명은 [글또 - NMT 시리즈] 를 참고해 주세요!
저는 우선 라우트에 이렇게 각 query parameter 를 받도록 작성했습니다.
라우터에서 parameter 를 받은 뒤 service layer 로 전달하여 번역을 수행하고,
번역된 문장을 프론트로 리턴하는 코드입니다.
# app/routes/translate.py
from fastapi import APIRouter
from app.service import translate
# Create routing method
router = APIRouter()
# Query parameter
# https://translate.google.com/?sl=ko&tl=en&text=나는 다이너마이트처럼 빛나&op=translate
@router.post("/")
async def get_mt(sl: str = "ko", tl = "en", text: str = "나는 다이너마이트처럼 빛나") -> dict:
# Service Layer 로 parameter 전달
mt = await translate.get_mt(sl, tl, text)
# 아직 번역 모델을 서빙하지 않았으므로 임시로 지정한 문자열을 리턴합니다.
return {"translated": "good!"}
async def get_mt(sl: str = "ko", tl = "en", text: str = "나는 다이너마이트처럼 빛나") -> dict
를 해석하자면
쿼리 매개변수는 경로에서 고정된 부분이 아니기 때문에 선택적일 수 있고 기본값을 가질 수 있습니다.
text parameter 만을 예로 들면,
text 값을 아무것도 넣지 않으면 기본적으로 text = "나는 다이너마이트처럼 빛나" 로 지정됩니다.
default 값을 지정할 수 있는 셈이지요.
(default 를 None 으로 해야 할지 다른 특정 값을 박아야 할지는 내내 고민중입니다.. 코드리뷰 부탁요.. 🙏)
추가적으로 각 매개변수가 string 인지 검증하고
arrow function ->
을 이용해서 이 함수의 리턴값이 딕셔너리임을 명시합니다.
이 코드를 실행하고 docs 에서 바로 확인해 볼까요?
개인적으로 쿼리 매개변수에 기본값을 지정하면 편리한 점이 기본값이 미리 들어 있어서
텍스트박스 안에 값을 일일이 입력하지 않고 버튼만 클릭해도 바로 서버에 쿼리를 전송하는 효과를 볼 수 있다는 점이었어요.
원래 pydantic 을 이용해 매개변수 검증을 하려고 했는데...
이렇게 짧은 query parameter 는 pydantic 을 이용해서 검증하는 게 더 번거롭게 느껴졌어요.
pydantic 을 이용한 데이터 검증은 DB작업에서 시도해 보겠습니다!
공식 문서
https://fastapi.tiangolo.com/ko/tutorial/query-params/