λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

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' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

[FastAPI] 미듀웨어  (0) 2024.02.20
[FastAPI] 경둜 μž‘λ™ μ„€μ •  (0) 2024.02.20
[FastAPI] λͺ¨λΈ  (0) 2024.02.20
[FastAPI] λ§€κ°œλ³€μˆ˜  (0) 2024.02.20
[FastAPI] λ™μ‹œμ„±κ³Ό async / await  (0) 2024.02.19