1

I have the below python code. It takes .wav file as an input via postman. It is received here as a base64 string which is then decoded back from base64. The code further processes the .wav file and generates the .png image. I have to save that in AWS S3. I am facing problems in saving it to AWS S3 because the file that is saved there does not open. It says photo viewer doesn't support this file format. Any idea how to do this?

import json
import base64
import boto3
#import scipy.io.wavfile as wav
#import scipy.signal as signal
import numpy as np
from matplotlib import pyplot as plt
from scipy import signal
import shutil
import wavio
import wave
import matplotlib.pylab as plt
from scipy.signal import butter, lfilter
from scipy.io import wavfile
import scipy.signal as sps
from io import BytesIO    

def lambda_handler(event, context):
   s3 = boto3.client("s3")
   
   # retrieving data from event. Which is the wave audio file
   get_file_content_from_postman = event["content"]
   
   # decoding data. Here the wava file is converted back to binary form
   decoded_file_name = base64.b64decode(get_file_content_from_postman)
   
   new_rate = 2000
   
   # Read file
   sample_rate, clip = wavfile.read(BytesIO(decoded_file_name))
   
   # Resample data
   number_of_samples = round(len(clip) * float(new_rate) / sample_rate)
   clip = sps.resample(clip, number_of_samples)
   
   #butter_bandpass_filter is another fuction
   a = butter_bandpass_filter(clip, 20, 400, 2000, order=4)
   
   filtered = 2*((a-min(a))/(max(a)-min(a)))-1
   
   fig = plt.figure(figsize=[1,1])
   ax = fig.add_subplot(212)
   ax.axes.get_xaxis().set_visible(False)
   ax.axes.get_yaxis().set_visible(False)
   ax.set_frame_on(False)
   powerSpectrum, freqenciesFound, time, imageAxis = plt.specgram(filtered, Fs=2000)
   
   #filename is referring to the AWS Lambda /tmp directory
   filename  = '/tmp/' + 'image.png'
   
   plt.savefig(filename, dpi=400, bbox_inches='tight',pad_inches=0)
   
   s3_upload = s3.put_object( Bucket="aaa", Key="filename.png", Body=filename)
   return {
   'statusCode': 200,
   'body': json.dumps("Executed successfully")
   }

1 Answer 1

1

You are using put_object which means that Body is not a file name:

  • Body (bytes or seekable file-like object) -- Object data.

If you want to keep using put_object, then it should be:

with open(filename, 'rb') as file_obj:
   s3_upload = s3.put_object( Bucket="aaa", Key="filename.png", Body=file_obj)

Or use upload_file which is more intuitive.

Sign up to request clarification or add additional context in comments.

2 Comments

@MuhammadArsalanHassan No problem. Glad it worked out.
Thanks mate! You made my day.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.