๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Back-end & Server/FastAPI

[FastAPI] Form

728x90
๋ฐ˜์‘ํ˜•

 

๐Ÿฐ FastAPI ๊ณต์‹๋ฌธ์„œ๋ฅผ ๋ณด๋ฉด์„œ ๊ฐœ์ธ์ ์œผ๋กœ ์ •๋ฆฌํ•œ ๊ธ€ ์ž…๋‹ˆ๋‹ค.

 

์‘๋‹ต์ƒํƒœ

HTTP์—์„œ๋Š” ์‘๋‹ต์ƒํƒœ์— ๋”ฐ๋ผ ์ƒํƒœ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

FastAPI์—์„œ๋Š” status_code ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‘๋‹ต์— ๋Œ€ํ•œ HTTP ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๋ชจ๋“  ์ƒํƒœ์ฝ”๋“œ๋ฅผ ์™ธ์šธ ํ•„์š” ์—†์ด fastapi์˜ ํ•˜์œ„ ํด๋ž˜์Šค status์—์„œ ๋ณ€์ˆ˜๋ฅผ ์ฐพ์•„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

from fastapi import FastAPI, status

app = FastAPI()


@app.post("/items/", status_code=status.HTTP_201_CREATED)
async def create_item(name: str):
    return {"name": name}

 

 

Form

Form ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Form ํ•„๋“œ์˜ ๋™์ž‘์„ ์ œ์–ดํ•˜๊ณ  ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ฃผ์š” ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  1. default : ํ•„๋“œ์˜ ๊ธฐ๋ณธ๊ฐ’์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ํ•ด๋‹น ํ•„๋“œ์˜ ๊ฐ’์„ ์ž…๋ ฅํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์ด ๊ฐ’์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  2. title : ํ•„๋“œ์˜ ์ œ๋ชฉ์ด๋‚˜ ๋ผ๋ฒจ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ’์€ ํผ ์š”์†Œ์— ๋ ˆ์ด๋ธ”๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
  3. description : ํ•„๋“œ์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์„ค๋ช…์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ’์€ ํผ ์š”์†Œ์˜ ์„ค๋ช…์œผ๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
  4. min_length ๋ฐ max_length : ์ž…๋ ฅ ๊ฐ’์˜ ์ตœ์†Œ ๊ธธ์ด์™€ ์ตœ๋Œ€ ๊ธธ์ด๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  5. regex : ์ž…๋ ฅ ๊ฐ’์˜ ํ˜•์‹์„ ์ •๊ทœ์‹์œผ๋กœ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค. ์ž…๋ ฅ ๊ฐ’์€ ์ด ์ •๊ทœ์‹๊ณผ ์ผ์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  6. deprecated : ํ•„๋“œ๊ฐ€ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋„๋ก ํ‘œ์‹œํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ False์ž…๋‹ˆ๋‹ค.
  7. alias : ํ•„๋“œ์˜ ๋ณ„์นญ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋ฉด ํ•„๋“œ์˜ ์ด๋ฆ„์„ ๋‹ค๋ฅธ ์ด๋ฆ„์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  8. ge์™€ le : ์ˆซ์ž ํ˜•์‹์˜ ํ•„๋“œ์—์„œ ์‚ฌ์šฉ๋˜๋ฉฐ, ์ตœ์†Œ๊ฐ’ (ge)๊ณผ ์ตœ๋Œ€๊ฐ’ (le)์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
from typing import Union
from fastapi import FastAPI, Form
from fastapi.responses import HTMLResponse
from pydantic import BaseModel, EmailStr
app = FastAPI()


class UserIn(BaseModel):
    username: str
    password: str
    email: EmailStr
    nickname: str


class UserOut(BaseModel):
    username: str
    email: EmailStr
    nickname: str


forms = {
    'username': {'min_length': 5, 'max_length': 15, 'title': 'Username', 'description': 'ID'},
    'password': {'min_length': 8, 'max_length': 15, 'title': 'Password', 'description': 'ํŒจ์Šค์›Œ๋“œ'},
    'email': {'min_length': 5, 'max_length': 20, 'title': 'Email', 'description': '์ด๋ฉ”์ผ'},
    'nickname': {'min_length': 2, 'max_length': 8, 'title': 'Nick_Name', 'description': '๋‹‰๋„ค์ž„'}
}


@app.post("/user/", response_model=UserOut)
async def createUser(
    username: str = Form(..., **forms['username']),
    password: str = Form(..., **forms['password']),
    email: str = Form(..., **forms['email']),
    nickname: str = Form(..., **forms['nickname'])
):
    user = UserIn(username=username, password=password,
                  email=email, nickname=nickname)
    return user
context = """
<body>
    <form method="post" action="/user">
        ID : <input type="text" name="username"><br>
        PW : <input type="password" name="password"><br>
        Email : <input type="email" name="email"><br>
        Nickname : <input type="text" name="nickname"><br>
        <input type='submit'>
    </form>
</body>
"""


