I'm uploading an audio file to a Starlette server and I'm trying to access it the way they recommend in the docs, but it's giving me a not callable error. I gather the issue is calling .form()
on the request
object, but I'm not sure how else to read it in.
Server Route:
@app.route('/api/upload_track/', methods=['POST'])
async def separate_vocals(request):
audio_data = await request.form()
separator = Separator('spleeter:2stems')
audio_bytes = await (audio_data['file'].read())
return audio_data
Client:
function FileUploadSingle() {
const [file, setFile] = useState([]);
const handleFileChange = (e) => {
if (e.target.files) {
setFile(e.target.files[0]);
}
};
let audioData = new FormData();
const blob = new Blob([file], {type: 'audio/mpeg'});
audioData.append('file', file, 'file');
console.log(file);
console.log(audioData.get('file'));
// 👇 Uploading the file using the fetch API to the server
fetch(`${RESTAPI_URL}/api/upload_track/`, {
method: 'POST',
body: audioData,
})
.then((res) => res.json())
.then((data) => console.log(data))
.catch((err) => console.error(err));
};
}
export default FileUploadSingle;
The following error:
TypeError: 'FormData' object is not callable
is caused when returning the FormData
object you obtained, by using await request.form()
, from your endpoint (i.e., return audio_data
)—which I am sure it is not the one you would like to return in the first place, but rather the audio_bytes
. Now, if you attempted to return the byte array using return audio_bytes
, you would get:
TypeError: 'bytes' object is not callable
In Starlette, you could use the Response
class to return bytes
, for example:
from starlette.responses import Response
@app.route('/upload', methods=['POST'])
async def upload(request):
form = await request.form()
contents = await form['file'].read()
return Response(contents)
The Response
class also allows you to specify the MIME type (also known as media type), using the media_type
parameter.