how to use REST API to download zip file?

1,656 views
Skip to first unread message

Dov Kruger

unread,
Jan 20, 2016, 11:39:53 PM1/20/16
to Canvas LMS Users
Just getting started with REST API.  I am using perl and can get assignments, people, etc as JSON.  However, there does not seem to be an API call to get all the uploaded files for an assignment.
For manual grading, I would go to the assignment, and on the right is a link "download submissions."  So I copies that link.  This is the URL:


If clicking on this results in a zip file being downloaded, I expected the same to happen with my curl command:

my $cmd = "curl -H 'Authorization: Bearer $auth' https:://canvas.instructure.com/api/v1/courses/6501/assignments/28167/submissions?zip=1";

can anyone tell me what I am doing wrong?

Becky Kinney

unread,
Jan 21, 2016, 8:54:21 AM1/21/16
to canvas-l...@googlegroups.com
I'm not a Canvas developer, but I'm pretty sure that your expectation is simply wrong. The API doesn't act the way you are hoping it does. In fact, I don't think there is an API endpoint for file download of any kind. You can get a link address for a file or an attachment, which will be some long horrible thing pointing to amazon with an authorization code. That's where Canvas files are really stored. As for assignment zip files, my guess is that they are created on-the-fly when requested, and most likely not stored at all. 

Why do you need the API anyway? Wouldn't it be simpler to just redirect to the exact url for the download? If the logged in user has permission to read it, the link should work. If not, I think you are out of luck.

Becky Kinney
Academic Technology Services

--

---
You received this message because you are subscribed to the Google Groups "Canvas LMS Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to canvas-lms-use...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Dov Kruger

unread,
Jan 21, 2016, 5:24:58 PM1/21/16
to Canvas LMS Users
I have an automatic grading program that currently takes a zip file that is download, unpacks it , builds the programs inside it, runs them, and displays the text of the code and the output for grading.
I want to incorporate the downloading of the assignment into the script.

Surely if I can click on a link and download, I can trigger the same behavior (and follow up with my program).

Becky Kinney

unread,
Jan 22, 2016, 12:02:09 PM1/22/16
to canvas-l...@googlegroups.com
I agree. I just don't think you can do it via the API. There is no endpoint for it. There is an endpoint for assignment submissions that can return the individual attachments, but you don't get the data directly. Just a url.

Becky Kinney
Academic Technology Services

--

Dov Kruger

unread,
Jan 22, 2016, 12:22:09 PM1/22/16
to Canvas LMS Users
If the link to download submissions is:


If the link will do it, then why can't my program, running with my authorization, do the same thing?

This is not listed in the API, but it obviously works in the code.  I am asking someone at instructure to help me get the data that is clearly available.

The API is supposed to get the data in and out of Canvas.  This is a critical piece of data.  If it's not supported, then it should be.  If I need to get it some other way, please tell me how to do it.  One student at a time? Fine.


Cody Cutrer

unread,
Jan 22, 2016, 12:28:03 PM1/22/16
to canvas-l...@googlegroups.com
Dov,

Yes, you are supposed to download the submissions one at a time. If you will notice when you use your browser to download a zip file, it's not a simple link that just starts downloading. As was previously surmised, Canvas generates that zip file on demand. So the browser will send a request to start generating the zip file, and poll until completion, and _then_ download the temporary file.

Downloading a zip of submissions is the only way for a browser to get all submissions in a user friendly way. Imagine how the user would respond if their browser suddenly asked them to save 100 files, because the course has 100 students? However, when scripting against the API, you have much finer control of your environment. You're not prompting a user where to save each submission as you encounter them. Therefore, it's not a problem to just enumerate the submissions and download them one at a time, _without_ the complexity of an asynchronous API call that you have to poll for completion.

Cody Cutrer
Software Engineer
Instructure

Graham Ballantyne

unread,
Jan 22, 2016, 1:40:09 PM1/22/16
to canvas-l...@googlegroups.com
Following up on what Cody said…
If the link to download submissions is:


If the link will do it, then why can't my program, running with my authorization, do the same thing?
Presumably your program is trying to make requests with your API token (either with the "Authorization: Bearer <token>" header or an "access_token=<token>" query param). The assignment submissions URL you're trying to hit isn't an API URL; it doesn't accept an API token as authentication. User-land UI requests like that use a combination of your session cookie and a the X-CSRF-Token header (and/or cookie) to authenticate you. Try clicking that link with your browser's development tools open and inspect the network request; you'll see the cookies and header (e.g. https://www.dropbox.com/s/19gsqgcxxalox04/Screenshot_2016-01-22_10_25_31.png?dl=0).



--
Graham Ballantyne
IT Services
Simon Fraser University

Dov Kruger

unread,
Jan 23, 2016, 11:39:00 AM1/23/16
to Canvas LMS Users
Cody,

The purpose of this posting is to find out how to interact with the server. You just said that I can download one file at a time.
HOW?  I don't see anything in the API.
Just tell me the sequence of operations.  How do I walk through the submissions, get the id of the files, and request them?

Becky Kinney

unread,
Jan 24, 2016, 9:53:15 AM1/24/16
to canvas-l...@googlegroups.com
/api/v1/courses/:course_id'/assignments/:assignment_id/submissions?include[]=user";

This is what I use. Each submission has a sub-array ['attachments']. You don't get the files, but you get urls you can use to retrieve them individually. This endpoint only returns the most recent submission for each student.


Becky Kinney
Academic Technology Services

--

Dov Kruger

unread,
Jan 24, 2016, 8:15:01 PM1/24/16
to Canvas LMS Users
Thanks!  That's exactly what I needed.

Dov Kruger

unread,
Jan 25, 2016, 3:39:02 PM1/25/16
to Canvas LMS Users
Sorry, this doesn't work for me.  I do not understand the syntax of this, even after looking at the docs.  What am I doing wrong?


sh: include[]: bad array subscript

Graham Ballantyne

unread,
Jan 25, 2016, 4:39:09 PM1/25/16
to canvas-l...@googlegroups.com
This isn't a Canvas problem; your shell (sh) is having a problem with the unescaped square brackets in the URL. You probably need to wrap the URL in quotes, and/or escape the brackets with a backslash:

Curl running under bash and zsh (not sh) will take the unquoted, unescaped URL, but needs the -g option passed to disable globbing; otherwise, it needs to be quoted.


Sorry, this doesn't work for me.  I do not understand the syntax of this, even after looking at the docs.  What am I doing wrong?


sh: include[]: bad array subscript


--

---
You received this message because you are subscribed to the Google Groups "Canvas LMS Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to canvas-lms-use...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Patricia Goldweic

unread,
Aug 23, 2016, 4:11:51 PM8/23/16
to Canvas LMS Users
Does the method described by Becky constitute the current accepted practice? This certainly works to retrieve all the submission attachments one by one, although the method is NOT really documented in the Canvas API (in fact, the 'attachments' field is not even documented in the API), which leads me to believe there's no guarantee that it will continue to work in the future. Could Cody or another Instructure person comment on this? 
Reply all
Reply to author
Forward
0 new messages