Celebrate Excellence in Education: Nominate Outstanding Educators by April 15!
Found this content helpful? Log in or sign up to leave a like!
Hello everyone, hope your day is going great so far.
I have a question about the Canvas API. I have used the API for different scripts and it has been working fine but now I cannot seem to figure out how to update or create a rubric on Canvas through the API.
I am able to change the name of the rubric but I cannot figure out how to actually add the criteria to it. I tried to do it like the Canvas API description specifies (or at least how I understand it) but I must be doing something wrong.
As example, the JSON I want to send over as "data" for the API call.
{
"id": "rubric_id",
"rubric_association_id": "course_association_id",
"rubric[title]": "My Rubric 4",
"rubric[criteria]": {
"1": {
"description": "BBBB",
"points": 7,
"ratings": [
{
"description": "Fuller",
"long_description": "",
"points": 7
},
{
"description": "Nope",
"long_description": "",
"points": 0
}
]
}
}
}
This works as long as I do not include the "rubric[criteria]". So the name change works, so I must be doing something right. I tried replacing the "1" with: 0, 1, "0", "one", "zero". I also tried to replace the whole "rubric[criteria]" with a JSONArray instead of the hash list, just because I can. It always ends up giving me a "internal server error", this error always seems to happen if it is unhappy with the JSON.
This is my call with the http being the api url and as mentioned it works if I only try to change the name, so I guess this is ok and just my JSON is off.
res = requests.put(http +'courses/'+str(id)+'/rubrics/'+str(rubric_id), data= x, headers = header)
If anyone has an idea what is wrong in my JSON I would really appreciate it. I am at a loss on what else to try.
Thank you very much!
Solved! Go to Solution.
It looks like the last piece you are missing is to convert 'x' into a JSON string.
To do this in Python you will need to import json at the top of your code file.
Then, in your code you will need to use json.dumps(x) to convert 'x' into a JSON string. json.dumps() in Python
id= 72360000000 # id taken from the IP after finding the course
# trying to build the JSON
x = {
"rubric_association": {
"association_type": "Course",
"association_id": id
},
"rubric": {
"title": "My Rubric 7",
"criteria": {
"1": {
"description": "BBBB",
"ratings": {
"1": {
"description": "Fuller",
"long_description": "",
"points": 7
},
"2": {
"description": "Nope",
"long_description": "",
"points": 0
}
}
}
}
}
}
formattedData = json.dumps(x)
header = {
'Authorization': 'Bearer ' + c_token,
'Content-Type': 'application/json'
}
http = "https://canvas.instructure.com/api/v1/"
# the get request works if I put it in like this, so it seems to be an ok header and id
# res = requests.get(http +'courses/'+str(id)+'/rubrics/', headers = header)
res = requests.post(http +'courses/'+str(id)+'/rubrics/', data= formattedData, headers = header)
Are you able to get it to work if you update it like the following? This would be closer to the format I used before when I needed to test trying to create a rubric with the API.
{
"id": "rubric_id",
"rubric_association_id": "course_association_id",
"rubric": {
"title": "My Rubric 4",
"criteria": {
"1": {
"description": "BBBB",
"points": 7,
"ratings": [
{
"description": "Fuller",
"long_description": "",
"points": 7
},
{
"description": "Nope",
"long_description": "",
"points": 0
}
]
}
}
}
}
Thank you for your answer. Sadly no, it gives me the same error. When I use or the whole json you send with the rubric_id and rubric_association_id replaced with mine.
This works:
{
"id": "rubric_id",
"rubric_association_id": "course_association_id",
"rubric[title]": "My Rubric 4"
}
But even this below gives me a server error again.
{
"id": "rubric_id",
"rubric_association_id": "course_association_id",
"rubric": {
"title": "My Rubric 4"
}
Adding criteria to any of them will also lead to server errors.
I wish Canvas would give a more detailed error message of what it does not like instead of "An error occurred".
Thanks again!
Sorry that didn't fully resolve the issue. In reviewing the request that I got to work, I see there are some additional differences I forgot to update.
Could you try the following?
{
"rubric_association": {
"association_type": "Course",
"association_id": id
},
"rubric": {
"title": "My Rubric 4",
"criteria": {
"1": {
"description": "BBBB",
"ratings": {
"1": {
"description": "Fuller",
"long_description": "",
"points": 7
},
"2": {
"description": "Nope",
"long_description": "",
"points": 0
}
}
}
}
}
}
Also, for the request, this is the format that I use for the Create a single rubric endpoint:
res = requests.post(http +'/api/v1/courses/'+str(id)+'/rubrics/', data= x, headers = header)
*It looks like http is a variable you defined, so just make sure it is the full base URL for your instance (ex: https://canvas.instructure.com)
Sadly it still gives me the same thing.
This is my http variable: https://canvas.instructure.com/api/v1/
the "id" is my correct course id and the association_id I used the id from the course, is that correct? So the same is "id" or should that be something different?
Weird that this works for you but I cannot seem to get it to work.
Thank you I really appreciate your help!
x = {
"rubric_association": {
"association_type": "Course",
"association_id": "723600000001740"
},
"rubric": {
"title": "My Rubric 7",
"criteria": {
"1": {
"description": "BBBB",
"points": 7,
"ratings": {
"1": {
"description": "Fuller",
"long_description": "",
"points": 7
},
"2": {
"description": "Nope",
"long_description": "",
"points": 0
}
}
}
}
}
}
id= 723600000001740
header = {'Authorization': 'Bearer ' + c_token}
http = "https://canvas.instructure.com/api/v1/"
res = requests.post(http +'courses/'+str(id)+'/rubrics/', data= x, headers = header)
That is correct that the ID in the URL and the association_id should both be the same course ID.
Try removing the "points" before the ratings. It looks like points only need to be set within the ratings.
Also, since you are making a request using JSON formatted data, you will need to update the header to set the content type too (Canvas API😞
header = {
'Authorization': 'Bearer ' + c_token,
'Content-Type': 'application/json'
}
Good points about the header. Still sadly it does not work. I worried the id might be wrong but calling a "get" on all the rubrics with that id gives me all the existing rubrics of that course. So that seems to be ok.
This is what I have now and it still gives me "500 internal server error"
id= 72360000000 # id taken from the IP after finding the course
# trying to build the JSON
x = {
"rubric_association": {
"association_type": "Course",
"association_id": id
},
"rubric": {
"title": "My Rubric 7",
"criteria": {
"1": {
"description": "BBBB",
"ratings": {
"1": {
"description": "Fuller",
"long_description": "",
"points": 7
},
"2": {
"description": "Nope",
"long_description": "",
"points": 0
}
}
}
}
}
}
header = {
'Authorization': 'Bearer ' + c_token,
'Content-Type': 'application/json'
}
http = "https://canvas.instructure.com/api/v1/"
# the get request works if I put it in like this, so it seems to be an ok header and id
# res = requests.get(http +'courses/'+str(id)+'/rubrics/', headers = header)
res = requests.post(http +'courses/'+str(id)+'/rubrics/', data= x, headers = header)
.
I really appreciate your help, I know it must be something I do wrong but I cannot find it.
It looks like the last piece you are missing is to convert 'x' into a JSON string.
To do this in Python you will need to import json at the top of your code file.
Then, in your code you will need to use json.dumps(x) to convert 'x' into a JSON string. json.dumps() in Python
id= 72360000000 # id taken from the IP after finding the course
# trying to build the JSON
x = {
"rubric_association": {
"association_type": "Course",
"association_id": id
},
"rubric": {
"title": "My Rubric 7",
"criteria": {
"1": {
"description": "BBBB",
"ratings": {
"1": {
"description": "Fuller",
"long_description": "",
"points": 7
},
"2": {
"description": "Nope",
"long_description": "",
"points": 0
}
}
}
}
}
}
formattedData = json.dumps(x)
header = {
'Authorization': 'Bearer ' + c_token,
'Content-Type': 'application/json'
}
http = "https://canvas.instructure.com/api/v1/"
# the get request works if I put it in like this, so it seems to be an ok header and id
# res = requests.get(http +'courses/'+str(id)+'/rubrics/', headers = header)
res = requests.post(http +'courses/'+str(id)+'/rubrics/', data= formattedData, headers = header)
Oh my gosh, that did it! I can't believe that it was so easy at the end. Thank you so very very much. This makes my day, really!!!!
I appreciate you very much!
Alex
@amehl ...
Have you taken a look at the Canvancement (Canvas Enhancement) from @James Jones that allows you to create a rubric from a spreadsheet. To me, this seems a lot easier than your process with the API ... but I'm sure you have your reasons for wanting to do that. I've used James' process hundred and hundreds of times, and it's pretty awesome! Here's a link for you:
Importing Rubrics from a Spreadsheet - Instructure Community - 264527 (canvaslms.com)
I hope this will be helpful to you!
To participate in the Instructure Community, you need to sign up or log in:
Sign In