Generate and download file with Django and Nginx - python

My problem is: I need to generate a csv file from the data I have in the database and then download it. Seems easy, but I cannot find a solution that will allow me to do it in the background so the user won't be redirected anywhere.
What I need is user clicking a button and the download starting immediately with the user staying on the same page. Something like a simple html download attribute, but with actually generating a file first. I cannot generate file in advance as the data changes all the time and I need to output the most recent version of it, also, user may specify some filters for the data, so I need to take it into account.
I use Django with Nginx as a production server. Django should always return a response, so I'm not sure I would be able to do what I want at all. Is there any different way to do it then?
I've searched for a long time, but unable to find anything similar to my request. Thanks everyone!

Related

Is it wrong to use modules like wget to let users download files on django?

I am working on a django application in which users can download their own files. I need to make the files secure and only let them download it.
At first, I was thinking of using something like
{%if files%}
<a href='/media/files/pics/photo.png' download>
Then i realised that anyone can brute force my site and get any files. So I thought of handling the download through views. I am very beginner and don't know how to make my own download view. So I used something like:
at views.py
def download(id):
file = data.objects.get(pk=id)
url = file.fileurl
filename = wget.download(url)
and call the function when the user want to download the file. I am using wget module. I think I am doing wrong, So I decided to ask for some suggestions.
At last my question is :
Is it wrong to use other modules to download files? Or how to write a download view on Django?
Thank you!!
How to download a file in Django depends on your needs. any library that can download and store the file somewhere should be fine. How to serve them to other users on the other hand is a different story.
As you mentioned, you need URLs to be private so only the authorized user can download the file. In this case, You can set up a view and authorize the user and then let your webserver know that it should serve a specific file to this user.
You can use X-Accel-Redirect if you're using Nginx. Other web servers such as Apache have a similar option named X-Sendfile.
Take a look here for nginx example: Django and Nginx X-accel-redirect
As for saving files, you should save the files somewhere and store the path to that file in the database and link it to a user (with a foreignkey for example) and let only the owner of the file download the file. It is also worth mentioning that downloading files might take a long time so it's a good idea to lunch a background task for downloading the files and allow users to start the download when it's finished. You can take a look at Celery for background tasks.

How to get file from dropbox and upload on my server by using python

I am working on application where I am giving a functionality to user where they can signin from dropbox by using my application but when I am trying to get the file from Dropbox I am unable to do it. When user choose the desired file from dropbox and click on choose and then nothing happen. Can anyone please help out either is it possible to do it or not? If yes, how can we do it? I am at beginner level. Please help me out and explain the whole process to do it in detail.
Are you using public Dropbox files?
Then you just need to fetch the item by URL and download it. If this happens in a browser tool, you'll need JavaScript and not Python to download it.
Or you leave out JS and just use Python to render an HTML page where a button is for a Dropbox file and clicking the button triggers a download of the file. That is a generic HTML task you can search for.
If you need access to sign in Dropbox and view private files, consider using a Python library built around Dropbox.
See the Python Dropbox guide. Are you using a library like that? Please share as your question was vague.
https://www.dropbox.com/developers/documentation/python#
Also please share an explanation of what your logic is or a small code snippet. I can't see what you are doing yet so I don't know where you are missing something or making a mistake.
From the screenshot, I see you're using the Dropbox Chooser. That's a pre-built way to let your end-users select files from their Dropbox accounts and give them to your app.
Make sure you implement the success and cancel callback methods as documented there for the Chooser.
In the success callback, you'll get the information for the selected file(s). That occurs in JavaScript in the browser though, so if you need that on your server, you'll need to write some JavaScript to send that up to your server, e.g., via an AJAX call or a form or whatever means you use in your app.

Looking for a 1-click add a web (or local) file to email solution. Not sure if it exists

