diff --git a/README.md b/README.md
index 8be1844..0b17585 100644
--- a/README.md
+++ b/README.md
@@ -73,14 +73,9 @@ Welcome to Labelbox Notebooks! These documents are directly linked from our Labe
- Export data |
-  |
-  |
-
-
- Exporting to CSV |
-  |
-  |
+ Composite mask export |
+  |
+  |
Export v1 to v2 migration support |
@@ -88,9 +83,14 @@ Welcome to Labelbox Notebooks! These documents are directly linked from our Labe
 |
- Composite mask export |
-  |
-  |
+ Exporting to CSV |
+  |
+  |
+
+
+ Export data |
+  |
+  |
@@ -107,9 +107,9 @@ Welcome to Labelbox Notebooks! These documents are directly linked from our Labe
- Multimodal chat project |
-  |
-  |
+ Queue management |
+  |
+  |
Prompt response projects |
@@ -127,9 +127,9 @@ Welcome to Labelbox Notebooks! These documents are directly linked from our Labe
 |
- Queue management |
-  |
-  |
+ Multimodal chat project |
+  |
+  |
@@ -146,19 +146,9 @@ Welcome to Labelbox Notebooks! These documents are directly linked from our Labe
- LLM data generation |
-  |
-  |
-
-
- Tiled |
-  |
-  |
-
-
- PDF |
-  |
-  |
+ Offline multimodal chat evaluation |
+  |
+  |
DICOM |
@@ -171,29 +161,29 @@ Welcome to Labelbox Notebooks! These documents are directly linked from our Labe
 |
- Offline multimodal chat evaluation |
-  |
-  |
+ Conversational LLM |
+  |
+  |
+
+
+ LLM data generation |
+  |
+  |
Text |
 |
 |
-
- Conversational LLM |
-  |
-  |
-
HTML |
 |
 |
- Prompt response |
-  |
-  |
+ PDF |
+  |
+  |
Image |
@@ -201,15 +191,25 @@ Welcome to Labelbox Notebooks! These documents are directly linked from our Labe
 |
- Video |
-  |
-  |
+ Tiled |
+  |
+  |
Conversational |
 |
 |
+
+ Video |
+  |
+  |
+
+
+ Prompt response |
+  |
+  |
+
@@ -225,30 +225,30 @@ Welcome to Labelbox Notebooks! These documents are directly linked from our Labe
- Langchain |
-  |
-  |
+ Meta SAM video |
+  |
+  |
+
+
+ Meta SAM |
+  |
+  |
Huggingface custom embeddings |
 |
 |
+
+ Langchain |
+  |
+  |
+
Import YOLOv8 annotations |
 |
 |
-
- Meta SAM |
-  |
-  |
-
-
- Meta SAM video |
-  |
-  |
-
@@ -263,16 +263,6 @@ Welcome to Labelbox Notebooks! These documents are directly linked from our Labe
-
- Custom metrics demo |
-  |
-  |
-
-
- Model slices |
-  |
-  |
-
Model predictions to project |
 |
@@ -283,6 +273,16 @@ Welcome to Labelbox Notebooks! These documents are directly linked from our Labe
 |
 |
+
+ Custom metrics demo |
+  |
+  |
+
+
+ Model slices |
+  |
+  |
+
@@ -297,46 +297,46 @@ Welcome to Labelbox Notebooks! These documents are directly linked from our Labe
+
+ Conversational predictions |
+  |
+  |
+
PDF predictions |
 |
 |
+
+ Conversational LLM predictions |
+  |
+  |
+
Text predictions |
 |
 |
- Geospatial predictions |
-  |
-  |
+ HTML predictions |
+  |
+  |
- Conversational predictions |
-  |
-  |
+ Image predictions |
+  |
+  |
- Conversational LLM predictions |
-  |
-  |
+ Geospatial predictions |
+  |
+  |
Video predictions |
 |
 |
