From 1f3563ffec023dfdd19d32259da36881804f2589 Mon Sep 17 00:00:00 2001 From: simonliu Date: Mon, 28 Nov 2022 09:06:33 +0000 Subject: [PATCH] Add end-user journey and insight --- docs/screenplay/e2e-journey-operation.ipynb | 1060 +++++++++++++++++++ docs/screenplay/insight-operation.ipynb | 291 +++++ 2 files changed, 1351 insertions(+) create mode 100644 docs/screenplay/e2e-journey-operation.ipynb create mode 100644 docs/screenplay/insight-operation.ipynb diff --git a/docs/screenplay/e2e-journey-operation.ipynb b/docs/screenplay/e2e-journey-operation.ipynb new file mode 100644 index 0000000..55bec23 --- /dev/null +++ b/docs/screenplay/e2e-journey-operation.ipynb @@ -0,0 +1,1060 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "4f77e0ee", + "metadata": {}, + "source": [ + "# Getting Started with PrimeHub Python SDK\n", + "PrimeHub Python SDK makes you automation with PrimeHub Platform.\n", + "\n", + "In order to make the SDK working, you have to\n", + "\n", + "- install the library with pip\n", + "- create a config file in the ~/.primehub/config.json" + ] + }, + { + "cell_type": "markdown", + "id": "4604b5a2", + "metadata": {}, + "source": [ + "# Part 1: prerequisite: Configure the environment." + ] + }, + { + "cell_type": "markdown", + "id": "6299410e", + "metadata": {}, + "source": [ + "## 1. Install with pip\n", + "Let's install PrimeHub Python SDK with pip." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "907df9ff", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: primehub-python-sdk in /opt/conda/lib/python3.7/site-packages (0.3.8)\n", + "Requirement already satisfied: tabulate==0.8.9 in /opt/conda/lib/python3.7/site-packages (from primehub-python-sdk) (0.8.9)\n", + "Requirement already satisfied: types-tabulate==0.8.2 in /opt/conda/lib/python3.7/site-packages (from primehub-python-sdk) (0.8.2)\n", + "Requirement already satisfied: types-requests in /opt/conda/lib/python3.7/site-packages (from primehub-python-sdk) (2.28.11.5)\n", + "Requirement already satisfied: requests in /opt/conda/lib/python3.7/site-packages (from primehub-python-sdk) (2.27.1)\n", + "Requirement already satisfied: idna<4,>=2.5 in /opt/conda/lib/python3.7/site-packages (from requests->primehub-python-sdk) (3.3)\n", + "Requirement already satisfied: charset-normalizer~=2.0.0 in /opt/conda/lib/python3.7/site-packages (from requests->primehub-python-sdk) (2.0.12)\n", + "Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/lib/python3.7/site-packages (from requests->primehub-python-sdk) (2020.6.20)\n", + "Requirement already satisfied: urllib3<1.27,>=1.21.1 in /opt/conda/lib/python3.7/site-packages (from requests->primehub-python-sdk) (1.26.9)\n", + "Requirement already satisfied: types-urllib3<1.27 in /opt/conda/lib/python3.7/site-packages (from types-requests->primehub-python-sdk) (1.26.25.4)\n" + ] + } + ], + "source": [ + "!pip install primehub-python-sdk" + ] + }, + { + "cell_type": "markdown", + "id": "6f1cb62e", + "metadata": {}, + "source": [ + "## 2. Request the API Token\n", + "In order to get the token, you have to have an account in the PrimeHub cluster, the following process will ask you loing with your account.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "2c6b24ab", + "metadata": {}, + "outputs": [], + "source": [ + "# PLEASE UPDATE PRIMEHUB_CLUSTER to your cluster\n", + "PRIMEHUB_CLUSTER = 'http://primehub-python-sdk.primehub.io'" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "eeb4218a", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "from primehub import PrimeHub, PrimeHubConfig\n", + "\n", + "ph = PrimeHub(PrimeHubConfig())\n", + "if not os.path.isfile(os.path.join(os.getenv(\"HOME\"), \".primehub/config.json\")):\n", + " ph.config.generate(PRIMEHUB_CLUSTER)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "04943d0e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "PrimeHub Python SDK setup successfully\n", + "Current Group: {'id': '11945641-279a-4042-8688-ef88769c21ca', 'name': 'demo_showcase', 'displayName': 'demo_showcase'}\n" + ] + } + ], + "source": [ + "ph = PrimeHub(PrimeHubConfig())\n", + "if ph.is_ready():\n", + " print(\"PrimeHub Python SDK setup successfully\")\n", + " print(\"Current Group:\", ph.primehub_config.current_group)\n", + "else:\n", + " print(\"PrimeHub Python SDK couldn't get the group information, please check the configuration.\")" + ] + }, + { + "cell_type": "markdown", + "id": "75a015ef", + "metadata": {}, + "source": [ + "## 3. Check the account is Admin account\n", + "\n", + "Use `ph.me.me` to know that the account is admin account." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "98c6e517", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "account_information = ph.me.me()\n", + "account_information['isAdmin']" + ] + }, + { + "cell_type": "markdown", + "id": "87d72f53", + "metadata": {}, + "source": [ + "## 4. Clean up the previous testing data.\n", + "\n", + "We need to clean up the previous data to prevent the notebook error," + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "a2c205c5", + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd" + ] + }, + { + "cell_type": "markdown", + "id": "28ca4583", + "metadata": {}, + "source": [ + "# Part 2: End-User Journey or End2End ML Journey\n", + "We will test:\n", + "\n", + "- Submit a Job/schedule job\n", + "- List running jobs(status) submitted by the user\n", + "- List registered models with all of versions\n", + "- Submit a registered model as a deployment\n", + "- Update the deployment with other version of the model" + ] + }, + { + "cell_type": "markdown", + "id": "9ba000a8", + "metadata": {}, + "source": [ + "### 1. Submit a Job/schedule job" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "2f02cbf7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'id': 'job-202211280818-5ojjpm', 'displayName': 'short-job', 'cancel': False, 'command': 'echo \"test1\"\\necho \"test2\"', 'groupId': '11945641-279a-4042-8688-ef88769c21ca', 'groupName': 'demo_showcase', 'image': 'base-notebook', 'instanceType': {'id': 'cpu-1', 'name': 'cpu-1', 'displayName': 'CPU 1', 'cpuLimit': 1, 'memoryLimit': 2, 'gpuLimit': 0}, 'userId': '35985b6b-21c9-4362-902d-4d6bb89074bf', 'userName': 'simonliu@infuseai.io', 'phase': 'Pending', 'reason': None, 'message': None, 'createTime': '2022-11-28T08:18:18Z', 'startTime': None, 'finishTime': None, 'recurrence': None}\n", + "[ Waiting ]\n", + "[ Job Done ]\n", + "[ Job Logs ]\n", + "test1\n", + "test2\n", + "Artifacts: no artifact found\n", + "\n" + ] + } + ], + "source": [ + "# Submit a job\n", + "config = {\n", + " \"instanceType\": \"cpu-1\",\n", + " \"image\": \"base-notebook\",\n", + " \"displayName\": \"short-job\",\n", + " \"command\": \"echo \\\"test1\\\"\\necho \\\"test2\\\"\"\n", + "}\n", + "\n", + "short_job = ph.jobs.submit(config)\n", + "print(short_job)\n", + "\n", + "# Wait the job to be done\n", + "print('[ Waiting ]')\n", + "ph.jobs.wait(short_job['id'])\n", + "print('[ Job Done ]')\n", + "\n", + "# Get logs\n", + "logs = ph.jobs.logs(short_job['id'])\n", + "print('[ Job Logs ]')\n", + "for l in logs:\n", + " print(l.decode(\"utf-8\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "ec484cf1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'id': 'recurrence-9oybl9', 'displayName': 'test', 'recurrence': {'type': 'daily', 'cron': ''}, 'invalid': False, 'message': None, 'command': 'echo \"test!\"', 'groupId': '11945641-279a-4042-8688-ef88769c21ca', 'groupName': 'demo_showcase', 'image': 'base-notebook', 'instanceType': {'id': 'cpu-1', 'name': 'cpu-1', 'displayName': 'CPU 1', 'cpuLimit': 1, 'memoryLimit': 2, 'gpuLimit': 0}, 'userId': '35985b6b-21c9-4362-902d-4d6bb89074bf', 'userName': 'simonliu@infuseai.io', 'nextRunTime': None}\n" + ] + } + ], + "source": [ + "# Create a recurring job that runs at every 4 AM\n", + "config = {\n", + " \"instanceType\": \"cpu-1\",\n", + " \"image\": \"base-notebook\",\n", + " \"displayName\": \"test\",\n", + " \"command\": \"echo \\\"test!\\\"\",\n", + " \"recurrence\": {\n", + " \"type\":\"daily\",\n", + " \"cron\":\"\"\n", + " }\n", + "}\n", + "\n", + "recurring_job = ph.recurring_jobs.create(config)\n", + "print(recurring_job)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "4286e865", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
iddisplayNamerecurrenceinvalidmessagecommandgroupIdgroupNameimageinstanceTypeuserIduserNamenextRunTime
0recurrence-9oybl9test{'type': 'daily', 'cron': ''}FalseNoneecho \"test!\"11945641-279a-4042-8688-ef88769c21cademo_showcasebase-notebook{'id': 'cpu-1', 'name': 'cpu-1', 'displayName'...35985b6b-21c9-4362-902d-4d6bb89074bfsimonliu@infuseai.io2022-11-28T20:00:00Z
\n", + "
" + ], + "text/plain": [ + " id displayName recurrence invalid \\\n", + "0 recurrence-9oybl9 test {'type': 'daily', 'cron': ''} False \n", + "\n", + " message command groupId groupName \\\n", + "0 None echo \"test!\" 11945641-279a-4042-8688-ef88769c21ca demo_showcase \n", + "\n", + " image instanceType \\\n", + "0 base-notebook {'id': 'cpu-1', 'name': 'cpu-1', 'displayName'... \n", + "\n", + " userId userName \\\n", + "0 35985b6b-21c9-4362-902d-4d6bb89074bf simonliu@infuseai.io \n", + "\n", + " nextRunTime \n", + "0 2022-11-28T20:00:00Z " + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.DataFrame.from_records(list(ph.recurring_jobs.list()))\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "51b9df81", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'id': 'recurrence-9oybl9'}" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ph.recurring_jobs.delete(recurring_job['id'])" + ] + }, + { + "cell_type": "markdown", + "id": "c158195c", + "metadata": {}, + "source": [ + "### 2. List running jobs(status) submitted by the user\n" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "4324fe2c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
iddisplayNamecancelcommandgroupIdgroupNameimageinstanceTypeuserIduserNamephasereasonmessagecreateTimestartTimefinishTimerecurrence
0job-202211280835-c4lbkdshort-jobNoneecho \"test1\"\\necho \"test2\"11945641-279a-4042-8688-ef88769c21cademo_showcasebase-notebook{'id': 'cpu-1', 'name': 'cpu-1', 'displayName'...35985b6b-21c9-4362-902d-4d6bb89074bfsimonliu@infuseai.ioRunningPodRunningJob is currently running2022-11-28T08:35:27Z2022-11-28T08:35:32ZNoneNone
\n", + "
" + ], + "text/plain": [ + " id displayName cancel command \\\n", + "0 job-202211280835-c4lbkd short-job None echo \"test1\"\\necho \"test2\" \n", + "\n", + " groupId groupName image \\\n", + "0 11945641-279a-4042-8688-ef88769c21ca demo_showcase base-notebook \n", + "\n", + " instanceType \\\n", + "0 {'id': 'cpu-1', 'name': 'cpu-1', 'displayName'... \n", + "\n", + " userId userName phase \\\n", + "0 35985b6b-21c9-4362-902d-4d6bb89074bf simonliu@infuseai.io Running \n", + "\n", + " reason message createTime \\\n", + "0 PodRunning Job is currently running 2022-11-28T08:35:27Z \n", + "\n", + " startTime finishTime recurrence \n", + "0 2022-11-28T08:35:32Z None None " + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.DataFrame.from_records(list(ph.jobs.list()))\n", + "df[(df['phase']==\"Running\") & (df['userName']==\"simonliu@infuseai.io\")]" + ] + }, + { + "cell_type": "markdown", + "id": "82408add", + "metadata": {}, + "source": [ + "### 3. List registered models with all of versions\n" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "id": "e7c49418", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namecreationTimestamplastUpdatedTimestampdescriptionlatestVersion
0mnist2021-09-30 04:48:392021-09-30 05:15:16None2
1tf-screw-model2021-11-18 16:43:532022-01-17 04:01:03None1
2example2022-07-14 06:28:532022-07-14 06:28:54None1
3mask-detection-model2022-10-05 05:20:372022-11-14 06:50:29None4
\n", + "
" + ], + "text/plain": [ + " name creationTimestamp lastUpdatedTimestamp description \\\n", + "0 mnist 2021-09-30 04:48:39 2021-09-30 05:15:16 None \n", + "1 tf-screw-model 2021-11-18 16:43:53 2022-01-17 04:01:03 None \n", + "2 example 2022-07-14 06:28:53 2022-07-14 06:28:54 None \n", + "3 mask-detection-model 2022-10-05 05:20:37 2022-11-14 06:50:29 None \n", + "\n", + " latestVersion \n", + "0 2 \n", + "1 1 \n", + "2 1 \n", + "3 4 " + ] + }, + "execution_count": 73, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.DataFrame.from_records(ph.models.list())\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "id": "ab62447a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
nameversioncreationTimestamplastUpdatedTimestampdeployedBy
0mnist12021-09-30 04:48:392021-09-30 04:48:39[{'id': 'mnist-1209-a9wjo', 'name': 'mnist-120...
1mnist22021-09-30 05:15:162021-09-30 05:15:16[{'id': 'mnist-9ofpg', 'name': 'mnist'}]
\n", + "
" + ], + "text/plain": [ + " name version creationTimestamp lastUpdatedTimestamp \\\n", + "0 mnist 1 2021-09-30 04:48:39 2021-09-30 04:48:39 \n", + "1 mnist 2 2021-09-30 05:15:16 2021-09-30 05:15:16 \n", + "\n", + " deployedBy \n", + "0 [{'id': 'mnist-1209-a9wjo', 'name': 'mnist-120... \n", + "1 [{'id': 'mnist-9ofpg', 'name': 'mnist'}] " + ] + }, + "execution_count": 72, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.DataFrame.from_records(ph.models.list_versions('mnist'))\n", + "df" + ] + }, + { + "cell_type": "markdown", + "id": "3d617436", + "metadata": {}, + "source": [ + "### 4. Submit a registered model as a deployment\n" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "id": "b2894613", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'id': 'deploymeny-from-sdk-zxy', 'name': 'deploymeny-from-sdk', 'modelImage': 'base-notebook', 'imagePullSecret': None, 'description': None, 'replicas': 1, 'stop': False, 'endpointAccessType': 'public', 'endpointClients': [], 'status': 'Deploying', 'endpoint': None, 'availableReplicas': None, 'message': None, 'pods': []}\n" + ] + } + ], + "source": [ + "# Create a deployment\n", + "config = {\n", + " \"id\": \"deploymeny-from-sdk-zxy\",\n", + " \"name\": \"deploymeny-from-sdk\",\n", + " \"modelImage\": \"base-notebook\",\n", + " \"modelURI\": \"test/module/uri\",\n", + " \"instanceType\": \"cpu-1\",\n", + " \"replicas\": 1\n", + "}\n", + "\n", + "deployment = ph.deployments.create(config)\n", + "print(deployment)" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "id": "fd6cdd5f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idnamemodelImageimagePullSecretdescriptionreplicasstopendpointAccessTypeendpointClientsstatusendpointavailableReplicasmessagepods
0deploymeny-from-sdk-zxydeploymeny-from-sdkbase-notebookNoneNone1Falsepublic[]Deployinghttps://c.demo.primehub.io/deployment/deployme...NaNFailed because of wrong image settings.\\npod[d...[{'name': 'deploy-deploymeny-from-sdk-zxy-cf9b...
\n", + "
" + ], + "text/plain": [ + " id name modelImage \\\n", + "0 deploymeny-from-sdk-zxy deploymeny-from-sdk base-notebook \n", + "\n", + " imagePullSecret description replicas stop endpointAccessType \\\n", + "0 None None 1 False public \n", + "\n", + " endpointClients status \\\n", + "0 [] Deploying \n", + "\n", + " endpoint availableReplicas \\\n", + "0 https://c.demo.primehub.io/deployment/deployme... NaN \n", + "\n", + " message \\\n", + "0 Failed because of wrong image settings.\\npod[d... \n", + "\n", + " pods \n", + "0 [{'name': 'deploy-deploymeny-from-sdk-zxy-cf9b... " + ] + }, + "execution_count": 76, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.DataFrame.from_records(ph.deployments.list())\n", + "df[df['name'] == \"deploymeny-from-sdk\"]" + ] + }, + { + "cell_type": "markdown", + "id": "6843b2b1", + "metadata": {}, + "source": [ + "### 5. Update the deployment with other version of the model" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "id": "cfe67c0d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'id': 'deploymeny-from-sdk-zxy',\n", + " 'name': 'deploymeny-from-sdk',\n", + " 'modelImage': 'base-notebook',\n", + " 'imagePullSecret': None,\n", + " 'description': None,\n", + " 'replicas': 2,\n", + " 'stop': False,\n", + " 'endpointAccessType': 'public',\n", + " 'endpointClients': [],\n", + " 'status': 'Deploying',\n", + " 'endpoint': 'https://c.demo.primehub.io/deployment/deploymeny-from-sdk-zxy/api/v1.0/predictions',\n", + " 'availableReplicas': None,\n", + " 'message': 'Failed because of wrong image settings.\\npod[deploy-deploymeny-from-sdk-zxy-cf9b9bc6f-fmd7d] failed\\n reason: ContainersNotInitialized, message: containers with incomplete status: [model-storage-initializer]\\n container state: Waiting, reason: ImagePullBackOff, message Back-off pulling image \"gcr.io/kfserving/storage-initializer:v0.4.0\"',\n", + " 'pods': [{'name': 'deploy-deploymeny-from-sdk-zxy-cf9b9bc6f-fmd7d'}]}" + ] + }, + "execution_count": 77, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Update the deployment\n", + "update_config = {\n", + " \"replicas\": 2\n", + "}\n", + "\n", + "ph.deployments.update(deployment['id'], update_config)" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "id": "4e934562", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idnamemodelImageimagePullSecretdescriptionreplicasstopendpointAccessTypeendpointClientsstatusendpointavailableReplicasmessagepods
0deploymeny-from-sdk-zxydeploymeny-from-sdkbase-notebookNoneNone2Falsepublic[]Deployinghttps://c.demo.primehub.io/deployment/deployme...NaNFailed because of wrong image settings.\\npod[d...[{'name': 'deploy-deploymeny-from-sdk-zxy-cf9b...
\n", + "
" + ], + "text/plain": [ + " id name modelImage \\\n", + "0 deploymeny-from-sdk-zxy deploymeny-from-sdk base-notebook \n", + "\n", + " imagePullSecret description replicas stop endpointAccessType \\\n", + "0 None None 2 False public \n", + "\n", + " endpointClients status \\\n", + "0 [] Deploying \n", + "\n", + " endpoint availableReplicas \\\n", + "0 https://c.demo.primehub.io/deployment/deployme... NaN \n", + "\n", + " message \\\n", + "0 Failed because of wrong image settings.\\npod[d... \n", + "\n", + " pods \n", + "0 [{'name': 'deploy-deploymeny-from-sdk-zxy-cf9b... " + ] + }, + "execution_count": 78, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.DataFrame.from_records(ph.deployments.list())\n", + "df[df['name'] == \"deploymeny-from-sdk\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "id": "3ef611a1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'id': 'deploymeny-from-sdk-zxy'}" + ] + }, + "execution_count": 79, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Delete a deployment\n", + "ph.deployments.delete(deployment['id'])" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "id": "2f21afc6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idnamemodelImageimagePullSecretdescriptionreplicasstopendpointAccessTypeendpointClientsstatusendpointavailableReplicasmessagepods
\n", + "
" + ], + "text/plain": [ + "Empty DataFrame\n", + "Columns: [id, name, modelImage, imagePullSecret, description, replicas, stop, endpointAccessType, endpointClients, status, endpoint, availableReplicas, message, pods]\n", + "Index: []" + ] + }, + "execution_count": 80, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.DataFrame.from_records(ph.deployments.list())\n", + "df[df['name'] == \"deploymeny-from-sdk\"]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "13803df3", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.7.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/screenplay/insight-operation.ipynb b/docs/screenplay/insight-operation.ipynb new file mode 100644 index 0000000..bcc0d93 --- /dev/null +++ b/docs/screenplay/insight-operation.ipynb @@ -0,0 +1,291 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "721c2b0e", + "metadata": {}, + "source": [ + "In order to make the SDK working, you have to\n", + "\n", + "- install the library with pip\n", + "- create a config file in the ~/.primehub/config.json" + ] + }, + { + "cell_type": "markdown", + "id": "43754ebb", + "metadata": {}, + "source": [ + "# Part 1: prerequisite: Configure the environment." + ] + }, + { + "cell_type": "markdown", + "id": "9f960f00", + "metadata": {}, + "source": [ + "## 1. Install with pip\n", + "Let's install PrimeHub Python SDK with pip." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "00159582", + "metadata": {}, + "outputs": [], + "source": [ + "!pip install -q primehub-python-sdk" + ] + }, + { + "cell_type": "markdown", + "id": "bd8c43ab", + "metadata": {}, + "source": [ + "## 2. Request the API Token\n", + "In order to get the token, you have to have an account in the PrimeHub cluster, the following process will ask you loing with your account.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "bc0382a7", + "metadata": {}, + "outputs": [], + "source": [ + "# PLEASE UPDATE PRIMEHUB_CLUSTER to your cluster\n", + "PRIMEHUB_CLUSTER = 'http://primehub-python-sdk.primehub.io'" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "796d206c", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "from primehub import PrimeHub, PrimeHubConfig\n", + "\n", + "ph = PrimeHub(PrimeHubConfig())\n", + "if not os.path.isfile(os.path.join(os.getenv(\"HOME\"), \".primehub/config.json\")):\n", + " ph.config.generate(PRIMEHUB_CLUSTER)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "2e9fd865", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "PrimeHub Python SDK setup successfully\n", + "Current Group: {'id': '11945641-279a-4042-8688-ef88769c21ca', 'name': 'demo_showcase', 'displayName': 'demo_showcase'}\n" + ] + } + ], + "source": [ + "ph = PrimeHub(PrimeHubConfig())\n", + "if ph.is_ready():\n", + " print(\"PrimeHub Python SDK setup successfully\")\n", + " print(\"Current Group:\", ph.primehub_config.current_group)\n", + "else:\n", + " print(\"PrimeHub Python SDK couldn't get the group information, please check the configuration.\")" + ] + }, + { + "cell_type": "markdown", + "id": "15d83e19", + "metadata": {}, + "source": [ + "## 3. Check the account is Admin account\n", + "\n", + "Use `ph.me.me` to know that the account is admin account." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "afeb3b85", + "metadata": {}, + "outputs": [], + "source": [ + "account_information = ph.me.me()\n", + "account_information['isAdmin']" + ] + }, + { + "cell_type": "markdown", + "id": "5f8aa428", + "metadata": {}, + "source": [ + "# Part 2: Insight operation\n", + "We will test:\n", + " \n", + "- Get a user list of a group\n", + "- Get a group list\n", + "- Get a self-hosted image list (with size)\n", + "- To learn the summary of occupied resources by running Notebooks(user) & Jobs(user) & Deployments(user) & Apps(user) (of a group)" + ] + }, + { + "cell_type": "markdown", + "id": "a10f85c0", + "metadata": {}, + "source": [ + "## 1. Get a user list of a group" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1dfd6a6a", + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6031d352", + "metadata": {}, + "outputs": [], + "source": [ + "pd.DataFrame.from_records(list(ph.admin.groups.list()))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "88e91909", + "metadata": {}, + "outputs": [], + "source": [ + "pd.DataFrame.from_records(list(ph.admin.users.list()))" + ] + }, + { + "cell_type": "markdown", + "id": "1b36937d", + "metadata": {}, + "source": [ + "## 2. Get a group list" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6d4b852e", + "metadata": {}, + "outputs": [], + "source": [ + "pd.DataFrame.from_records(list(ph.admin.groups.list()))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4eef640b", + "metadata": {}, + "outputs": [], + "source": [ + "pd.DataFrame.from_records(list(ph.groups.list()))" + ] + }, + { + "cell_type": "markdown", + "id": "48a4543a", + "metadata": {}, + "source": [ + "### 3. Get a self-hosted image list" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1406dd20", + "metadata": {}, + "outputs": [], + "source": [ + "pd.DataFrame.from_records(list(ph.admin.images.list()))" + ] + }, + { + "cell_type": "markdown", + "id": "30ad5bfb", + "metadata": {}, + "source": [ + "### 4. To learn the summary of occupied resources by running Notebooks(user) & Jobs(user) & Deployments(user) & Apps(user) (of a group)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f4dbaa86", + "metadata": {}, + "outputs": [], + "source": [ + "df = pd.DataFrame.from_records(list(ph.jobs.list()))\n", + "df[df['userName'] == \"hlb@infuseai.io\"]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "502bdfb4", + "metadata": {}, + "outputs": [], + "source": [ + "df = pd.DataFrame.from_records(list(ph.deployments.list()))\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "177665a3", + "metadata": {}, + "outputs": [], + "source": [ + "df = pd.DataFrame.from_records(list(ph.apps.list()))\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0d213e0b", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.7.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}