deeploy-adubowski commited on
Commit
3f46b34
·
1 Parent(s): f556343

Add prediction app to Iris deployment

Browse files
Files changed (5) hide show
  1. .gitignore +2 -0
  2. README.md +8 -1
  3. app.py +204 -0
  4. deeploy_logo_wide.png +0 -0
  5. requirements.txt +3 -0
.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ __pycache__
2
+ .venv
README.md CHANGED
@@ -9,4 +9,11 @@ app_file: app.py
9
  pinned: false
10
  ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
9
  pinned: false
10
  ---
11
 
12
+ # Deeploy Template
13
+ This space holds the template for a Streamlit app using a model deployed with Deeploy.
14
+
15
+ ## Usage
16
+ To use this template, duplicate this space and adjust the `app.py` file to make your own Streamlit app.
17
+
18
+ ## Deployment
19
+ To deploy your app, simply push your changes to your Hugging Face repository. The app will be automatically deployed on Hugging Face spaces.
app.py ADDED
@@ -0,0 +1,204 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # type: ignore -- ignores linting import issues when using multiple virtual environments
2
+ import streamlit.components.v1 as components
3
+ import streamlit as st
4
+ import pandas as pd
5
+ import logging
6
+ from deeploy import Client
7
+ from shap import TreeExplainer
8
+
9
+
10
+ # reset Plotly theme after streamlit import
11
+ import plotly.io as pio
12
+
13
+
14
+ pio.templates.default = "plotly"
15
+
16
+ logging.basicConfig(level=logging.INFO)
17
+
18
+ st.set_page_config(layout="wide")
19
+
20
+ st.title("Your title")
21
+
22
+ st.markdown(
23
+ """
24
+ <style>
25
+ section[data-testid="stSidebar"] {
26
+ width: 300px !important;
27
+ }
28
+ </style>
29
+ """,
30
+ unsafe_allow_html=True,
31
+ ) # Set the side bar width to fit the Deeploy logo
32
+
33
+
34
+ def get_model_url():
35
+ """Function to get Deeploy model URL and split it into workspace and deployment ID."""
36
+ model_url = st.text_area(
37
+ "Model URL (without the /explain endpoint, default is the demo deployment)",
38
+ "https://api.app.deeploy.ml/workspaces/708b5808-27af-461a-8ee5-80add68384c7/deployments/9155091a-0abb-45b3-8b3b-24ac33fa556b/",
39
+ height=125,
40
+ )
41
+ elems = model_url.split("/")
42
+ try:
43
+ workspace_id = elems[4]
44
+ deployment_id = elems[6]
45
+ except IndexError:
46
+ workspace_id = ""
47
+ deployment_id = ""
48
+ return model_url, workspace_id, deployment_id
49
+
50
+
51
+ def ChangeButtonColour(widget_label, font_color, background_color="transparent"):
52
+ """Function to change the color of a button (after it is defined)."""
53
+ htmlstr = f"""
54
+ <script>
55
+ var elements = window.parent.document.querySelectorAll('button');
56
+ for (var i = 0; i < elements.length; ++i) {{
57
+ if (elements[i].innerText == '{widget_label}') {{
58
+ elements[i].style.color ='{font_color}';
59
+ elements[i].style.background = '{background_color}'
60
+ }}
61
+ }}
62
+ </script>
63
+ """
64
+ components.html(f"{htmlstr}", height=0, width=0)
65
+
66
+ def predict():
67
+ with st.spinner("Loading prediction and explanation..."):
68
+ try:
69
+ # Call the explain endpoint as it also includes the prediction
70
+ exp = client.predict(
71
+ request_body=request_body, deployment_id=deployment_id
72
+ )
73
+ except Exception as e:
74
+ logging.error(e)
75
+ st.error(
76
+ "Failed to get prediction."
77
+ + "Check whether you are using the right model URL and token for predictions. "
78
+ + "Contact Deeploy if the problem persists."
79
+ )
80
+ return
81
+ st.session_state.exp = exp
82
+ st.session_state.evaluation_submitted = False
83
+ hide_expander()
84
+
85
+ def hide_expander():
86
+ st.session_state.expander_toggle = False
87
+
88
+ def show_expander():
89
+ st.session_state.expander_toggle = True
90
+
91
+ def submit_and_clear(evaluation: str):
92
+ if evaluation == "yes":
93
+ st.session_state.evaluation_input["result"] = 0 # Agree with the prediction
94
+ else:
95
+ desired_output = not predictions[0]
96
+ st.session_state.evaluation_input["result"] = 1
97
+ st.session_state.evaluation_input["value"] = {"predictions": [desired_output]}
98
+ try:
99
+ # Call the explain endpoint as it also includes the prediction
100
+ client.evaluate(
101
+ deployment_id, request_log_id, prediction_log_id, st.session_state.evaluation_input
102
+ )
103
+ st.session_state.evaluation_submitted = True
104
+ st.session_state.exp = None
105
+ show_expander()
106
+ except Exception as e:
107
+ logging.error(e)
108
+ st.error(
109
+ "Failed to submit feedback."
110
+ + "Check whether you are using the right model URL and token for evaluations. "
111
+ + "Contact Deeploy if the problem persists."
112
+ )
113
+
114
+
115
+ # Define defaults for the session state
116
+ if "expander_toggle" not in st.session_state:
117
+ st.session_state.expander_toggle = True
118
+
119
+ if "exp" not in st.session_state:
120
+ st.session_state.exp = None
121
+
122
+ if "evaluation_submitted" not in st.session_state:
123
+ st.session_state.evaluation_submitted = False
124
+
125
+ # Define sidebar for configuration of Deeploy connection
126
+ with st.sidebar:
127
+ st.image("deeploy_logo_wide.png", width=250)
128
+
129
+ # Ask for model URL and token
130
+ host = st.text_input("Host (Changing is optional)", "app.deeploy.ml")
131
+ model_url, workspace_id, deployment_id = get_model_url()
132
+ deployment_token = st.text_input("Deeploy Model Token", "my-secret-token")
133
+ if deployment_token == "my-secret-token":
134
+ st.warning("Please enter Deeploy API token.")
135
+
136
+ # In case you need to debug the workspace and deployment ID:
137
+ # st.write("Values below are for debug only:")
138
+ # st.write("Workspace ID: ", workspace_id)
139
+ # st.write("Deployment ID: ", deployment_id)
140
+
141
+ client_options = {
142
+ "host": host,
143
+ "deployment_token": deployment_token,
144
+ "workspace_id": workspace_id,
145
+ }
146
+ client = Client(**client_options)
147
+
148
+ # For debugging the session state you can uncomment the following lines:
149
+ # with st.expander("Debug session state", expanded=False):
150
+ # st.write(st.session_state)
151
+
152
+ # Input (for IRIS dataset)
153
+ with st.expander("Input values for prediction", expanded=st.session_state.expander_toggle):
154
+ st.write("Please input the values for the model.")
155
+ col1, col2 = st.columns(2)
156
+ with col1:
157
+ sep_len = st.number_input("Sepal length", value=1.0, step=0.1, key="Sepal length")
158
+ sep_wid = st.number_input("Sepal width", value=1.0, step=0.1, key="Sepal width")
159
+ with col2:
160
+ pet_len = st.number_input("Petal length", value=1.0, step=0.1, key="Petal length")
161
+ pet_wid = st.number_input("Petal width", value=1.0, step=0.1, key="Petal width")
162
+
163
+ request_body = {
164
+ "instances": [
165
+ [
166
+ sep_len,
167
+ sep_wid,
168
+ pet_len,
169
+ pet_wid,
170
+ ],
171
+ ]
172
+ }
173
+
174
+ # Predict and explain
175
+ predict_button = st.button("Predict", on_click=predict)
176
+ if st.session_state.exp is not None:
177
+ st.write(st.session_state.exp)
178
+ # predictions = st.session_state.exp["predictions"]
179
+ # request_log_id = exp["requestLogId"]
180
+ # prediction_log_id = exp["predictionLogIds"][0]
181
+
182
+ # # exp_df = pd.DataFrame(
183
+ # # [exp["explanations"][0]["shap_values"]], columns=exp["featureLabels"]
184
+ # # )
185
+ # st.write("Predictions:", predictions)
186
+
187
+ # # Evaluation
188
+ # if st.session_state.evaluation_submitted is False:
189
+ # evaluation = st.radio("Do you agree with the prediction?", ("yes", "no"))
190
+ # if evaluation == "no":
191
+ # desired_output = # TODO
192
+ # st.session_state.evaluation_input = {
193
+ # "result": 1,
194
+ # "value": {"predictions": [desired_output]},
195
+ # }
196
+ # else:
197
+ # st.session_state.evaluation_input = {"result": 0}
198
+
199
+ # submit_button = st.button("Submit evaluation", on_click=submit_and_clear, args=(evaluation,))
200
+ # else:
201
+ # st.success("Evaluation submitted successfully.")
202
+
203
+
204
+
deeploy_logo_wide.png ADDED
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ deeploy==1.2.1
2
+ streamlit==1.29.0
3
+ plotly==5.18.0