-
- Image predictions |
-  |
-  |
-
-
- HTML predictions |
-  |
-  |
-
diff --git a/basics/user_management.ipynb b/basics/user_management.ipynb
index a190b99..b704a3f 100644
--- a/basics/user_management.ipynb
+++ b/basics/user_management.ipynb
@@ -6,8 +6,8 @@
{
"metadata": {},
"source": [
- "\n",
- " \n",
+ " | ",
+ " ",
" | \n"
],
"cell_type": "markdown"
@@ -43,20 +43,14 @@
},
{
"metadata": {},
- "source": [
- "%pip install \"labelbox[data]\""
- ],
+ "source": "%pip install \"labelbox[data]\"",
"cell_type": "code",
"outputs": [],
"execution_count": null
},
{
"metadata": {},
- "source": [
- "import labelbox as lb\n",
- "import os\n",
- "from labelbox.schema.user_group import UserGroup, UserGroupColor"
- ],
+ "source": "import labelbox as lb",
"cell_type": "code",
"outputs": [],
"execution_count": null
@@ -71,12 +65,7 @@
},
{
"metadata": {},
- "source": [
- "# Add your api key\n",
- "API_KEY = None\n",
- "client = lb.Client(api_key=API_KEY)\n",
- "organization = client.get_organization()"
- ],
+ "source": "# Add your api key\nAPI_KEY = None\nclient = lb.Client(api_key=API_KEY)\norganization = client.get_organization()",
"cell_type": "code",
"outputs": [],
"execution_count": null
@@ -92,11 +81,7 @@
},
{
"metadata": {},
- "source": [
- "roles = client.get_roles()\n",
- "for name, role in roles.items():\n",
- " print(role.name, \":\", role.uid)"
- ],
+ "source": "roles = client.get_roles()\nfor name, role in roles.items():\n print(role.name, \":\", role.uid)",
"cell_type": "code",
"outputs": [],
"execution_count": null
@@ -128,31 +113,21 @@
},
{
"metadata": {},
- "source": [
- "# First make sure that you have enough seats:\n",
- "organization.invite_limit()"
- ],
+ "source": "# First make sure that you have enough seats:\norganization.invite_limit()",
"cell_type": "code",
"outputs": [],
"execution_count": null
},
{
"metadata": {},
- "source": [
- "USER_EMAIL = \"\"\n",
- "invite = organization.invite_user(USER_EMAIL, roles[\"LABELER\"])"
- ],
+ "source": "USER_EMAIL = \"\"\ninvite = organization.invite_user(USER_EMAIL, roles[\"LABELER\"])",
"cell_type": "code",
"outputs": [],
"execution_count": null
},
{
"metadata": {},
- "source": [
- "print(invite.created_at)\n",
- "print(invite.organization_role_name)\n",
- "print(invite.email)"
- ],
+ "source": "print(invite.created_at)\nprint(invite.organization_role_name)\nprint(invite.email)",
"cell_type": "code",
"outputs": [],
"execution_count": null
@@ -168,16 +143,7 @@
},
{
"metadata": {},
- "source": [
- "USER_EMAIL = \"\"\n",
- "project = client.create_project(\n",
- " name=\"test_user_management\", media_type=lb.MediaType.Image\n",
- ")\n",
- "project_role = lb.ProjectRole(project=project, role=roles[\"REVIEWER\"])\n",
- "invite = organization.invite_user(\n",
- " USER_EMAIL, roles[\"NONE\"], project_roles=[project_role]\n",
- ")"
- ],
+ "source": "USER_EMAIL = \"\"\nproject = client.create_project(name=\"test_user_management\",\n media_type=lb.MediaType.Image)\nproject_role = lb.ProjectRole(project=project, role=roles[\"REVIEWER\"])\ninvite = organization.invite_user(USER_EMAIL,\n roles[\"NONE\"],\n project_roles=[project_role])",
"cell_type": "code",
"outputs": [],
"execution_count": null
@@ -193,10 +159,7 @@
},
{
"metadata": {},
- "source": [
- "users = list(organization.users())\n",
- "print(users[0])"
- ],
+ "source": "users = list(organization.users())\nprint(users[0])",
"cell_type": "code",
"outputs": [],
"execution_count": null
@@ -212,29 +175,7 @@
},
{
"metadata": {},
- "source": [
- "# Get all users in the organization\n",
- "users = organization.users()\n",
- "\n",
- "# Filter the desired user using their email\n",
- "USER_EMAIL = \"\"\n",
- "user = next((u for u in users if u.email == USER_EMAIL), None)\n",
- "\n",
- "if user:\n",
- " print(f\"User found: {user.name} ({user.email})\")\n",
- "else:\n",
- " print(\"User not found.\")\n",
- "\n",
- "# Give the user organization level permissions\n",
- "user.update_org_role(roles[\"LABELER\"])\n",
- "print(user.org_role())\n",
- "# Restore project level permissions\n",
- "user.update_org_role(roles[\"NONE\"])\n",
- "print(user.org_role())\n",
- "# Make the user a labeler for the current project\n",
- "user.upsert_project_role(project, roles[\"LABELER\"])\n",
- "print(user.org_role())"
- ],
+ "source": "# Get all users in the organization\nusers = organization.users()\n\n# Filter the desired user using their email\nUSER_EMAIL = \"\"\nuser = next((u for u in users if u.email == USER_EMAIL), None)\n\nif user:\n print(f\"User found: {user.name} ({user.email})\")\nelse:\n print(\"User not found.\")\n\n# Give the user organization level permissions\nuser.update_org_role(roles[\"LABELER\"])\nprint(user.org_role())\n# Restore project level permissions\nuser.update_org_role(roles[\"NONE\"])\nprint(user.org_role())\n# Make the user a labeler for the current project\nuser.upsert_project_role(project, roles[\"LABELER\"])\nprint(user.org_role())",
"cell_type": "code",
"outputs": [],
"execution_count": null
@@ -247,16 +188,23 @@
],
"cell_type": "markdown"
},
+ {
+ "metadata": {},
+ "source": "# Remove the user from a project\nuser.remove_from_project(project)\n# Alternatively, set the project role to none\nuser.update_org_role(roles[\"NONE\"])\n# Remove the user from the org\norganization.remove_user(user)",
+ "cell_type": "code",
+ "outputs": [],
+ "execution_count": null
+ },
{
"metadata": {},
"source": [
- "# Remove the user from a project\n",
- "user.remove_from_project(project)\n",
- "# Alternatively, set the project role to none\n",
- "user.update_org_role(roles[\"NONE\"])\n",
- "# Remove the user from the org\n",
- "organization.remove_user(user)"
+ "## Manage user groups"
],
+ "cell_type": "markdown"
+ },
+ {
+ "metadata": {},
+ "source": "# Prerequisites for user group management\nfrom labelbox.schema.user_group import (\n UserGroup,\n UserGroupColor,\n UserGroupMember,\n)",
"cell_type": "code",
"outputs": [],
"execution_count": null
@@ -264,26 +212,13 @@
{
"metadata": {},
"source": [
- "## Manage user groups\n",
"### Create user groups"
],
"cell_type": "markdown"
},
{
"metadata": {},
- "source": [
- "# Define a user group\n",
- "user_group = UserGroup(\n",
- " client=client,\n",
- " name=\"New User Group\",\n",
- " color=UserGroupColor.BLUE\n",
- " users=set(user, user1, user2),\n",
- " projects=set(project)\n",
- ")\n",
- "\n",
- "# Create the defined user group\n",
- "created_group = user_group.create() "
- ],
+ "source": "# Define a user group\nuser_group = UserGroup(\n client=client,\n name=\"User Group with Explicit Roles\",\n color=UserGroupColor.GREEN,\n description=\"This is a user group\",\n members={\n UserGroupMember(user=user1, role=roles[\"LABELER\"]),\n UserGroupMember(user=user2, role=roles[\"REVIEWER\"]),\n UserGroupMember(user=user3, role=roles[\"LABELER\"]),\n },\n projects={project},\n)\n\n# Create the user group with explicit member roles\ncreated_group = user_group.create()",
"cell_type": "code",
"outputs": [],
"execution_count": null
@@ -297,26 +232,7 @@
},
{
"metadata": {},
- "source": [
- "# Define the user group properties to be updated\n",
- "user_group.name = \"Updated User Group Name\"\n",
- "user_group.color = UserGroupColor.GREEN\n",
- "\n",
- "# Add new projects to the group\n",
- "projects = []\n",
- "projects.append(user_group.projects)\n",
- "projects.append([project_1, project_2])\n",
- "user_group.projects = projects\n",
- "\n",
- "# Add new users to the group\n",
- "\n",
- "users = user_group.users\n",
- "users.append([new_user_1, new_user_2])\n",
- "user_group.users = users\n",
- "\n",
- "# Push the changes to the group\n",
- "user_group.update()"
- ],
+ "source": "# Update the user group properties\nuser_group.name = \"Updated User Group Name\"\nuser_group.color = UserGroupColor.GREEN\nuser_group.description = \"Updated description\"\n\n# Add new projects to the group (assuming you have additional projects)\nuser_group.projects.add(project_1) # Add individual projects\nuser_group.projects.update({project_2, project_3}) # Add multiple projects\n\n# OR add new members with explicit roles (V3 approach)\nuser_group.members.add(UserGroupMember(user=new_user, role=roles[\"REVIEWER\"]))\nuser_group.members.update({\n UserGroupMember(user=new_user_1, role=roles[\"LABELER\"]),\n UserGroupMember(user=new_user_2, role=roles[\"REVIEWER\"]),\n})\n\n# Push the changes to the group\nuser_group.update()",
"cell_type": "code",
"outputs": [],
"execution_count": null
@@ -324,14 +240,13 @@
{
"metadata": {},
"source": [
- "## Remove all members and projects from the group\n",
- "user_group.users = []\n",
- "user_group.projects = []\n",
- "user_group.update()\n",
- "\n",
- "# Push the changes to the group\n",
- "user_group.update()"
+ "### Reset user group"
],
+ "cell_type": "markdown"
+ },
+ {
+ "metadata": {},
+ "source": "## Remove all members and projects from the group\nuser_group.users = set() # Clear users (Set, not list)\nuser_group.members = set() # Clear members (Set, not list)\nuser_group.projects = set() # Clear projects (Set, not list)\n\n# Push the changes to the group\nuser_group.update()",
"cell_type": "code",
"outputs": [],
"execution_count": null
@@ -339,9 +254,13 @@
{
"metadata": {},
"source": [
- "# Delete a user group\n",
- "user_group.delete()"
+ "### Delete user group"
],
+ "cell_type": "markdown"
+ },
+ {
+ "metadata": {},
+ "source": "# Delete a user group\nuser_group.delete()",
"cell_type": "code",
"outputs": [],
"execution_count": null
@@ -355,22 +274,7 @@
},
{
"metadata": {},
- "source": [
- "# Get info of a user group\n",
- "user_group.get()\n",
- "\n",
- "# Get all user groups in your workspace\n",
- "user_groups = UserGroup(client).get_user_groups()\n",
- "\n",
- "# Search for a user group by its name\n",
- "example_group = next(\n",
- " (group for group in user_groups if group.name == \"example_name\"), None\n",
- ")\n",
- "if example_group:\n",
- " print(f\"Found user group 'example_name' with ID: {example_group.id}\")\n",
- "else:\n",
- " print(\"No user group named 'example_name' found\")"
- ],
+ "source": "# Get info of a user group\nuser_group.get()\n\n# Get all user groups in your workspace\nuser_groups = UserGroup.get_user_groups(client)\n\n# Search for a user group by its name\ngroup_name = \"example_name\"\nexample_group = next(\n (group for group in user_groups if group.name == group_name), None)\nif example_group:\n print(f\"Found user group 'example_name' with ID: {example_group.id}\")\nelse:\n print(\"No user group named 'example_name' found\")",
"cell_type": "code",
"outputs": [],
"execution_count": null
@@ -385,9 +289,7 @@
},
{
"metadata": {},
- "source": [
- "project.delete()"
- ],
+ "source": "project.delete()",
"cell_type": "code",
"outputs": [],
"execution_count": null
diff --git a/requirements-dev.lock b/requirements-dev.lock
index 1b1aa86..b79828c 100644
--- a/requirements-dev.lock
+++ b/requirements-dev.lock
@@ -14,7 +14,7 @@ annotated-types==0.7.0
asttokens==3.0.0
# via stack-data
black==25.1.0
-click==8.1.8
+click==8.2.1
# via black
# via typer
commonmark==0.9.1
@@ -28,7 +28,7 @@ gitdb==4.0.12
# via gitpython
gitpython==3.1.44
# via databooks
-ipython==9.1.0
+ipython==9.3.0
# via black
ipython-pygments-lexers==1.1.1
# via ipython
@@ -36,31 +36,31 @@ jedi==0.19.2
# via ipython
matplotlib-inline==0.1.7
# via ipython
-mypy-extensions==1.0.0
+mypy-extensions==1.1.0
# via black
-numpy==2.2.4
+numpy==2.3.0
# via pandas
-packaging==24.2
+packaging==25.0
# via black
-pandas==2.2.3
+pandas==2.3.0
parso==0.8.4
# via jedi
pathspec==0.12.1
# via black
pexpect==4.9.0
# via ipython
-platformdirs==4.3.7
+platformdirs==4.3.8
# via black
# via yapf
-prompt-toolkit==3.0.50
+prompt-toolkit==3.0.51
# via ipython
ptyprocess==0.7.0
# via pexpect
pure-eval==0.2.3
# via stack-data
-pydantic==2.11.3
+pydantic==2.11.7
# via databooks
-pydantic-core==2.33.1
+pydantic-core==2.33.2
# via pydantic
pygments==2.19.1
# via ipython
@@ -81,22 +81,22 @@ smmap==5.0.2
# via gitdb
stack-data==0.6.3
# via ipython
-tokenize-rt==6.1.0
+tokenize-rt==6.2.0
# via black
tomli==2.2.1
# via databooks
traitlets==5.14.3
# via ipython
# via matplotlib-inline
-typer==0.15.2
+typer==0.16.0
# via databooks
-typing-extensions==4.13.2
+typing-extensions==4.14.0
# via databooks
# via pydantic
# via pydantic-core
# via typer
# via typing-inspection
-typing-inspection==0.4.0
+typing-inspection==0.4.1
# via pydantic
tzdata==2025.2
# via pandas