cancel
Showing results for 
Search instead for 
Did you mean: 
hversemann
Community Participant

https POST requests to start, check status, and download a provisioning report

Jump to solution

I'm a C#.Net developer trying to submit https POST requests for a provisioning report, and have not been able to find thus far any specific examples of what data to put into the parameters object that must accompany each start provisioning report, check provisioning report status, and download provisioning report request. I have made several attempts to no avail and keep getting this message:

The remote server returned an error: (422) Unprocessable Entity.

when I try to send a start request.

I also need to have explained to me what the ":report" of the following uri :

POST /api/v1/accounts/:account_id/reports/:report

means (shown above) in the api under the heading of Start A Report.

The information presented gives a whole bunch of information, which seems to show all possible information that can be sent in a request, but without showing any more simple examples of the minimum data requirements, that need to be sent. Or does absolutely everything returned from the account reports for the provisioning report have to be set properly and then sent in every request to the api?

So far its been a little confusing and I'd appreciate any help in the way of parameter settings and logic examples, or additional links showing that type of examples?

Thanks for the help.

Henry 

1 Solution

Accepted Solutions
James
Community Champion

 @hversemann ,

Start with the List Available Reports.

GET /api/v1/accounts/:account_id/reports

This will give you an array of available reports that look like this.

{
    "title":"MGP Grade Export",
    "parameters":{
        "enrollment_term_id":{
            "required":true,
            "description":"The canvas id of the term to get grades from"
        }
    },
    "report":"mgp_grade_export_csv",
    "last_run":null
}‍‍‍‍‍‍‍‍‍‍‍

The important things are the "report" property, which tells you what you need to specify for the :report on the POST, and parameters that have a "required":true property. These are mandatory. Most parameters are optional and "required":false.

Now you take that information and move on to the Start a Report endpoint.

POST /api/v1/accounts/:account_id/reports/:report 

In the above example, you would replace :report with mgp_grade_export_csv.

POST /api/v1/accounts/:account_id/reports/mgp_grade_export_csv

We don't use Multiple Grading Periods, so I'm going to have to switch reports to get the next part. I'm going to look at the Last Enrollment Activity report.

{
    "title":"Last Enrollment Activity",
    "parameters":{
        "enrollment_term_id":{
            "required":false,
            "description":"The canvas id of the term's courses to get activity from"
        },
        "course_id":{
            "required":false,
            "description":"The course's enrollments to report on"
        }
    },
    "report":"last_enrollment_activity_csv",
    "last_run":null
},

The [parameters] instructions, with the argument being "string" is slightly confusing, but it's not too bad once you figure it out. You start off with parameters and then, inside brackets [], you specify the name of the parameter you want to include.

For my Last Enrollment Activity report, I want to specify enrollment_term_id = 6943, which is our Fall 2017 term. This would look like parameters[enrollment_term_id]=6943

POST api/v1/accounts/self/reports/last_user_access_csv?parameters[enrollment_term_id]=6943

This gives me the response:

{
    "id":356015,
    "progress":0,
    "parameters":{
        "enrollment_term_id":"6943"
    },
    "current_line":null,
    "status":"running",
    "report":"last_user_access_csv",
    "file_url":null
}

If you need to include more than one parameter, you repeat that as a second query parameter (separated with an ampersand). Here I want to include my MATH 113 course, which has a course ID of 2151249.

/api/v1/accounts/self/reports/last_user_access_csv?parameters[enrollment_term_id]=6943&parameters[course_id]=2151249

You can also use application/json as your content type and send a JSON encoded string (use the stringify method). Here's what the structure would look like.

{
    "parameters":{
        "enrollment_term_id":6943,
        "course_id":2151249
    }
}

You can also specify SIS IDs if you like. For example, instead of enrollment_term_id=6943, I could have used enrollment_term_id=sis_term_id:2017c. In JSON format, that would look like this.

{
    "parameters":{
        "enrollment_term_id":"sis_term_id:2017c",
        "course_id":2151249
    }
}

View solution in original post

10 Replies
chofer
Community Coach
Community Coach

Hi  @hversemann ...

While I do not have an answer for you myself, I wanted to let you know that I am going to share your question with the https://community.canvaslms.com/groups/canvas-developers?sr=search&searchId=d998e694-d3fc-4fd5-883b-...‌ group here in the Canvas Community in hopes that your question will get some additional exposure.  If you are not yet following this group, use the link I've provided, and then click on the "Follow" button at the top right corner of the page.  Also, you may need to click on the "Actions" >> "Join group" option located in that same area of the screen.  I hope this helps, Henry!  Good luck!

James
Community Champion

 @hversemann ,

Start with the List Available Reports.

GET /api/v1/accounts/:account_id/reports

This will give you an array of available reports that look like this.

{
    "title":"MGP Grade Export",
    "parameters":{
        "enrollment_term_id":{
            "required":true,
            "description":"The canvas id of the term to get grades from"
        }
    },
    "report":"mgp_grade_export_csv",
    "last_run":null
}‍‍‍‍‍‍‍‍‍‍‍

