Downloading a file in downloads directory - flask, python - python

I have a flask app in which it has a button to download an HTML report. The download button when hit creates an xlsx file. It worked fine until that app was running on my local server because the python code found my Downloads directory no matter what os it is using python's os module.
Now the app is deployed on a remote server, in this case, how do you let the system know the client's download directory path where this xlsx file can then be created? Or any other pointers for a better solution if I'm missing something?

To serve a user a file to download, the webserver needs to deliver it in a special way. You can't use the os module to write to the user's computer. It worked locally, because your server was the same computer as your user environment in the browser.
The correct way to serve a user a file for downloading is to use flask's send_file method.
To show you the process, I've created an example below. In this example, I'm assuming that you have a function called build_report(...) which accepts a report_id and returns an io.BytesIO object containing the content of the xlsx file.
from flask import send_file
#app.route("/download-report/<report_id>")
def download_report(report_id):
file_obj = build_report(report_id)
return send_file(
file_obj,
mimetype="application/vnd.ms-excel",
attachment_filename=f"report-{report_id}.xlsx",
)

If i understand correctly - you want to specify a directory to which the file should be downloaded on users computer when he/she hits download button.
This is not possible, and is handled fully by the browser.
Browser processes the request/stream of special type and then creates the output file in the location specified by the user in browser settings. The os library which you mentioned relates to your server machine not client, so any os opertaions that you provide in your code will be executed on your server (like creating a file). So that's why it worked on your local machine - which was server and client at once.
Why it's dissalowed?
Imagine a "virus file" being uploaded to your C:\Windows\System32. Web applications could be granted control over your machine with a simple button download. The huge security issue doesnt allow for client's machine access from web application

Related

Unable to render aspx files when uploaded to SharePoint programmatically

I am new to SharePoint. I have written a simple python script that basically connects to SharePoint and uploads files (aspx and other frontend files) from a folder on my local machine to a specific folder on SharePoint site.
To facilitate the script to communicate with the SharePoint, I have a created an App principal under SharePoint using the SharePoint App-Only model. I have done this by calling the appregnew.aspx, example: https://spo.test.com/sites/MYSITE/\_layouts/15/appregnew.aspx , below is the sample page when 'appregnew.aspx' is called
Then, I have provided the below permissions to the App principal through 'appinv.aspx', example - https://spo.test.com/sites/MYSITE/\_layouts/15/appinv.aspx
<AppPermissionRequests AllowAppOnlyPolicy="true">
<AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web" Right="FullControl"/>
</AppPermissionRequests>
Next, I use the Client ID and Client Secret under the Python script to establish communication with SharePoint and to upload files to a specific folder (folder already exists and is not created by the program) on SharePoint, example path to which files are uploaded: https://spo.test.com/sites/MYSITE/Shared%20Documents/TeamDocs2
Note: This script uses Python library 'Office365-REST-Python-Client' to communicate with SharePoint
The script can successfully authenticate itself and also upload the files to the folder on SharePoint. But then when I manually go to the SharePoint folder and click on the aspx file, example : index.aspx; the file gets downloaded instead of getting rendered.
There is no issue with the file i.e. it is not corrupted because when I manually upload the same file onto the same folder, then there is no issue, the file gets rendered.
In regards to the permissions for the App principal, I've already given 'FullControl' at the scope 'sitecolletion/web' level. I also tried changing the scope from 'http://sharepoint/content/sitecollection/web' to 'http://sharepoint/content/sitecollection', this didn't work as well
Please can somebody help me with this. Thanks in advance
The reason the .aspx page is being downloaded is related to security risk mitigation in SharePoint. If you consider that Javascript (.js) files and .aspx files are executable files in the browser, then it should also be self evident that allowing users to upload such files to SharePoint could pose risk. Because of this, Microsoft has disabled custom script on all modern sites by default. You can choose to overrule this setting, but it should be done with extreme caution.

Python deployment on webserver with CGI

I have a python script that I want to make accessible through a website with an userinterface.
I was experimenting with Flask, but I'm not sure this is the right tool for what I want to do.
My script takes userdata (.doc/.txt files), does something with it and returns it to the user. I don't want to save anything and I don't think that I need a database for this (is this right?). The file will be temporarily saved on the server and everything will be deleted once the user downloaded the modified file.
My webhosting provider supports Python and only accepts CGI. I read that WSGI is the preferred method to use with Python and that CGI has scaling issues and can only process one request at a time. I'm not sure if I understand this correctly. If several users would upload files at the same time, the server would only accept one request or overwrite previous requests? Or it can do one request per unique IP address/user?
Would CGI be ok for the simple get/process/return task of my python script or should I look into a hosting service that uses WSGI?
I had a look at Heroku and Render to deploy a flask app, but I think I could do that through my webhosting provider I guess.
For anyone interested in this topic,
I decided to deploy my app on render.com, which supports gunicorn (WSGI).

Is there a way to update just one file in microsoft azure without having to redeploy everything?

I am making a web app with python and running it on azure. It the program creates jsons and stores them. If I want to update the program is there a way to just redeploy the main python file so that it doesnt overwrite all of the josn files stored on the server?
You could update the file using FileZilla or some other FTP client. The publish profile contains the info you need. Download the publish profile from the app service overview blade, open it in Notepad, pull out the FTP address, username, and password, and import those into FileZilla. Then just drag the file across.

How to add credentials for googleapiclient on AppEngine

I am using Python Google API Client by following this tutorial. I was able to run the API locally by downloading the credential JSON and running export GOOGLE_APPLICATION_CREDENTIALS="[PATH]". Now, I would like to deploy my application that uses the API to AppEngine. How can I do so? Do I have to somehow download JSON on my AppEngine machine and run export via app.yaml?
Place the JSON file inside your application directory and it will be deployed to GAE as part of your application. Then you can reference it in your app with just a file path (relative to the your app.yaml file). Easiest is to put it right beside your app.yaml file and reference it with just the filename, no file path.
The exact way to reference it may be depending on the GAE environment and runtime your app uses (which you didn't mention), exporting GOOGLE_APPLICATION_CREDENTIALS via app.yaml may be right.
You may want to check your app's handlers and ensure that you don't accidentally respond with the JSON file to a properly crafted external request - you probably don't want that file served to an external request :)

Create local files from a Django web

I have written a Django web run under Linux server, the web is used to read a
file path and generate some folders and files on the local machine which browse
the web, not sure how to do that, currently it can only generate the files on
the server runs the web locally.
Does it need to use the python package paramiko?
Thanks,
Le
Django runs on server and every web server has no access to local (user) computer - it can't create folder on local computer (and it can't steal your files). It can only generate file and user can download it.

Categories