File upload to web server DAT

Has anyone been able to implement a web server DAT that supports uploading files? I’m looking to create a small web ui (ideally hosted in a web server DAT) that includes a file upload form for clients to submit files which get saved in a temp folder that TD can access.

There are a number of posts related to sending files through a web client DAT but I can’t find any related to receiving files.

Very much depends on how the uplaod is handled.
The easy way would be to simply send the raw data as bytes and write them in to a file. For this idealy you would send the filename in the header of your request.
If you want to send additional data you might either want to look in to MultipartFormData (and how to parse it [ or a pip-package] ) or run your own solution based on JSON (as in both cases you are sending text.)

For the first it could look like this:

	if request["method"] == "POST":
		with Path("Upload", Filename ).open("wb") as uploadFile:
			uploadFile.write( request["data"] )

You could parse the header for Content-Disposition for see if there is a filename.

For MultiPart I would use a library. Something like this for example?
https://stackoverflow.com/questions/33369306/parse-multipart-form-data-received-from-requests-post

1 Like

I spent a while struggling to get the multi-part approach working using both python-multipart requests-toolbelt.
Instead I managed to get it working using an octet stream upload:

function uploadFile(){
		const file = $('#file-input')[0].files[0];
		fetch('/upload_stream', {
			method: 'POST',
			headers: {
				'Content-Type': 'application/octet-stream',
				'X-Filename': file.name,
			},
			body: file
		});
	}

and on the receiving end I used your routed webserver (which is great btw).

def upload_stream_handler(request, response, server)
	try:
		ext.controller.handleFileUpload(request.data, request.header['x-filename'])
	except Exception as e:
		import traceback
		traceback.print_exc()
		raise server.Exceptions.InternalServerError(f"File upload stream failed: {str(e)}")
	response.statuscode = 200
	response.statusreason = "OK"
	response.header["Content-Type"] = "application/json"
	response.data = '{"success": true}'

and

	def handleFileUpload(self, data, fileName):
		logger.info('File upload received named %s', fileName)
		fileName = _sanitizeFilename(fileName)
		stamp = datetime.now().strftime('%Y%m%d%H%M%S')
		fileName = f'upload-{stamp}-{fileName}'
		filePath = Path('content') / fileName
		if not filePath.parent.exists():
			filePath.parent.mkdir(parents=True, exist_ok=True)
		with open(filePath, 'wb') as f:
			f.write(data)
		logger.info(f'File saved: {filePath}')
		if not filePath.exists() or not filePath.is_file():
			raise ContentException(f'Failed to save file: {filePath}')
		return filePath