From 2786aaa319ecab4626ed21b8b3679529117f7ae7 Mon Sep 17 00:00:00 2001 From: paulnoirel <87332996+paulnoirel@users.noreply.github.com> Date: Mon, 16 Jun 2025 16:08:16 +0100 Subject: [PATCH 1/5] Fix example following update --- basics/user_management.ipynb | 309 +++++++++++++++++++++-------------- 1 file changed, 182 insertions(+), 127 deletions(-) diff --git a/basics/user_management.ipynb b/basics/user_management.ipynb index a190b99..a36a8b0 100644 --- a/basics/user_management.ipynb +++ b/basics/user_management.ipynb @@ -1,18 +1,16 @@ { - "nbformat": 4, - "nbformat_minor": 5, - "metadata": {}, "cells": [ { + "cell_type": "markdown", "metadata": {}, "source": [ "\n", " \n", "\n" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "\n", @@ -24,10 +22,10 @@ "\n", "" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "# User Management\n", @@ -38,136 +36,137 @@ " * assign users to projects\n", " * set / update / revoke project role\n", " * delete users from org" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ "%pip install \"labelbox[data]\"" - ], - "cell_type": "code", - "outputs": [], - "execution_count": null + ] }, { + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ "import labelbox as lb\n", - "import os\n", - "from labelbox.schema.user_group import UserGroup, UserGroupColor" - ], - "cell_type": "code", - "outputs": [], - "execution_count": null + "from labelbox.schema.user_group import UserGroup, UserGroupColor, UserGroupMember" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "# API Key and Client\n", "Provide a valid api key below in order to properly connect to the Labelbox Client." - ], - "cell_type": "markdown" + ] }, { + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ "# Add your api key\n", "API_KEY = None\n", "client = lb.Client(api_key=API_KEY)\n", "organization = client.get_organization()" - ], - "cell_type": "code", - "outputs": [], - "execution_count": null + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "## Roles\n", "* When inviting a new user to an organization, there are various roles to select from.\n", "* All available roles to your org can be accessed via `client.get_roles()`" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ "roles = client.get_roles()\n", "for name, role in roles.items():\n", " print(role.name, \":\", role.uid)" - ], - "cell_type": "code", - "outputs": [], - "execution_count": null + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "* Above we printed out all of the roles available to the current org.\n", "* Notice the `NONE`. That is for project level roles" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "## Create\n", "* Users are created by sending an invite\n", "* An email will be sent to them and they will be asked to join your organization" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Organization Level Permissions\n", "* Invite a new labeler with labeling permissions on all projects" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ "# First make sure that you have enough seats:\n", "organization.invite_limit()" - ], - "cell_type": "code", - "outputs": [], - "execution_count": null + ] }, { + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ "USER_EMAIL = \"\"\n", "invite = organization.invite_user(USER_EMAIL, roles[\"LABELER\"])" - ], - "cell_type": "code", - "outputs": [], - "execution_count": null + ] }, { + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ "print(invite.created_at)\n", "print(invite.organization_role_name)\n", "print(invite.email)" - ], - "cell_type": "code", - "outputs": [], - "execution_count": null + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Project Level Permissions\n", "* Invite a new labeler with labeling permissions specific to a set of projects\n", "* Here we set organization level permissions to Roles.NONE to indicate that the user only has project level permissions" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ "USER_EMAIL = \"\"\n", "project = client.create_project(\n", @@ -177,41 +176,41 @@ "invite = organization.invite_user(\n", " USER_EMAIL, roles[\"NONE\"], project_roles=[project_role]\n", ")" - ], - "cell_type": "code", - "outputs": [], - "execution_count": null + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "## Read\n", "* Outstanding invites cannot be queried for at this time. This information can be found in the members tab of the web app.\n", "* You are able to query for members once they have joined." - ], - "cell_type": "markdown" + ] }, { + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ "users = list(organization.users())\n", "print(users[0])" - ], - "cell_type": "code", - "outputs": [], - "execution_count": null + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "## Update\n", "* There is no update on invites. Instead you must delete and resend them\n", "* You can update User roles" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ "# Get all users in the organization\n", "users = organization.users()\n", @@ -234,21 +233,21 @@ "# Make the user a labeler for the current project\n", "user.upsert_project_role(project, roles[\"LABELER\"])\n", "print(user.org_role())" - ], - "cell_type": "code", - "outputs": [], - "execution_count": null + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "## Delete\n", "You can remove users from projects and your organization using the SDK. Invites can only be deleted using the **Members** tab on the web platform at this moment." - ], - "cell_type": "markdown" + ] }, { + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ "# Remove the user from a project\n", "user.remove_from_project(project)\n", @@ -256,141 +255,197 @@ "user.update_org_role(roles[\"NONE\"])\n", "# Remove the user from the org\n", "organization.remove_user(user)" - ], - "cell_type": "code", - "outputs": [], - "execution_count": null + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "## Manage user groups\n", "### Create user groups" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "code", + "execution_count": null, + "id": "e76c09a1", "metadata": {}, + "outputs": [], "source": [ - "# Define a user group\n", + "# Define a user group where all users have the same role\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", + " color=UserGroupColor.BLUE,\n", + " description=\"This is a new user group\",\n", + " users={user, user1, user2},\n", + " default_role=roles[\"LABELER\"], # mandatory with \"users\"\n", + " projects={project} \n", ")\n", "\n", "# Create the defined user group\n", - "created_group = user_group.create() " - ], - "cell_type": "code", - "outputs": [], - "execution_count": null + "created_group = user_group.create() \n", + "\n", + "# OR define a user group with explicit roles for each member\n", + "from labelbox.schema.user_group import UserGroupMember\n", + "\n", + "user_group_with_roles = UserGroup(\n", + " client=client,\n", + " name=\"User Group with Explicit Roles\",\n", + " color=UserGroupColor.GREEN,\n", + " description=\"This is a user group with explicit roles\",\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\n", + "created_group_with_roles = user_group_with_roles.create()" + ] }, { + "cell_type": "markdown", + "id": "d4da5c26", "metadata": {}, "source": [ "### Update user groups" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "code", + "execution_count": null, + "id": "5df7f685", "metadata": {}, + "outputs": [], "source": [ - "# Define the user group properties to be updated\n", + "# Update the user group properties\n", "user_group.name = \"Updated User Group Name\"\n", "user_group.color = UserGroupColor.GREEN\n", + "user_group.description = \"Updated description\"\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", + "# Add new projects to the group (assuming you have additional projects)\n", + "user_group.projects.add(project_1) # Add individual projects\n", + "user_group.projects.update({project_2, project_3}) # Add multiple projects\n", "\n", - "# Add new users to the group\n", + "# Add new users to the group (legacy approach)\n", + "# user_group.default_role = roles[\"REVIEWER\"]\n", + "# user_group.users.add(new_user) # Add individual user\n", + "# user_group.users.update({new_user_1, new_user_2}) # Add multiple users\n", "\n", - "users = user_group.users\n", - "users.append([new_user_1, new_user_2])\n", - "user_group.users = users\n", + "# OR add new members with explicit roles (V3 approach)\n", + "user_group.members.add(UserGroupMember(user=new_user, role=roles[\"REVIEWER\"]))\n", + "user_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\n", "user_group.update()" - ], - "cell_type": "code", - "outputs": [], - "execution_count": null + ] }, { + "cell_type": "markdown", + "id": "c3acc7ea", + "metadata": {}, + "source": [ + "### Reset user group" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1a6c8f0f", "metadata": {}, + "outputs": [], "source": [ "## Remove all members and projects from the group\n", - "user_group.users = []\n", - "user_group.projects = []\n", - "user_group.update()\n", + "user_group.users = set() # Clear users (Set, not list)\n", + "user_group.members = set() # Clear members (Set, not list)\n", + "user_group.projects = set() # Clear projects (Set, not list)\n", "\n", "# Push the changes to the group\n", "user_group.update()" - ], - "cell_type": "code", - "outputs": [], - "execution_count": null + ] }, { + "cell_type": "markdown", + "id": "04982c2b", "metadata": {}, "source": [ - "# Delete a user group\n", - "user_group.delete()" - ], + "### Delete user group" + ] + }, + { "cell_type": "code", + "execution_count": null, + "id": "a4f0c275", + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# Delete a user group\n", + "user_group.delete()" + ] }, { + "cell_type": "markdown", + "id": "22544b0f", "metadata": {}, "source": [ "## Get user group info" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "code", + "execution_count": null, + "id": "f4fd9d6f", "metadata": {}, + "outputs": [], "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", + "user_groups = UserGroup.get_user_groups(client)\n", "\n", "# Search for a user group by its name\n", + "group_name = \"example_name\"\n", "example_group = next(\n", - " (group for group in user_groups if group.name == \"example_name\"), None\n", + " (group for group in user_groups if group.name == group_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\")" - ], - "cell_type": "code", - "outputs": [], - "execution_count": null + ] }, { + "cell_type": "markdown", + "id": "48c40b21", "metadata": {}, "source": [ "## Cleanup\n", "Delete the project if you no longer need it:" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "code", + "execution_count": null, + "id": "3e73e5eb", "metadata": {}, + "outputs": [], "source": [ "project.delete()" - ], - "cell_type": "code", - "outputs": [], - "execution_count": null + ] } - ] -} \ No newline at end of file + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From e04c52f7093415c1ab2d94ce6d7d00b78ecb755f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 16 Jun 2025 15:09:56 +0000 Subject: [PATCH 2/5] :art: Cleaned --- basics/user_management.ipynb | 354 ++++++++++------------------------- requirements-dev.lock | 28 +-- 2 files changed, 108 insertions(+), 274 deletions(-) diff --git a/basics/user_management.ipynb b/basics/user_management.ipynb index a36a8b0..3185a50 100644 --- a/basics/user_management.ipynb +++ b/basics/user_management.ipynb @@ -1,16 +1,18 @@ { + "nbformat": 4, + "nbformat_minor": 5, + "metadata": {}, "cells": [ { - "cell_type": "markdown", "metadata": {}, "source": [ - "\n", - " \n", + "", + " ", "\n" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "markdown", "metadata": {}, "source": [ "\n", @@ -22,10 +24,10 @@ "\n", "" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "markdown", "metadata": {}, "source": [ "# User Management\n", @@ -36,416 +38,248 @@ " * assign users to projects\n", " * set / update / revoke project role\n", " * delete users from org" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "%pip install \"labelbox[data]\"", + "cell_type": "code", "outputs": [], - "source": [ - "%pip install \"labelbox[data]\"" - ] + "execution_count": null }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "import labelbox as lb\nfrom labelbox.schema.user_group import (\n UserGroup,\n UserGroupColor,\n UserGroupMember,\n)", + "cell_type": "code", "outputs": [], - "source": [ - "import labelbox as lb\n", - "from labelbox.schema.user_group import UserGroup, UserGroupColor, UserGroupMember" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "# API Key and Client\n", "Provide a valid api key below in order to properly connect to the Labelbox Client." - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# Add your api key\nAPI_KEY = None\nclient = lb.Client(api_key=API_KEY)\norganization = client.get_organization()", + "cell_type": "code", "outputs": [], - "source": [ - "# Add your api key\n", - "API_KEY = None\n", - "client = lb.Client(api_key=API_KEY)\n", - "organization = client.get_organization()" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "## Roles\n", "* When inviting a new user to an organization, there are various roles to select from.\n", "* All available roles to your org can be accessed via `client.get_roles()`" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "roles = client.get_roles()\nfor name, role in roles.items():\n print(role.name, \":\", role.uid)", + "cell_type": "code", "outputs": [], - "source": [ - "roles = client.get_roles()\n", - "for name, role in roles.items():\n", - " print(role.name, \":\", role.uid)" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "* Above we printed out all of the roles available to the current org.\n", "* Notice the `NONE`. That is for project level roles" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "markdown", "metadata": {}, "source": [ "## Create\n", "* Users are created by sending an invite\n", "* An email will be sent to them and they will be asked to join your organization" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Organization Level Permissions\n", "* Invite a new labeler with labeling permissions on all projects" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# First make sure that you have enough seats:\norganization.invite_limit()", + "cell_type": "code", "outputs": [], - "source": [ - "# First make sure that you have enough seats:\n", - "organization.invite_limit()" - ] + "execution_count": null }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "USER_EMAIL = \"\"\ninvite = organization.invite_user(USER_EMAIL, roles[\"LABELER\"])", + "cell_type": "code", "outputs": [], - "source": [ - "USER_EMAIL = \"\"\n", - "invite = organization.invite_user(USER_EMAIL, roles[\"LABELER\"])" - ] + "execution_count": null }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "print(invite.created_at)\nprint(invite.organization_role_name)\nprint(invite.email)", + "cell_type": "code", "outputs": [], - "source": [ - "print(invite.created_at)\n", - "print(invite.organization_role_name)\n", - "print(invite.email)" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Project Level Permissions\n", "* Invite a new labeler with labeling permissions specific to a set of projects\n", "* Here we set organization level permissions to Roles.NONE to indicate that the user only has project level permissions" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "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": [], - "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", - ")" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "## Read\n", "* Outstanding invites cannot be queried for at this time. This information can be found in the members tab of the web app.\n", "* You are able to query for members once they have joined." - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "users = list(organization.users())\nprint(users[0])", + "cell_type": "code", "outputs": [], - "source": [ - "users = list(organization.users())\n", - "print(users[0])" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "## Update\n", "* There is no update on invites. Instead you must delete and resend them\n", "* You can update User roles" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "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": [], - "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())" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "## Delete\n", "You can remove users from projects and your organization using the SDK. Invites can only be deleted using the **Members** tab on the web platform at this moment." - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "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": [], - "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)" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "## Manage user groups\n", "### Create user groups" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, - "id": "e76c09a1", "metadata": {}, + "source": "# Define a user group where all users have the same role\nuser_group = UserGroup(\n client=client,\n name=\"New User Group\",\n color=UserGroupColor.BLUE,\n description=\"This is a new user group\",\n users={user, user1, user2},\n default_role=roles[\"LABELER\"], # mandatory with \"users\"\n projects={project},\n)\n\n# Create the defined user group\ncreated_group = user_group.create()\n\n# OR define a user group with explicit roles for each member\nfrom labelbox.schema.user_group import UserGroupMember\n\nuser_group_with_roles = UserGroup(\n client=client,\n name=\"User Group with Explicit Roles\",\n color=UserGroupColor.GREEN,\n description=\"This is a user group with explicit roles\",\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_with_roles = user_group_with_roles.create()", + "cell_type": "code", "outputs": [], - "source": [ - "# Define a user group where all users have the same role\n", - "user_group = UserGroup(\n", - " client=client,\n", - " name=\"New User Group\",\n", - " color=UserGroupColor.BLUE,\n", - " description=\"This is a new user group\",\n", - " users={user, user1, user2},\n", - " default_role=roles[\"LABELER\"], # mandatory with \"users\"\n", - " projects={project} \n", - ")\n", - "\n", - "# Create the defined user group\n", - "created_group = user_group.create() \n", - "\n", - "# OR define a user group with explicit roles for each member\n", - "from labelbox.schema.user_group import UserGroupMember\n", - "\n", - "user_group_with_roles = UserGroup(\n", - " client=client,\n", - " name=\"User Group with Explicit Roles\",\n", - " color=UserGroupColor.GREEN,\n", - " description=\"This is a user group with explicit roles\",\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\n", - "created_group_with_roles = user_group_with_roles.create()" - ] + "execution_count": null }, { - "cell_type": "markdown", - "id": "d4da5c26", "metadata": {}, "source": [ "### Update user groups" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, - "id": "5df7f685", "metadata": {}, + "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# Add new users to the group (legacy approach)\n# user_group.default_role = roles[\"REVIEWER\"]\n# user_group.users.add(new_user) # Add individual user\n# user_group.users.update({new_user_1, new_user_2}) # Add multiple users\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": [], - "source": [ - "# Update the user group properties\n", - "user_group.name = \"Updated User Group Name\"\n", - "user_group.color = UserGroupColor.GREEN\n", - "user_group.description = \"Updated description\"\n", - "\n", - "# Add new projects to the group (assuming you have additional projects)\n", - "user_group.projects.add(project_1) # Add individual projects\n", - "user_group.projects.update({project_2, project_3}) # Add multiple projects\n", - "\n", - "# Add new users to the group (legacy approach)\n", - "# user_group.default_role = roles[\"REVIEWER\"]\n", - "# user_group.users.add(new_user) # Add individual user\n", - "# user_group.users.update({new_user_1, new_user_2}) # Add multiple users\n", - "\n", - "# OR add new members with explicit roles (V3 approach)\n", - "user_group.members.add(UserGroupMember(user=new_user, role=roles[\"REVIEWER\"]))\n", - "user_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\n", - "user_group.update()" - ] + "execution_count": null }, { - "cell_type": "markdown", - "id": "c3acc7ea", "metadata": {}, "source": [ "### Reset user group" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, - "id": "1a6c8f0f", "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": [], - "source": [ - "## Remove all members and projects from the group\n", - "user_group.users = set() # Clear users (Set, not list)\n", - "user_group.members = set() # Clear members (Set, not list)\n", - "user_group.projects = set() # Clear projects (Set, not list)\n", - "\n", - "# Push the changes to the group\n", - "user_group.update()" - ] + "execution_count": null }, { - "cell_type": "markdown", - "id": "04982c2b", "metadata": {}, "source": [ "### Delete user group" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, - "id": "a4f0c275", "metadata": {}, + "source": "# Delete a user group\nuser_group.delete()", + "cell_type": "code", "outputs": [], - "source": [ - "# Delete a user group\n", - "user_group.delete()" - ] + "execution_count": null }, { - "cell_type": "markdown", - "id": "22544b0f", "metadata": {}, "source": [ "## Get user group info" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, - "id": "f4fd9d6f", "metadata": {}, + "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": [], - "source": [ - "# Get info of a user group\n", - "user_group.get()\n", - "\n", - "# Get all user groups in your workspace\n", - "user_groups = UserGroup.get_user_groups(client)\n", - "\n", - "# Search for a user group by its name\n", - "group_name = \"example_name\"\n", - "example_group = next(\n", - " (group for group in user_groups if group.name == group_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\")" - ] + "execution_count": null }, { - "cell_type": "markdown", - "id": "48c40b21", "metadata": {}, "source": [ "## Cleanup\n", "Delete the project if you no longer need it:" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, - "id": "3e73e5eb", "metadata": {}, + "source": "project.delete()", + "cell_type": "code", "outputs": [], - "source": [ - "project.delete()" - ] + "execution_count": null } - ], - "metadata": { - "language_info": { - "name": "python" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} + ] +} \ No newline at end of file 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 From 97d55ef30b52574f5e8a81d41fcf03d973ff7fb3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 16 Jun 2025 15:10:41 +0000 Subject: [PATCH 3/5] :memo: README updated --- README.md | 172 +++++++++++++++++++++++++++--------------------------- 1 file changed, 86 insertions(+), 86 deletions(-) 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 - Open In Colab - Open In Github - - - Exporting to CSV - Open In Colab - Open In Github + Composite mask export + Open In Colab + Open In Github Export v1 to v2 migration support @@ -88,9 +83,14 @@ Welcome to Labelbox Notebooks! These documents are directly linked from our Labe Open In Github - Composite mask export - Open In Colab - Open In Github + Exporting to CSV + Open In Colab + Open In Github + + + Export data + Open In Colab + Open In Github @@ -107,9 +107,9 @@ Welcome to Labelbox Notebooks! These documents are directly linked from our Labe - Multimodal chat project - Open In Colab - Open In Github + Queue management + Open In Colab + Open In Github Prompt response projects @@ -127,9 +127,9 @@ Welcome to Labelbox Notebooks! These documents are directly linked from our Labe Open In Github - Queue management - Open In Colab - Open In Github + Multimodal chat project + Open In Colab + Open In Github @@ -146,19 +146,9 @@ Welcome to Labelbox Notebooks! These documents are directly linked from our Labe - LLM data generation - Open In Colab - Open In Github - - - Tiled - Open In Colab - Open In Github - - - PDF - Open In Colab - Open In Github + Offline multimodal chat evaluation + Open In Colab + Open In Github DICOM @@ -171,29 +161,29 @@ Welcome to Labelbox Notebooks! These documents are directly linked from our Labe Open In Github - Offline multimodal chat evaluation - Open In Colab - Open In Github + Conversational LLM + Open In Colab + Open In Github + + + LLM data generation + Open In Colab + Open In Github Text Open In Colab Open In Github - - Conversational LLM - Open In Colab - Open In Github - HTML Open In Colab Open In Github - Prompt response - Open In Colab - Open In Github + PDF + Open In Colab + Open In Github Image @@ -201,15 +191,25 @@ Welcome to Labelbox Notebooks! These documents are directly linked from our Labe Open In Github - Video - Open In Colab - Open In Github + Tiled + Open In Colab + Open In Github Conversational Open In Colab Open In Github + + Video + Open In Colab + Open In Github + + + Prompt response + Open In Colab + Open In Github + @@ -225,30 +225,30 @@ Welcome to Labelbox Notebooks! These documents are directly linked from our Labe - Langchain - Open In Colab - Open In Github + Meta SAM video + Open In Colab + Open In Github + + + Meta SAM + Open In Colab + Open In Github Huggingface custom embeddings Open In Colab Open In Github + + Langchain + Open In Colab + Open In Github + Import YOLOv8 annotations Open In Colab Open In Github - - Meta SAM - Open In Colab - Open In Github - - - Meta SAM video - Open In Colab - Open In Github - @@ -263,16 +263,6 @@ Welcome to Labelbox Notebooks! These documents are directly linked from our Labe - - Custom metrics demo - Open In Colab - Open In Github - - - Model slices - Open In Colab - Open In Github - Model predictions to project Open In Colab @@ -283,6 +273,16 @@ Welcome to Labelbox Notebooks! These documents are directly linked from our Labe Open In Colab Open In Github + + Custom metrics demo + Open In Colab + Open In Github + + + Model slices + Open In Colab + Open In Github + @@ -297,46 +297,46 @@ Welcome to Labelbox Notebooks! These documents are directly linked from our Labe + + Conversational predictions + Open In Colab + Open In Github + PDF predictions Open In Colab Open In Github + + Conversational LLM predictions + Open In Colab + Open In Github + Text predictions Open In Colab Open In Github - Geospatial predictions - Open In Colab - Open In Github + HTML predictions + Open In Colab + Open In Github - Conversational predictions - Open In Colab - Open In Github + Image predictions + Open In Colab + Open In Github - Conversational LLM predictions - Open In Colab - Open In Github + Geospatial predictions + Open In Colab + Open In Github Video predictions Open In Colab Open In Github - - Image predictions - Open In Colab - Open In Github - - - HTML predictions - Open In Colab - Open In Github - From ca454a989247cdb6b574d3bde346908eb358ac0f Mon Sep 17 00:00:00 2001 From: paulnoirel <87332996+paulnoirel@users.noreply.github.com> Date: Mon, 16 Jun 2025 23:06:50 +0100 Subject: [PATCH 4/5] Examples updates. "users" removed --- basics/user_management.ipynb | 341 +++++++++++++++++++++++++---------- 1 file changed, 247 insertions(+), 94 deletions(-) diff --git a/basics/user_management.ipynb b/basics/user_management.ipynb index 3185a50..f245fa3 100644 --- a/basics/user_management.ipynb +++ b/basics/user_management.ipynb @@ -1,18 +1,16 @@ { - "nbformat": 4, - "nbformat_minor": 5, - "metadata": {}, "cells": [ { + "cell_type": "markdown", "metadata": {}, "source": [ - "", - " ", + "\n", + " \n", "\n" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "\n", @@ -24,10 +22,10 @@ "\n", "" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "# User Management\n", @@ -38,248 +36,403 @@ " * assign users to projects\n", " * set / update / revoke project role\n", " * delete users from org" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "%pip install \"labelbox[data]\"", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "%pip install \"labelbox[data]\"" + ] }, { - "metadata": {}, - "source": "import labelbox as lb\nfrom labelbox.schema.user_group import (\n UserGroup,\n UserGroupColor,\n UserGroupMember,\n)", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "import labelbox as lb" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "# API Key and Client\n", "Provide a valid api key below in order to properly connect to the Labelbox Client." - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "# Add your api key\nAPI_KEY = None\nclient = lb.Client(api_key=API_KEY)\norganization = client.get_organization()", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# Add your api key\n", + "API_KEY = None\n", + "client = lb.Client(api_key=API_KEY)\n", + "organization = client.get_organization()" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "## Roles\n", "* When inviting a new user to an organization, there are various roles to select from.\n", "* All available roles to your org can be accessed via `client.get_roles()`" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "roles = client.get_roles()\nfor name, role in roles.items():\n print(role.name, \":\", role.uid)", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "roles = client.get_roles()\n", + "for name, role in roles.items():\n", + " print(role.name, \":\", role.uid)" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "* Above we printed out all of the roles available to the current org.\n", "* Notice the `NONE`. That is for project level roles" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "## Create\n", "* Users are created by sending an invite\n", "* An email will be sent to them and they will be asked to join your organization" - ], - "cell_type": "markdown" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Organization Level Permissions\n", "* Invite a new labeler with labeling permissions on all projects" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "# First make sure that you have enough seats:\norganization.invite_limit()", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# First make sure that you have enough seats:\n", + "organization.invite_limit()" + ] }, { - "metadata": {}, - "source": "USER_EMAIL = \"\"\ninvite = organization.invite_user(USER_EMAIL, roles[\"LABELER\"])", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "USER_EMAIL = \"\"\n", + "invite = organization.invite_user(USER_EMAIL, roles[\"LABELER\"])" + ] }, { - "metadata": {}, - "source": "print(invite.created_at)\nprint(invite.organization_role_name)\nprint(invite.email)", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "print(invite.created_at)\n", + "print(invite.organization_role_name)\n", + "print(invite.email)" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Project Level Permissions\n", "* Invite a new labeler with labeling permissions specific to a set of projects\n", "* Here we set organization level permissions to Roles.NONE to indicate that the user only has project level permissions" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "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", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "USER_EMAIL = \"\"\n", + "project = client.create_project(name=\"test_user_management\",\n", + " media_type=lb.MediaType.Image)\n", + "project_role = lb.ProjectRole(project=project, role=roles[\"REVIEWER\"])\n", + "invite = organization.invite_user(USER_EMAIL,\n", + " roles[\"NONE\"],\n", + " project_roles=[project_role])" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "## Read\n", "* Outstanding invites cannot be queried for at this time. This information can be found in the members tab of the web app.\n", "* You are able to query for members once they have joined." - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "users = list(organization.users())\nprint(users[0])", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "users = list(organization.users())\n", + "print(users[0])" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "## Update\n", "* There is no update on invites. Instead you must delete and resend them\n", "* You can update User roles" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "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", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "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())" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "## Delete\n", "You can remove users from projects and your organization using the SDK. Invites can only be deleted using the **Members** tab on the web platform at this moment." - ], - "cell_type": "markdown" + ] }, { + "cell_type": "code", + "execution_count": null, "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)", + "outputs": [], + "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)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Manage user groups" + ] + }, + { "cell_type": "code", + "execution_count": null, + "id": "8576348c", + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# Prerequisites for user group management\n", + "from labelbox.schema.user_group import (\n", + " UserGroup,\n", + " UserGroupColor,\n", + " UserGroupMember,\n", + ")" + ] }, { + "cell_type": "markdown", + "id": "e9dfaba7", "metadata": {}, "source": [ - "## Manage user groups\n", "### Create user groups" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "# Define a user group where all users have the same role\nuser_group = UserGroup(\n client=client,\n name=\"New User Group\",\n color=UserGroupColor.BLUE,\n description=\"This is a new user group\",\n users={user, user1, user2},\n default_role=roles[\"LABELER\"], # mandatory with \"users\"\n projects={project},\n)\n\n# Create the defined user group\ncreated_group = user_group.create()\n\n# OR define a user group with explicit roles for each member\nfrom labelbox.schema.user_group import UserGroupMember\n\nuser_group_with_roles = UserGroup(\n client=client,\n name=\"User Group with Explicit Roles\",\n color=UserGroupColor.GREEN,\n description=\"This is a user group with explicit roles\",\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_with_roles = user_group_with_roles.create()", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# Define a user group\n", + "user_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\n", + "created_group = user_group.create()" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Update user groups" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "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# Add new users to the group (legacy approach)\n# user_group.default_role = roles[\"REVIEWER\"]\n# user_group.users.add(new_user) # Add individual user\n# user_group.users.update({new_user_1, new_user_2}) # Add multiple users\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", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# Update the user group properties\n", + "user_group.name = \"Updated User Group Name\"\n", + "user_group.color = UserGroupColor.GREEN\n", + "user_group.description = \"Updated description\"\n", + "\n", + "# Add new projects to the group (assuming you have additional projects)\n", + "user_group.projects.add(project_1) # Add individual projects\n", + "user_group.projects.update({project_2, project_3}) # Add multiple projects\n", + "\n", + "# OR add new members with explicit roles (V3 approach)\n", + "user_group.members.add(UserGroupMember(user=new_user, role=roles[\"REVIEWER\"]))\n", + "user_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\n", + "user_group.update()" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### 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", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "## Remove all members and projects from the group\n", + "user_group.users = set() # Clear users (Set, not list)\n", + "user_group.members = set() # Clear members (Set, not list)\n", + "user_group.projects = set() # Clear projects (Set, not list)\n", + "\n", + "# Push the changes to the group\n", + "user_group.update()" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "### Delete user group" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "# Delete a user group\nuser_group.delete()", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# Delete a user group\n", + "user_group.delete()" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "## Get user group info" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "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", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "# Get info of a user group\n", + "user_group.get()\n", + "\n", + "# Get all user groups in your workspace\n", + "user_groups = UserGroup.get_user_groups(client)\n", + "\n", + "# Search for a user group by its name\n", + "group_name = \"example_name\"\n", + "example_group = next(\n", + " (group for group in user_groups if group.name == group_name), None)\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\")" + ] }, { + "cell_type": "markdown", "metadata": {}, "source": [ "## Cleanup\n", "Delete the project if you no longer need it:" - ], - "cell_type": "markdown" + ] }, { - "metadata": {}, - "source": "project.delete()", "cell_type": "code", + "execution_count": null, + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "project.delete()" + ] } - ] -} \ No newline at end of file + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From e0bdaa7eda0628adda0a8a9c02c540776b57d49b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 16 Jun 2025 22:07:48 +0000 Subject: [PATCH 5/5] :art: Cleaned --- basics/user_management.ipynb | 338 ++++++++++------------------------- 1 file changed, 99 insertions(+), 239 deletions(-) diff --git a/basics/user_management.ipynb b/basics/user_management.ipynb index f245fa3..b704a3f 100644 --- a/basics/user_management.ipynb +++ b/basics/user_management.ipynb @@ -1,16 +1,18 @@ { + "nbformat": 4, + "nbformat_minor": 5, + "metadata": {}, "cells": [ { - "cell_type": "markdown", "metadata": {}, "source": [ - "\n", - " \n", + "", + " ", "\n" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "markdown", "metadata": {}, "source": [ "\n", @@ -22,10 +24,10 @@ "\n", "" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "markdown", "metadata": {}, "source": [ "# User Management\n", @@ -36,403 +38,261 @@ " * assign users to projects\n", " * set / update / revoke project role\n", " * delete users from org" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "%pip install \"labelbox[data]\"", + "cell_type": "code", "outputs": [], - "source": [ - "%pip install \"labelbox[data]\"" - ] + "execution_count": null }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "import labelbox as lb", + "cell_type": "code", "outputs": [], - "source": [ - "import labelbox as lb" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "# API Key and Client\n", "Provide a valid api key below in order to properly connect to the Labelbox Client." - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# Add your api key\nAPI_KEY = None\nclient = lb.Client(api_key=API_KEY)\norganization = client.get_organization()", + "cell_type": "code", "outputs": [], - "source": [ - "# Add your api key\n", - "API_KEY = None\n", - "client = lb.Client(api_key=API_KEY)\n", - "organization = client.get_organization()" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "## Roles\n", "* When inviting a new user to an organization, there are various roles to select from.\n", "* All available roles to your org can be accessed via `client.get_roles()`" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "roles = client.get_roles()\nfor name, role in roles.items():\n print(role.name, \":\", role.uid)", + "cell_type": "code", "outputs": [], - "source": [ - "roles = client.get_roles()\n", - "for name, role in roles.items():\n", - " print(role.name, \":\", role.uid)" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "* Above we printed out all of the roles available to the current org.\n", "* Notice the `NONE`. That is for project level roles" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "markdown", "metadata": {}, "source": [ "## Create\n", "* Users are created by sending an invite\n", "* An email will be sent to them and they will be asked to join your organization" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Organization Level Permissions\n", "* Invite a new labeler with labeling permissions on all projects" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# First make sure that you have enough seats:\norganization.invite_limit()", + "cell_type": "code", "outputs": [], - "source": [ - "# First make sure that you have enough seats:\n", - "organization.invite_limit()" - ] + "execution_count": null }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "USER_EMAIL = \"\"\ninvite = organization.invite_user(USER_EMAIL, roles[\"LABELER\"])", + "cell_type": "code", "outputs": [], - "source": [ - "USER_EMAIL = \"\"\n", - "invite = organization.invite_user(USER_EMAIL, roles[\"LABELER\"])" - ] + "execution_count": null }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "print(invite.created_at)\nprint(invite.organization_role_name)\nprint(invite.email)", + "cell_type": "code", "outputs": [], - "source": [ - "print(invite.created_at)\n", - "print(invite.organization_role_name)\n", - "print(invite.email)" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Project Level Permissions\n", "* Invite a new labeler with labeling permissions specific to a set of projects\n", "* Here we set organization level permissions to Roles.NONE to indicate that the user only has project level permissions" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "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": [], - "source": [ - "USER_EMAIL = \"\"\n", - "project = client.create_project(name=\"test_user_management\",\n", - " media_type=lb.MediaType.Image)\n", - "project_role = lb.ProjectRole(project=project, role=roles[\"REVIEWER\"])\n", - "invite = organization.invite_user(USER_EMAIL,\n", - " roles[\"NONE\"],\n", - " project_roles=[project_role])" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "## Read\n", "* Outstanding invites cannot be queried for at this time. This information can be found in the members tab of the web app.\n", "* You are able to query for members once they have joined." - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "users = list(organization.users())\nprint(users[0])", + "cell_type": "code", "outputs": [], - "source": [ - "users = list(organization.users())\n", - "print(users[0])" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "## Update\n", "* There is no update on invites. Instead you must delete and resend them\n", "* You can update User roles" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "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": [], - "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())" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "## Delete\n", "You can remove users from projects and your organization using the SDK. Invites can only be deleted using the **Members** tab on the web platform at this moment." - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "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": [], - "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)" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "## Manage user groups" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, - "id": "8576348c", "metadata": {}, + "source": "# Prerequisites for user group management\nfrom labelbox.schema.user_group import (\n UserGroup,\n UserGroupColor,\n UserGroupMember,\n)", + "cell_type": "code", "outputs": [], - "source": [ - "# Prerequisites for user group management\n", - "from labelbox.schema.user_group import (\n", - " UserGroup,\n", - " UserGroupColor,\n", - " UserGroupMember,\n", - ")" - ] + "execution_count": null }, { - "cell_type": "markdown", - "id": "e9dfaba7", "metadata": {}, "source": [ "### Create user groups" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "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": [], - "source": [ - "# Define a user group\n", - "user_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\n", - "created_group = user_group.create()" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Update user groups" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "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": [], - "source": [ - "# Update the user group properties\n", - "user_group.name = \"Updated User Group Name\"\n", - "user_group.color = UserGroupColor.GREEN\n", - "user_group.description = \"Updated description\"\n", - "\n", - "# Add new projects to the group (assuming you have additional projects)\n", - "user_group.projects.add(project_1) # Add individual projects\n", - "user_group.projects.update({project_2, project_3}) # Add multiple projects\n", - "\n", - "# OR add new members with explicit roles (V3 approach)\n", - "user_group.members.add(UserGroupMember(user=new_user, role=roles[\"REVIEWER\"]))\n", - "user_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\n", - "user_group.update()" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Reset user group" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "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": [], - "source": [ - "## Remove all members and projects from the group\n", - "user_group.users = set() # Clear users (Set, not list)\n", - "user_group.members = set() # Clear members (Set, not list)\n", - "user_group.projects = set() # Clear projects (Set, not list)\n", - "\n", - "# Push the changes to the group\n", - "user_group.update()" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "### Delete user group" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "# Delete a user group\nuser_group.delete()", + "cell_type": "code", "outputs": [], - "source": [ - "# Delete a user group\n", - "user_group.delete()" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "## Get user group info" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "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": [], - "source": [ - "# Get info of a user group\n", - "user_group.get()\n", - "\n", - "# Get all user groups in your workspace\n", - "user_groups = UserGroup.get_user_groups(client)\n", - "\n", - "# Search for a user group by its name\n", - "group_name = \"example_name\"\n", - "example_group = next(\n", - " (group for group in user_groups if group.name == group_name), None)\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\")" - ] + "execution_count": null }, { - "cell_type": "markdown", "metadata": {}, "source": [ "## Cleanup\n", "Delete the project if you no longer need it:" - ] + ], + "cell_type": "markdown" }, { - "cell_type": "code", - "execution_count": null, "metadata": {}, + "source": "project.delete()", + "cell_type": "code", "outputs": [], - "source": [ - "project.delete()" - ] + "execution_count": null } - ], - "metadata": { - "language_info": { - "name": "python" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} + ] +} \ No newline at end of file