frontend(vue.js)에서 FastAPI로 타입이 여러개 담긴 Formdata 보내기
1. formdata로 FastAPI에 값 보내기
formdata로 파일만 보내는 경우가 있지만, 때로는 formdata로 파일도 보내고 싶고
string이나 integer 등등 단순 데이터도 같이 보내고 싶을 수 있다
//vue.js
async stopSoundToKeyword () {
this.isLoading = true
this.isRecording = false
this.mediaRecorder.stop()
this.mediaRecorder.onstop = (event) => {
const blob = new Blob(this.audioArray, {type: 'audio/mp3'})
this.audioArray.splice(0)
const formData = new FormData()
formData.append('audio', blob, 'recoding.mp3')
formData.append('title', this.form.title)
if (this.form.writer != null) {
formData.append('writer', this.form.writer)
}
axios
.post('/fast/reviews/sound', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then(result => {
this.form.keyword = result.data.words
this.form.content = result.data.review
this.form.score = result.data.star
this.isLoading = false
})
.catch(err => {
console.log(err)
})
}
},
formdata에 보내고 싶은 데이터를 전부 append시킨다
const blob = new Blob(this.audioArray, {type: 'audio/mp3'})
this.audioArray.splice(0)
const formData = new FormData()
formData.append('audio', blob, 'recoding.mp3')
formData.append('title', this.form.title)
if (this.form.writer != null) {
formData.append('writer', this.form.writer)
}
그리고 axios로 formdata를 보내는데 headers 설정을 꼭 해줘야한다
'Content-Type': 'multipart/form-data'라고 설정을 꼭 해주자
axios
.post('/fast/reviews/sound', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then(result => {
this.form.keyword = result.data.words
this.form.content = result.data.review
this.form.score = result.data.star
this.isLoading = false
})
.catch(err => {
console.log(err)
})
}
그러면 frontend에서 FastAPI로 어떻게 보내긴했는데.. 문제는 FastAPI에서 어떻게 받느냐인데
인자로 audio: UploadFile = File(...), title: str = Form(...), writer: str = Form(...)으로 받아주면 된다
그러면 FastAPI가 알아서 formdata의 구성요소를 분리해서 받는다
from fastapi import FastAPI,File,UploadFile,Form
"""
input:mp3 file(keyword), title
output:review & point prediction
"""
@app.post("/fast/reviews/sound")
async def sound_to_review(audio: UploadFile = File(...), title: str = Form(...), writer: str = Form(default=None)):
#read mp3 file to byte string
data = await audio.read()
headers = {
"X-NCP-APIGW-API-KEY-ID": client_id,
"X-NCP-APIGW-API-KEY": client_secret,
"Content-Type": "application/octet-stream"
}
response = requests.post(STT_URL, data=data, headers=headers)
rescode = response.status_code
if(rescode == 200):
words = json.loads(response.text)['text'] #stt result
length = np.random.choice(REVIEWLENGTH)
review,star = create_gpt_review(title,words,writer,length)
return {"words": words, "review":review,"star":star,"respond":1}
else:
return {"words": words, "review":'', "star":0, "respond":0}
때로는 default값을 설정하고 싶을때가 있다
예를 들어 writer같은 경우, frontend에서 formdata로 보내지 않을때, 그럼에도 불구하고 보낼수도 있으니까..
보내지 않는 경우는 None으로 쓰고 싶은거임
그러면 writer: str = Form(default = None)으로 설정해주면 된다
----------------------------------------------------------------------------------------
2. 주의할 점
javascript에서 None을 나타내는 값은 null이고 python에서 None을 나타내는 값은 None이라
이게 둘이 다른데
javascript에서 null로 설정하고 null을 담아 보낸다면??
구체적으로...
//vue.js
const blob = new Blob(this.audioArray, {type: 'audio/mp3'})
this.audioArray.splice(0)
const formData = new FormData()
formData.append('audio', blob, 'recoding.mp3')
formData.append('title', this.form.title)
formData.append('writer', null)
그리고 fastapi에서 null을 보내면 None을 받는거라고 생각해서 default로 따로 설정 안하고
from fastapi import FastAPI,File,UploadFile,Form
"""
input:mp3 file(keyword), title
output:review & point prediction
"""
@app.post("/fast/reviews/sound")
async def sound_to_review(audio: UploadFile = File(...), title: str = Form(...), writer: str = Form(...)):
이러면 FastAPI에서는 놀랍게도?... javascript에서 온 null을 None으로 인식하는게 아니라
문자열 'null'로 인식해버림
실험한게 있었는데... 귀찮다