입력 형태로 데이터를 받고 싶을 경우 활용하는 모듈
python-multipart가 필요함
pip install python-multipart
Frontend도 간단히 만들기 위해 Jinja2 설치
pip install Jinja2
# 파일 이름 : ex.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sample Login</title>
</head>
<body>
<form method="post">
<input type="string" name="username" value="{{username}}"/>
<input type="password" name="password" value="{{password}}"/>
<input type="submit">
</form>
</body>
</html>
value="{{username}}" : Key는 username이며, 해당 input 공간에 입력된 값이 Value가 됨
value="{{password}}" : Key는 password이며, 해당 input 공간에 입력된 값이 Value가 됨
<input type='submit'>
: 따로 POST Mapping할 URI가 주어지지 않았으므로, 해당 HTML 파일을 띄우는 URI 그대로 POST 요청을 보낼 것
from fastapi import FastAPI, Form, Request
from fastapi.templating import Jinja2Templates
import uvicorn
app = FastAPI()
templates = Jinja2Templates(directory='./')
@app.get('/login')
def get_login_form(request: Request):
return templates.TemplateResponse('ex.html',
context={'request':request})
# /login을 입력하면 ex.html과 연결하는 것
@app.post('/login')
def login(username:str=Form(...), password:str=Form(...)):
return {"username":username, "password":password}
if __name__=='__main__':
uvicorn.run(app, host='0.0.0.0', port = 8000)
get_login_form 함수에 접근함
templates.TemplateResopnse() 메서드에 의해 ex.html로 이동함
ex.html 창이 Frontend로 뜨게 됨
ID와 Password를 입력하고 Submit 버튼을 누르면 POST Method로써 /login에 요청이 가므로, login() 메서드가 수행됨
login() 메서드는 {"username":username, "password":password}
형식 데이터를 반환하므로, 아래 사진과 같은 결과를 반환함
중요한 점!
templates.TemplateResponse()
메서드를 수행시킬 때 꼭 contex={'request':Request'}
를 통해 get_login_form 메서드가 받은 Request를 전달해 줘야 함Form(...) : Required(필수 요소)
"어떤 Frontend 파일"에 "어떤 데이터"를 보낼 것인지 명시하는 메서드이다.
위에서는 Request 객체를 ex.html에 보낸다는 의미이다.
그렇다면, Request 객체 이외에 다른 임의 데이터도 HTML 등에 보낼 수 있을까?
정답은, 가능하다!
아래 코드 예시와 결과를 통해 확인하자
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sample Login</title>
</head>
<body>
<form method="post">
<input type="string" name="username" value="{{username}}"/>
<input type="password" name="password" value="{{password}}"/>
# 이 부분만 추가됨
# 즉, id라는 값을 받아서 Frontend에 띄우는 것
<input type="text" value="{{id}}" disabled>
<input type="submit">
</form>
</body>
</html>
from fastapi import FastAPI, Form, Request
from fastapi.templating import Jinja2Templates
import uvicorn
app = FastAPI()
templates = Jinja2Templates(directory='./')
# 바뀐 부분. context에 Request만 보내는게 아니라 "id":2라는 새로운 값, 쌍을 포함시켜 보냄
@app.get('/login')
def get_login_form(request: Request):
return templates.TemplateResponse('ex.html', context={'request':request, "id":2})
@app.post('/login')
def login(username:str=Form(...), password:str=Form(...)):
return {"username":username, "password":password}
if __name__=='__main__':
uvicorn.run(app, host='0.0.0.0', port = 8000)
value="{{id}}"
부분이 채워졌음을 알 수 있다. 즉, Request 뿐만이 아닌 내가 원하는 데이터로 미리 Frontend 파일을 채울 수도 있다는 것이다HTML에서 <form action='/files' enctype='multipart/form-data' method='post'>
를 통해 어떤 URI에 어떤 데이터를 넘길지 명명함
File이 넘어온 데이터는 from fastapi import File
을 통해 상속받을 수 있는 File(...)
을 통해 받을 수 있음
from typing import List
from fastapi import FastAPI, File, UploadFile
import uvicorn
app = FastAPI()
@app.post("/files")
def create(files:List[bytes] = File(...)):
return {"file_sizes":[len(file) for file in files]}
@app.post("/uploadedfiles")
def create_uploaded(files:List[UploadFile] = File(...)):
return {"file_sizes":[file.filename for file in files]}
...
create() : File(...)
을 통해 File 객체를 받을 수 있음을 알 수 있다. 하지만, UploadFile 객체를 받는 것이 아니라 bytes 형태로 File을 받는다.
create_upload() : 동일하게 File 객체를 받음을 알 수 있다. 이 때에는 UploadFile의 List형식을 받는다고 되어 있다.
즉, User가 Upload한 파일 그 자체를 넘겨받는 것이다.
따라서, File의 Name인 file.filename도 접근할 수 있게 되는 것이다
(create() 메서드에서는 filename을 알 수는 없음. 데이터 자체가 Bytes로 변환되어 오기 때문)
아 이 내용을 딱 찾고있었는데 정말 감사드립니다