cancel
Showing results for 
Search instead for 
Did you mean: 
de_millington
Community Contributor

Programming

Jump to solution

I have some programming experience in VBA and Access SQL and was hoping to join your developers forum to get tips on where to start programming the building blocks in Canvas. For instance Blackboard uses JAVA whereas I gather, from the limited video clips I have seen, Canvas uses JSON. I am looking to take things from inception to the API integration stage. If anyone could offer some advice and guidance as to where I should start, would be much appreciated.

Thanks.

Tags (1)
47 Replies
garth
Community Champion

 @de_millington ‌ you can use Postman to string together multiple API calls, but that is not the road I would go.  Postman is not a software development tool, personally I don't find it well suited for running full algorithms / business logic.

I would continue to pursue the use of PowerShell if that's what you know, doing a quick search just here in the community I found this: How to POST in powershell  You can likely find more relevant resources with your own search.

JavaScript is also a good option, and also returns good search results.   @James  did a nice post on a use case for JavaScript here: Sorting Rubrics Made Easy 

sjmorris3
Community Participant

 @de_millington ‌

 

You would want to use a programming language to loop through a list of course ids and make an API call at each loop. Maybe something like this PowerShell script.

 

$csv = import-csv -Delimiter "," -Path 'C:\temp\example.csv' 

foreach ($line in $csv){

$token = "your token here"
$headers =@{"Authorization"="Bearer "+$token}
$url = "https://institution.beta.instructure.com:443/api/v1/courses/"+ $line.destination_id +"/content_migrations"
$Body = @{"migration_type"="course_copy_importer";"settings[source_course_id]"=$line.source_id}

Invoke-RestMethod -Method Post -Headers $headers -Uri $url -Body $Body

}

I would be very careful running a script like this and make sure you know what each line does. Also make sure you are working within the beta server instance since API scripts can cause vast changes to a system. Definitely use cation with it.

This is how your CSV file should look with the Source_id and Destination_id headers:

########CSV Example############
##Source_id,destination_id
##1000,2000
##3000,4000

# The numbers in the above example csv file are course ids.
# The Source_id column in the csv file is for courses that have the content that you want copied into the new courses. 
de_millington
Community Contributor

OK thanks Jaap, we seem to be going back to start now with APIs. I have read about half in detail and glanced through all of Canvas APIs: Getting started, the practical ins and outs, gotchas, tips, and tricks and cannot find any helpful pointers on how to apply scripts in APIs for multiple courses.  I will however, press on with any general resources I can find. If you do in the meantime come across specifics I'm interested in, I would be grateful if you can place any links in this space.

Thanks again for all your contributions..

de_millington
Community Contributor

