cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
MikeBrinkman
Community Participant

Use the SIS Term ID with API instead of the Canvas Term ID?

Jump to solution

I was wondering if it is possible to use the SIS Term ID with API instead of the Canvas Term ID? I know in user API calls, I can use api/v1/users/sis_user_id: (which isn't documented), I'm hoping that there's a similar undocumented part in the API for using sis_term_id.

My current code:

 

def post_new_course(sci, n, sti):
    api_url = 'https://mycanvasurl:443/api/v1/accounts/1/courses'
    parameters = {
        'course[course_code]': sci,
        'course[sis_course_id]': sci,
        'course[name]': n,
        'course[term_id]': get_canvas_terms(sti)
    }
    result = requests.post(api_url,headers=header,data=parameters).json()

 

To get the term_id, I had to write this ridiculous bit of code:

 

def get_canvas_terms(sti):
    api_url = 'https://mycanvasurl:443/api/v1/accounts/1/terms'
    result = requests.get(api_url,headers=header).json()
    for (i, j) in result.items():
        items = j
        for item in items:
            terms = item
            for (k, v) in terms.items():
                #print (k, v)
                if v == sti:
                    term_id = terms.get('id')
                    print ("Term ID: " + str(term_id))
                    return term_id

 

Obviously this can be tightened up, but I'd like to have a more elegant solution if possible so I can skip this bit. Any suggestions are welcome!

0 Kudos
1 Solution
JamesSekcienski
Community Contributor

Hello @MikeBrinkman 

If you make the following update, you should be able to eliminate the need for the second function to get the Canvas term id based on the SIS term id.  This worked for me when I tested it using the format for the sis_term_id

 

 

import json

def post_new_course(sci, n, sti):
    api_url = 'https://mycanvasurl:443/api/v1/accounts/1/courses'
    parameters = json.dumps({
        "course": {
            "course_code": sci,
            "sis_course_id": sci,
            "name": n,
            "term_id": f"sis_term_id:{sti}"
        }
    })
    result = requests.post(api_url,headers=header,data=parameters).json()

 

 

 

I'm not sure how you have your header defined, but with the above format, you will need to include the following in the header too since it is using JSON format for the payload (https://canvas.instructure.com/doc/api/index.html

 

 

'Content-Type': 'application/json'

 

 

 

View solution in original post

7 Replies
matthew_buckett
Community Contributor

There is some documentation on how to specify SIS IDs in Canvas, I've only used this for URLs, but you may also be able to use this encoding in HTTP parameters as well:

https://canvas.instructure.com/doc/api/file.object_ids.html

matthew_buckett
Community Contributor

I just tried using the specified format in a parameter to create a course and I was getting a 404 when using a SIS ID in the `course[term_id]` parameter value:

 

curl -H "Authorization: Bearer ....." -X POST -d "course[term_id]=sis_term_id:academic-22" -d "course[name]=Term SIS ID Test" https://instance.instructure.com/api/v1/accounts/self/courses 

 

 

However it works fine if I use the Canvas ID (number).

 

Thanks @matthew_buckett ! I will look into this further. If I have any success, I will follow up on this. As I'm sure you can tell, I'm not a pro developer, so a lot of my code looks pretty hacked. 😄

0 Kudos
JamesSekcienski
Community Contributor

Hello @MikeBrinkman 

If you make the following update, you should be able to eliminate the need for the second function to get the Canvas term id based on the SIS term id.  This worked for me when I tested it using the format for the sis_term_id

 

 

import json

def post_new_course(sci, n, sti):
    api_url = 'https://mycanvasurl:443/api/v1/accounts/1/courses'
    parameters = json.dumps({
        "course": {
            "course_code": sci,
            "sis_course_id": sci,
            "name": n,
            "term_id": f"sis_term_id:{sti}"
        }
    })
    result = requests.post(api_url,headers=header,data=parameters).json()

 

 

 

I'm not sure how you have your header defined, but with the above format, you will need to include the following in the header too since it is using JSON format for the payload (https://canvas.instructure.com/doc/api/index.html

 

 

'Content-Type': 'application/json'

 

 

 

That is what I was looking for, thanks @JamesSekcienski !

All I needed to do was change

 

'course[term_id]': get_canvas_terms(sti)

 

to

 

'course[term_id]': f'sis_term_id:{sti}'

 

On the bright side, the original code I wrote forced me to think a bit about how to access the data, so maybe that will pay off some other time.

If there's ever another in-person Instructurecon, I'll have to buy you a beer or two! 😄

Hello @MikeBrinkman 

I'm glad that it was an even easier adjustment for you to get it to work! 

I definitely hope to attend an in-person InstructureCon in the future.  Based on the past blogs and recordings on YouTube they looked like great events and there were a lot more dev workshops. 🍻

Thanks,

James Sekcienski

0 Kudos

@JamesSekcienski wrote:

Hello @MikeBrinkman onevanilla

If you make the following update, you should be able to eliminate the need for the second function to get the Canvas term id based on the SIS term id.  This worked for me when I tested it using the format for the sis_term_id

 

 

import json

def post_new_course(sci, n, sti):
    api_url = 'https://mycanvasurl:443/api/v1/accounts/1/courses'
    parameters = json.dumps({
        "course": {
            "course_code": sci,
            "sis_course_id": sci,
            "name": n,
            "term_id": f"sis_term_id:{sti}"
        }
    })
    result = requests.post(api_url,headers=header,data=parameters).json()

 

 

 

I'm not sure how you have your header defined, but with the above format, you will need to include the following in the header too since it is using JSON format for the payload (https://canvas.instructure.com/doc/api/index.html

 

 

'Content-Type': 'application/json'

 

 

 


The solution worked for me thanks to the community and the members for the solution.