I want to allow a user to generate a CSV file based on data on the page.
It feels like I’m asking an obvious question but I’ve searched the documentation for “download” and tried other things on the IDE & can’t figure it out.
I want to allow a user to generate a CSV file based on data on the page.
It feels like I’m asking an obvious question but I’ve searched the documentation for “download” and tried other things on the IDE & can’t figure it out.
That’s a good question! The info is all in the docs, but we haven’t brought it all together into a tutorial yet. I have added “make a tutorial about file downloads” to our TODO list, but for now here’s a quick summary:
Whatever you want to download is probably a Media object. (If it’s not already, construct one from a string with BlobMedia()
.)
Any Media object that can be retrieved from the server has a url
attribute. Just set that URL as the url
property of a Link
component, and when you click on the link you will download the media.
To be downloadable from the server, the media object has to be stored somewhere. If you just create a BlobMedia
from a string, that object’s url
attribute will be None
, because it only exists in the browser (or during one server call) - there’s nowhere to get it from when you click the link.
To make data downloadable, you can save it in a Media column of a data table row, or as a file in Google Drive. (Exporting a data table as CSV using the to_csv()
method also produces a downloadable media object. You can also call to_csv()
on a data table view.)
Advanced alternative: If you do want to generate data on the fly, rather than saving it somewhere, create an HTTP API endpoint that returns a Media object. Then use the URL for that API endpoint as the url
property of your Link
component.
Note: If you hit an HTTP API endpoint from within a browser session - eg by clicking on a Link
component - you can access the session state from the endpoint function. So, eg, if you’re logged into the Users service, the HTTP endpoint function can check anvil.users.get_user()
to see whether the download should be permitted.
If you want to see this in action, check out the Secure Download Portal example. The files for download are stored in a Media column in a data table. The media from those columns is then used as the url
for a Link
object.
(Extra note: The url
property of a Media object is a session-specific URL - for security, it will stop working after you’ve closed the app. If you want to make a long-lived URL you can access from other contexts, create an HTTP endpoint instead.)
I hope this helps!
I’ve been banging my head against the wall trying to figure out a way to enable the client to download files (i.e. pdf’s and images) stored on a computer with an Anvil uplink. I like the freedom the Server Uplink gives as well as enabling me to easier comply with the upcomming GDPR. Therefore, Google Drive is sadly not an option.
Should I create an HTTP API endpoint (callable function on the pc with server uplink) for this or is there another way? I am having trouble grasping the current Anvil docs on HTTP APIs on returning files.