Thanks for your regular contributions and I apologise for pressing you relentlessly, mostly on a daily basis ( I'd also give you a virtual cigar or glass of your favourite brew for your patience). The use of PowerShell is not what I know, but what our IS department are quite familiar with. They, however, have lost 2 of their most experienced staff, one swapping the education arena for the high-paying commercial security industry, while the other is on indeterminate compassionate leave. I had intended to teach myself all this and accomplish the course rollover process before set deadlines, but I think I was too ambitious within the time frames I'd set myself.

The challenges I see with the programming guides in the Canvas Community is they provide glimpses into the process, with no clear examples connecting the dots, from start to finish. Our institution will have to cough up the dollars for Canvas and let them do it this time. At least (I hope) by this time next year I will be in a state to do this myself. Thanks again!

de_millington
Community Contributor

Thanks Sam, this is possibly the most concise and at the same time fullest examples yet of how to pursue this code-wise. I am familiar with the looping concept from my self taught VBA experiences, but will have to tackle this in PowerShell to see how it should really be applied. May well get back to this space to pick your brains some more. I just wonder how this compares with the brevity of Python? Besides the need to get to grips with PS, I was rather sold on the idea of Python when I discovered how concise it's coding was compared to JavaScript. 

sjmorris3
Community Participant

 @de_millington ‌,

 

I don’t have a programming background, so PowerShell was easier to learn for me than Python or JavaScript. PowerShell scripts seem to be easier to break apart and find out what each command does. When I looked at Python, at least for me, I had a hard time getting over the new to programming aspect of the language vs PowerShell’s more scripting language than programming where you can run each command at a prompt.

This is a little bit off topic, but one of the things that I like about PowerShell is that they add new CmdLets and parameters to old CmdLets with each new version of PowerShell. For example with PowerShell Core version 6, they added a parameter that handles Pagination for you in the “Invoke-RestMethod” command. When you make an API Get call against Canvas, they limit you to 10 or 100 results per call with a link to the next call that contains the next 10 or 100 results. As an example, if you were making a call to gather all the courses in a specific term and there were more than 100 results you would need to handle the Pagination next rel links to get courses 101 to 200 and so on. This was making writing a script more complex, but with the “-FollowRelLink” parameter in PS Core 6, it handles all of that process for you. I had spent several days trying to figure out how to use Pagination before I found out that the newer PS version could do it automatically with a parameter.     

 

This is what the command looks like in PS Core 6 that handles Pagination:

 

Invoke-RestMethod -Method Get -Header $headers -Uri $URL -FollowRelLink -MaximumFollowRelLink 20 
de_millington
Community Contributor

A couple of questions if you please Samuel Morris.

I presume single # is to comment out the code, but what does ## do?

The source_id and destination_id as written in your example:

##1000,2000

##3000,4000

If I was to tabulate this, would I be correct in assuming this schematically corresponds as follows:

source_id

destination_id

1000

2000

3000

4000

So presumably one would input these codes, line by line, small to large in a csv file. Assuming PS will stop execution when it reaches the last line, why then would a loop be required as you intimated previously?

sjmorris3
Community Participant

 @de_millington ‌,

The two ## are just comment signs I had in my PS script. I forgot to take them out when I was adding it to the reply. The looping part is done within the “foreach” command. The $line variable with either the .destination_id or .source_id part is what tells the loop what course id to grab. Once a line in the CSV file becomes null, from no object or string, it will end the loop from my understanding. The loop will cause the code to run the API Post for every course id in the CSV file. For each course copy, you need a separate API call which the "foreach" command handles. The PS “foreach” command loops through the content contained within the { } brackets.

You can get a list of course IDs from running either a provisioning report or using an API Get call against the accounts API. One of the fields will contain the course id. Here's the API call.

GET /api/v1/accounts/:account_id/courses 

The way you have the table formatted is correct. From my understanding, the course IDs don't have to be organized sequentially since each "foreach" loop is considered a separate API call.

de_millington
Community Contributor

OK Samuel, I had a go at running this for the first time in PS based on your code. I have clearly run into some parsing issues, plus I'm not sure where you get the number 443 in your code on line number 6.

Also I may have made the same mistake as when I was attempting to parse the one course copy tester, where I used course id rather than the page number that you pointed out (correction Jaap pointed out) corresponds with the course home page.

I generated the token within the beta environment, but Canvas is having a problem with it ( see response in red) and also a comment about a closing bracket not being there.

Any ideas what's going wrong?

Thanks.

PS Microsoft.PowerShell.Core\FileSystem::\\thfs1\TNL_MC00515> $csv = import-csv -Delimiter "," -Path ‘L:\Teaching and Learning\Learning Resources\eLearning\Canvas\Rollover\1819\RolloverFiles\Mapping2017-18\Final\Shells\Map\Map2017-2018_ManualCourse.csv’

foreach ($line in $csv){

$token = "Token here"

$headers =@ {"Authorization"="Bearer "+$token}

$url = "https://institution.beta.instructure.com: 443/api/v1/courses/"+ $line.destination_id +"/content_migrations"

$Body = @{"migration_type"="course_copy_importer";"settings[source_course_id]"=$line.source_id}

Invoke-RestMethod -Method Post -Headers $headers -Uri $url -Body $Body

At line:4 char:11

+ $headers =@ {"Authorization"="Bearer "+$token}

+ ~

Unrecognized token in source text.

At line:2 char:24

+ foreach ($line in $csv){

+ ~

Missing closing '}' in statement block or type definition.

At line:4 char:14

+ $headers =@ {"Authorization"="Bearer "+$token}

+ ~~~~~~~~~~~~~~~

The assignment expression is not valid. The input to an assignment operator must be an object that is able to accept assignments, such as a

variable or a property.

+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException

+ FullyQualifiedErrorId : UnrecognizedToken

sjmorris3
Community Participant

 @de_millington ‌,

You will need to change the $url variable to match your Canvas instance. The Institution part of the url is just an example of how it should look. The 443 is the HTTPS port number of the url. You can get your url link from the Live API course copy area.

I would also edit your last post to remove the token you included, so no one can see it who views your post.