In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
"
],
"text/plain": [
"Pipeline(steps=[('columntransformer',\n",
" ColumnTransformer(transformers=[('standardscaler',\n",
" StandardScaler(),\n",
" ['CreditScore', 'Age',\n",
" 'Tenure', 'Balance',\n",
" 'NumOfProducts', 'HasCrCard',\n",
" 'IsActiveMember',\n",
" 'EstimatedSalary']),\n",
" ('onehotencoder',\n",
" OneHotEncoder(handle_unknown='ignore'),\n",
" ['Geography'])])),\n",
" ('xgbclassifier',\n",
" XGBClassifier(base_score=None, booster=None, callbac...\n",
" feature_types=None, gamma=None, grow_policy=None,\n",
" importance_type=None,\n",
" interaction_constraints=None, learning_rate=0.1,\n",
" max_bin=None, max_cat_threshold=None,\n",
" max_cat_to_onehot=None, max_delta_step=None,\n",
" max_depth=4, max_leaves=None,\n",
" min_child_weight=None, missing=nan,\n",
" monotone_constraints=None, multi_strategy=None,\n",
" n_estimators=200, n_jobs=None,\n",
" num_parallel_tree=None, random_state=42, ...))])"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Store the best model\n",
"best_model = grid_search.best_estimator_\n",
"best_model"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "7K5BB3_M2Bk5"
},
"source": [
"The classification threshold is important because it controls precision and recall trade-offs.\n",
"- Since customer churn prediction is a retention problem, a higher recall is preferred. We want to correctly identify as many churners as possible, even if it means getting some false positives.\n",
"- We'll lower the classification threshold to 0.45 from 0.5 to increase the recall."
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {
"id": "rvYz9c-QhWDx"
},
"outputs": [],
"source": [
"# Set the classification threshold\n",
"classification_threshold = 0.45"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {
"id": "Fi-WqyVOhecQ"
},
"outputs": [],
"source": [
"# Make predictions on the training data\n",
"y_pred_train_proba = best_model.predict_proba(Xtrain)[:, 1]\n",
"y_pred_train = (y_pred_train_proba >= classification_threshold).astype(int)\n",
"\n",
"# Make predictions on the test data\n",
"y_pred_test_proba = best_model.predict_proba(Xtest)[:, 1]\n",
"y_pred_test = (y_pred_test_proba >= classification_threshold).astype(int)"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "DW9AG_ONc7PD",
"outputId": "3e5066ae-83d9-48f4-ec0c-91766625ee6c"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" precision recall f1-score support\n",
"\n",
" 0 0.96 0.81 0.88 6365\n",
" 1 0.54 0.85 0.66 1636\n",
"\n",
" accuracy 0.82 8001\n",
" macro avg 0.75 0.83 0.77 8001\n",
"weighted avg 0.87 0.82 0.83 8001\n",
"\n"
]
}
],
"source": [
"# Generate a classification report to evaluate model performance on training set\n",
"print(classification_report(ytrain, y_pred_train))"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "GlOJwOE2SA4m",
"outputId": "e587fba0-2f43-49d8-8acd-eab75c4fecd6"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" precision recall f1-score support\n",
"\n",
" 0 0.93 0.79 0.86 1599\n",
" 1 0.48 0.78 0.60 402\n",
"\n",
" accuracy 0.79 2001\n",
" macro avg 0.71 0.78 0.73 2001\n",
"weighted avg 0.84 0.79 0.80 2001\n",
"\n"
]
}
],
"source": [
"# Generate a classification report to evaluate model performance on test set\n",
"print(classification_report(ytest, y_pred_test))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ptaeTmSxqEe5"
},
"source": [
"- We can see that the **overfitting has significantly reduced**.\n",
"- The **test set recall for the class corresponding to churn** has also **significantly improved** (by ~25%) to 78%.\n",
"- As expected, while recall has improved, precision has dropped.\n",
"\n",
"We'll go ahead with this model as our final model."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "lqkUvTHzO3UH"
},
"source": [
"# Model Serialization"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {
"id": "SwIewqGpiRtW"
},
"outputs": [],
"source": [
"# Create a folder for storing the files needed for web app deployment\n",
"os.makedirs(\"deployment_files\", exist_ok=True)"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "E5-0ybugEl_5",
"outputId": "9815d03e-3894-4015-ab56-eec141e6c468"
},
"outputs": [
{
"data": {
"text/plain": [
"['deployment_files/churn_prediction_model_v1_0.joblib']"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Define the file path to save (serialize) the trained model along with the data preprocessing steps\n",
"saved_model_path = \"deployment_files/churn_prediction_model_v1_0.joblib\"\n",
"\n",
"# Save the trained model pipeline using joblib\n",
"joblib.dump(best_model, saved_model_path)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "qATgOdleEwCg"
},
"source": [
"This code is used to save a trained machine learning model pipeline using `joblib`, which is a library for efficient object serialization in Python.\n",
"\n",
"**Breakdown:** \n",
"1. **`saved_model_path = \"churn_prediction_model_v1_0.joblib\"`** \n",
" - Defines the file path where the model will be saved. \n",
" - The model will be stored as a `.joblib` file, a format optimized for large NumPy arrays and machine learning models. \n",
" - The last part of the filename (`v1_0`) specifies a version number, which is a good practice to track changes and maintain multiple model iterations\n",
"\n",
"2. **`joblib.dump(model_pipeline, saved_model_path)`** \n",
" - Saves the trained `model_pipeline` object to the specified path (`model.joblib`). \n",
" - `joblib.dump()` is preferred over `pickle.dump()` for saving large models because it is faster and more efficient with numerical data. \n",
" - The saved file can be loaded later using `joblib.load(\"model.joblib\")` for inference or further training. \n",
"\n",
"This approach ensures that the model pipeline, including preprocessing steps and the trained model, is preserved for later use."
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {
"id": "uNR7Dxj2MTM9"
},
"outputs": [],
"source": [
"# Load the saved model pipeline from the file\n",
"saved_model = joblib.load(\"deployment_files/churn_prediction_model_v1_0.joblib\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "FwEnJLtfFEw4"
},
"source": [
"1. **`joblib.load(\"churn_prediction_model_v1_0.joblib\")`** \n",
" - Loads the previously saved machine learning model (or pipeline) from the `model.joblib` file. \n",
" - The model retains all trained parameters, including preprocessing steps and learned patterns.\n",
"\n",
"2. **`saved_model`** \n",
" - This variable stores the deserialized model, allowing it to be used for inference, further training, or evaluation.\n",
"\n",
"This allows you to reuse the trained model **without retraining it.**"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 249
},
"id": "LoPE6PZUM7Uh",
"outputId": "cdfe55e4-520a-428a-ab0e-582e4e16b4e7"
},
"outputs": [
{
"data": {
"text/html": [
"
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
"
],
"text/plain": [
"Pipeline(steps=[('columntransformer',\n",
" ColumnTransformer(transformers=[('standardscaler',\n",
" StandardScaler(),\n",
" ['CreditScore', 'Age',\n",
" 'Tenure', 'Balance',\n",
" 'NumOfProducts', 'HasCrCard',\n",
" 'IsActiveMember',\n",
" 'EstimatedSalary']),\n",
" ('onehotencoder',\n",
" OneHotEncoder(handle_unknown='ignore'),\n",
" ['Geography'])])),\n",
" ('xgbclassifier',\n",
" XGBClassifier(base_score=None, booster=None, callbac...\n",
" feature_types=None, gamma=None, grow_policy=None,\n",
" importance_type=None,\n",
" interaction_constraints=None, learning_rate=0.1,\n",
" max_bin=None, max_cat_threshold=None,\n",
" max_cat_to_onehot=None, max_delta_step=None,\n",
" max_depth=4, max_leaves=None,\n",
" min_child_weight=None, missing=nan,\n",
" monotone_constraints=None, multi_strategy=None,\n",
" n_estimators=200, n_jobs=None,\n",
" num_parallel_tree=None, random_state=42, ...))])"
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"saved_model"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "UJMu1yQztach"
},
"source": [
"Let's try making predictions on the test set using the deserialized model.\n",
"\n",
"- Please ensure that the saved model is loaded before making predictions."
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "MzpxBjtSM9f-",
"outputId": "90db0d65-d3ba-4254-a8dc-af87c90c5484"
},
"outputs": [
{
"data": {
"text/plain": [
"array([0, 0, 0, ..., 0, 0, 1], shape=(2001,))"
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"saved_model.predict(Xtest)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "oxj1WOs1uxt_"
},
"source": [
"- As we can see, the model can be directly used for making predictions without any retraining."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "o81KHMBZTwXR"
},
"source": [
"# Creating a Web App using Streamlit"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "U3x2eyoA49uL"
},
"source": [
"We want to create a web app using Streamlit that can do the following:\n",
"1. Create a UI for users to provide their input\n",
"2. Load a serialized ML model\n",
"3. Take the user input and loaded model to make a prediction\n",
"4. Display the prediction from the model to the user"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Jdck5Mso5R_1"
},
"source": [
"For this, we write an **`app.py`** script that'll do all the above steps in one shot."
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "3oT-EsXmTvbu",
"outputId": "197a323b-0a8a-48fa-8188-9545a6512250"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Writing deployment_files/app.py\n"
]
}
],
"source": [
"%%writefile deployment_files/app.py\n",
"\n",
"import streamlit as st\n",
"import pandas as pd\n",
"import joblib\n",
"\n",
"# Load the trained model\n",
"def load_model():\n",
" return joblib.load(\"churn_prediction_model_v1_0.joblib\")\n",
"\n",
"model = load_model()\n",
"\n",
"# Streamlit UI for Customer Churn Prediction\n",
"st.title(\"Customer Churn Prediction App\")\n",
"st.write(\"The Customer Churn Prediction App is an internal tool for bank staff that predicts whether customers are at risk of churning based on their details.\")\n",
"st.write(\"Kindly enter the customer details to check whether they are likely to churn.\")\n",
"\n",
"# Collect user input\n",
"CreditScore = st.number_input(\"Credit Score (customer's credit score)\", min_value=300, max_value=900, value=650)\n",
"Geography = st.selectbox(\"Geography (country where the customer resides)\", [\"France\", \"Germany\", \"Spain\"])\n",
"Age = st.number_input(\"Age (customer's age in years)\", min_value=18, max_value=100, value=30)\n",
"Tenure = st.number_input(\"Tenure (number of years the customer has been with the bank)\", value=12)\n",
"Balance = st.number_input(\"Account Balance (customer’s account balance)\", min_value=0.0, value=10000.0)\n",
"NumOfProducts = st.number_input(\"Number of Products (number of products the customer has with the bank)\", min_value=1, value=1)\n",
"HasCrCard = st.selectbox(\"Has Credit Card?\", [\"Yes\", \"No\"])\n",
"IsActiveMember = st.selectbox(\"Is Active Member?\", [\"Yes\", \"No\"])\n",
"EstimatedSalary = st.number_input(\"Estimated Salary (customer’s estimated salary)\", min_value=0.0, value=50000.0)\n",
"\n",
"# Convert categorical inputs to match model training\n",
"input_data = pd.DataFrame([{\n",
" 'CreditScore': CreditScore,\n",
" 'Geography': Geography,\n",
" 'Age': Age,\n",
" 'Tenure': Tenure,\n",
" 'Balance': Balance,\n",
" 'NumOfProducts': NumOfProducts,\n",
" 'HasCrCard': 1 if HasCrCard == \"Yes\" else 0,\n",
" 'IsActiveMember': 1 if IsActiveMember == \"Yes\" else 0,\n",
" 'EstimatedSalary': EstimatedSalary\n",
"}])\n",
"\n",
"# Set the classification threshold\n",
"classification_threshold = 0.45\n",
"\n",
"# Predict button\n",
"if st.button(\"Predict\"):\n",
" prediction_proba = model.predict_proba(input_data)[0, 1]\n",
" prediction = (prediction_proba >= classification_threshold).astype(int)\n",
" result = \"churn\" if prediction == 1 else \"not churn\"\n",
" st.write(f\"Based on the information provided, the customer is likely to {result}.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Dh7JAZWJu9UA"
},
"source": [
"- It's important to note that the library import calls have to be mentioned in the script, as it won't automatically happen in the hosting platform."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "luytCgCGXYdb"
},
"source": [
"# Creating a Dependencies File"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "VllfgdDo4kAA",
"outputId": "2a3c247a-3aa4-4624-fa42-68c3d8e0efe4"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Writing deployment_files/requirements.txt\n"
]
}
],
"source": [
"%%writefile deployment_files/requirements.txt\n",
"pandas==2.2.2\n",
"numpy==2.0.2\n",
"scikit-learn==1.6.1\n",
"xgboost==2.1.4\n",
"joblib==1.4.2\n",
"streamlit==1.43.2"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Ou9pmcKNRgte"
},
"source": [
"A **`requirements.txt`** file is essential for ensuring that your project runs smoothly across different environments. It's like a **blueprint** for setting up your ML project!"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Vh6L3EqqiDbw"
},
"source": [
"# Dockerfile"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "af2KN5Zxibak"
},
"source": [
"**Note for Learners**\n",
"\n",
"In the case study recording on **Introduction to Model Deployment**, we deployed a Streamlit app using the **Hugging Face Spaces template**. At that time, Hugging Face allowed direct deployment using the **Streamlit SDK template**, and a `Dockerfile` was *not required*.\n",
"\n",
"However, Hugging Face has since updated their platform, and now **Streamlit apps must be deployed using the Docker template**, which requires a valid `Dockerfile`. While the recording does not show the `Dockerfile` creation, we have included the necessary `Dockerfile` code in this notebook for your reference.\n",
"\n",
"Don't worry — we'll cover the `Dockerfile` structure and containerization **in depth** in the upcoming week on **Containerization**.\n"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {
"id": "5xgEHj3fiGHq"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Writing deployment_files/Dockerfile\n"
]
}
],
"source": [
"%%writefile deployment_files/Dockerfile\n",
"# Use a minimal base image with Python 3.9 installed\n",
"FROM python:3.9-slim\n",
"\n",
"# Set the working directory inside the container to /app\n",
"WORKDIR /app\n",
"\n",
"# Copy all files from the current directory on the host to the container's /app directory\n",
"COPY . .\n",
"\n",
"# Install Python dependencies listed in requirements.txt\n",
"RUN pip3 install -r requirements.txt\n",
"\n",
"# Define the command to run the Streamlit app on port 8501 and make it accessible externally\n",
"CMD [\"streamlit\", \"run\", \"app.py\", \"--server.port=8501\", \"--server.address=0.0.0.0\", \"--server.enableXsrfProtection=false\"]"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'C:\\\\Users\\\\adity\\\\Model_Deployment'"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pwd"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "GChQ7KMTXmfa"
},
"source": [
"# Uploading Files to Hugging Face Repository"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "FPsXhZQ7YIyc"
},
"source": [
"Once create the following files in the notebook, lets upload it in to the hugging face space\n",
"- **`churn_prediction_model_v1_0.joblib`**\n",
"- **`requirements.txt`**\n",
"- **`Dockerfile`**\n",
"- **`app.py`**"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"id": "TsW6UmL9GIFL"
},
"outputs": [
{
"ename": "HTTPError",
"evalue": "Invalid user token.",
"output_type": "error",
"traceback": [
"\u001b[31m---------------------------------------------------------------------------\u001b[39m",
"\u001b[31mHTTPError\u001b[39m Traceback (most recent call last)",
"\u001b[36mFile \u001b[39m\u001b[32m~\\miniconda3\\envs\\md\\Lib\\site-packages\\huggingface_hub\\utils\\_http.py:409\u001b[39m, in \u001b[36mhf_raise_for_status\u001b[39m\u001b[34m(response, endpoint_name)\u001b[39m\n\u001b[32m 408\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m409\u001b[39m response.raise_for_status()\n\u001b[32m 410\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m HTTPError \u001b[38;5;28;01mas\u001b[39;00m e:\n",
"\u001b[36mFile \u001b[39m\u001b[32m~\\miniconda3\\envs\\md\\Lib\\site-packages\\requests\\models.py:1024\u001b[39m, in \u001b[36mResponse.raise_for_status\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 1023\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m http_error_msg:\n\u001b[32m-> \u001b[39m\u001b[32m1024\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m HTTPError(http_error_msg, response=\u001b[38;5;28mself\u001b[39m)\n",
"\u001b[31mHTTPError\u001b[39m: 401 Client Error: Unauthorized for url: https://huggingface.co/api/whoami-v2",
"\nThe above exception was the direct cause of the following exception:\n",
"\u001b[31mHfHubHTTPError\u001b[39m Traceback (most recent call last)",
"\u001b[36mFile \u001b[39m\u001b[32m~\\miniconda3\\envs\\md\\Lib\\site-packages\\huggingface_hub\\hf_api.py:1664\u001b[39m, in \u001b[36mHfApi.whoami\u001b[39m\u001b[34m(self, token)\u001b[39m\n\u001b[32m 1663\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m-> \u001b[39m\u001b[32m1664\u001b[39m hf_raise_for_status(r)\n\u001b[32m 1665\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m HTTPError \u001b[38;5;28;01mas\u001b[39;00m e:\n",
"\u001b[36mFile \u001b[39m\u001b[32m~\\miniconda3\\envs\\md\\Lib\\site-packages\\huggingface_hub\\utils\\_http.py:481\u001b[39m, in \u001b[36mhf_raise_for_status\u001b[39m\u001b[34m(response, endpoint_name)\u001b[39m\n\u001b[32m 479\u001b[39m \u001b[38;5;66;03m# Convert `HTTPError` into a `HfHubHTTPError` to display request information\u001b[39;00m\n\u001b[32m 480\u001b[39m \u001b[38;5;66;03m# as well (request id and/or server error message)\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m481\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m _format(HfHubHTTPError, \u001b[38;5;28mstr\u001b[39m(e), response) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01me\u001b[39;00m\n",
"\u001b[31mHfHubHTTPError\u001b[39m: 401 Client Error: Unauthorized for url: https://huggingface.co/api/whoami-v2 (Request ID: Root=1-6847119b-459f1d1f4a27a0e8241704c7;3e4f0b8f-9f77-41a9-8ffe-df042ec507bd)\n\nInvalid credentials in Authorization header",
"\nThe above exception was the direct cause of the following exception:\n",
"\u001b[31mHTTPError\u001b[39m Traceback (most recent call last)",
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[14]\u001b[39m\u001b[32m, line 5\u001b[39m\n\u001b[32m 2\u001b[39m repo_id = \u001b[33m\"\u001b[39m\u001b[33madityasharma0511/gldeploy\u001b[39m\u001b[33m\"\u001b[39m \u001b[38;5;66;03m# Your Hugging Face space id\u001b[39;00m\n\u001b[32m 4\u001b[39m \u001b[38;5;66;03m# Login to Hugging Face platform with the access token\u001b[39;00m\n\u001b[32m----> \u001b[39m\u001b[32m5\u001b[39m login(token=access_key)\n\u001b[32m 7\u001b[39m \u001b[38;5;66;03m# Initialize the API\u001b[39;00m\n\u001b[32m 8\u001b[39m api = HfApi()\n",
"\u001b[36mFile \u001b[39m\u001b[32m~\\miniconda3\\envs\\md\\Lib\\site-packages\\huggingface_hub\\utils\\_deprecation.py:101\u001b[39m, in \u001b[36m_deprecate_arguments.._inner_deprecate_positional_args..inner_f\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 99\u001b[39m message += \u001b[33m\"\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[33m\"\u001b[39m + custom_message\n\u001b[32m 100\u001b[39m warnings.warn(message, \u001b[38;5;167;01mFutureWarning\u001b[39;00m)\n\u001b[32m--> \u001b[39m\u001b[32m101\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m f(*args, **kwargs)\n",
"\u001b[36mFile \u001b[39m\u001b[32m~\\miniconda3\\envs\\md\\Lib\\site-packages\\huggingface_hub\\utils\\_deprecation.py:31\u001b[39m, in \u001b[36m_deprecate_positional_args.._inner_deprecate_positional_args..inner_f\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 29\u001b[39m extra_args = \u001b[38;5;28mlen\u001b[39m(args) - \u001b[38;5;28mlen\u001b[39m(all_args)\n\u001b[32m 30\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m extra_args <= \u001b[32m0\u001b[39m:\n\u001b[32m---> \u001b[39m\u001b[32m31\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m f(*args, **kwargs)\n\u001b[32m 32\u001b[39m \u001b[38;5;66;03m# extra_args > 0\u001b[39;00m\n\u001b[32m 33\u001b[39m args_msg = [\n\u001b[32m 34\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mname\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m=\u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00marg\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m\"\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(arg, \u001b[38;5;28mstr\u001b[39m) \u001b[38;5;28;01melse\u001b[39;00m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mname\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m=\u001b[39m\u001b[38;5;132;01m{\u001b[39;00marg\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m\n\u001b[32m 35\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m name, arg \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mzip\u001b[39m(kwonly_args[:extra_args], args[-extra_args:])\n\u001b[32m 36\u001b[39m ]\n",
"\u001b[36mFile \u001b[39m\u001b[32m~\\miniconda3\\envs\\md\\Lib\\site-packages\\huggingface_hub\\_login.py:126\u001b[39m, in \u001b[36mlogin\u001b[39m\u001b[34m(token, add_to_git_credential, new_session, write_permission)\u001b[39m\n\u001b[32m 119\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m add_to_git_credential:\n\u001b[32m 120\u001b[39m logger.info(\n\u001b[32m 121\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mThe token has not been saved to the git credentials helper. Pass \u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 122\u001b[39m \u001b[33m\"\u001b[39m\u001b[33m`add_to_git_credential=True` in this function directly or \u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 123\u001b[39m \u001b[33m\"\u001b[39m\u001b[33m`--add-to-git-credential` if using via `huggingface-cli` if \u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 124\u001b[39m \u001b[33m\"\u001b[39m\u001b[33myou want to set the git credential as well.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 125\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m126\u001b[39m _login(token, add_to_git_credential=add_to_git_credential)\n\u001b[32m 127\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m is_notebook():\n\u001b[32m 128\u001b[39m notebook_login(new_session=new_session)\n",
"\u001b[36mFile \u001b[39m\u001b[32m~\\miniconda3\\envs\\md\\Lib\\site-packages\\huggingface_hub\\_login.py:404\u001b[39m, in \u001b[36m_login\u001b[39m\u001b[34m(token, add_to_git_credential)\u001b[39m\n\u001b[32m 401\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m token.startswith(\u001b[33m\"\u001b[39m\u001b[33mapi_org\u001b[39m\u001b[33m\"\u001b[39m):\n\u001b[32m 402\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[33m\"\u001b[39m\u001b[33mYou must use your personal account token, not an organization token.\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m404\u001b[39m token_info = whoami(token)\n\u001b[32m 405\u001b[39m permission = token_info[\u001b[33m\"\u001b[39m\u001b[33mauth\u001b[39m\u001b[33m\"\u001b[39m][\u001b[33m\"\u001b[39m\u001b[33maccessToken\u001b[39m\u001b[33m\"\u001b[39m][\u001b[33m\"\u001b[39m\u001b[33mrole\u001b[39m\u001b[33m\"\u001b[39m]\n\u001b[32m 406\u001b[39m logger.info(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mToken is valid (permission: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mpermission\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m).\u001b[39m\u001b[33m\"\u001b[39m)\n",
"\u001b[36mFile \u001b[39m\u001b[32m~\\miniconda3\\envs\\md\\Lib\\site-packages\\huggingface_hub\\utils\\_validators.py:114\u001b[39m, in \u001b[36mvalidate_hf_hub_args.._inner_fn\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 111\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m check_use_auth_token:\n\u001b[32m 112\u001b[39m kwargs = smoothly_deprecate_use_auth_token(fn_name=fn.\u001b[34m__name__\u001b[39m, has_token=has_token, kwargs=kwargs)\n\u001b[32m--> \u001b[39m\u001b[32m114\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m fn(*args, **kwargs)\n",
"\u001b[36mFile \u001b[39m\u001b[32m~\\miniconda3\\envs\\md\\Lib\\site-packages\\huggingface_hub\\hf_api.py:1677\u001b[39m, in \u001b[36mHfApi.whoami\u001b[39m\u001b[34m(self, token)\u001b[39m\n\u001b[32m 1675\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m effective_token == _get_token_from_file():\n\u001b[32m 1676\u001b[39m error_message += \u001b[33m\"\u001b[39m\u001b[33m The token stored is invalid. Please run `huggingface-cli login` to update it.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m-> \u001b[39m\u001b[32m1677\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m HTTPError(error_message, request=e.request, response=e.response) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01me\u001b[39;00m\n\u001b[32m 1678\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m r.json()\n",
"\u001b[31mHTTPError\u001b[39m: Invalid user token."
]
}
],
"source": [
"access_key = \"hf_token\" # Your Hugging Face token created from access keys in write mode\n",
"repo_id = \"adityasharma0511/gldeploy\" # Your Hugging Face space id\n",
"\n",
"# Login to Hugging Face platform with the access token\n",
"login(token=access_key)\n",
"\n",
"# Initialize the API\n",
"api = HfApi()\n",
"\n",
"# Upload Streamlit app files stored in the folder called deployment_files\n",
"api.upload_folder(\n",
" folder_path=\"C:\\\\Users\\\\adity\\\\Model_Deployment\", # Local folder path in azureml\n",
" repo_id=repo_id, # Hugging face space id\n",
" repo_type=\"space\", # Hugging face repo type \"space\"\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "_i3RxMaYNDtX"
},
"source": [
"1. **Define authentication and repository details:** \n",
" - `hf_token` stores the Hugging Face API token for authentication. \n",
" - `repo_id` specifies the Hugging Face **Space** repository where files will be uploaded. \n",
"\n",
"2. **Authenticate with Hugging Face:** \n",
" - The `login(token=hf_token)` function logs into Hugging Face using the provided API token. \n",
"\n",
"3. **Initialize Hugging Face API object:** \n",
" - `api = HfApi()` creates an instance of `HfApi`, which allows interaction with the Hugging Face Hub. \n",
"\n",
"4. **Upload files from the local folder to Hugging Face Space:** \n",
" - `api.upload_folder()` uploads all files from the `deployment_files` folder to the specified Hugging Face repository. \n",
" - `folder_path=\"/content/deployment_files\"` specifies the local directory containing the files. \n",
" - `repo_id=repo_id` sets the target Hugging Face **Space** repository. \n",
" - `repo_type=\"space\"` ensures that the upload is directed to a **Space** repository, which is used for hosting applications like Streamlit. \n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "cfrgxVM66grM"
},
"source": [
"Here's how the web app looks like."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "98iM0_0w6kPU"
},
"source": [
""
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "LswDabmTHofd"
},
"source": [
"Power Ahead!\n",
"___"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"application/vnd.databricks.v1+notebook": {
"dashboards": [],
"language": "python",
"notebookMetadata": {
"pythonIndentUnit": 4
},
"notebookName": "machine_failure_prediction",
"widgets": {}
},
"colab": {
"collapsed_sections": [
"o5Iixw4vHWG9",
"niLZjnkCHWG_",
"bQrbzi5RHWHC",
"iT25LmvoHWHD",
"Cl7T7_jFHWHE",
"lqkUvTHzO3UH",
"o81KHMBZTwXR",
"luytCgCGXYdb",
"Vh6L3EqqiDbw",
"GChQ7KMTXmfa"
],
"provenance": []
},
"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.13.4"
}
},
"nbformat": 4,
"nbformat_minor": 4
}