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

do_course_copy.py and API

Jump to solution

Hi everyone,

For the last two semesters we've used the do_course_copy.py 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.

Thanks,

Dave

Labels (1)
1 Solution

Accepted Solutions
ddieckmeyer
Community Participant

After a bit of head banging we called our Canvas CSM who was able to help with the 'do_course_copy.py' 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 = 'your_https_url.instructure.com'
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 = requests.post(url2, headers=headers, params=querystring)

I hope someone can use it.

But HEY! No guarantees right??

View solution in original post

10 Replies
themidiman
Community Champion

Have you looked into Blueprint courses as a means of pushing/copying content into other courses in an automated fashion? 

dgrobani
Community Champion

JEFHQ12951‌'s suggestion is a great one.

If you'd like a fix in the meantime, try replacing lines 37 & 38 with:

params = {'migration_type': 'course_copy_importer', 'settings[source_course_id]': _copy[source_column_name]}
copy_url = 'https://%s/api/v1/courses/%s/content_migrations' % (user['domain'],_copy[destination_column_name])  

Please note that I haven't had time to test this.

ddieckmeyer
Community Participant

Hi Jeffery

Yes, thank you. We are looking into this but are not ready just yet.

dgrobani
Community Champion

Whoops, I was focused on replacing the API call and didn't fully take in on the first read the error message you're getting. Sorry, I can't tell what's causing that error.

ddieckmeyer
Community Participant

Hi Daniel,

I think you have the right code for line #37, but the script balks at line #38. I inserted a "print(key)" between Line #31 and #32 and am able to successfully read the first set of keys, so I don't understand why it doesn't continue.

The traceback error is this: (my line #62 corresponds to the original code line #38 - otherwise all things are equal)

Traceback (most recent call last):
  File "C:<python_directory>\CourseCopyTemplate\do_course_copy.py", line 62, in <module>
    copy_url = 'https://%s/api/v1/courses/%s/content_migrations' % (user['domain'],_copy[destination_column_name])
KeyError: 'destination_course_id'

I appreciate the look. Dave

ddieckmeyer
Community Participant

I am wondering if the "destination_course_id" column name is not being recognized anymore and if the API was changed.

Reading the documentation and the code, it seems to me that the values of the source_column_name and destination_column_name variables set at lines 7 & 8 are supposed to correspond to the column headers of your CSV file. What are the two columns in your CSV file labeled? Are they the same values specified in lines 7 & 8?

ddieckmeyer
Community Participant

Yes, they are the same. And just to make sure before I posted here, I copied and pasted the column names into the script. I may just have to start over or get the course designer to determine what they want in a blueprint course. But like I said the errors are new. This was a working script a couple of months ago.

Thanks for the assist....

 @ddieckmeyer ‌, if you email me the Python file you’re running and your CSV file, I’d be happy to take a closer look.