Sending file as an attachment - python

in my attempt to send a file to the user iam using the following:
return static_file( filename, root='/home/nikos/public_html/static/files' )
But when it comes to .pdf files it opens them to the browser instead of just sendign the file and all other files like .docx it sends them with the filename being just 'file' and not with original file's filename.
How can i send the files properly as attachments?

As mentioned in the docs you can simply pass a download=True argument and that should be it.
e.g.
return static_file(filename, root='/static/files', download=True)
You can also suggest a different filename for the download and pass that instead of True, e.g. download="Custom "+filename

Related

Download specific files from .txt url using Python

How to download specific files from .txt url?
I have a url https://.storage.public.eu/opendata/files/open_data_files_access.txt (not real) with multiple files (here are just a few, in reality there are around 5k files) that can be downloaded separately, however I would need to download only specific files, and do this with Python.
For instance, I have a list with folder name and list of file name. How do I download only those file that are on the list? Let's say the list is:
files = ['folder1_file_1.jpg', 'folder1_file_2.jpg', 'folder1_file_3.jpg', 'folder1_file_4.jpg', 'folder1_file_10.jpg', 'folder2_file_2.jpg', 'folder2_file_3.jpg', 'folder3_file_1.jpg', 'folder3_file_3.jpg', 'folder3_file_4.jpg']
How to download only these in the list and save in specified directory?
I assume that the answer is somewhere here, but no work for me:
uurl = 'https://.storage.public.eu/opendata/files/open_data_files_access.txt'
from requests import get # to make GET request
def download(url, file_name):
# open in binary mode
with open(file_name, "wb") as file:
# get request
response = get(url)
# write to file
file.write(response.content)
file_name' = ['folder1_file_1.jpg', 'folder1_file_2.jpg', 'folder1_file_3.jpg', 'folder1_file_4.jpg', 'folder1_file_10.jpg', 'folder2_file_2.jpg', 'folder2_file_3.jpg', 'folder3_file_1.jpg', 'folder3_file_3.jpg', 'folder3_file_4.jpg']
download(uurl, file_name)

How can I specify the exact folder IN STREAMLIT for the uploaded file to be saved to?

I am trying to create a simple GUI with streamlit and python for my aspect-based sentiment analysis project, the user should be able to upload a .txt file so that I can run the model on that file. I already created the widget for uploading a file. My question is:
The uploaded file should be added to a specific folder, how can I specify an exact location for the uploaded file to be saved?
uploaded_file = st.file_uploader('FILE UPLOAD')
(This is the code for the upload widget)
The file_uploader function does not save the file to disk, it writes to a BytesIO buffer.
The UploadedFile class is a subclass of BytesIO, and therefore it is “file-like”. This means you can pass them anywhere where a file is expected.
https://docs.streamlit.io/en/stable/api.html?highlight=file_uploader#streamlit.file_uploader
If you want to save the result as a file, use the standard Python file io capabilities:
with open(filename, "wb") as f:
f.write(buf.getbuffer())
To add to what #RandyZwitch said you can use this function to save to a directory of your choice (directory/folder "tempDir")
def save_uploaded_file(uploadedfile):
with open(os.path.join("tempDir",uploadedfile.name),"wb") as f:
f.write(uploadedfile.getbuffer())
return st.success("Saved file :{} in tempDir".format(uploadedfile.name))
And apply the function below your uploaded file like below
datafile = st.file_uploader("Upload CSV",type=['csv'])
if datafile is not None:
file_details = {"FileName":datafile.name,"FileType":datafile.type}
df = pd.read_csv(datafile)
st.dataframe(df)
# Apply Function here
save_uploaded_file(datafile)
You can define path like this:
from pathlib import Path
path = "C:/Projects/ex1/your_file"
file_path = Path(path)
uploaded_file = st.file_uploader(file_path)

How to download a file from blob and send it has a file response

