0

Overview:

I am trying to get save/load functionality working as part of a web app I am building, but cannot properly reload a file after I've downloaded it.

Backend:

I have a list a of lists in python that looks something like

[[bytes, bytes, int, list, list, str], [...], [...], etc].

This is the data I care about. I then pickle it using

with open(file_path, 'wb') as fp:
   pickle.dump(save_this_arr, fp) 

and send it using Flask's send_file:

return send_file(file_path, as_attachment=True)

Frontend:

On the front end, I am creating a blob, encoding a data url, and then setting it as the src of a hidden <iframe>:

let blob = new Blob([response.data], { type: "application/octet-stream" });
let url = window.URL.createObjectURL(blob);
self.downloader.src = url 

This works fine and gets me a file that I can re-upload.

Problem:

I am getting stuck on how to properly decode the URL so that I can pickle.load the result. The two links below seem like they're what I need, but I'm getting UnicodeDecodeErrors when I apply it to my code.

Current Attempt:

with open(file_path, "rb") as fid:
     contents = fid.read()
data = urllib.parse.parse_qs(contents, encoding='utf-16')
with open(file_path, 'wb') as fid:
    fid.write(text)
with open(file_path, 'rb') as fid:
    myList = pickle.load(fid)

EDIT:

The original question asked about decoding a url because I misunderstood what window.URL.createObjectURL(blob) was doing. From this blog post, I realized that we are actually creating a reference to an in-memory blob. So what I actually want to do is read a Blob in Python.

References:

Url decode UTF-8 in Python

decoding URL encoded byte stream data in python

Community
  • 1
  • 1
GreatScott87
  • 1
  • 1
  • 5

1 Answers1

0

I'm not sure why I was unable to decode the blob directly, but encoding to a base64 string before writing the file works.

Backend (writing to disk):

import base64
with open(file_path, 'wb') as fp:
    data = pickle.dumps(save_this_arr)
    encoded = base64.b64encode(data)
    fp.write(encoded)

Frontend (copied from question - no change):

let blob = new Blob([response.data], { type: "application/octet-stream" });
let url = window.URL.createObjectURL(blob);
self.downloader.src = url 

Backend (reading from disk):

with open(file_path, "rb") as fid:
    contents = fid.read()
    decoded = base64.b64decode(contents)
    myList = pickle.loads(decoded)
GreatScott87
  • 1
  • 1
  • 5