{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Deploy a custom application with Pulumi\n",
    "\n",
    "<a class=\"md-button\" href=\"https://s3.amazonaws.com/datarobot-doc-assets/deploy-dr-app.ipynb\">Download this notebook</a>\n",
    "\n",
    "This notebook outlines how to use Pulumi to deploy a custom application."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Initialize the environment\n",
    "\n",
    "Start the environment and import the DataRobot library. Before proceeding, [download the necessary assets](https://datarobot-doc-assets.s3.us-east-1.amazonaws.com/deploy_custom_app.zip) to execute the tasks in this notebook."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import datarobot as dr\n",
    "\n",
    "os.environ['PULUMI_CONFIG_PASSPHRASE'] = 'default'\n",
    "\n",
    "assert 'DATAROBOT_API_TOKEN' in os.environ, 'Please set the DATAROBOT_API_TOKEN environment variable'\n",
    "assert 'DATAROBOT_ENDPOINT' in os.environ, 'Please set the DATAROBOT_ENDPOINT environment variable'\n",
    "\n",
    "dr.Client()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Set up a project\n",
    "\n",
    "Set up functions to create and build or destroy your Pulumi stack."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pulumi import automation as auto\n",
    "\n",
    "\n",
    "def stack_up(project_name: str, stack_name: str, program: callable) -> auto.Stack:\n",
    "    # create (or select if one already exists) a stack that uses our inline program\n",
    "    stack = auto.create_or_select_stack(\n",
    "        stack_name=stack_name, project_name=project_name, program=program\n",
    "    )\n",
    "\n",
    "    stack.refresh(on_output=print)\n",
    "\n",
    "    stack.up(on_output=print)\n",
    "    return stack\n",
    "\n",
    "\n",
    "def destroy_project(stack: auto.Stack):\n",
    "    \"\"\"Destroy pulumi project\"\"\"\n",
    "    stack_name = stack.name\n",
    "    stack.destroy(on_output=print)\n",
    "\n",
    "    stack.workspace.remove_stack(stack_name)\n",
    "    print(f\"stack {stack_name} in project removed\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create a declarative custom application deployment\n",
    "\n",
    "Use this cell to create a custom application deployment. Add your source code to DataRobot and then initialize the application. The `make_custom_application` function below shows how to declaratively do this. You'll see some variant of this across all application templates."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pulumi_datarobot as datarobot\n",
    "import pulumi\n",
    "\n",
    "\n",
    "def make_custom_application():\n",
    "    \"\"\"Make a custom app on DataRobot.\n",
    "\n",
    "    Upload source code to create source. Then initialize application.\n",
    "    \"\"\"\n",
    "\n",
    "    file_mapping = [\n",
    "        (\"frontend/app.py\", \"app.py\"),\n",
    "        (\"frontend/requirements.txt\", \"requirements.txt\"),\n",
    "        (\"frontend/start-app.sh\", \"start-app.sh\"),\n",
    "    ]\n",
    "\n",
    "    app_source = datarobot.ApplicationSource(\n",
    "        resource_name=\"App Template Minis - Custom App Source\",\n",
    "        files=file_mapping,\n",
    "        base_environment_id=\"6542cd582a9d3d51bf4ac71e\",  # Python 3.9 streamlit environment\n",
    "    )\n",
    "\n",
    "    app = datarobot.CustomApplication(\n",
    "        resource_name=\"App Template Minis - Custom App\",\n",
    "        source_version_id=app_source.version_id,\n",
    "    )\n",
    "    pulumi.export(\"Application Source Id\", app_source.id)\n",
    "    pulumi.export(\"Application Id\", app.id)\n",
    "    pulumi.export(\"Application Url\", app.application_url)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Run the Pulumi stack\n",
    "\n",
    "You can now run the Pulumi stack. Doing so takes the files in the `frontend` directory from the downloaded assets, puts them into DataRobot, and initializes the application."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "project_name = \"AppTemplateMinis-CustomApplications\"\n",
    "stack_name = \"MarshallsCustomApplicationDeployer\"\n",
    "\n",
    "stack = stack_up(project_name, stack_name, program=make_custom_application)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Interact with outputs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import webbrowser\n",
    "\n",
    "outputs = stack.outputs()\n",
    "app_url = outputs.get(\"Application Url\").value\n",
    "webbrowser.open(app_url)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Clear your work\n",
    "\n",
    "You may not be interested in keeping the application. Use this cell to shut down the stack, deleting any assets created in DataRobot."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "destroy_project(stack)"
   ]
  }
 ],
 "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.8.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