I have a client page which will list all the file in the container, on choosing a file the filename along with the container name is sent to the server.
The server should initiate the file download and should send the file as response to the client request, please refer to the image below:
I tried with get_blob_to_stream
#app.route("/blobs/testDownload/")
def testDownload():
container_name =request.args.get("containerName")
print(container_name)
local_file_name= request.args.get("fileName")
with BytesIO() as input_blob:
with BytesIO() as output_blob:
# Download as a stream
block_blob_service.get_blob_to_stream(container_name, local_file_name, input_blob)
copyfileobj(input_blob, output_blob)
newFile = str(output_blob.getvalue())
with open("file.txt","a") as f:
f.write(newFile)
f.close()
return send_file('file.txt',attachment_filename='sample.txt',as_attachment=True,mimetype='text/plain')
But the file which is getting downloaded is in only text file format, I want to download file irrespective of its format. and I know this is not the right way to download file via Web API.
You're using a fixed file-name "file.txt" for all the blobs which may be the reason. Using a stream seems useless here. try get_blob_to_path() instead, check out the following modified code:
--- // your code // ---
block_blob_service.get_blob_to_path(container_name, local_file_name, local_file_name)
# notice that I'm reusing the local_file_name here, hence no input/output blobs are required
return send_file(local_file_name,attachment_filename=local_file_name,as_attachment=True,mimetype='text/plain')
Complete Code:
#app.route("/blobs/testDownload/")
def testDownload():
container_name =request.args.get("containerName")
print(container_name)
local_file_name= request.args.get("fileName")
# Download as a file
block_blob_service.get_blob_to_path(container_name, local_file_name, local_file_name)
return send_file(local_file_name,attachment_filename=local_file_name,as_attachment=True,mimetype='text/plain')
See if that works!
try not to hard-code the extension, as the extension is part of the blob name, whichever method you are using from the documentation. Have a look at the method get_blob_to_path as you are downloading the file first locally. The Local file name is the same as the filename in the blob container.
You can try to get the blob.name for each blob file in the container. Blob name contains the file extension(you just have to parse it) which you can use as a parameter for the method above, and that way you do not have to hard-code it:
Below you can find an example of how you can iterate through the files in the container and get the blob name, and you can just adjust it for your use-case:
block_blob_service = BlockBlobService(account_name=accountName, account_key=accountKey)
# create container if not exists called 'batches'
container_name ='batches'
block_blob_service.create_container(container_name)
# Set the permission so the blobs are public.
block_blob_service.set_container_acl(container_name, public_access=PublicAccess.Container)
# Calculation
blobs = block_blob_service.list_blobs(container_name)
for blob in blobs.items:
file_name = blob.name
So now you can use file_name and split method for '/', and the last item is the filename.extension.

Uploaded Files get overwritten in Dropbox

I am trying to upload users files to DropBox in Django. When I use the built in 'open()' function, it throws the following exception:
expected str, bytes or os.PathLike object, not TemporaryUploadedFile
When I don't, the file gets uploaded successfully but is blank (write mode).
UPLOAD HANDLER:
def upload_handler(DOC, PATH):
dbx = dropbox.Dropbox(settings.DROPBOX_APP_ACCESS_TOKEN)
with open(DOC, 'rb') as f:
dbx.files_upload(f.read(), PATH)
dbx.sharing_create_shared_link_with_settings(PATH)
How do I upload files or pass a mode to DropBox API without it being overwritten?
To specify a write mode when uploading files to Dropbox, pass the desired WriteMode to the files_upload method as the mode parameter. That would look like this:
dbx.files_upload(f.read(), PATH, mode=dropbox.files.WriteMode('overwrite')
This only controls how Dropbox commits the file (see the WriteMode docs for info); it doesn't control what data you're uploading. In your code, it is uploading whatever is returned by f.read(), so make sure that's what you expect it to be.

How to access temporary uploaded file in web2py?

I am using a sqlform to upload a video file and want to encoding the video file while uploading. But I noticed that the upload file is not saved to uploads directory utill it is completely uploaded. Is there a temporary file and how can I access it ?Thanks.
I'm not sure how you might be able to process the file while it is uploading (i.e., process the bytes as they are received by the server), but if you can wait until the file is fully uploaded, you can access the uploaded file as a Python cgi.FieldStorage object:
def upload():
if request.vars.myfile:
video = encode_video(request.vars.myfile.file)
[do something with video]
form = SQLFORM.factory(Field('myfile', 'upload',
uploadfolder='/path/to/upload')).process()
return dict(form=form)
Upon upload, request.vars.myfile will be a cgi.FieldStorage object, and the open file object will be in request.vars.myfile.file. Note, if the encoding takes a while, you might want to pass it off to a task queue rather than handle it in the controller.

Categories