0
# Content Management
1
2
Pages, files, folders, modules, external tools, and content organization within courses. Comprehensive content creation and management capabilities for structuring course materials.
3
4
## Capabilities
5
6
### Pages
7
8
Create and manage wiki-style pages for course content.
9
10
```python { .api }
11
class Course(CanvasObject):
12
def get_pages(self, **kwargs) -> PaginatedList[Page]:
13
"""
14
List pages in the course.
15
16
Parameters:
17
- sort: Sort pages by field ('title', 'created_at', 'updated_at')
18
- order: Sort order ('asc', 'desc')
19
- search_term: Search term to filter pages
20
- published: Filter by published status
21
- include: Additional data ('body', 'locked_for_user', 'can_edit')
22
23
Returns:
24
Paginated list of Page objects
25
"""
26
27
def create_page(self, wiki_page: dict, **kwargs) -> Page:
28
"""
29
Create a new page.
30
31
Parameters:
32
- wiki_page: Dictionary with page attributes:
33
- title: Page title (required)
34
- body: Page content (HTML)
35
- editing_roles: Who can edit ('teachers', 'students', 'members', 'public')
36
- notify_of_update: Notify users of page creation
37
- published: Whether page is published
38
- front_page: Whether this is the course front page
39
40
Returns:
41
Page object
42
"""
43
44
def get_page(self, url_or_id, **kwargs) -> Page:
45
"""
46
Get a specific page by URL or ID.
47
48
Parameters:
49
- url_or_id: Page URL slug or page ID
50
- include: Additional data to include
51
52
Returns:
53
Page object
54
"""
55
56
class Page(CanvasObject):
57
def edit(self, **kwargs) -> Page:
58
"""
59
Edit page content and settings.
60
61
Parameters:
62
- wiki_page: Dictionary with page updates:
63
- title: Page title
64
- body: Page content (HTML)
65
- editing_roles: Who can edit the page
66
- notify_of_update: Notify users of changes
67
- published: Publication status
68
- front_page: Whether this is the front page
69
70
Returns:
71
Updated Page object
72
"""
73
74
def delete(self, **kwargs) -> Page:
75
"""Delete the page."""
76
77
def get_revisions(self, **kwargs) -> PaginatedList[PageRevision]:
78
"""
79
Get page revision history.
80
81
Returns:
82
Paginated list of PageRevision objects
83
"""
84
85
def show_latest_revision(self, **kwargs) -> PageRevision:
86
"""Get the latest revision of the page."""
87
```
88
89
### Files and Folders
90
91
Manage course file storage and organization.
92
93
```python { .api }
94
def get_files(self, **kwargs) -> PaginatedList[File]:
95
"""
96
List files in the course.
97
98
Parameters:
99
- content_types: Filter by MIME type
100
- exclude_content_types: Exclude specific MIME types
101
- search_term: Search term to filter files
102
- include: Additional data ('user', 'usage_rights', 'context_asset_string')
103
- only: Filter file types ('names', 'folders')
104
- sort: Sort files by field ('name', 'size', 'created_at', 'updated_at', 'content_type')
105
- order: Sort order ('asc', 'desc')
106
107
Returns:
108
Paginated list of File objects
109
"""
110
111
def get_folders(self, **kwargs) -> PaginatedList[Folder]:
112
"""
113
List folders in the course.
114
115
Parameters:
116
- sort: Sort folders by field
117
- order: Sort order
118
119
Returns:
120
Paginated list of Folder objects
121
"""
122
123
def create_folder(self, name: str, **kwargs) -> Folder:
124
"""
125
Create a new folder.
126
127
Parameters:
128
- name: Folder name
129
- parent_folder_id: Parent folder ID
130
- locked: Whether folder is locked
131
- hidden: Whether folder is hidden from students
132
- position: Position in folder list
133
134
Returns:
135
Folder object
136
"""
137
138
def get_file(self, file_id, **kwargs) -> File:
139
"""Get a specific file by ID."""
140
141
class File(CanvasObject):
142
def delete(self, **kwargs) -> File:
143
"""Delete the file."""
144
145
def get_contents(self, **kwargs) -> bytes:
146
"""
147
Download file contents.
148
149
Returns:
150
File contents as bytes
151
"""
152
153
def get_public_url(self, **kwargs) -> dict:
154
"""
155
Get a public URL for the file.
156
157
Returns:
158
Dictionary with public_url and expires_at
159
"""
160
161
class Folder(CanvasObject):
162
def edit(self, **kwargs) -> Folder:
163
"""
164
Edit folder properties.
165
166
Parameters:
167
- name: Folder name
168
- parent_folder_id: Parent folder ID
169
- locked: Whether folder is locked
170
- hidden: Whether folder is hidden
171
- position: Position in folder list
172
173
Returns:
174
Updated Folder object
175
"""
176
177
def delete(self, **kwargs) -> Folder:
178
"""Delete the folder."""
179
180
def get_files(self, **kwargs) -> PaginatedList[File]:
181
"""List files in this folder."""
182
183
def get_folders(self, **kwargs) -> PaginatedList[Folder]:
184
"""List subfolders in this folder."""
185
186
def create_folder(self, name: str, **kwargs) -> Folder:
187
"""Create a subfolder in this folder."""
188
189
def upload_file(self, file_path: str, **kwargs) -> File:
190
"""
191
Upload a file to this folder.
192
193
Parameters:
194
- file_path: Path to file to upload
195
- name: Custom name for uploaded file
196
- on_duplicate: Action for duplicate files ('overwrite', 'rename')
197
198
Returns:
199
File object
200
"""
201
```
202
203
### Modules
204
205
Organize course content into sequential learning modules.
206
207
```python { .api }
208
def get_modules(self, **kwargs) -> PaginatedList[Module]:
209
"""
210
List modules in the course.
211
212
Parameters:
213
- include: Additional data ('items', 'content_details')
214
- search_term: Search term to filter modules
215
- student_id: Get modules as seen by specific student
216
217
Returns:
218
Paginated list of Module objects
219
"""
220
221
def create_module(self, module: dict, **kwargs) -> Module:
222
"""
223
Create a new module.
224
225
Parameters:
226
- module: Dictionary with module attributes:
227
- name: Module name (required)
228
- unlock_at: Date when module becomes available
229
- position: Position in module list
230
- require_sequential_progress: Items must be completed in order
231
- prerequisite_module_ids: List of prerequisite module IDs
232
- publish_final_grade: Publish grades when module completed
233
- completion_requirements: List of completion requirements
234
235
Returns:
236
Module object
237
"""
238
239
class Module(CanvasObject):
240
def edit(self, **kwargs) -> Module:
241
"""
242
Edit module properties.
243
244
Parameters:
245
- module: Dictionary with module updates (same as create_module)
246
247
Returns:
248
Updated Module object
249
"""
250
251
def delete(self, **kwargs) -> Module:
252
"""Delete the module."""
253
254
def get_module_items(self, **kwargs) -> PaginatedList[ModuleItem]:
255
"""
256
List items in this module.
257
258
Parameters:
259
- include: Additional data ('content_details', 'mastery_paths')
260
- search_term: Search term to filter items
261
- student_id: Get items as seen by specific student
262
263
Returns:
264
Paginated list of ModuleItem objects
265
"""
266
267
def create_module_item(self, module_item: dict, **kwargs) -> ModuleItem:
268
"""
269
Create a new module item.
270
271
Parameters:
272
- module_item: Dictionary with item attributes:
273
- title: Item title
274
- type: Item type ('File', 'Page', 'Discussion', 'Assignment', 'Quiz', 'SubHeader', 'ExternalUrl', 'ExternalTool')
275
- content_id: ID of the content object
276
- position: Position in module
277
- indent: Indentation level (0-3)
278
- page_url: For Page items, the page URL
279
- external_url: For ExternalUrl items
280
- new_tab: Open external content in new tab
281
- completion_requirement: Completion requirement for this item
282
283
Returns:
284
ModuleItem object
285
"""
286
287
class ModuleItem(CanvasObject):
288
def edit(self, **kwargs) -> ModuleItem:
289
"""Edit module item properties."""
290
291
def delete(self, **kwargs) -> ModuleItem:
292
"""Delete the module item."""
293
294
def mark_as_done(self, **kwargs) -> ModuleItem:
295
"""Mark item as done for current user."""
296
297
def mark_as_not_done(self, **kwargs) -> ModuleItem:
298
"""Mark item as not done for current user."""
299
```
300
301
### External Tools
302
303
Integrate external applications and LTI tools.
304
305
```python { .api }
306
def get_external_tools(self, **kwargs) -> PaginatedList[ExternalTool]:
307
"""
308
List external tools in the course.
309
310
Parameters:
311
- search_term: Search term to filter tools
312
- selectable: Filter by selectable tools
313
- include_parents: Include tools from parent account
314
315
Returns:
316
Paginated list of ExternalTool objects
317
"""
318
319
def create_external_tool(self, **kwargs) -> ExternalTool:
320
"""
321
Create an external tool.
322
323
Parameters:
324
- name: Tool name
325
- privacy_level: Privacy level ('anonymous', 'name_only', 'public')
326
- consumer_key: OAuth consumer key
327
- shared_secret: OAuth shared secret
328
- url: Tool launch URL
329
- domain: Tool domain (alternative to URL)
330
- description: Tool description
331
- custom_fields: Custom fields for tool launch
332
- account_navigation: Account navigation settings
333
- user_navigation: User navigation settings
334
- course_navigation: Course navigation settings
335
- editor_button: Rich editor button settings
336
- homework_submission: Homework submission settings
337
- link_selection: Link selection settings
338
- migration_selection: Migration selection settings
339
- resource_selection: Resource selection settings
340
- tool_configuration: Tool configuration settings
341
- not_selectable: Whether tool is selectable
342
343
Returns:
344
ExternalTool object
345
"""
346
347
class ExternalTool(CanvasObject):
348
def edit(self, **kwargs) -> ExternalTool:
349
"""Edit external tool settings."""
350
351
def delete(self, **kwargs) -> ExternalTool:
352
"""Delete the external tool."""
353
```
354
355
### Content Migration
356
357
Import content from external sources or other Canvas courses.
358
359
```python { .api }
360
def create_content_migration(self, migration_type: str, **kwargs) -> ContentMigration:
361
"""
362
Create a content migration.
363
364
Parameters:
365
- migration_type: Type of migration ('course_copy_importer', 'zip_file_importer', 'qti_converter', 'moodle_converter', etc.)
366
- pre_attachment: File attachment for migration
367
- settings: Migration-specific settings dictionary:
368
- source_course_id: For course copy migrations
369
- folder_id: Target folder for file imports
370
- overwrite_quizzes: Whether to overwrite existing quizzes
371
- question_bank_id: Target question bank
372
- question_bank_name: Name for new question bank
373
- date_shift_options: Options for shifting dates:
374
- shift_dates: Whether to shift dates
375
- old_start_date: Original course start date
376
- old_end_date: Original course end date
377
- new_start_date: New course start date
378
- new_end_date: New course end date
379
- day_substitutions: Day of week substitutions
380
- selective_import: Whether to allow selective import
381
382
Returns:
383
ContentMigration object
384
"""
385
386
def get_content_migrations(self, **kwargs) -> PaginatedList[ContentMigration]:
387
"""
388
List content migrations for the course.
389
390
Returns:
391
Paginated list of ContentMigration objects
392
"""
393
394
class ContentMigration(CanvasObject):
395
def get_progress(self, **kwargs) -> Progress:
396
"""Get progress of the migration."""
397
398
def get_migration_issues(self, **kwargs) -> PaginatedList[MigrationIssue]:
399
"""Get issues encountered during migration."""
400
401
def update(self, **kwargs) -> ContentMigration:
402
"""Update migration settings."""
403
```
404
405
### Usage Rights
406
407
Manage copyright and usage rights for course content.
408
409
```python { .api }
410
def set_usage_rights(self, file_ids: list, usage_rights: dict, **kwargs) -> UsageRights:
411
"""
412
Set usage rights for files.
413
414
Parameters:
415
- file_ids: List of file IDs
416
- usage_rights: Dictionary with rights information:
417
- use_justification: Justification ('own_copyright', 'used_by_permission', 'fair_use', 'public_domain', 'creative_commons')
418
- legal_copyright: Copyright information
419
- license: License type for Creative Commons
420
421
Returns:
422
UsageRights object
423
"""
424
425
def remove_usage_rights(self, file_ids: list, **kwargs) -> UsageRights:
426
"""Remove usage rights from files."""
427
428
class UsageRights(CanvasObject):
429
"""Represents usage rights and copyright information for content."""
430
```
431
432
## Usage Examples
433
434
### Creating and Organizing Course Content
435
436
```python
437
from canvasapi import Canvas
438
439
canvas = Canvas("https://canvas.example.com", "your-token")
440
course = canvas.get_course(12345)
441
442
# Create course pages
443
syllabus = course.create_page({
444
'title': 'Course Syllabus',
445
'body': '''
446
<h1>Introduction to Computer Science</h1>
447
<h2>Course Description</h2>
448
<p>This course introduces fundamental concepts of computer science...</p>
449
<h2>Learning Objectives</h2>
450
<ul>
451
<li>Understand basic programming concepts</li>
452
<li>Learn problem-solving techniques</li>
453
<li>Apply algorithms to real-world problems</li>
454
</ul>
455
''',
456
'published': True,
457
'front_page': True,
458
'editing_roles': 'teachers'
459
})
460
461
# Create additional content pages
462
resources_page = course.create_page({
463
'title': 'Additional Resources',
464
'body': '<h1>Helpful Links and References</h1><p>Here are some additional resources...</p>',
465
'published': True,
466
'editing_roles': 'teachers,students'
467
})
468
469
# Create folder structure for file organization
470
lectures_folder = course.create_folder('Lecture Materials')
471
assignments_folder = course.create_folder('Assignment Templates')
472
resources_folder = course.create_folder('Additional Resources')
473
474
# Upload files to specific folders
475
lecture1_file = lectures_folder.upload_file(
476
'/path/to/lecture1.pdf',
477
name='Lecture 1 - Introduction.pdf'
478
)
479
480
assignment_template = assignments_folder.upload_file(
481
'/path/to/assignment_template.docx',
482
name='Assignment Template.docx'
483
)
484
```
485
486
### Creating Learning Modules
487
488
```python
489
# Create modules for course organization
490
week1_module = course.create_module({
491
'name': 'Week 1: Introduction to Programming',
492
'unlock_at': '2024-01-15T00:00:00Z',
493
'require_sequential_progress': True,
494
'completion_requirements': [
495
{
496
'type': 'must_view',
497
'min_score': None,
498
'completed': False
499
}
500
]
501
})
502
503
# Add items to the module
504
# Add the syllabus page
505
syllabus_item = week1_module.create_module_item({
506
'title': 'Course Syllabus',
507
'type': 'Page',
508
'page_url': syllabus.url,
509
'position': 1,
510
'completion_requirement': {
511
'type': 'must_view'
512
}
513
})
514
515
# Add lecture file
516
lecture_item = week1_module.create_module_item({
517
'title': 'Lecture 1: Introduction',
518
'type': 'File',
519
'content_id': lecture1_file.id,
520
'position': 2,
521
'completion_requirement': {
522
'type': 'must_view'
523
}
524
})
525
526
# Add external resource
527
external_item = week1_module.create_module_item({
528
'title': 'Python Tutorial (External)',
529
'type': 'ExternalUrl',
530
'external_url': 'https://docs.python.org/3/tutorial/',
531
'position': 3,
532
'new_tab': True,
533
'completion_requirement': {
534
'type': 'must_view'
535
}
536
})
537
538
# Add assignment (assuming assignment exists)
539
assignment = course.get_assignment(67890)
540
assignment_item = week1_module.create_module_item({
541
'title': 'Week 1 Assignment',
542
'type': 'Assignment',
543
'content_id': assignment.id,
544
'position': 4,
545
'completion_requirement': {
546
'type': 'must_submit'
547
}
548
})
549
```
550
551
### Managing External Tools
552
553
```python
554
# Create an external LTI tool
555
external_tool = course.create_external_tool(
556
name="Code Execution Environment",
557
privacy_level="public",
558
consumer_key="your_consumer_key",
559
shared_secret="your_shared_secret",
560
url="https://coderunner.example.com/lti",
561
description="Interactive coding environment for assignments",
562
custom_fields={
563
'course_id': '$Canvas.course.id',
564
'user_id': '$Canvas.user.id'
565
},
566
course_navigation={
567
'enabled': True,
568
'text': 'Code Runner',
569
'visibility': 'public'
570
},
571
editor_button={
572
'enabled': True,
573
'icon_url': 'https://coderunner.example.com/icon.png',
574
'text': 'Insert Code',
575
'url': 'https://coderunner.example.com/editor_select'
576
}
577
)
578
579
# Add external tool as module item
580
tool_item = week1_module.create_module_item({
581
'title': 'Interactive Coding Exercise',
582
'type': 'ExternalTool',
583
'content_id': external_tool.id,
584
'position': 5,
585
'completion_requirement': {
586
'type': 'must_view'
587
}
588
})
589
```
590
591
### Content Migration
592
593
```python
594
# Import content from another Canvas course
595
migration = course.create_content_migration(
596
migration_type='course_copy_importer',
597
settings={
598
'source_course_id': 54321, # Source course ID
599
'selective_import': True
600
},
601
date_shift_options={
602
'shift_dates': True,
603
'old_start_date': '2023-08-01',
604
'old_end_date': '2023-12-15',
605
'new_start_date': '2024-01-15',
606
'new_end_date': '2024-05-15',
607
'day_substitutions': {
608
'monday': 'tuesday', # Move Monday classes to Tuesday
609
'wednesday': 'thursday' # Move Wednesday to Thursday
610
}
611
}
612
)
613
614
# Monitor migration progress
615
progress = migration.get_progress()
616
print(f"Migration status: {progress.workflow_state}")
617
print(f"Progress: {progress.completion}%")
618
619
# Check for migration issues
620
if progress.workflow_state == 'completed':
621
issues = migration.get_migration_issues()
622
for issue in issues:
623
print(f"Migration issue: {issue.description}")
624
625
# Import from a ZIP file
626
zip_migration = course.create_content_migration(
627
migration_type='zip_file_importer',
628
pre_attachment={
629
'name': 'course_content.zip',
630
'size': 1024000 # File size in bytes
631
}
632
# File upload would be handled separately
633
)
634
```
635
636
### Managing Usage Rights
637
638
```python
639
# Set usage rights for course files
640
files_to_update = [lecture1_file.id, assignment_template.id]
641
642
usage_rights = course.set_usage_rights(
643
file_ids=files_to_update,
644
usage_rights={
645
'use_justification': 'own_copyright',
646
'legal_copyright': '© 2024 University Name. All rights reserved.'
647
}
648
)
649
650
# Set Creative Commons license
651
cc_files = [resources_file.id]
652
cc_rights = course.set_usage_rights(
653
file_ids=cc_files,
654
usage_rights={
655
'use_justification': 'creative_commons',
656
'license': 'cc_by_sa', # Creative Commons Attribution-ShareAlike
657
'legal_copyright': 'Licensed under CC BY-SA 4.0'
658
}
659
)
660
```
661
662
### Advanced File Management
663
664
```python
665
# Get all files in course and organize them
666
all_files = course.get_files(
667
sort='created_at',
668
order='desc',
669
include=['user']
670
)
671
672
# Create folders by file type
673
image_folder = course.create_folder('Images')
674
document_folder = course.create_folder('Documents')
675
video_folder = course.create_folder('Videos')
676
677
# Organize files by type
678
for file in all_files:
679
if file.content_type.startswith('image/'):
680
target_folder = image_folder
681
elif file.content_type in ['application/pdf', 'application/msword']:
682
target_folder = document_folder
683
elif file.content_type.startswith('video/'):
684
target_folder = video_folder
685
else:
686
continue
687
688
# Move file to appropriate folder (would require file update API)
689
print(f"Would move {file.display_name} to {target_folder.name}")
690
691
# Get file usage statistics
692
for file in all_files[:10]: # Check first 10 files
693
print(f"File: {file.display_name}")
694
print(f"Size: {file.size} bytes")
695
print(f"Downloads: {file.view_count if hasattr(file, 'view_count') else 'N/A'}")
696
print(f"Created: {file.created_at}")
697
print("---")
698
```