├── requirements.txt ├── iris_decision_tree.joblib ├── .ipynb_checkpoints └── iris_decision_tree-checkpoint.ipynb ├── Dockerfile ├── README.md ├── main.py └── iris_decision_tree.ipynb /requirements.txt: -------------------------------------------------------------------------------- 1 | ipykernel==5.1.4 2 | jupyter==1.0.0 3 | scikit-learn==0.24.1 4 | joblib==1.0.1 5 | flask==1.1.1 -------------------------------------------------------------------------------- /iris_decision_tree.joblib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stevanusandrianta/bangkit-ml-deployment/HEAD/iris_decision_tree.joblib -------------------------------------------------------------------------------- /.ipynb_checkpoints/iris_decision_tree-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [], 3 | "metadata": {}, 4 | "nbformat": 4, 5 | "nbformat_minor": 5 6 | } 7 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.8-slim-buster 2 | 3 | WORKDIR /app 4 | 5 | COPY requirements.txt requirements.txt 6 | RUN pip3 install -r requirements.txt 7 | 8 | COPY . . 9 | 10 | ENV FLASK_APP=main 11 | 12 | CMD ["python3", "-m" , "flask", "run", "--host=0.0.0.0"] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Deployment 2 | 3 | ```bash 4 | export FLASK_APP=main 5 | flask run 6 | ``` 7 | 8 | 9 | # Send request 10 | 11 | ```bash 12 | curl localhost:5000 13 | 14 | curl -X POST -d "1" localhost:5000/predict 15 | ``` 16 | 17 | 18 | # Docker 19 | 20 | ```bash 21 | docker build -t bangkit-ml-deployment:latest . 22 | 23 | docker run bangkit-ml-deployment:latest 24 | ``` -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import json 2 | import joblib 3 | 4 | from flask import Flask, request 5 | 6 | app = Flask(__name__) 7 | 8 | iris_decision_tree = joblib.load("iris_decision_tree.joblib") 9 | 10 | @app.route("/") 11 | def hello(): 12 | return "Hello, World!" 13 | 14 | @app.route("/predict", methods=["POST"]) 15 | def predict(): 16 | request_json = request.json 17 | print("data: {}".format(request_json)) 18 | print("type: {}".format(type(request_json))) 19 | 20 | prediction = iris_decision_tree.predict(request_json.get('data')) 21 | prediction_string = [str(d) for d in prediction] 22 | response_json = { 23 | "data" : request_json.get("data"), 24 | "prediction" : list(prediction_string) 25 | } 26 | 27 | return json.dumps(response_json) 28 | 29 | if __name__ == '__main__': 30 | app.run(host='0.0.0.0', port=5000) -------------------------------------------------------------------------------- /iris_decision_tree.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "requested-childhood", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "from sklearn import datasets\n", 11 | "from sklearn.metrics import accuracy_score\n", 12 | "from sklearn.model_selection import train_test_split\n", 13 | "from sklearn.tree import DecisionTreeClassifier\n", 14 | "\n", 15 | "import joblib" 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": 2, 21 | "id": "charitable-insertion", 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [ 25 | "iris = datasets.load_iris()\n", 26 | "X = iris.data\n", 27 | "y = iris.target" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 3, 33 | "id": "ambient-aluminum", 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [ 37 | "X_train, X_test, y_train, y_test = (\n", 38 | " train_test_split(X, y, test_size=0.2, random_state=216))" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": 4, 44 | "id": "chicken-strategy", 45 | "metadata": {}, 46 | "outputs": [ 47 | { 48 | "data": { 49 | "text/plain": [ 50 | "DecisionTreeClassifier()" 51 | ] 52 | }, 53 | "execution_count": 4, 54 | "metadata": {}, 55 | "output_type": "execute_result" 56 | } 57 | ], 58 | "source": [ 59 | "tree = DecisionTreeClassifier()\n", 60 | "tree.fit(X_train, y_train)" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 13, 66 | "id": "stainless-following", 67 | "metadata": {}, 68 | "outputs": [ 69 | { 70 | "name": "stdout", 71 | "output_type": "stream", 72 | "text": [ 73 | "accuracy: 0.9\n" 74 | ] 75 | } 76 | ], 77 | "source": [ 78 | "prediction = tree.predict(X_test)\n", 79 | "print(\"accuracy: {}\".format(accuracy_score(y_test, prediction)))" 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": 6, 85 | "id": "finite-giving", 86 | "metadata": {}, 87 | "outputs": [ 88 | { 89 | "data": { 90 | "text/plain": [ 91 | "['iris_decision_tree.joblib']" 92 | ] 93 | }, 94 | "execution_count": 6, 95 | "metadata": {}, 96 | "output_type": "execute_result" 97 | } 98 | ], 99 | "source": [ 100 | "#export sklearn model into file\n", 101 | "joblib.dump(tree, 'iris_decision_tree.joblib')" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": null, 107 | "id": "continental-cleaning", 108 | "metadata": {}, 109 | "outputs": [], 110 | "source": [] 111 | } 112 | ], 113 | "metadata": { 114 | "kernelspec": { 115 | "display_name": "Python 3", 116 | "language": "python", 117 | "name": "python3" 118 | }, 119 | "language_info": { 120 | "codemirror_mode": { 121 | "name": "ipython", 122 | "version": 3 123 | }, 124 | "file_extension": ".py", 125 | "mimetype": "text/x-python", 126 | "name": "python", 127 | "nbconvert_exporter": "python", 128 | "pygments_lexer": "ipython3", 129 | "version": "3.7.6" 130 | } 131 | }, 132 | "nbformat": 4, 133 | "nbformat_minor": 5 134 | } 135 | --------------------------------------------------------------------------------