Showing results for 
Show  only  | Search instead for 
Did you mean: 
Community Participant and API

Jump to solution

Hi everyone,

For the last two semesters we've used the script in the GitHub Unsupported canvas pages to apply a template course to other courses, with great success. I tried to use it for the up-coming semester, which starts in January, but am getting errors now. My error is a KeyError generated by line #38. It doesn't like the "_copy[destination_column_name])".

I noticed that in the "course_copy" API there is a note that it says "DEPRECATED: Please use the Content Migrations API. So I went there but am now confused about how to get the template ("source" in the previous code) to apply to the course ("destination" in the previous code).

If anyone has a better method, or a fix, I am open to hearing from you.



Labels (1)
10 Replies
Community Participant

After a bit of head banging we called our Canvas CSM who was able to help with the '' script mentioned above. He said "don't use it!" Ha ha! I knew that....

What we did was write a different Python script to use a different API specifically for migration - which was exactly what we needed. Here is what we ended up with. 

The Canvas api we used:   POST /api/v1/courses/:course_id/content_migrations

I set up all the required variables::

domain = ''
api_prefix = '/api/v1/courses/'
api_suffix = '/content_migrations'
source_course = 'sis_course_id:course_template_201740'  ## this is the  </:course_id/>  listed in the API 
c_list_file = './test_course_ids.csv'  ## a CSV list of courses you want to apply the migration to with a header row labeled 'course_id' ... 

token = <token>

headers = {  'Authorization': 'Bearer %s' % token, }

querystring = {'settings[source_course_id]': source_course,'migration_type':'course_copy_importer'}

## apply migration loop

if __name__ == '__main__':
      with open(c_list_file, 'r') as f:
            reader = csv.DictReader(f)
            for row in reader:
                  course_id = row['course_id']
                    url2 = (domain + api_prefix + course_id + api_suffix)
                    response =, headers=headers, params=querystring)

I hope someone can use it.

But HEY! No guarantees right??

View solution in original post