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)으로 설정해주면 된다

 

대충  docs로 실험해보면 결과가 잘 나온다는 사진

 

 

 

----------------------------------------------------------------------------------------

 

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'로 인식해버림

 

실험한게 있었는데... 귀찮다

TAGS.

Comments