{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "ed27ecca-f323-4606-810a-214f3d87a518",
   "metadata": {
    "tags": []
   },
   "source": [
    "## From Training to Prediction: Deploying a Rent Forecast Model with Ray Serve\n",
    "In this notebook, we illustrate a streamlined workflow for **building a machine learning model** to forecast rental prices, **evaluating its accuracy**, and **deploying it for real-time predictions** using **Ray Serve**. The process unfolds as follows:\n",
    "\n",
    "#### 1. Model Training:\n",
    "We begin by training a **Random Forest model** on a simulated dataset of rental properties, capturing details like *square footage, bedrooms, bathrooms, and furnishing status* to predict monthly rent prices.\n",
    "\n",
    "#### 2. Model Evaluation:\n",
    "The model's predictive performance is assessed using **Mean Absolute Error (MAE)** on a subset of the data reserved for testing.\n",
    "\n",
    "#### 3. Serialization and Deployment:\n",
    "After training, **the model is saved to disk and deployed as a web service with Ray Serve**, which manages request handling and scalability.\n",
    "\n",
    "#### 4. Real-time Predictions:\n",
    "We conclude **by sending HTTP requests to the deployed model**, demonstrating how to obtain instant rent forecasts based on property features.\n",
    "\n",
    "This workflow showcases the complete cycle from model development to deployment, providing a practical example of utilizing machine learning predictions in real-world applications."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "eac352cb-c3af-417c-a69f-5eb09a3d9c73",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "eb4266aa-2f92-44c6-8f8d-e332546cc898",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   square_footage  bedrooms  bathrooms  furnished  monthly_rent\n",
      "0            1360         2          3          0          2269\n",
      "1            1794         1          2          1          2242\n",
      "2            1630         4          3          1          3034\n",
      "3            1595         3          3          1          2583\n",
      "4            2138         3          2          1          3200\n"
     ]
    }
   ],
   "source": [
    "# Simulating dataset with 100 entries\n",
    "np.random.seed(42)  # For reproducibility\n",
    "\n",
    "square_footage = np.random.randint(500, 3000, 100)\n",
    "bedrooms = np.random.randint(1, 5, 100)\n",
    "bathrooms = np.random.randint(1, 4, 100)\n",
    "furnished = np.random.randint(0, 2, 100)\n",
    "monthly_rent = square_footage * 1 + bedrooms * 250 + bathrooms * 100 + furnished * 75 + np.random.randint(-250, 250, 100)\n",
    "\n",
    "data = {\n",
    "    'square_footage': square_footage,\n",
    "    'bedrooms': bedrooms,\n",
    "    'bathrooms': bathrooms,\n",
    "    'furnished': furnished,\n",
    "    'monthly_rent': monthly_rent\n",
    "}\n",
    "df = pd.DataFrame(data)\n",
    "\n",
    "# Display the first few rows of the dataset\n",
    "print(df.head())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "0be48c51-4573-4d1a-908e-4f29574b9b30",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.ensemble import RandomForestRegressor\n",
    "from sklearn.metrics import mean_absolute_error"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "9b163659-2836-4813-aee0-307460ef7238",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Date has been prepared.\n"
     ]
    }
   ],
   "source": [
    "# Preparing input features and target variable\n",
    "X = df.drop('monthly_rent', axis=1)\n",
    "y = df['monthly_rent']\n",
    "\n",
    "# Splitting the data into training and testing sets\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n",
    "\n",
    "print(\"Date has been prepared.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "83aea3d2-1045-418a-9a2a-9511dcbfd214",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Mean Absolute Error: $158.50\n"
     ]
    }
   ],
   "source": [
    "# Training the Random Forest model\n",
    "model = RandomForestRegressor(n_estimators=100, random_state=42)\n",
    "model.fit(X_train, y_train)\n",
    "\n",
    "# Predicting rent prices for the test set\n",
    "y_pred = model.predict(X_test)\n",
    "\n",
    "# Evaluating the model\n",
    "mae = mean_absolute_error(y_test, y_pred)\n",
    "print(f\"Mean Absolute Error: ${mae:.2f}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "e99e4950-7fd2-44cd-bb7a-b870aa605336",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "image/png": "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REREVMoJgoC9e/eiQYMG+P3339WONWzYEHfv3sWsWbNgbm4uUYe6iWGLiIiIiKgUi4uLQ4cOHdCpUyecP38ekydPVrs+CwAsLCwk6k63MWwREREREZVCiYmJGDBgABo2bIg///xTrJuZmeHhw4cSdlZyMGwREREREZUiqampmDp1KqpXr47169eL12hVrlwZmzdvxt9//w1HR0eJuywZeGUbEREREVEpIAgCvvnmGwQHB+Px48di3crKCjNnzsTIkSNhZGQkYYclD8MWEREREVEpIJPJsH//fjFoGRkZYezYsQgMDISVlZXE3ZVMXEZIRERERFRKLFy4EPr6+ujbty+uXr2KsLAwBi0tYtgiIiIiIiphrl69ik8//RRbtmxRq9esWRMJCQnYsGEDKlWqJFF3pQfDFhERERFRCfHgwQOMHDkStWrVwo4dOxAYGIjMzEy1MU5OThJ1V/owbBERERER6bgXL15g7ty5qFq1KpYvXw6FQgEAePXqFa5fvy5xd6UXwxYRERERkY5SKBRYtWoVqlevjpkzZyI9PR0AYG5ujuDgYFy/fh21a9eWuMvSi7sREhERERHpoD179iAgIAAXL14Ua3K5HF9++SVmz54NOzs7sa5QAEeOAMnJgIMD4OkJyOVSdF26MGwREREREemgjRs3qgWt7t27Y8GCBahRo4bauKgoYNw44O7df2tOTkBkJODrW1Tdlk5cRkhEREREpIPmzp0LQ0NDNGvWDIcPH8b27dvzDVo9e6oHLQBISlLVo6KKsOFSSCYIgiB1E8VdWloaLC0tkZqaCgsLC6nbISIiIqL3oKtL6Z49e4b58+ejdu3aGDBggNqxc+fOoU6dOpDJZHmep1AALi55g1YumUw1w5WQoBt/DsWFJtlA0pmt5cuXo27durCwsICFhQU8PDywZ88e8biXlxdkMpnax/Dhw9XOkZiYCB8fH5iamsLW1hYBAQHIyclRGxMTE4OGDRvCyMgIVatWxdq1a4vi7RERERFRMREVpQoerVsDffqoPru4FO+ZnczMTHz99ddwdXVFeHg4pk6dihcvXqiNqVu3br5BC1AFy7cFLQAQBODOHdU40g5Jw5aTkxMWLFiA06dP49SpU2jTpg26deumtvZ02LBhSE5OFj/CwsLEYwqFAj4+PsjKysKxY8ewbt06rF27FrNmzRLHJCQkwMfHB61b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ePeW8bmPlyxRjSMiIiIiKukYtkqpK1euoHv37mjZsiVOnDgBAAgJCcHz588/6Lx5t4xXcXJS1X19P+j0REREREQ6g8sIS5kHDx4gKCgIP/zwAxSv7cFeu3ZthIWFwdzc/INfw9cX6NZNtetgcrLqGi1PT85oEREREVHpwrBVSrx48QKLFi1CeHg40tPTxbqjoyNCQkLg5+cHeSGmIbkc8PIqtNMREREREekchq1SICsrC3Xq1EFCQoJYMzc3x9SpU+Hv7w8zMzMJuyMiIiIiKpl4zVYpYGhoiB49egAA5HI5Ro4cifj4eEyfPp1Bi4iIiIhISzizVQKdOXMGNWrUUAtS06ZNw/379zFjxgzUqFFDwu6IiIiIiEoHzmyVILdu3ULfvn3RqFEjLF68WO2YlZUV1q9fz6BFRERERFREGLZKgKdPnyIgIAA1atTApk2bAABhYWF48OCBxJ0REREREZVeXEaowzIzM/G///0Pc+fOxdOnT8W6tbU1Zs2aVeCbERMRERERUeFj2NJBSqUSW7ZswbRp03Dr1i2xbmxsDH9/f0ydOhWWlpbSNUhERERERAxbukYQBLRr1w4HDx4UazKZDP3790dISAgqVqwoYXdERERERJSL12zpGJlMhlatWomP27dvjzNnzmDdunUMWkRERERExQhntnTQxIkTcezYMUyYMAHe3t5St0NERERERPlg2NJB5ubm2Ldvn9RtEBERERHRO3AZIRERERERkRYwbBEREREREWkBwxYREREREZEWMGwRERERERFpAcMWERERERGRFjBsERERERERaQHDFhERERERkRYwbBEREREREWkBwxYREREREZEWMGwRERERERFpAcMWERERERGRFjBsERERERERaQHDFhERERERkRYwbBEREREREWkBwxYREREREZEWMGwRERERERFpAcMWERERERGRFjBsERERERERaYG+1A3oAkEQAABpaWkSd0JERERERFLKzQS5GeFdGLYK4Pnz5wAAZ2dniTshIiIiIqLi4Pnz57C0tHznGJlQkEhWyimVStz7v/buPKiq8o0D+Pey3CsElyU2UVZhcEFxra6VoqJcoSaNadDUwXRsNM0y96UhbfxRzpg6imYTbk2jpSNmbpOiQBQuKFdEGRoRpQwkURBEEOT5/eFwpqOYIF5A+X5mzsw9533Oe95Xn3nx8Zx7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",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "# Actual vs. Predicted Rent Prices graph\n",
    "plt.figure(figsize=(10, 6))\n",
    "plt.scatter(y_test, y_pred, color='blue', label='Predictions')\n",
    "plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'k--', lw=2, label='Perfect Fit')\n",
    "plt.xlabel('Actual Rent')\n",
    "plt.ylabel('Predicted Rent')\n",
    "plt.title('Actual vs. Predicted Rent Prices')\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "12aea7b6-67d1-476f-ac96-114dc7859ccd",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['rent_prediction_model.joblib']"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from joblib import dump\n",
    "\n",
    "# Dumping the model to deploy it with Ray-Serve\n",
    "model_path = \"rent_prediction_model.joblib\"\n",
    "dump(model, model_path)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "94a42d27-fb2a-4fe9-b9d0-983dc8daae1e",
   "metadata": {
    "tags": []
   },
   "source": [
    "At this point, the model is ready. We will now deploy it using Ray Serve, where serving will be handled by a Ray Cluster deployed in EZAF. \n",
    "\n",
    "This section covers the necessary steps for initializing the Ray environment and starting Ray Serve with appropriate settings for smooth deployment and service operation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "423432bf-df67-4641-b1a9-d261baf1b22a",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Binding is completed.\n",
      "2024-08-19 17:32:04,594\tINFO handle.py:126 -- Created DeploymentHandle 'nttvkrg4' for Deployment(name='RentPredictor', app='app1').\n",
      "2024-08-19 17:32:04,594\tINFO handle.py:126 -- Created DeploymentHandle 'pfsh9unf' for Deployment(name='RentPredictor', app='app1').\n",
      "2024-08-19 17:32:04,597\tINFO scripts.py:848 -- The auto-generated application names default to `app1`, `app2`, ... etc. Rename as necessary.\n",
      "\n",
      "\u001b[0m"
     ]
    }
   ],
   "source": [
    "# Building Ray Serve app\n",
    "# !serve build <module_name>:<app_name> -o <config_file_name>.yaml\n",
    "# This will generate config file\n",
    "!serve build --app-dir \"./\" ray_serve_app:rent_predictor_app -o rent_predictor_app_config.yaml"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ce558a1e-9efc-4bf4-a5d9-e3596117845e",
   "metadata": {
    "tags": []
   },
   "source": [
    "## Attention! \n",
    "Following cell is a workaround. Currently, `serve deploy` does not support `--working-dir` directly.\n",
    "Please see https://github.com/ray-project/ray/issues/29354\n",
    "\n",
    "Suggested way to provide files from NB side to Ray cluster as below:\n",
    "1. Create connection with `JobSubmissionClient` with working dir option but without entrypoint.\n",
    "2. `JobSubmissionClient` will upload working_dir to GCS and print the URI.\n",
    "3. Specify the above mentioned URI in config file as below example:\n",
    "```\n",
    "  runtime_env:\n",
    "    working_dir: \"gcs://_ray_pkg_fef565b457f470d9.zip\"\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "44835e90-9fa7-4229-a657-9e30812c2b81",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2024-08-19 17:56:55,397\tINFO dashboard_sdk.py:338 -- Uploading package gcs://_ray_pkg_c8acbba64acf4141.zip.\n",
      "2024-08-19 17:56:55,399\tINFO packaging.py:530 -- Creating a file package for local directory './'.\n"
     ]
    }
   ],
   "source": [
    "# Workaround!\n",
    "# This is to upload the working dir to GCS\n",
    "# Once the URI is ready, please modify config dir before deployment\n",
    "import ray\n",
    "from ray.job_submission import JobSubmissionClient\n",
    "\n",
    "ray_head_ip = \"kuberay-head-svc.kuberay.svc.cluster.local\"\n",
    "ray_head_port = 8265\n",
    "ray_address = f\"http://{ray_head_ip}:{ray_head_port}\"\n",
    "client = JobSubmissionClient(ray_address)\n",
    "\n",
    "job_id = client.submit_job(\n",
    "    entrypoint=\"\",\n",
    "    runtime_env={\n",
    "        \"working_dir\": \"./\",\n",
    "    }\n",
    ")\n",
    "\n",
    "# We do not need this connection    \n",
    "ray.shutdown()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "9a9372b9-ea63-439f-8531-ad44046dc692",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2024-08-19 17:58:03,923\tINFO scripts.py:243 -- Deploying from config file: 'rent_predictor_app_config.yaml'.\n",
      "2024-08-19 17:58:07,848\tSUCC scripts.py:350 -- \u001b[32m\n",
      "Sent deploy request successfully.\n",
      " * Use `serve status` to check applications' statuses.\n",
      " * Use `serve config` to see the current application config(s).\n",
      "\u001b[39m\n",
      "\u001b[0m"
     ]
    }
   ],
   "source": [
    "# Deploying the app\n",
    "# Please avoid using \"serve run\" which uses deprecated client API \"ray.init()\" under the cover\n",
    "# !serve run [OPTIONS] <config_file_name>.yaml\n",
    "# Important! Please modify config file as described above to push working dir\n",
    "!serve deploy --address \"http://kuberay-head-svc.kuberay.svc.cluster.local:8265\" rent_predictor_app_config.yaml"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "5cafb76d-869e-4006-bd81-b619c71520da",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'predicted_rent': 1861.12}\n"
     ]
    }
   ],
   "source": [
    "import requests\n",
    "\n",
    "# Example request data\n",
    "data = {\n",
    "    \"square_footage\": 1200,\n",
    "    \"bedrooms\": 2,\n",
    "    \"bathrooms\": 2,\n",
    "    \"furnished\": 1\n",
    "}\n",
    "\n",
    "# Sending a prediction request to Ray cluster where Serve is running\n",
    "try:\n",
    "    response = requests.post(\"http://kuberay-head-svc.kuberay.svc.cluster.local:8000/\", json=data)\n",
    "    print(response.json())\n",
    "except requests.exceptions.RequestException as e:\n",
    "    print(f\"Request failed: {e}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "f30220ff-0c04-41c1-83e2-32ed38587ee5",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2024-08-19 17:59:35,229\tSUCC scripts.py:747 -- \u001b[32mSent shutdown request; applications will be deleted asynchronously.\u001b[39m\n",
      "\u001b[0m"
     ]
    }
   ],
   "source": [
    "# Terminating the deployment\n",
    "!serve shutdown --address \"http://kuberay-head-svc.kuberay.svc.cluster.local:8265\" -y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f52d0a2d-ecfd-40e5-baac-9b2ff3159973",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Ray",
   "language": "python",
   "name": "ray"
  },
  "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.11.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
