폼 데이터

폼 데이터 (Form Data)

JSON 대신 폼 필드를 받아야 할 때는 Form을 사용할 수 있습니다.

!!! note "참고" 폼을 사용하려면 먼저 python-multipart를 설치하세요.

프로젝트에 추가합니다:

```
$ uv add python-multipart
```

출처: 공식문서

Form 임포트하기 (Import Form)

fastapi에서 Form을 임포트하세요:

from typing import Annotated

from fastapi import FastAPI, Form

app = FastAPI()


@app.post("/login/")
async def login(username: Annotated[str, Form()], password: Annotated[str, Form()]):
    return {"username": username}

🤓 다른 버전과 변형

!!! tip "팁" 가능하다면 Annotated 버전을 사용하는 걸 권장합니다.

from fastapi import FastAPI, Form

app = FastAPI()


@app.post("/login/")
async def login(username: str = Form(), password: str = Form()):
    return {"username": username}

Form 파라미터 정의하기 (Define Form parameters)

BodyQuery와 같은 방식으로 폼 파라미터를 만듭니다:

from typing import Annotated

from fastapi import FastAPI, Form

app = FastAPI()


@app.post("/login/")
async def login(username: Annotated[str, Form()], password: Annotated[str, Form()]):
    return {"username": username}

🤓 다른 버전과 변형

!!! tip "팁" 가능하다면 Annotated 버전을 사용하는 걸 권장합니다.

from fastapi import FastAPI, Form

app = FastAPI()


@app.post("/login/")
async def login(username: str = Form(), password: str = Form()):
    return {"username": username}

예를 들어 OAuth2 스펙을 쓸 수 있는 방법 중 하나("password flow"라고 부르는)에서는 usernamepassword를 폼 필드로 보내야 합니다.

그 스펙은 필드의 이름이 정확히 usernamepassword이어야 하고, JSON이 아니라 폼 필드로 전송되어야 한다고 요구합니다.

Form으로 Body(그리고 Query, Path, Cookie)와 같은 설정들을 선언할 수 있습니다. 검증, 예시, 별칭(예: username 대신 user-name) 등을 포함해서요.

!!! note "참고" FormBody에서 직접 상속받는 클래스입니다.

!!! tip "팁" 폼 바디를 선언하려면 명시적으로 Form을 사용해야 합니다. 그렇지 않으면 파라미터들이 쿼리 파라미터나 바디(JSON) 파라미터로 해석되기 때문입니다.

"폼 필드"에 대하여 (About "Form Fields")

HTML 폼(<form></form>)이 데이터를 서버로 보내는 방식은 보통 그 데이터에 대해 "특수한" 인코딩을 사용하는데, JSON과는 다릅니다.

FastAPI는 JSON 대신 올바른 위치에서 그 데이터를 읽도록 해 줍니다.

!!! info "기술적 세부사항 (Technical Details)" 폼의 데이터는 보통 "media type" application/x-www-form-urlencoded로 인코딩됩니다.

하지만 폼에 파일이 포함되면 `multipart/form-data`로 인코딩됩니다. 파일 처리에 대해서는 다음 장에서 배우게 됩니다.

이런 인코딩과 폼 필드에 대해 더 읽고 싶다면 [MDN 웹 문서의 `POST`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST)를 참고하세요.

!!! warning "경고" 경로 동작 에서 여러 Form 파라미터를 선언할 수는 있지만, JSON으로 받을 것으로 예상되는 Body 필드는 함께 선언할 수 없습니다. 요청이 application/json이 아닌 application/x-www-form-urlencoded로 인코딩된 바디를 가지기 때문입니다.

이것은 **FastAPI**의 제한이 아니라, HTTP 프로토콜의 일부입니다.

요약 (Recap)

Form을 사용해서 폼 데이터 입력 파라미터를 선언하세요.

더 알아보기 (Learn more)

  • 폼 데이터를 받으려면 먼저 python-multipart를 설치해야 합니다.
  • Form으로 Body와 같은 설정(검증, 예시, 별칭 등)을 폼 필드에 적용할 수 있습니다.
  • 폼(또는 파일)과 함께 JSON Body 필드를 선언할 수는 없습니다(HTTP 프로토콜 제약).