{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Workspace API Client quickstart guide\n",
    "\n",
    "`evo.workspaces.WorkspaceAPIClient` facilitates communication with the Workspace API. The first step is to set up the Authorizer and the APIConnector required for the SDK setup. For more information, take a look at the  `quickstart.ipynb` and `oauth.ipynb` examples."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from evo.aio import AioTransport\n",
    "from evo.oauth import AuthorizationCodeAuthorizer, EvoScopes, OAuthConnector\n",
    "\n",
    "# OAuth client app credentials\n",
    "# See: https://developer.seequent.com/docs/guides/getting-started/apps-and-tokens\n",
    "REDIRECT_URL = \"http://localhost:3000/signin-callback\"\n",
    "CLIENT_NAME = \"Your Client Name\"\n",
    "CLIENT_ID = \"your-client-id\"\n",
    "\n",
    "transport = AioTransport(\n",
    "    user_agent=CLIENT_NAME,\n",
    ")\n",
    "\n",
    "connector = OAuthConnector(\n",
    "    transport=transport,\n",
    "    client_id=CLIENT_ID,\n",
    ")\n",
    "\n",
    "authorizer = AuthorizationCodeAuthorizer(\n",
    "    oauth_connector=connector,\n",
    "    redirect_url=REDIRECT_URL,\n",
    "    scopes=EvoScopes.all_evo | EvoScopes.offline_access,\n",
    ")\n",
    "\n",
    "# Login to the Evo platform.\n",
    "await authorizer.login()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## WorkspaceAPIClient\n",
    "\n",
    "Now that the `authorizer` is set up, we can set up the `WorkspaceServiceClient`. This client wraps endpoint functionality to provide a cohesive interface to the underlying API client implementation.\n",
    "\n",
    "For initialization the client requires:\n",
    "* The organization ID since all workspace service operations are currently bound by this ID.\n",
    "* The hub URL to connect to the workspace service."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import uuid\n",
    "\n",
    "from evo.common import APIConnector\n",
    "from evo.workspaces import WorkspaceAPIClient\n",
    "\n",
    "# See \"quickstart.ipynb\" for assistance in obtaining your organization ID and hub URL\n",
    "ORG_ID = uuid.UUID(\"<ORG_ID>\")\n",
    "HUB_URL = \"https://your-hub-url\"\n",
    "\n",
    "workspace_client = WorkspaceAPIClient(\n",
    "    connector=APIConnector(HUB_URL, transport, authorizer),\n",
    "    org_id=ORG_ID,\n",
    ")\n",
    "\n",
    "service_health = await workspace_client.get_service_health()\n",
    "\n",
    "print(f\"Workspace API is {service_health.status.name.lower()}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Workspace operations\n",
    "In this section we will go over some of the available workspace operations.\n",
    "\n",
    "### Listing workspaces\n",
    "To list the workspaces you can either use `WorkspaceAPIClient.list_workspaces()` method:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from evo.common import Page\n",
    "from evo.workspaces import Workspace\n",
    "\n",
    "paginated_workspaces: Page[Workspace] = await workspace_client.list_workspaces(limit=5, offset=0)\n",
    "for item in paginated_workspaces.items():\n",
    "    print(item)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `list_workspaces` will return a `evo.common.Page` object that encapsulates the paginated response by the Workspace Service.\n",
    "Alternatively, you can list all workspaces available to the given user by calling the `WorkspaceServiceClient.list_all_workspaces()` method:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "all_workspaces: list[Workspace] = await workspace_client.list_all_workspaces()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Both `list_workspaces` and `list_all_workspaces` support all the query parameters supported by the workspace service's [List Workspaces](https://developer.seequent.com/docs/api/workspaces/list-workspaces) endpoint:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "workspaces = await workspace_client.list_workspaces(\n",
    "    limit=5,\n",
    "    offset=0,\n",
    "    deleted=False,\n",
    "    order_by={\"name\": \"asc\"},\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Creating a workspace"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "new_workspace: Workspace = await workspace_client.create_workspace(\n",
    "    name=\"My New Workspace\",\n",
    "    description=\"This is a new workspace\",\n",
    "    bounding_box_coordinates=[\n",
    "        (85.8287, -90.0),\n",
    "        (85.8287, 69.84278),\n",
    "        (-180.0, 69.84278),\n",
    "        (-180.0, -90.0),\n",
    "        (85.8287, -90.0),\n",
    "    ],\n",
    "    # A square bounding box. It is important to mention that the first and last coordinates must be the same.\n",
    "    # Also, the first coordinate element must be the longitude and the second element must be the latitude.\n",
    ")\n",
    "print(new_workspace)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Updating a workspace"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "updated_workspace: Workspace = await workspace_client.update_workspace(\n",
    "    workspace_id=new_workspace.id,\n",
    "    name=\"My Updated Workspace\",\n",
    "    description=\"This is an updated workspace\",\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Deleting a workspace"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "await workspace_client.delete_workspace(workspace_id=new_workspace.id)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Users operation\n",
    "\n",
    "In this section we will go over some of the available user related operations.\n",
    "\n",
    "### Get current user's workspace role"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from evo.workspaces import User, UserRole\n",
    "\n",
    "user_role: UserRole = await workspace_client.get_current_user_role(workspace_id=new_workspace.id)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Get list of users with access to a workspace."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "users: list[User] = await workspace_client.list_user_roles(workspace_id=new_workspace.id)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Assign a user to a workspace"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from evo.workspaces import WorkspaceRole\n",
    "\n",
    "new_users_role: UserRole = await workspace_client.assign_user_role(\n",
    "    workspace_id=new_workspace.id, user_id=uuid.UUID(\"<some-user-id>\"), role=WorkspaceRole.viewer\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Remove a user from a workspace"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "await workspace_client.delete_user_role(\n",
    "    workspace_id=new_workspace.id,\n",
    "    user_id=uuid.UUID(\"<some-user-id>\"),\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Instance user operations\n",
    "\n",
    "In this section we show the various endpoints that can be used to manage instance users"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### List instance users"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "instance_users = await workspace_client.list_instance_users()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Add user to instance"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from evo.workspaces import AddedInstanceUsers\n",
    "\n",
    "email = \"<user_email>\"\n",
    "role_ids = [uuid.UUID(\"<role-id-1>\"), uuid.UUID(\"<role-id-2>\")]\n",
    "users = {email: role_ids}\n",
    "added_users: AddedInstanceUsers = await workspace_client.add_users_to_instance(users)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### List instance user invitations"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "invitations = await workspace_client.list_instance_user_invitations()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Delete instance user invitation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "invitation_id = uuid.UUID(\"<invitation-id>\")\n",
    "\n",
    "await workspace_client.delete_instance_user_invitation(invitation_id=invitation_id)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### List instance user roles"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from evo.workspaces import InstanceRoleWithPermissions\n",
    "\n",
    "roles: list[InstanceRoleWithPermissions] = await workspace_client.list_instance_roles()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Remove instance user"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "user_id = uuid.UUID(\"<user-id>\")\n",
    "\n",
    "await workspace_client.remove_instance_user(user_id=user_id)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Update instance user roles"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from evo.workspaces import InstanceUser\n",
    "\n",
    "user_id = uuid.UUID(\"<user-id>\")\n",
    "roles = [uuid.UUID(\"<role-id>\")]\n",
    "\n",
    "updated_user: InstanceUser = await workspace_client.update_instance_user_roles(user_id=user_id, roles=roles)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "eps",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
