gws.plugin.upload_helper

Helper for chunked file uploads.

Large files are uploaded by the client in chunks, one request per chunk. The helper stores the chunks in the ephemeral directory and, when asked for the upload, joins them into one file. The helper does not provide endpoints of its own: an action declares an endpoint that receives the chunks and passes them to the helper, and another endpoint that processes the finished upload.

Each chunk request contains the file name, the total size, the number of chunks and the chunk number, starting from 0. The first chunk has an empty uploadUid, which starts a new upload. The handler responds with the uploadUid, which subsequent chunks must provide. Chunks can come in any order. The total size and the number of chunks are limited by maxSize: the maximum number of chunks is derived from it, so that a chunk is at least 500 KB on average.

Once the client has sent all chunks, it calls another endpoint of the action with the uploadUid. That endpoint calls get_upload to get the final file. The file is stored in a temporary location and should be moved to a permanent location if necessary.

Example:

helpers+ { type "upload" maxSize 2000 }

Example:

import gws.plugin.upload_helper as uh


@gws.ext.command.api('myUpload')
def do_upload(self, req, p: uh.ChunkRequest) -> uh.ChunkResponse:
    # check permissions, etc...
    helper = self.root.app.helper('upload')
    return helper.handle_chunk_request(req, p)

@gws.ext.command.api('myProcessUploadedFile')
def do_process(self, req, p: MyProcessRequest):
    helper = self.root.app.helper('upload')
    try:
        upload = helper.get_upload(p.uploadUid)
    except uh.Error:
        ...upload not ready yet...
    ...process(upload.path)

Source code: gws.plugin.upload_helper

Package Contents

class gws.plugin.upload_helper.ChunkRequest(*args, **kwargs)

Bases: gws.Request

Request that carries one chunk of an upload.

chunkCount: int

Total number of chunks.

chunkNumber: int

Number of this chunk, starting from 0.

content: bytes

Chunk content.

fileName: str

Name of the uploaded file.

totalSize: int

Total size of the file in bytes.

uploadUid: str = ''

Upload uid returned for the first chunk, empty for the first chunk.

class gws.plugin.upload_helper.ChunkResponse(*args, **kwargs)

Bases: gws.Response

Response to a chunk request.

uploadUid: str

Upload uid, to be passed with subsequent chunks.

class gws.plugin.upload_helper.Config(*args, **kwargs)

Bases: gws.Config

Helper that receives chunked file uploads.

maxSize: int = 1000

Maximum upload size in megabytes.

exception gws.plugin.upload_helper.Error

Bases: gws.Error

Upload error, raised for invalid chunks and incomplete or missing uploads.

class gws.plugin.upload_helper.Object

Bases: gws.Node

Upload helper, which receives file uploads in chunks and assembles them.

maxChunkCount: int

Maximum number of chunks per upload.

maxSize: int

Maximum upload size in bytes.

configure()

Configuration hook.

Called when the node is initialized. Raising an exception here aborts the creation of the node.

get_upload(uid: str) → Upload

Get a finished upload, joining its chunks into one file on the first call.

Parameters:

uid – Upload uid.

Returns:

The upload, with path pointing to the assembled file.

Raises:

Error – If the upload is not found, not complete or the file size does not match.

handle_chunk_request(req: gws.WebRequester, p: ChunkRequest) → ChunkResponse

Store a chunk of an upload, starting a new upload if uploadUid is empty.

Parameters:
  • req – Web requester.

  • p – Chunk request.

Returns:

Response with the upload uid.

Raises:

gws.BadRequestError – If the chunk or the upload is invalid.

class gws.plugin.upload_helper.Upload(*args, **kwargs)

Bases: gws.Data

State of an upload.

chunkCount: int

Total number of chunks.

fileName: str

Name of the uploaded file, as sent by the client.

path: str

Path of the assembled file, empty until the upload is finalized.

totalSize: int

Total size of the file in bytes.

uid: str

Upload uid.