|
| 1 | +{ |
| 2 | + "cells": [ |
| 3 | + { |
| 4 | + "cell_type": "markdown", |
| 5 | + "metadata": {}, |
| 6 | + "source": [ |
| 7 | + "# My Project\n", |
| 8 | + "\n", |
| 9 | + "In addition to being a place to experiment, this project has been structured to build and serve your model in a Flask application. The purpose is to allow data science exploration to easily transition into deployed services and applications on the OpenShift platform. After saving this project to git, it can be built on the OpenShift platform to serve models.\n", |
| 10 | + "\n", |
| 11 | + "Your dependencies will live in `requirements.txt` and your prediction function will live in `prediction.py`. As a Python based s2i application, this project can be configured and built upon to fit your needs.\n", |
| 12 | + "\n", |
| 13 | + "### Project Organization\n", |
| 14 | + "```\n", |
| 15 | + ".\n", |
| 16 | + "├── README.md\n", |
| 17 | + "├── LICENSE\n", |
| 18 | + "├── requirements.txt <- Used to install packages for s2i application\n", |
| 19 | + "├── 0_start_here.ipynb <- Instructional notebook\n", |
| 20 | + "├── 1_run_flask.ipynb <- Notebook for running flask locally to test\n", |
| 21 | + "├── 2_test_flask.ipynb <- Notebook for testing flask requests\n", |
| 22 | + "├── .gitignore <- standard python gitignore\n", |
| 23 | + "├── .s2i <- hidden folder for advanced s2i configuration\n", |
| 24 | + "│ └── environment <- s2i environment settings\n", |
| 25 | + "├── gunicorn_config.py <- configuration for gunicorn when run in OpenShift\n", |
| 26 | + "├── prediction.py <- the predict function called from Flask\n", |
| 27 | + "└── wsgi.py <- basic Flask application\n", |
| 28 | + "```\n", |
| 29 | + "\n", |
| 30 | + "### Basic Flow\n", |
| 31 | + "1. Install and manage dependencies in `requirements.txt`.\n", |
| 32 | + "1. Experiment as usual.\n", |
| 33 | + "1. Extract your prediction into the `prediction.py` file.\n", |
| 34 | + "1. Update any dependencies.\n", |
| 35 | + "1. Run and test your application locally.\n", |
| 36 | + "1. Save to git.\n", |
| 37 | + "\n", |
| 38 | + "For a complete overview, please read the [README.md](./README.md)" |
| 39 | + ] |
| 40 | + }, |
| 41 | + { |
| 42 | + "cell_type": "markdown", |
| 43 | + "metadata": {}, |
| 44 | + "source": [ |
| 45 | + "## Install Dependencies" |
| 46 | + ] |
| 47 | + }, |
| 48 | + { |
| 49 | + "cell_type": "code", |
| 50 | + "execution_count": null, |
| 51 | + "metadata": { |
| 52 | + "cellView": "both", |
| 53 | + "id": "KUu4vOt5zI9d" |
| 54 | + }, |
| 55 | + "outputs": [], |
| 56 | + "source": [ |
| 57 | + "import sys\n", |
| 58 | + "!{sys.executable} -m pip install -r requirements.txt" |
| 59 | + ] |
| 60 | + }, |
| 61 | + { |
| 62 | + "cell_type": "markdown", |
| 63 | + "metadata": {}, |
| 64 | + "source": [ |
| 65 | + "## Experiment\n", |
| 66 | + "\n", |
| 67 | + "Experiment with data and create your prediction function. Create any serialized models needed." |
| 68 | + ] |
| 69 | + }, |
| 70 | + { |
| 71 | + "cell_type": "code", |
| 72 | + "execution_count": null, |
| 73 | + "metadata": {}, |
| 74 | + "outputs": [], |
| 75 | + "source": [ |
| 76 | + "def predict(args_dict):\n", |
| 77 | + " return {'prediction': 'not implemented'}\n", |
| 78 | + "\n", |
| 79 | + "predict({'keys': 'values'})" |
| 80 | + ] |
| 81 | + }, |
| 82 | + { |
| 83 | + "cell_type": "markdown", |
| 84 | + "metadata": {}, |
| 85 | + "source": [ |
| 86 | + "## Create a Predict Function\n", |
| 87 | + "\n", |
| 88 | + "Extract the prediction logic into a standalone python file, `prediction.py` in a `predict` function. Also, make sure `requirements.txt` is updated with any additional packages you've used and need for prediction." |
| 89 | + ] |
| 90 | + }, |
| 91 | + { |
| 92 | + "cell_type": "code", |
| 93 | + "execution_count": null, |
| 94 | + "metadata": {}, |
| 95 | + "outputs": [], |
| 96 | + "source": [ |
| 97 | + "def predict(args_dict):\n", |
| 98 | + " return {'prediction': 'not implemented'}" |
| 99 | + ] |
| 100 | + }, |
| 101 | + { |
| 102 | + "cell_type": "markdown", |
| 103 | + "metadata": {}, |
| 104 | + "source": [ |
| 105 | + "## Test Predict Function" |
| 106 | + ] |
| 107 | + }, |
| 108 | + { |
| 109 | + "cell_type": "code", |
| 110 | + "execution_count": null, |
| 111 | + "metadata": {}, |
| 112 | + "outputs": [], |
| 113 | + "source": [ |
| 114 | + "from prediction import predict\n", |
| 115 | + "\n", |
| 116 | + "predict({'keys': 'values'})\n", |
| 117 | + "\n" |
| 118 | + ] |
| 119 | + }, |
| 120 | + { |
| 121 | + "cell_type": "markdown", |
| 122 | + "metadata": {}, |
| 123 | + "source": [ |
| 124 | + "### Run Flask\n", |
| 125 | + "\n", |
| 126 | + "Run flask in a separate notebook ([1_run_flask.ipynb](./1_run_flask.ipynb)) to create a local service to try it out. You must run the application in a separate notebook since it will use the kernel until stopped.\n", |
| 127 | + "\n", |
| 128 | + "```\n", |
| 129 | + "!FLASK_ENV=development FLASK_APP=wsgi.py flask run\n", |
| 130 | + "```" |
| 131 | + ] |
| 132 | + }, |
| 133 | + { |
| 134 | + "cell_type": "markdown", |
| 135 | + "metadata": {}, |
| 136 | + "source": [ |
| 137 | + "### Test the Flask Endpoint\n", |
| 138 | + "\n", |
| 139 | + "Test your new service endpoint in this notebook or from a separate notebook ([2_test_flask.ipynb](./2_test_flask.ipynb)) to try it out. You can \n" |
| 140 | + ] |
| 141 | + }, |
| 142 | + { |
| 143 | + "cell_type": "code", |
| 144 | + "execution_count": null, |
| 145 | + "metadata": {}, |
| 146 | + "outputs": [], |
| 147 | + "source": [ |
| 148 | + "!curl -X POST -H \"Content-Type: application/json\" --data '{\"data\": \"hello world\"}' http://localhost:5000/predictions\n" |
| 149 | + ] |
| 150 | + }, |
| 151 | + { |
| 152 | + "cell_type": "code", |
| 153 | + "execution_count": null, |
| 154 | + "metadata": {}, |
| 155 | + "outputs": [], |
| 156 | + "source": [ |
| 157 | + "import requests\n", |
| 158 | + "import json\n", |
| 159 | + "response = requests.post('http://127.0.0.1:5000/predictions', '{\"hello\":\"world\"}')\n", |
| 160 | + "response.json()" |
| 161 | + ] |
| 162 | + }, |
| 163 | + { |
| 164 | + "cell_type": "markdown", |
| 165 | + "metadata": {}, |
| 166 | + "source": [ |
| 167 | + "### Save Your Project to Git (and Build)\n", |
| 168 | + "\n", |
| 169 | + "Now that you've created and tested your prediction and service endpoint, push the code up to git. This can be built as an s2i application on OpenShift.\n", |
| 170 | + "\n", |
| 171 | + "\n" |
| 172 | + ] |
| 173 | + }, |
| 174 | + { |
| 175 | + "cell_type": "code", |
| 176 | + "execution_count": null, |
| 177 | + "metadata": {}, |
| 178 | + "outputs": [], |
| 179 | + "source": [] |
| 180 | + } |
| 181 | + ], |
| 182 | + "metadata": { |
| 183 | + "accelerator": "GPU", |
| 184 | + "colab": { |
| 185 | + "collapsed_sections": [], |
| 186 | + "name": "Object detection", |
| 187 | + "private_outputs": true, |
| 188 | + "provenance": [], |
| 189 | + "toc_visible": true |
| 190 | + }, |
| 191 | + "kernelspec": { |
| 192 | + "display_name": "Python 3", |
| 193 | + "language": "python", |
| 194 | + "name": "python3" |
| 195 | + }, |
| 196 | + "language_info": { |
| 197 | + "codemirror_mode": { |
| 198 | + "name": "ipython", |
| 199 | + "version": 3 |
| 200 | + }, |
| 201 | + "file_extension": ".py", |
| 202 | + "mimetype": "text/x-python", |
| 203 | + "name": "python", |
| 204 | + "nbconvert_exporter": "python", |
| 205 | + "pygments_lexer": "ipython3", |
| 206 | + "version": "3.6.8" |
| 207 | + } |
| 208 | + }, |
| 209 | + "nbformat": 4, |
| 210 | + "nbformat_minor": 4 |
| 211 | +} |
0 commit comments