Skip to content

Instantly share code, notes, and snippets.

@randyphoa
Created June 7, 2022 06:43
Show Gist options
  • Save randyphoa/d5ad98cbd04b3f8c722ce1b2f09702cf to your computer and use it in GitHub Desktop.
Save randyphoa/d5ad98cbd04b3f8c722ce1b2f09702cf to your computer and use it in GitHub Desktop.
Deploy R in online mode - complete example notebook
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'SUCCESS'"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import requests\n",
"import ibm_watson_machine_learning\n",
"\n",
"SPACE_ID = \"4a9d3d67-8208-4564-a78f-bebdebf864f8\"\n",
"API_KEY = \"xxx\"\n",
"CPD_URL = \"https://cpd-cpd.itzroks-550003aw18-72fhj7-6ccd7f378ae819553d37d5f2ee142bd6-0000.au-syd.containers.appdomain.cloud\"\n",
"wml_credentials = {\n",
" \"username\": \"admin\",\n",
" \"apikey\": API_KEY,\n",
" \"url\": CPD_URL,\n",
" \"instance_id\": \"openshift\",\n",
" \"version\": \"4.0\",\n",
"}\n",
"wml_client = ibm_watson_machine_learning.APIClient(wml_credentials)\n",
"wml_client.set.default_space(SPACE_ID)"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Creating package extensions\n",
"SUCCESS\n",
"SUCCESS\n"
]
},
{
"data": {
"text/plain": [
"'SUCCESS'"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"config_yaml = \"\"\"\n",
"name: custom\n",
"channels:\n",
" - conda-forge\n",
"dependencies:\n",
" - r\n",
" - libiconv\n",
"\"\"\"\n",
"with open(\"config.yaml\", \"w\", encoding=\"utf-8\") as f:\n",
" f.write(config_yaml)\n",
"\n",
"# create a custom software specification\n",
"# note, you can also create a custom software specificaton using the user interface from Watson Machine Learning.\n",
"\n",
"software_spec_uid = wml_client.software_specifications.get_uid_by_name(\"custom-r\")\n",
"if software_spec_uid != \"Not Found\":\n",
" software_spec_details = wml_client.software_specifications.get_details(software_spec_uid)\n",
" package_ext_uid = software_spec_details[\"entity\"][\"software_specification\"][\"package_extensions\"][0][\"metadata\"][\"asset_id\"]\n",
" wml_client.package_extensions.delete(package_ext_uid)\n",
" wml_client.software_specifications.delete(software_spec_uid)\n",
"\n",
"meta_props = {wml_client.package_extensions.ConfigurationMetaNames.NAME: \"custom-r\", wml_client.package_extensions.ConfigurationMetaNames.TYPE: \"conda_yml\"}\n",
"package_ext_details = wml_client.package_extensions.store(meta_props=meta_props, file_path=\"config.yaml\")\n",
"package_ext_uid = wml_client.package_extensions.get_uid(package_ext_details)\n",
"meta_props = {\n",
" wml_client.software_specifications.ConfigurationMetaNames.NAME: \"custom-r\",\n",
" wml_client.software_specifications.ConfigurationMetaNames.BASE_SOFTWARE_SPECIFICATION: {\"guid\": wml_client.software_specifications.get_uid_by_name(\"runtime-22.1-py3.9\")},\n",
"}\n",
"software_spec_details = wml_client.software_specifications.store(meta_props=meta_props)\n",
"software_spec_uid = wml_client.software_specifications.get_uid(software_spec_details)\n",
"wml_client.software_specifications.add_package_extension(software_spec_uid, package_ext_uid)\n"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\n",
"#######################################################################################\n",
"\n",
"Synchronous deployment creation for uid: '7981d407-f0a9-42c4-9d42-d5c71534ee6b' started\n",
"\n",
"#######################################################################################\n",
"\n",
"\n",
"initializing\n",
"Note: online_url is deprecated and will be removed in a future release. Use serving_urls instead.\n",
"...........................................................................................................................\n",
"ready\n",
"\n",
"\n",
"------------------------------------------------------------------------------------------------\n",
"Successfully finished deployment creation, deployment_uid='d5e98822-5461-4397-b067-8f033f0d8e10'\n",
"------------------------------------------------------------------------------------------------\n",
"\n",
"\n"
]
},
{
"data": {
"text/plain": [
"{'entity': {'asset': {'id': '7981d407-f0a9-42c4-9d42-d5c71534ee6b'},\n",
" 'custom': {},\n",
" 'deployed_asset_type': 'function',\n",
" 'hardware_spec': {'id': 'b128f957-581d-46d0-95b6-8af5cd5be580',\n",
" 'name': 'XXS',\n",
" 'num_nodes': 1},\n",
" 'name': 'iris xgb deployment',\n",
" 'online': {},\n",
" 'space_id': '4a9d3d67-8208-4564-a78f-bebdebf864f8',\n",
" 'status': {'online_url': {'url': 'https://cpd-cpd.itzroks-550003aw18-72fhj7-6ccd7f378ae819553d37d5f2ee142bd6-0000.au-syd.containers.appdomain.cloud/ml/v4/deployments/d5e98822-5461-4397-b067-8f033f0d8e10/predictions'},\n",
" 'serving_urls': ['https://cpd-cpd.itzroks-550003aw18-72fhj7-6ccd7f378ae819553d37d5f2ee142bd6-0000.au-syd.containers.appdomain.cloud/ml/v4/deployments/d5e98822-5461-4397-b067-8f033f0d8e10/predictions'],\n",
" 'state': 'ready'}},\n",
" 'metadata': {'created_at': '2022-06-07T05:02:45.598Z',\n",
" 'id': 'd5e98822-5461-4397-b067-8f033f0d8e10',\n",
" 'modified_at': '2022-06-07T05:02:45.598Z',\n",
" 'name': 'iris xgb deployment',\n",
" 'owner': '1000330999',\n",
" 'space_id': '4a9d3d67-8208-4564-a78f-bebdebf864f8'},\n",
" 'system': {'warnings': [{'id': 'Deprecated',\n",
" 'message': 'online_url is deprecated and will be removed in a future release. Use serving_urls instead.'}]}}"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"params = {\n",
" \"wml_credentials\": wml_credentials, \n",
" \"space_id\": SPACE_ID,\n",
" \"script\": \"predict.R\",\n",
" \"required_assets\": [\"iris_xgb.model\"],\n",
" \"r_packages\": [\"jsonlite\", \"xgboost\"],\n",
"}\n",
"\n",
"def r_function(params=params):\n",
" \"\"\"\n",
" Deployable Python function which downloads the required assets from a WML deployment space and runs the specified R Script.\n",
" \"\"\"\n",
" import json\n",
" import subprocess\n",
" from ibm_watson_machine_learning import APIClient\n",
"\n",
" wml_client = APIClient(params[\"wml_credentials\"])\n",
" wml_client.set.default_space(params[\"space_id\"])\n",
" script = params[\"script\"]\n",
" assets = {x[\"metadata\"][\"name\"]: x[\"metadata\"][\"asset_id\"] for x in wml_client.data_assets.get_details()[\"resources\"]}\n",
"\n",
" # download required assets\n",
" wml_client.data_assets.download(assets[script], script)\n",
" for x in params[\"required_assets\"]:\n",
" wml_client.data_assets.download(assets[x], x)\n",
" \n",
" # install R and other libraries\n",
" subprocess.run([\"Rscript\", \"-e\", 'install.packages(c(\"jsonlite\", \"data.table\", \"stringi\", \"stringr\"), repos=\"https://cloud.r-project.org\")'])\n",
" if \"xgboost\" in params[\"r_packages\"]:\n",
" params[\"r_packages\"].remove(\"xgboost\")\n",
" subprocess.run([\"Rscript\", \"-e\", 'install.packages(\"https://cloud.r-project.org/src/contrib/Archive/xgboost/xgboost_1.5.2.1.tar.gz\", repos=NULL, type=\"source\")'])\n",
" subprocess.run([\"Rscript\", \"-e\", 'install.packages(c(' + \",\".join([f'\"{x}\"' for x in params[\"r_packages\"]]) + '), repos=\"https://cloud.r-project.org\")'])\n",
"\n",
" def score(payload):\n",
" d = payload[\"input_data\"][0][\"values\"][0]\n",
" inputs = d[\"inputs\"]\n",
" inputs = json.dumps(inputs)\n",
" result = subprocess.run([\"Rscript\", \"--vanilla\", script, inputs], stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n",
" out = result.stdout.decode(\"utf-8\")\n",
" try:\n",
" out = json.loads(out)\n",
" except:\n",
" out = result.stdout.decode(\"utf-8\")\n",
" err = result.stderr.decode(\"utf-8\") \n",
" return {\"predictions\": [{\"out\": out, \"err\": err}]}\n",
"\n",
" return score\n",
"\n",
"meta_props = {\n",
" wml_client.repository.FunctionMetaNames.NAME: \"iris xgb\",\n",
" wml_client.repository.FunctionMetaNames.SOFTWARE_SPEC_ID: wml_client.software_specifications.get_uid_by_name(\"custom-r\"),\n",
"}\n",
"function_details = wml_client.repository.store_function(function=r_function, meta_props=meta_props)\n",
"function_uid = wml_client.repository.get_function_id(function_details)\n",
"meta_props = {\n",
" wml_client.deployments.ConfigurationMetaNames.NAME: \"iris xgb deployment\",\n",
" wml_client.deployments.ConfigurationMetaNames.ONLINE: {},\n",
"}\n",
"wml_client.deployments.create(function_uid, meta_props=meta_props)\n"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[{'setosa': 0.3561,\n",
" 'versicolor': 0.3218,\n",
" 'virginica': 0.3221,\n",
" 'probability': 0.3561,\n",
" 'prediction': 'setosa'},\n",
" {'setosa': 0.3561,\n",
" 'versicolor': 0.3218,\n",
" 'virginica': 0.3221,\n",
" 'probability': 0.3561,\n",
" 'prediction': 'setosa'},\n",
" {'setosa': 0.3561,\n",
" 'versicolor': 0.3218,\n",
" 'virginica': 0.3221,\n",
" 'probability': 0.3561,\n",
" 'prediction': 'setosa'}]"
]
},
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"endpoint = \"https://cpd-cpd.itzroks-550003aw18-72fhj7-6ccd7f378ae819553d37d5f2ee142bd6-0000.au-syd.containers.appdomain.cloud/ml/v4/deployments/d5e98822-5461-4397-b067-8f033f0d8e10/predictions?version=2022-06-07\"\n",
"\n",
"inputs = [\n",
" {\"Sepal.Length\": 5.1, \"Sepal.Width\": 3.5, \"Petal.Length\": 1.4, \"Petal.Width\": 0.2},\n",
" {\"Sepal.Length\": 4.9, \"Sepal.Width\": 3.1, \"Petal.Length\": 1.4, \"Petal.Width\": 0.2},\n",
" {\"Sepal.Length\": 5.3, \"Sepal.Width\": 6.1, \"Petal.Length\": 1.4, \"Petal.Width\": 0.2},\n",
"]\n",
"\n",
"payload = {\"input_data\": [{\"values\": [{\"inputs\": inputs}]}]}\n",
"headers = {\"Content-Type\": \"application/json\", \"Accept\": \"application/json\", \"Authorization\": wml_client._get_headers()[\"Authorization\"]}\n",
"\n",
"response = requests.post(url=endpoint, headers=headers,json=payload, verify=False).json()\n",
"response[\"predictions\"][0][\"out\"]\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"interpreter": {
"hash": "2fd8ffa6155755da6e46d79320aeff097111fde3e362ae0d899ff1703ff23477"
},
"kernelspec": {
"display_name": "Python 3.10.4 ('ml')",
"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.10.4"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment