0

I am trying to send a zip file stored in static/downloads/67 called August_#1.zip. Everything I have tried has not worked, not doing anything different or returning any errors.

I have tried using send_file with all the different types of directory strings like; static/download/67 and /Users/...

@app.route('/download')
def download():

    try:
        #print(directory[:-(len(name)+1)])
        #print(name)

        #static_file_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'static')
        #print(static_file_dir)

        #return send_from_directory(static_file_dir+"/downloads/67", "August_1.zip", as_attachment=True)

        url = request.args.get('url', 0, type=str)

        print(url)

        d = "/Users/<...>/static/downloads/67"

        return send_from_directory(d, "August_#1.zip")

    except Exception as e:

        #print("Error")

        return str(e)

    return "Nothing"

I would like the zip file to be downloaded on the clients web browser.

I am new to web dev so I am not very confident with flask.

Thanks.

Edit:

After some help I have got the problem down to be the button press code in the index.html:

<div class="row" style="margin-bottom: 15px;margin-right: 0;margin-left: 0;">
<div class="col-md-6" style="padding-right: 0px;padding-left: 0%;width: 100%;">
<div class="d-flex justify-content-center align-items-center" style="margin-top: 0px;width: 100%;margin-left: 0px;height: 100%;padding-top: 6px;padding-bottom: 6px;"><input class="d-flex d-xl-flex justify-content-center m-auto align-items-xl-center" type="text" style="margin: 0px;padding: 0px;margin-right: 0px;width: 90%;height: 27px;padding-left: 5px;" name="url"></div>
</div>
<div class="col-md-6" style="padding-right: 0px;padding-left: 0px;">
<div class="d-flex justify-content-center justify-content-md-start justify-content-lg-start justify-content-xl-start align-items-xl-center" style="margin-top: 0px;width: 100%;height: 100%;padding-top: 6px;padding-bottom: 6px;"><button class="btn btn-primary text-center border-dark d-flex justify-content-center" style="height: 27px;padding: 0px;background-color: rgb(255,255,255);color: rgb(14,14,14);width: 20%;min-width: 90px;" type="button", id = "download" >Download</button></div>
</div>
</div>

...

    <script type=text/javascript> 
        $(function() {
            $('#download').bind('click', function() {
            $.getJSON('/download', {
                url: $('input[name="url"]').val(),
            });
            return false;
            });
        }); 
    </script> 
Ramesh
  • 2,297
  • 2
  • 20
  • 42
  • So there's no exception being thrown? What are you getting in your client when you . make the request? Just a 200 with no file? – Jtcruthers Oct 10 '19 at 18:16
  • @Jtcruthers This is what i get when I look up in the response header: ```HTTP/1.1 200 OK; Accept-Ranges: bytes; Cache-Control: public, max-age=43200; Content-Length: 19012622; Content-Type: application/zip; Date: Thu, 10 Oct 2019 18:29:51 GMT; Etag: "1570689074.527-19012622-2168333630"; Expires: Fri, 11 Oct 2019 06:29:51 GMT Last-Modified: Thu, 10 Oct 2019 06:31:14 GMT; Server: Werkzeug/0.16.0 Python/3.7.4``` – Callum Osborne Oct 10 '19 at 18:33
  • `Content-Length: 19012622;`. Check the size of your zip. I bet its 19012622 bytes. Are you absolutely positive it isn't being downloaded when you hit it? Those headers look like it's working – Jtcruthers Oct 10 '19 at 18:39
  • What client are you using? Just your browser or Insomnia or what? I'd recommend trying on insomnia/postman to see if you get a bunch of bytes back. – Jtcruthers Oct 10 '19 at 18:50
  • I'm just using chrome, is there anything i should be adding to the HTML that allows the client to download it? I did not see anything online about it. – Callum Osborne Oct 10 '19 at 18:51
  • No, you dont need to add anything else. You can do a minimal test to make sure its working outside of your normal stuff. Follow this to get your hello world app working https://flask.palletsprojects.com/en/1.1.x/quickstart/#a-minimal-application. Then replace `return 'hello world'` with `return send_from_directory("/absolute/path/to/dir", "filename")`. Make sure that works. When you go to the link it will download it without a prompt. – Jtcruthers Oct 10 '19 at 19:02
  • It works when i copy the exact same code into the homePage function, so it would download it when I refresh the page, but when i put it into the other function it does not download, why could that be? – Callum Osborne Oct 10 '19 at 21:38
  • Can you just send me a link to the code? It's really weird because your original headers act like it's getting the zip. You just can't see it or something? I'm not sure – Jtcruthers Oct 10 '19 at 21:54
  • https://pastebin.com/jDm9X3eN – Callum Osborne Oct 10 '19 at 23:41
  • so, after some messing around, i have found the cause of the problem, it only occurs when i try to return the send_from_directory(...), i can use it in the function and it will work, only when i try to return it. – Callum Osborne Oct 11 '19 at 03:26
  • I just copy and pasted your code, changed the directory to one on my machine, and it worked on `0.0.0.0:5000/download`. I really don't know what to tell you. You're able to download it on the root, so it seems your path is correct. I'm not sure the next steps – Jtcruthers Oct 11 '19 at 04:45
  • It works for me too when i put ```0.0.0.0:5000/download``` in my browser, so it must be something to do with the button, i'll copy the code to the button press in the question, must be something to do with that – Callum Osborne Oct 11 '19 at 16:04
  • Wait, that means it works then? You're defining `@app.route('/download')` as a function that just returns the zip file. So when you hit that URL, it is working. What are you wanting to happen? Do it on a button press? Having them redirect to the page is the easiest way, but that's a completely different question. – Jtcruthers Oct 11 '19 at 16:15
  • But flask is the backend, so when you hit that endpoint, it is returning the file. That endpoint is working as expected then. – Jtcruthers Oct 11 '19 at 16:16
  • Why does it not work when i press the download button? – Callum Osborne Oct 11 '19 at 17:08
  • That's a frontend question, and definitely out of the scope of this. Post another question with the frontend code. Your flask server is working fine. – Jtcruthers Oct 11 '19 at 17:13
  • You can google things like "Download binary file jquery". I'm by no means a jquery master, so sorry. Here's a quick link that may be related. https://stackoverflow.com/questions/33902299/using-jquery-ajax-to-download-a-binary-file – Jtcruthers Oct 11 '19 at 17:23

1 Answers1

1

It was due to a front end problem, I was using JS to call the function which was creating an error when the file was returned. I have figured out why, but i managed to solve the problem by using forms in html with the action attribute:

<form class="row" style="margin-bottom: 15px;margin-right: 0;margin-left: 0;" action = "http://localhost:5000/download" method = "post">