API wrapper for the Canvas LMS
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Conversations, announcements, messaging, and notification management within Canvas. Comprehensive communication tools for connecting students, instructors, and administrators.
Canvas's internal messaging system for private communication between users.
def get_conversations(self, **kwargs) -> PaginatedList[Conversation]:
"""
Get list of conversations for the current user.
Parameters:
- scope: Filter conversations ('unread', 'starred', 'sent', 'archived')
- filter: Additional filters ('course_123', 'group_456', 'user_789')
- filter_mode: Filter mode ('and', 'or', 'default')
- interleave_submissions: Include submission comments
- include_all_conversation_ids: Include all conversation IDs in response
- include: Additional data ('participant_avatars', 'participant_contexts')
Returns:
Paginated list of Conversation objects
"""
def get_conversation(self, conversation, **kwargs) -> Conversation:
"""
Get a single conversation by ID.
Parameters:
- conversation: Conversation object or conversation ID
- include: Additional data to include
- auto_mark_as_read: Automatically mark as read when retrieved
Returns:
Conversation object
"""
def create_conversation(self, recipients: list, body: str, **kwargs) -> list[Conversation]:
"""
Create a new conversation.
Parameters:
- recipients: List of recipient IDs (can include 'course_123', 'group_456' prefixes)
- body: Message body text
- subject: Conversation subject
- force_new: Force creation of new conversation vs adding to existing
- group_conversation: Create as group conversation
- attachment_ids: List of file attachment IDs
- media_comment_id: Media comment ID
- media_comment_type: Media comment type ('audio', 'video')
- user_note: Add as user note
- mode: Conversation mode ('sync', 'async')
- scope: Conversation scope ('unread', 'starred', etc.)
- filter: Additional filters
- filter_mode: Filter mode
- context_code: Context for the conversation
Returns:
List of Conversation objects (may be multiple if sent to different contexts)
"""Manage existing conversations with bulk operations and status updates.
def conversations_batch_update(self, conversation_ids: list, event: str, **kwargs) -> Progress:
"""
Perform batch operations on multiple conversations.
Parameters:
- conversation_ids: List of conversation IDs (max 500)
- event: Action to perform ('mark_as_read', 'mark_as_unread', 'star', 'unstar', 'archive', 'destroy')
Returns:
Progress object for tracking the batch operation
"""
def conversations_mark_all_as_read(self, **kwargs) -> bool:
"""
Mark all conversations as read for the current user.
Returns:
True if successful
"""
def conversations_unread_count(self, **kwargs) -> dict:
"""
Get the number of unread conversations.
Returns:
Dictionary with 'unread_count' key
"""
def conversations_get_running_batches(self, **kwargs) -> dict:
"""
Get currently running conversation batch operations.
Returns:
Dictionary with list of batch objects
"""Operations on specific conversation objects.
class Conversation(CanvasObject):
def edit(self, **kwargs) -> Conversation:
"""
Update conversation properties.
Parameters:
- conversation: Dictionary with updates:
- workflow_state: New state ('read', 'unread', 'archived')
- subscribed: Whether user is subscribed
- starred: Whether conversation is starred
- scope: Conversation scope filter
- filter: Additional filters
- filter_mode: Filter mode
Returns:
Updated Conversation object
"""
def delete(self, **kwargs) -> Conversation:
"""Delete/remove the conversation."""
def add_recipients(self, recipients: list, **kwargs) -> Conversation:
"""
Add recipients to the conversation.
Parameters:
- recipients: List of recipient IDs to add
Returns:
Updated Conversation object
"""
def add_message(self, body: str, **kwargs) -> Conversation:
"""
Add a message to the conversation.
Parameters:
- body: Message body text
- attachment_ids: List of file attachment IDs
- media_comment_id: Media comment ID
- media_comment_type: Media comment type
- recipients: List of specific recipients for this message
- included_messages: List of message IDs to include in context
- user_note: Add as user note
Returns:
Updated Conversation object with new message
"""Course and account-level announcements for broad communication.
def get_announcements(self, context_codes: list, **kwargs) -> PaginatedList[DiscussionTopic]:
"""
List announcements from specified contexts.
Parameters:
- context_codes: List of context codes ('course_123', 'account_456')
- start_date: Start date for filtering announcements
- end_date: End date for filtering announcements
- active_only: Only return active announcements
- latest_only: Only return latest announcement per context
- include: Additional data ('sections', 'course_section')
Returns:
Paginated list of DiscussionTopic objects representing announcements
"""System-generated messages and notifications sent to users.
def get_comm_messages(self, user, **kwargs) -> PaginatedList[CommMessage]:
"""
Get communication messages sent to a user.
Parameters:
- user: User object or user ID
- start_time: Start date for filtering messages
- end_time: End date for filtering messages
Returns:
Paginated list of CommMessage objects
"""
class CommMessage(CanvasObject):
"""Represents a communication message sent to a user."""
# Read-only object representing system messagesManage how users receive different types of notifications.
class NotificationPreference(CanvasObject):
"""
Represents user notification preferences for different communication channels.
Attributes:
- notification: Type of notification
- category: Notification category
- frequency: How often to send ('immediately', 'daily', 'weekly', 'never')
"""Extended functionality for discussion-based communication.
class DiscussionTopic(CanvasObject):
def edit(self, **kwargs) -> DiscussionTopic:
"""
Edit discussion topic/announcement.
Parameters:
- title: Discussion title
- message: Discussion message/content
- discussion_type: Type ('side_comment', 'threaded')
- published: Whether published
- delayed_post_at: When to automatically publish
- lock_at: When to automatically lock
- podcast_enabled: Enable podcast feed
- podcast_has_student_posts: Include student posts in podcast
- require_initial_post: Require initial post before viewing replies
- assignment: Assignment data if graded discussion
- is_announcement: Whether this is an announcement
Returns:
Updated DiscussionTopic object
"""
def delete(self, **kwargs) -> DiscussionTopic:
"""Delete the discussion topic/announcement."""
def post_entry(self, **kwargs) -> DiscussionEntry:
"""
Post an entry (reply) to the discussion.
Parameters:
- message: Entry message text
- attachment: File attachment
- parent_id: Parent entry ID (for replies to specific posts)
Returns:
DiscussionEntry object
"""
def get_entries(self, **kwargs) -> PaginatedList[DiscussionEntry]:
"""
Get discussion entries (posts/replies).
Parameters:
- ids: Specific entry IDs to retrieve
- include_new_entries: Include entries newer than specified date
Returns:
Paginated list of DiscussionEntry objects
"""
def mark_as_read(self, **kwargs) -> bool:
"""Mark discussion as read for current user."""
def mark_as_unread(self, **kwargs) -> bool:
"""Mark discussion as unread for current user."""
def subscribe(self, **kwargs) -> bool:
"""Subscribe to discussion notifications."""
def unsubscribe(self, **kwargs) -> bool:
"""Unsubscribe from discussion notifications."""from canvasapi import Canvas
canvas = Canvas("https://canvas.example.com", "your-token")
# Create a conversation with multiple recipients
recipients = [
'123', # Individual user ID
'456', # Another user ID
'course_789', # All users in course 789
'group_101' # All users in group 101
]
conversations = canvas.create_conversation(
recipients=recipients,
subject="Important Course Update",
body="Hello everyone! I wanted to update you on the upcoming assignment changes...",
group_conversation=True
)
# The API may return multiple conversation objects if recipients are in different contexts
for conversation in conversations:
print(f"Created conversation {conversation.id} with {len(conversation.participants)} participants")
# Get all conversations for current user
all_conversations = canvas.get_conversations(
scope='unread',
include=['participant_avatars']
)
for conv in all_conversations:
print(f"Unread conversation: {conv.subject} from {conv.last_authored_message_at}")# Get a specific conversation and add a reply
conversation = canvas.get_conversation(12345)
# Add a message to the conversation
updated_conv = conversation.add_message(
body="Thanks for the question! Here's the clarification you requested...",
attachment_ids=[file1.id, file2.id]
)
# Add more recipients to the conversation
conversation.add_recipients(['new_user_123', 'another_user_456'])
# Mark conversation as starred and read
conversation.edit(
conversation={
'starred': True,
'workflow_state': 'read'
}
)
# Batch operations on multiple conversations
conversation_ids = [conv.id for conv in all_conversations[:5]]
progress = canvas.conversations_batch_update(
conversation_ids=conversation_ids,
event='mark_as_read'
)
# Monitor the batch operation progress
print(f"Batch operation status: {progress.workflow_state}")# Get announcements from multiple courses
course_codes = ['course_123', 'course_456', 'course_789']
announcements = canvas.get_announcements(
context_codes=course_codes,
active_only=True,
start_date='2024-01-01',
end_date='2024-12-31'
)
for announcement in announcements:
print(f"Announcement: {announcement.title}")
print(f"Posted: {announcement.posted_at}")
print(f"Course: {announcement.context_code}")
print("---")
# Create an announcement in a course
course = canvas.get_course(12345)
announcement = course.create_discussion_topic(
title="Week 5 Assignment Reminder",
message="<p>Don't forget that your research papers are due this Friday at 11:59 PM.</p><p>Please submit them via Canvas.</p>",
is_announcement=True,
published=True,
delayed_post_at=None # Post immediately
)# Get a discussion topic and manage it
course = canvas.get_course(12345)
discussions = course.get_discussion_topics(
order_by='recent_activity',
include=['all_dates', 'sections']
)
for discussion in discussions:
print(f"Discussion: {discussion.title}")
# Get entries (posts) in the discussion
entries = discussion.get_entries()
for entry in entries:
print(f" Post by User {entry.user_id}: {entry.message[:100]}...")
# Reply to an entry
if entry.user_id != current_user.id: # Don't reply to own posts
reply = discussion.post_entry(
message="Thanks for sharing your perspective!",
parent_id=entry.id
)
# Subscribe to discussion notifications
discussion.subscribe()
# Create a graded discussion
graded_discussion = course.create_discussion_topic(
title="Week 3 Case Study Discussion",
message="Analyze the case study and provide your recommendations...",
discussion_type='threaded',
published=True,
require_initial_post=True,
assignment={
'name': 'Case Study Discussion',
'points_possible': 25,
'due_at': '2024-12-01T23:59:59Z',
'grading_type': 'points'
}
)# Get current user and manage communication channels
current_user = canvas.get_current_user()
# List existing communication channels
channels = current_user.get_communication_channels()
for channel in channels:
print(f"Channel: {channel.address} ({channel.type}) - {channel.workflow_state}")
# Add a new email communication channel
new_channel = current_user.create_communication_channel({
'address': 'alternate.email@example.com',
'type': 'email'
})
# The new channel will need to be confirmed before it becomes active
print(f"Created channel {new_channel.id} - Status: {new_channel.workflow_state}")# Get unread message count
unread_info = canvas.conversations_unread_count()
print(f"You have {unread_info['unread_count']} unread conversations")
# Get communication messages sent to a specific user (admin function)
user = canvas.get_user(12345)
comm_messages = canvas.get_comm_messages(
user=user,
start_time='2024-01-01T00:00:00Z',
end_time='2024-12-31T23:59:59Z'
)
for message in comm_messages:
print(f"Message sent: {message.created_at}")
print(f"Subject: {message.subject}")
print(f"Sent to: {message.to}")
# Check for running batch operations
running_batches = canvas.conversations_get_running_batches()
if running_batches:
print("Active batch operations:")
for batch in running_batches:
print(f" Batch {batch['id']}: {batch['workflow_state']}")Install with Tessl CLI
npx tessl i tessl/pypi-canvasapi