Buckets
The bucket API implements the server-side of file-uploads and can be used to make files accessible over HTTP. It does not implement the browser-side, so it is best used with a library like lona-dropzone.
A bucket is basically a temporary directory, that gets created when a bucket is initialized with a request object, and closed automatically when the view, associated with the request, gets removed from the server.
Usage
from lona import View, Bucket, HTML, A
class BucketView(View):
def handle_request(self, request):
self.bucket = Bucket(
request=request,
on_add=self.on_add, # optional
on_delete=self.on_delete, # optional
)
return HTML(
A(
'Bucket'
href=self.bucket.get_url(), # link to the bucket
target='_blank', # open link in new tab
interactive=False,
),
)
def on_add(self, file_names):
# this method gets called whenever a file gets added (uploaded)
# `file_names` is a list of strings
pass
def on_delete(self, file_names):
# this method gets called whenever a file gets deleted
# `file_names` is a list of strings
pass
Regardless of the URL of the view that opened the bucket, all buckets are accessible at /buckets/<request_id>/<bucket_id>.
To upload a file, issue a multipart POST request to /buckets/<request_id>/<bucket_id>/add.
To delete a file, issue a POST form request to /buckets/<request_id>/<bucket_id>/delete. The bucket will search for the form key name.
The URL prefix (/buckets/) can be changed using settings.BUCKETS_URL_PREFIX.
When Bucket.index is enabled, a generic frontend for listing, adding, and deleting files for a bucket is available at /buckets/<request_id>/<bucket_id>.
Arguments
lona.Bucket.__init__(
self,
request,
max_files=None,
max_size=None,
index=True,
on_add=None,
on_delete=None,
)
:request: `lona.Request` object :max_files: Maximum of files that can be added (uploaded) to the bucket as integer. If max_files is `None` any amount of files is allowed. :max_size: Maximum of bytes that can be added (uploaded) to the bucket as integer. If max_size is `None` any amount of bytes is allowed. :index: HTTP/HTML index is enabled. :on_add: Optional callback which is called with the list of added file names, when one or more files are added in a POST request. :on_delete: Optional callback which is called with the list of deleted file names, when one or more files are deleted in a POST request.
Methods
lona.Bucket.get_path(
self,
file_name='',
)
Returns the absolute path to the given file name, as a string. If no file name is given, the absolute path to the buckets directory is returned. :file_name: optional string file name
lona.Bucket.get_file_names(
self,
)
Returns a list of all file names in the bucket as strings.
lona.Bucket.get_size(
self,
)
Returns the sum of the sizes of all files in bytes, contained in the bucket, as integer.
lona.Bucket.get_url(
self,
file_name='',
)
Returns the URL to the given file name, as a string. If no file name is given, the URL to the buckets index is returned. :file_name: optional string file name
lona.Bucket.get_add_url(
self,
)
Returns the add (upload) URL of the bucket as a string.
lona.Bucket.get_delete_url(
self,
)
Returns the delete URL of the bucket as a string.
Customization
The Bucket index page can be customized by overriding the template lona/bucket.html.
<!-- templates/lona/bucket_index.html -->
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Lona Bucket {{ bucket.id }}</title>
<style>
body {
font-family: sans-serif;
}
.delete-form {
display: inline;
}
</style>
</head>
<body>
<h1>Lona Bucket {{ bucket.id }}</h1>
<table>
<tr>
<th>Max Files</th>
<td>{{ repr(bucket.max_files) }}</td>
</tr>
<tr>
<th>Max Size</th>
<td>{{ repr(bucket.max_size) }}</td>
</tr>
</table>
<h2>Add File</h2>
<form class="add-form" action="{{ bucket.get_add_url() }}?redirect={{ bucket.get_url() }}" method="POST" enctype="multipart/form-data">
<input type="file" name="files[]" multiple />
<input type="submit" value="Add" />
</form>
<h2>Files</h2>
{% set file_names=bucket.get_file_names() %}
{% if file_names %}
<ul>
{% for file_name in file_names %}
<li>
<a href="{{ bucket.get_url(file_name=file_name) }}">{{ file_name }}</a>
<form class="delete-form" action="{{ bucket.get_delete_url() }}?redirect={{ bucket.get_url() }}" method="POST">
<input type="hidden" name="name" value="{{ file_name }}" />
<input type="submit" value="Delete" />
</form>
</li>
{% endfor %}
</ul>
{% else %}
<p>No files yet</p>
{% endif %}
</body>
</html>