I'm sorry if this is the wrong place for this, but I not exactly sure where is the right place to pose this issue.
I'm being asked to make a web page or spread sheet with a table of PDFs and add a button where each PDF can be attached to an email. As in, a one-click solution to add the actual PDF into an email, not a link to the file. I don't think this is possible since the file is hosted on the web... BUT...
If the file is hosted locally on our internal server is there a code or function that would be able to do that?
Basically, the company owner is old and doesn't want to have to search for files to add to emails. He wants to just be able to open a list (web, excel, whatever), click on the one(s) he wants, and have them add to an email. I need to be able to manage and update the PDF files on the back end and update the table.
Of course the easy thing is to have a shared folder, but it lacks organization of an easily readable table. Alternately, he want to attach the actual file, not send a link.
I can't think of a way to do this, but plenty of people are smarter than I.
And advice or help is appreciated.

Send PDF file from Django website to LogicalDOC

I'm developing my Django website since about 2 months and I begin to get a good global result with my own functions.
But, now I have to start a very hard part (to my mind) and I need some advices, ideas before to do that.
My Django website creates some PDF files from HTML templates with Django variables. Up to now, I'm saving PDF files directly on my Desktop (in a specific folder) but it's completely unsecured.
So, I installed another web application which is named LogicalDoc in order to save PDF file directly on this application. PDF files are created and sent to LogicalDoc.
LogicalDoc owns 2 API : SOAP and REST (http://wiki.logicaldoc.com/rest/#/) and I know that Django could communicate with REST method.
I'm reading this part of Django documentation too in order to understand How I can process : https://docs.djangoproject.com/en/dev/topics/http/file-uploads/
I made a scheme in order to understand what I'm exposing :
Then, I write a script which makes some things :
When the PDF file is created, I create a folder inside LogicalDoc which takes for example the following name : lastname_firstname_birthday
Two possibilities : If the folder exists,I don't create a new folder, else I create it.
Once it's done, I send the PDF file directly inside the folder by comparing PDF name with folder name to do that
I have some questions about this process :
Firstly, is it possible to make this kind of things ?
Is it hard to do that ?
What kind of advices could you give me ?
Thank you so much !
PS : If you need some part of my script, mainly PDF creating part, I can post it just after my question ;)
An idea is pretty simple, however it always requires some practice.
I strongly advice you to use REST api and forget about SOAP as the only thing it can bring to you - is 'pain' :)
If we check documentation, document/create it gives next information.
Endpoint we have to communicate with.
[protocol]://[server]:[port]/document/create
HTTP method to use - POST
List of parameters to provide with your request: body,
document, content
Even more, you can test API by clicking on "Try it out" button and check requests in "Network" tab of your browser (if you open Developer Tools)
I am not sure what kind of metadata do you have to provide in 'document' parameter but what I know you can easy get an idea of what should be done by testing it and putting XML or JSON data into 'document' parameter.
Content is an array of bytes transferred to the server (which would be your file).
To sum up, a request to 'document/create' uri will be simple
body = { 'headers': {},'object': {},}
document = "<note>data</note>"
content=open('report.xls', 'rb') #r - reading, b - binary
r = requests.post('http://logicaldoc/document/create', body=body, document=document, content=content)
Please keep in mind that file transferring requests take time and sometimes you may get timeout exception. Your code will stop and will be waiting for response, so it may be a good idea to get some practice with asyncio or celery. Just keep in mind those kind of possible issues.

Showing processing message in Python

I want to show the processing information or log in the original page when the submitted request is being served until it completes the execution. I thought it would be meaningful to the user to know what is happening behind the request.
I don't find a clue to do so though, can you guys help me out as how people are doing like this one below one - for your reference
http://www.xml-sitemaps.com/
there are two ways i could imagine handling this:
have your backend script (python) output the information of a long process to a log of some sort (text file, database, session, etc...) and then have javascript grab the information via ajax and update the current page.
same deal, but instead of ajax just have a meta refresh on the page which would grab the latest updated information.
you may use python threading, which will create a new process in background
and display your messages on that thread
hope it helps ;)

Categories