How to Upload an Assignment via API using Powershell

Community Participant
1 0 844

You will require the following variables set up accordingly. Values such as $USERID, $COURSEID and $ASSIGNMENTID can be obtained from the API or looking at link URLs in the Canvas web interface.


>> $token = '<TOKEN>'
>> $headers = @{"Authorization"="Bearer "+$token}
>> $userId = 123
>> $asUserId = 456
>> $courseId = 789
>> $assignmentId = 101112
>> $fileName = 'submission.bmp'
>> $filePath = 'c:\submission.bmp'
>> $fileContentType = 'image/bmp' 


Step 1 - Initiate the assignment submission file upload process.

Note that the AS_USER_ID parameter is attached here to the URI to enable masquerading (otherwise you cannot upload a file to another user's account.)


>> $response = Invoke-RestMethod `
   -URI   "https://<HOST_NAME>:443/api/v1/courses/$courseId/assignments/$assignmentId/submissions/$userId/files?as_user_id=$asUserId" `
   -headers $headers `
   -method POST 


We obtain an upload URI from the $RESPONSE object.

>> $uploadUri = $response.upload_url


This upload URI has a life span of 30 minutes, and cannot be used after timeout. The response content contains a list of parameters called UPLOAD_PARAMS which should be included in the POST submission body along with the file data when the file is subsequently uploaded. For our school, these parameters are FILENAME and CONTENT_TYPE.


Step 2 - Construct a hashmap which includes the file to be uploaded, along with the file parameters specified in the response above. This hashmap is passed to the Invoke-RestMethod powershell command which sends the file as part of a form submission.

>> $form = @{

   filename = $fileName
   content_type = $fileContentType
   file = Get-Item -Path $filePath

>> $response = Invoke-RestMethod `
   -URI $uploadUri `
   -Method POST `
   -Form $form

>> Write-Host "$($response.size) bytes uploaded."




Step 3 - Associate the uploaded file with an assignment submission. The $RESPONSE object returned by the previous API call conveniently contains the ID of the file which was just uploaded. We create a $BODY hashmap which is then submitted as POST parameters to associate the assignment submission with the uploaded file. 


Note the braces "[]" which must be included after the "[file_ids]" parameter name.

>> $body = @{


>> $response = invoke-restmethod `
   -uri "https://<HOSTNAME>:443/api/v1/courses/$courseId/assignments/$assignmentId/submissions" `
   -headers $headers `
   -method POST `
   -body $body `
   -ContentType "multipart/form-data"


If no errors occur (these can be handled with TRY/CATCH) then the submission process has completed successfully. 

The $RESPONSE object returned by the previous call does contain values which might also be tested to determine if the submission has completed successfully (e.g. workflow_state='submitted') but I haven't yet encountered a scenario where a submission would fail without throwing a catchable error.