I am uploading a zip file through Streamlit that will be uploaded to a cloud computing service through an API. The API is
def upload_files(input_file, api_token):
#Input files to be uploaded.
file_upload = requests.post(
‘https://platform.rescale.com/api/v2/files/contents/’,
data=None,
files={‘file’: open(input_file,‘rb’)},
headers={‘Authorization’: f’Token {api_token}'}
)
It gives me this error
“TypeError: expected str, bytes or os.PathLike object, not UploadedFile”
Now how would I convert it to something understandable by the API. Keep in mind I tried io.bytesio and io.stringio.
We need to see the rest of your code where you uploaded the file.
However, from the error message, i suspect, that you did not convert the uploaded file to bytes.
This might be the solution (untested):
file_upload = requests.post(
"https://platform.rescale.com/api/v2/files/contents/",
data=None,
files={'file': input_file.getvalue()},
headers={'Authorization': f'Token {api_token}'}
)
Hi Franky. Thanks for your timely response. I got this error when I tried it:
“UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0x82 in position 10: invalid start byte”
This is a simple working example that shows your use-case.
However it is only tested against a dummy REST endpoint.
Adjust it to your needs.
File Upload and POST Example
import requests
import streamlit as st
st.set_page_config(page_title='File Upload Example',
page_icon=':file_folder:', layout='centered', initial_sidebar_state='collapsed')
st.header("File Upload and POST Example")
input_file = st.file_uploader("Upload a ZIP file", type="zip", accept_multiple_files=False)
if input_file is not None:
st.info("File uploaded successfully")
if st.button("Upload to API"):
st.info("Uploading file to API...")
file_bytes = input_file.getvalue()
api_token = "blablabla"
file_upload = requests.post(
url="https://httpbin.org/post",
files={'file': file_bytes},
headers={'Content-Type': 'application/zip',
'Authorization': f'Token {api_token}'}
)
st.subheader("Request POST Header - just for debugging")
st.json(dict(file_upload.request.headers))
st.subheader("Response Status Code - just for debugging")
st.info(f'Status Code: {file_upload.status_code}')
st.subheader("Response Header - just for debugging")
st.json(dict(file_upload.headers))
st.subheader("Response Content - just for debugging")
st.write(file_upload.content)
2 Likes
Thanks Franky! That small change in the API made it work. However, one thing to note, I did not send the input_file .getvalue(), I sent it as input_file right away as it will hold its file type/extension (which was zip) when sent and I need that to process it on the backend.