Overview
Ricecooker is a Python framework for creating content import scripts that can upload educational materials to Kolibri Studio programmatically. It enables automated content channel creation without using the web interface.
Ricecooker is ideal for importing content at scale, automating content updates, or integrating content from external sources.
Installation
Install ricecooker using pip:
Minimum supported version: 0.6.21
Recommended version: 0.7.3+
Authentication
Ricecooker uses token-based authentication. Generate an API token from your Kolibri Studio account settings.
Authentication Endpoint
POST / api / internal / authenticate_user_internal
Headers:
Authorization: Token {your_token}
Response:
{
"success" : true ,
"username" : "your_username" ,
"user_id" : 123 ,
"first_name" : "First" ,
"last_name" : "Last" ,
"is_admin" : false
}
Version Checking
Ricecooker automatically checks version compatibility with Studio:
POST / api / internal / check_version
Headers:
Authorization: Token {your_token}
Body:
{
"version" : "0.7.3"
}
Response:
{
"success" : true ,
"status" : 0 ,
"message" : "Ricecooker v0.7.3 is up-to-date."
}
Status Codes:
0: Version is up-to-date
1: Soft warning - upgrade recommended
2: Hard warning - upgrade strongly recommended
3: Error - version incompatible, must upgrade
Core Workflow
Ricecooker follows a three-step process:
1. Create Channel
Create a new channel or update an existing one:
POST / api / internal / create_channel
Headers:
Authorization: Token {your_token}
Body:
{
"channel_data" : {
"name" : "My Channel" ,
"description" : "Channel description" ,
"thumbnail" : "path/to/thumbnail.png" ,
"language" : "en"
}
}
Response:
{
"success" : true ,
"root" : "abc123def456" ,
"channel_id" : "a1b2c3d4e5f6g7h8i9j0"
}
The root is the chef tree root node ID where content will be added.
2. Add Content Nodes
Add topics, videos, exercises, and other content:
POST / api / internal / add_nodes
Headers:
Authorization: Token {your_token}
Body:
{
"root_id" : "abc123def456" ,
"content_data" : [
{
"kind" : "topic" ,
"title" : "Introduction" ,
"description" : "Getting started" ,
"node_id" : "topic-001"
},
{
"kind" : "video" ,
"title" : "Lesson 1" ,
"description" : "First lesson" ,
"license" : "CC BY" ,
"files" : [
{
"file_type" : "video/mp4" ,
"path" : "lesson1.mp4"
}
]
}
]
}
Response:
{
"success" : true ,
"root_ids" : {
"topic-001" : "node_pk_123" ,
"video-001" : "node_pk_124"
}
}
The response maps your node IDs to Studio’s internal node primary keys.
3. Finish Channel
Commit the chef tree to staging:
POST / api / internal / finish_channel
Headers:
Authorization: Token {your_token}
Body:
{
"channel_id" : "a1b2c3d4e5f6g7h8i9j0" ,
"stage" : true
}
Response:
{
"success" : true ,
"new_channel" : "a1b2c3d4e5f6g7h8i9j0" ,
"diff_task_id" : "task-uuid"
}
Setting stage: true moves content to the staging tree for review. Set to false to move directly to the main tree.
File Management
Check File Differences
Determine which files need to be uploaded:
POST / api / internal / file_diff
Headers:
Authorization: Token {your_token}
Body:
[ "checksum1.mp4" , "checksum2.pdf" , "checksum3.jpg" ]
Response:
Only files not already in storage are returned.
Upload Files
This endpoint is deprecated in ricecooker 0.7+. Files are now uploaded directly to cloud storage.
POST / api / internal / file_upload
Headers:
Authorization: Token {your_token}
Content - Type: multipart / form - data
Body:
file : < file data >
Publishing Channels
Publish your channel to make it available to Kolibri:
POST / api / internal / publish_channel
Headers:
Authorization: Token {your_token}
Body:
{
"channel_id" : "a1b2c3d4e5f6g7h8i9j0" ,
"version_notes" : "Initial release"
}
Response:
{
"success" : true ,
"channel" : "a1b2c3d4e5f6g7h8i9j0"
}
Checking Channel Status
Check the status of multiple channels:
POST / api / internal / get_channel_status_bulk
Body:
{
"channel_ids" : [ "channel-id-1" , "channel-id-2" ]
}
Response:
{
"success" : true ,
"statuses" : {
"channel-id-1" : "staged" ,
"channel-id-2" : "published"
}
}
Retrieving Tree Data
Get the complete tree structure (may timeout for large channels):
POST / api / internal / get_tree_data
Body:
{
"channel_id" : "a1b2c3d4e5f6g7h8i9j0" ,
"tree" : "main"
}
Tree options: main, chef, staging, previous
Response:
{
"success" : true ,
"tree" : [
{
"kind" : "topic" ,
"title" : "Topic" ,
"children" : [
{
"kind" : "exercise" ,
"title" : "Exercise" ,
"count" : 2
}
]
},
{
"kind" : "html5" ,
"title" : "HTML Title" ,
"file_size" : 145990
}
]
}
Get Node Tree Data (Paginated)
For large channels, use the paginated endpoint:
POST / api / internal / get_node_tree_data
Body:
{
"channel_id" : "a1b2c3d4e5f6g7h8i9j0" ,
"tree" : "main" ,
"node_id" : "node-uuid"
}
Returns one level of children for the specified node.
Editor Permissions
Check if a user can edit a channel:
POST / api / internal / check_user_is_editor
Headers:
Authorization: Token {your_token}
Body:
{
"channel_id" : "a1b2c3d4e5f6g7h8i9j0"
}
Response:
Returns 403 Forbidden if user is not authorized.
Resources
Ricecooker GitHub View the ricecooker source code, examples, and documentation
Ricecooker Documentation Complete ricecooker framework documentation
Next Steps
Kolibri Integration Learn how Kolibri imports published channels
API Reference Explore the complete API documentation