HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonflaskMinor

Saving temporary file for plotting audio waveform

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
filetemporaryplottingwaveformaudioforsaving

Problem

I am developing a web application in Flask - Python.

My goal is to let the user upload an mp3/wav file. This file will (for the scope of this question) get processed by the server and a picture showing the waveform of the audio file will be shown to the user.

My concern is that I am not experienced with neither Flask nor web applications. I would like this audio file to be saved somewhere temporarily, then get deleted. Similarly, I would like the picture of the waveform to just be shown without being saved after the user sees it. This is because I expect all the mp3/wav files to be different - there is no point in saving them.

Right now I have this method that gets called when a user uploads file:

def handle_file(file):
  filename = secure_filename(file.filename)
  filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
  file.save(filepath)
  mir.save_plot(filepath)
  os.remove(filepath)
  plot_filepath = PLOT_FOLDER + 'audio.png'
  return plot_filepath


As you can see, I first save the audio file to a directory in the server, then process it (mir.save_plot does that), then I remove it, and then I return the plot_filepath which will be used in the template to show the final plot picture.

The mir.py file is the following:

import librosa
import plot as plt

def save_plot(filename):
    y, sr = librosa.load(filename)
    plt.plot(y, 'audio', 'time', 'amplitude')


The plot.py file:

import matplotlib.pylab as plt

def plot(vector, name, xlabel=None, ylabel=None):
    plt.figure()
    plt.plot(vector)
    plt.xlabel(xlabel)
    plt.ylabel(ylabel)
    plt.plot()
    plt.savefig('static/plots/' + name)


I feel like my design is poor and there is a better way to do this. Am I right?

The rest of the code:

```
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == "GET":
return render_t

Solution

Instead of saving file you can create io.BytesIO object and use it instead of file.

Also

def allowed_file(filename):
      return (
          '.' in filename
          and os.splitext(filename)[1].lower() in ALLOWED_EXTENSIONS
      )


Also maybe you should check content-type header and not only extension.

Code Snippets

def allowed_file(filename):
      return (
          '.' in filename
          and os.splitext(filename)[1].lower() in ALLOWED_EXTENSIONS
      )

Context

StackExchange Code Review Q#162699, answer score: 2

Revisions (0)

No revisions yet.