Error 500 when uploading a file via API

Jump to solution
jack_c_kiefer
Community Novice

I swear to the LMS gods that the following Python requests code was working just yesterday:

import requests

# Step 1: Tell Canvas you're going to upload a file

filename = 'test.svg'
folderPath = '/myFolder/test'

size = os.path.getsize(filename)
data = { 'name' : filename,
'size' : str(size),
'content_type' : 'image/svg+xml',
'parent_folder_path' : folderPath }

response = requests.post(filesURL, json=data, headers=headers)
response.raise_for_status()
response = response.json()


# Step 2: Upload the file

files = list(response['upload_params'].items()) # Get all upload params
file_content = open('svg/'+filename, 'rb').read() # Read in file data
files.append((u'file', file_content)) # Add file data to payload
response = requests.post(response['upload_url'], files=files)
response.raise_for_status()
id = str(response.json()['id'])

However, in step 1, when I get the first response, it looks nothing like it used to or what's in the documentation:

{
'file_param': 'file',
'progress': None,
'upload_url': 'https://inst-fs-iad-prod.inscloudgate.net/files?token=<crazy long token>',
'upload_params':
{
'filename': 'c02s04n02a.svg',
'content_type': 'image/svg+xml'
}
}

The code produces the following error:

500 Server Error: Internal Server Error for url: https://inst-fs-iad-prod.inscloudgate.net/files?token=<blah etc.>

Am I missing something? Has a change of file repository occurred from AWS?

Would appreciate some help!

Thanks

Labels (1)
1 Solution
nicholas_matteo
Community Member

I had the same errors, and found that a "filename" parameter which Requests adds to multipart/form-data parts was the problem.

To prevent Requests from adding this, the files argument for requests.post can be provided with tuples of values, giving None in the first position, so we have a list like [('Name', (None, 'value')), ('Name2', (None, 'value2'))].

So in the code sample in the original post, it might help changing line 21 to

files = [(key, (None, val)) for key, val in response['upload_params'].items()] # Get all upload params

I figured this out from this Stackoverflow answer, so thanks to Martijn Pieters!

View solution in original post