Using uploaded files

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.

1 Like

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.

1 Like

:heart_eyes: thanks a lot … you made my day