Here's a script I just wrote to publish all courses in a specific account. Hopefully someone will find this helpful.
<SPAN class="keyword token">import</SPAN> requests<BR /><BR /><BR /><SPAN class="keyword token">def</SPAN> <SPAN class="token function">chunks</SPAN><SPAN class="punctuation token">(</SPAN>source_list<SPAN class="punctuation token">,</SPAN> chunk_size<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN><BR /> <SPAN class="string token">""</SPAN>"<BR /> Method to split up your list into chunks<BR /><BR /> Yield successive chunk_size<SPAN class="operator token">-</SPAN>sized chunks <SPAN class="keyword token">from</SPAN> list<SPAN class="punctuation token">.</SPAN><BR /><BR /> Source<SPAN class="punctuation token">:</SPAN> https<SPAN class="punctuation token">:</SPAN><SPAN class="operator token">//</SPAN>www<SPAN class="punctuation token">.</SPAN>datacamp<SPAN class="punctuation token">.</SPAN>com<SPAN class="operator token">/</SPAN>community<SPAN class="operator token">/</SPAN>tutorials<SPAN class="operator token">/</SPAN><SPAN class="number token">18</SPAN><SPAN class="operator token">-</SPAN>most<SPAN class="operator token">-</SPAN>common<SPAN class="operator token">-</SPAN>python<SPAN class="operator token">-</SPAN>list<SPAN class="operator token">-</SPAN>questions<SPAN class="operator token">-</SPAN>learn<SPAN class="operator token">-</SPAN>python<SPAN class="comment token">#question11</SPAN><BR /> <SPAN class="string token">""</SPAN>"<BR /><BR /> <SPAN class="keyword token">for</SPAN> i <SPAN class="keyword token">in</SPAN> range<SPAN class="punctuation token">(</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">,</SPAN> len<SPAN class="punctuation token">(</SPAN>source_list<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN> chunk_size<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN><BR /> <SPAN class="keyword token">yield</SPAN> source_list<SPAN class="punctuation token">[</SPAN>i<SPAN class="punctuation token">:</SPAN>i <SPAN class="operator token">+</SPAN> chunk_size<SPAN class="punctuation token">]</SPAN><BR /><BR /><BR /><SPAN class="keyword token">def</SPAN> <SPAN class="token function">publish_account_courses</SPAN><SPAN class="punctuation token">(</SPAN>base_url<SPAN class="punctuation token">,</SPAN> token<SPAN class="punctuation token">,</SPAN> sub_account_id<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN><BR /> account_courses_url <SPAN class="operator token">=</SPAN> base_url <SPAN class="operator token">+</SPAN> <SPAN class="string token">'accounts/'</SPAN> <SPAN class="operator token">+</SPAN> str<SPAN class="punctuation token">(</SPAN>sub_account_id<SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">+</SPAN> <SPAN class="string token">'/courses'</SPAN><BR /> header <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">{</SPAN><SPAN class="string token">'Authorization'</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="string token">'Bearer '</SPAN> <SPAN class="operator token">+</SPAN> token<SPAN class="punctuation token">}</SPAN><BR /><BR /> all_course_ids <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">]</SPAN><BR /><BR /> <SPAN class="comment token"># Get the first page of courses in the sub-account</SPAN><BR /> payload <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">{</SPAN><BR /> <SPAN class="string token">'per_page'</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="number token">100</SPAN> <SPAN class="comment token"># Per page max value appears to be 100</SPAN><BR /> <SPAN class="punctuation token">}</SPAN><BR /> response <SPAN class="operator token">=</SPAN> requests<SPAN class="punctuation token">.</SPAN>get<SPAN class="punctuation token">(</SPAN>url<SPAN class="operator token">=</SPAN>account_courses_url<SPAN class="punctuation token">,</SPAN> headers<SPAN class="operator token">=</SPAN>header<SPAN class="punctuation token">,</SPAN> data<SPAN class="operator token">=</SPAN>payload<SPAN class="punctuation token">)</SPAN><BR /> courses <SPAN class="operator token">=</SPAN> response<SPAN class="punctuation token">.</SPAN>json<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><BR /><BR /> <SPAN class="comment token"># Add the course IDs to the list</SPAN><BR /> <SPAN class="keyword token">for</SPAN> course <SPAN class="keyword token">in</SPAN> courses<SPAN class="punctuation token">:</SPAN><BR /> all_course_ids<SPAN class="punctuation token">.</SPAN>append<SPAN class="punctuation token">(</SPAN>course<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'id'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN><BR /><BR /> <SPAN class="comment token"># Get the remaining pages of courses, if any</SPAN><BR /> <SPAN class="keyword token">while</SPAN> <SPAN class="string token">'next'</SPAN> <SPAN class="keyword token">in</SPAN> response<SPAN class="punctuation token">.</SPAN>links<SPAN class="punctuation token">:</SPAN><BR /> <SPAN class="comment token"># No longer need to include params, the next link has them saved</SPAN><BR /> response <SPAN class="operator token">=</SPAN> requests<SPAN class="punctuation token">.</SPAN>get<SPAN class="punctuation token">(</SPAN>url<SPAN class="operator token">=</SPAN>response<SPAN class="punctuation token">.</SPAN>links<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'next'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="string token">'url'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> headers<SPAN class="operator token">=</SPAN>header<SPAN class="punctuation token">)</SPAN><BR /> courses <SPAN class="operator token">=</SPAN> response<SPAN class="punctuation token">.</SPAN>json<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><BR /><BR /> <SPAN class="comment token"># Add the course IDs to the list</SPAN><BR /> <SPAN class="keyword token">for</SPAN> course <SPAN class="keyword token">in</SPAN> courses<SPAN class="punctuation token">:</SPAN><BR /> all_course_ids<SPAN class="punctuation token">.</SPAN>append<SPAN class="punctuation token">(</SPAN>course<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'id'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN><BR /><BR /> <SPAN class="comment token"># We can only update 500 courses at a time. Need to split up list of course IDs if longer than that</SPAN><BR /> <SPAN class="comment token"># This is a new list - will contain lists of course IDs no longer than 500 each</SPAN><BR /> course_id_lists <SPAN class="operator token">=</SPAN> list<SPAN class="punctuation token">(</SPAN>chunks<SPAN class="punctuation token">(</SPAN>all_course_ids<SPAN class="punctuation token">,</SPAN> <SPAN class="number token">500</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN><BR /><BR /> <SPAN class="keyword token">for</SPAN> course_list <SPAN class="keyword token">in</SPAN> course_id_lists<SPAN class="punctuation token">:</SPAN><BR /> <SPAN class="comment token"># Take the list of course IDs and pass them to the 'Update courses' endpoint</SPAN><BR /> payload <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">{</SPAN><BR /> <SPAN class="string token">'course_ids[]'</SPAN><SPAN class="punctuation token">:</SPAN> course_list<SPAN class="punctuation token">,</SPAN><BR /> <SPAN class="string token">'event'</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="string token">'offer'</SPAN> <SPAN class="comment token"># Offer in the API is the same as Publish in the UI</SPAN><BR /> <SPAN class="punctuation token">}</SPAN><BR /> response <SPAN class="operator token">=</SPAN> requests<SPAN class="punctuation token">.</SPAN>put<SPAN class="punctuation token">(</SPAN>url<SPAN class="operator token">=</SPAN>account_courses_url<SPAN class="punctuation token">,</SPAN> headers<SPAN class="operator token">=</SPAN>header<SPAN class="punctuation token">,</SPAN> data<SPAN class="operator token">=</SPAN>payload<SPAN class="punctuation token">)</SPAN><BR /> response<SPAN class="punctuation token">.</SPAN>raise_for_status<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><BR /> <SPAN class="comment token"># I'm not bothering to check the progress of this operation since it's just changing the state</SPAN><BR /><BR /><BR /><SPAN class="comment token"># Canvas environment info</SPAN><BR />BASE_URL <SPAN class="operator token">=</SPAN> <SPAN class="string token">'PUT URL HERE'</SPAN><BR />TOKEN <SPAN class="operator token">=</SPAN> <SPAN class="string token">'PUT TOKEN HERE'</SPAN><BR /><BR />publish_account_courses<SPAN class="punctuation token">(</SPAN>base_url<SPAN class="operator token">=</SPAN>BASE_URL<SPAN class="punctuation token">,</SPAN> token<SPAN class="operator token">=</SPAN>TOKEN<SPAN class="punctuation token">,</SPAN> sub_account_id<SPAN class="operator token">=</SPAN><SPAN class="number token">8</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>