The important things are the "report" property, which tells you what you need to specify for the :report on the POST, and parameters that have a "required":true property. These are mandatory. Most parameters are optional and "required":false.

Now you take that information and move on to the Start a Report endpoint.

POST /api/v1/accounts/:account_id/reports/:report 

In the above example, you would replace :report with mgp_grade_export_csv.

POST /api/v1/accounts/:account_id/reports/mgp_grade_export_csv

We don't use Multiple Grading Periods, so I'm going to have to switch reports to get the next part. I'm going to look at the Last Enrollment Activity report.

{
    "title":"Last Enrollment Activity",
    "parameters":{
        "enrollment_term_id":{
            "required":false,
            "description":"The canvas id of the term's courses to get activity from"
        },
        "course_id":{
            "required":false,
            "description":"The course's enrollments to report on"
        }
    },
    "report":"last_enrollment_activity_csv",
    "last_run":null
},

The [parameters] instructions, with the argument being "string" is slightly confusing, but it's not too bad once you figure it out. You start off with parameters and then, inside brackets [], you specify the name of the parameter you want to include.

For my Last Enrollment Activity report, I want to specify enrollment_term_id = 6943, which is our Fall 2017 term. This would look like parameters[enrollment_term_id]=6943

POST api/v1/accounts/self/reports/last_user_access_csv?parameters[enrollment_term_id]=6943

This gives me the response:

{
    "id":356015,
    "progress":0,
    "parameters":{
        "enrollment_term_id":"6943"
    },
    "current_line":null,
    "status":"running",
    "report":"last_user_access_csv",
    "file_url":null
}

If you need to include more than one parameter, you repeat that as a second query parameter (separated with an ampersand). Here I want to include my MATH 113 course, which has a course ID of 2151249.

/api/v1/accounts/self/reports/last_user_access_csv?parameters[enrollment_term_id]=6943&parameters[course_id]=2151249

You can also use application/json as your content type and send a JSON encoded string (use the stringify method). Here's what the structure would look like.

{
    "parameters":{
        "enrollment_term_id":6943,
        "course_id":2151249
    }
}

You can also specify SIS IDs if you like. For example, instead of enrollment_term_id=6943, I could have used enrollment_term_id=sis_term_id:2017c. In JSON format, that would look like this.

{
    "parameters":{
        "enrollment_term_id":"sis_term_id:2017c",
        "course_id":2151249
    }
}

View solution in original post

hversemann
Community Participant

Chris,

Thanks for the extra exposure of my previous, and the help.

Henry

hversemann
Community Participant

James,

Thanks for the note.

It is helping greatly in figuring out some of the stuff that I was doing wrong.

Henry

hversemann
Community Participant

James,

Thanks for the note.

So the initial response that comes back from canvas after a report starts then will show the progress of the report thus far, as well as the report’s id value or identifier.

I’m not sure how long a provisioning report might take to run, so then do I need to send multiple status requests to get the progress of the report?

If so then I can use the id at the top of the initial report response object to then submit all subsequent report status check requests right?

So if the report is long running then do I need to set some kind of delay between report status requests, because I’ll have to probably send multiple report status requests? If so how long a delay to set?

Then once the response progress value comes back as 100 (meaning 100 percent complete) then I can use the “file_url” returned in the latest response as the next url to hit or send request using that url to actually get the report file. Correct?

Let me know when you can.

Thanks.

Henry

hversemann
Community Participant

James,

So I've been able to send both start report and check report status requests successfully. So in order to download the generated report then I would just send a GET request using the file_url returned in the last check report status response that I got back correct?

If so then how would I take the downloaded file object and save it somewhere on my local machine? 

Let me know when you can.

Thanks.

Henry

James
Community Champion

The initial report will show the progress, but there is also a Status of Report endpoint that is better. Take the report ID that is returned from the post (356015 in my example response).

Reports should not have the expectation of finishing immediately, but you can send more than one and let them run in the background (I have not verified that, so if it's wrong, let me know). Just keep track of the report ID as the List of Reports only returns the last one.

You will need to poll periodically to check and see when it's done with a report. The length it takes depends on the report, how much data there is, the load on the servers, etc. The status gives a progress, so you can start to get an idea if you track those, or you can just have it poll every 10 minutes or so depending on how quickly you need the data.

hversemann
Community Participant

James,

So far my experience is the same as yours in that the Provisioning report that I start finishes almost immediately.

I just need to figure out now what to do with the generated report file that the file_url download link in order to save it to my local machine.

Henry

James
Community Champion

The heads up on the download is that (if I remember right) it is a regular URL, not an API call. That is, there is no /api/v1 in front of the path. If you try to fetch it with the Authorization header, it will fail.

It's one of the simpler processes as it's not even a REST operation. You are just looking to save a file from an URL.  I can't give any .NET specific examples since I don't use that, but a quick search suggests there's a saveAs method available.