2

Internal error is faced when I upload an audio file in fastAPI

Hello, I am new to FastAPI I have to build and API for my deep learning audio classification model.

I have attempted to do this:

@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile = File(...)):
    y, sr = librosa.load(file.filename)
    print(file.filename)
    S = librosa.feature.melspectrogram(
        y, sr=sr, n_fft=2048, hop_length=512, n_mels=128)
    mfccs = librosa.feature.mfcc(S=librosa.power_to_db(S), n_mfcc=40)
    # mfccs = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=40)
    return mfccs
    #return {"filename": file.filename}

if __name__ == "__main__":
    # load model
    model = load_model("trained_heartbeat_classifier.h5")

classify_file = sys.argv[1]
x_test = []
x_test.append(create_upload_file(classify_file, 0.5))
x_test = np.asarray(x_test)
x_test = x_test.reshape(x_test.shape[0], x_test.shape[1], x_test.shape[2], 1)
pred = model.predict(x_test, verbose=1)
# print(pred)

pred_class = model.predict_classes(x_test)
if pred_class[0]:
    print("\nNormal heartbeat")
    print("confidence:", pred[0][1])
else:
    print("\nAbnormal heartbeat")
    print("confidence:", pred[0][0])

but I got the error when I upload an audio file: Internal Server Error

and in the terminal, it shows file not found.

So do we have to save an audio file in any temp folder?

desertnaut
  • 57,590
  • 26
  • 140
  • 166
Faizan.shaikh
  • 41
  • 1
  • 5
  • Maybe it will help you https://stackoverflow.com/a/63581187/13782669 – alex_noname Aug 30 '20 at 09:28
  • I believe you have to save it before opening a file. Otherwise, depending on how the library is implemented, you could directly feed the file content into the parser. Try `y, sr = librosa.load(file.file)` – lsabi Aug 30 '20 at 14:08

2 Answers2

1

UploadFile has following attibutes:

  • filename: A str with the original file name that was uploaded 

  • file: A SpooledTemporaryFile (a file-like object). This is the actual Python file that you can pass directly to other functions or libraries that expect a "file-like" object.

So If you call file.file, you will get the file content. Do your prediction and preprocessing activities inside router function because router function can not be called as traditional functions. The function is instantiated under router decorator(See the source code).

NB: You can use background task or work queue if you donot want to wait until the prediction comes, the acknowledgement from the work queue(Use Celery with redis/rabbitmq) will notify you about completation of task. The work queue also parralel the task if you can use multiple worker.

Mahir Mahbub
  • 126
  • 1
  • 11
0

May be this approach doesn't work for each format (they say it doesn't work with mp3, although I haven't checked), but for my task with .wav I came up with this solution, wrapping file into BytesIO and it worked:

def deal_with_sound_file(sound: bytes = File(...)):
   ... = librosa.load(io.BytesIO(sound))
   ...
Maryna Klokova
  • 431
  • 7
  • 14