@app.get('/')
async def main():
    return HTMLResponse(context)

 

 

File 

File์„ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์—…๋กœ๋“œํ•  ํŒŒ์ผ์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

File ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ์ผ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.(File์€ Form์„ ์ƒ์†ํ•œ ์ž์‹ ํด๋ž˜์Šค์ด๋‹ค.)

from fastapi import FastAPI, File

app = FastAPI()

@app.post("/file/")
async def createFile(file: bytes = File()):
    return {"file_size": len(file)}

 

File ๋Œ€์‹  UploadFile์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ์Šคํ’€ ํŒŒ์ผ ์‚ฌ์šฉ(์ตœ๋Œ€ ํฌ๊ธฐ ์ œํ•œ๊นŒ์ง€๋งŒ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋˜๊ณ , ์ดˆ๊ณผํ•˜๋Š” ๊ฒฝ์šฐ ๋””์Šคํฌ์— ์ €์žฅ)
  • ์ด๋ฏธ์ง€, ๋™์˜์ƒ, ํฐ ์ด์ง„์ฝ”๋“œ์™€ ๊ฐ™์€ ๋Œ€์šฉ๋Ÿ‰ ํŒŒ์ผ๋“ค์„ ๋งŽ์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์†Œ๋ชจํ•˜์ง€ ์•Š๊ณ  ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ
  • ์—…๋กœ๋“œ ๋œ ํŒŒ์ผ์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Œ
  • file-like async ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ฐ–๊ณ  ์žˆ์Œ
  • file-like object๋ฅผ ํ•„์š”๋กœํ•˜๋Š” ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์ง์ ‘์ ์œผ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” ํŒŒ์ด์ฌ SpooledTemporaryFile ๊ฐ์ฒด ๋ฐ˜ํ™˜

 

UploadFile์˜ ์†์„ฑ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • filename : ๋ฌธ์ž์—ด(str)๋กœ ๋œ ์—…๋กœ๋“œ๋œ ํŒŒ์ผ์˜ ํŒŒ์ผ๋ช… (์˜ˆ: myimage.jpg).
  • content_type : ๋ฌธ์ž์—ด(str)๋กœ ๋œ ํŒŒ์ผ ํ˜•์‹(MIME type / media type)์ด๋‹ค (์˜ˆ: image/jpeg).
  • file : SpooledTemporaryFile (ํŒŒ์ผ๋ฅ˜ ๊ฐ์ฒด)์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ "ํŒŒ์ผ๋ฅ˜" ๊ฐ์ฒด๋ฅผ ํ•„์š”๋กœํ•˜๋Š” ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์ง์ ‘์ ์œผ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” ์‹ค์งˆ์ ์ธ ํŒŒ์ด์ฌ ํŒŒ์ผ์ด๋‹ค.

UploadFile ์—๋Š” ๋‹ค์Œ์˜ async ๋ฉ”์†Œ๋“œ๋“ค์ด ์žˆ๋‹ค. ๋‚ด๋ถ€์ ์ธ SpooledTemporaryFile ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹นํ•˜๋Š” ํŒŒ์ผ ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

  • write(data): data(str ๋˜๋Š” bytes)๋ฅผ ํŒŒ์ผ์— ์ž‘์„ฑํ•œ๋‹ค.
  • read(size): ํŒŒ์ผ์˜ ๋ฐ”์ดํŠธ ๋ฐ ๊ธ€์ž์˜ size(int)๋ฅผ ์ฝ๋Š”๋‹ค.
  • close(): ํŒŒ์ผ์„ ๋‹ซ๋Š”๋‹ค.

 

from fastapi import FastAPI, UploadFile

app = FastAPI()

@app.post("/file/")
async def createFile(file: UploadFile):
    return {"file": file}

 

List๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ๊ฐœ์˜ ํŒŒ์ผ์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

from typing import List
from fastapi import FastAPI, UploadFile

app = FastAPI()

@app.post("/file/")
async def createFile(files: List[UploadFile]):
    return {"files": [f for f in files]}

 

 

from fastapi import FastAPI, UploadFile
from fastapi.responses import HTMLResponse
import pandas as pd

app = FastAPI()


@app.post("/file/")
async def createFile(file: UploadFile):
    contents = await file.read()
    df = pd.read_excel(contents)
    print(df.head(5))
    return {"msg": "success"}
context = """
<body>
    <form method="post" action="/file" enctype="multipart/form-data">
        file : <input type="file" name="file"><br>
        <input type='submit'>
    </form>
</body>
"""


@app.get('/')
async def main():
    return HTMLResponse(context)

 

728x90
๋ฐ˜์‘ํ˜•

'Back-end & Server > FastAPI' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€