sweatstack 0.56.0__py3-none-any.whl → 0.57.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sweatstack/streamlit.py +102 -31
- {sweatstack-0.56.0.dist-info → sweatstack-0.57.0.dist-info}/METADATA +1 -1
- {sweatstack-0.56.0.dist-info → sweatstack-0.57.0.dist-info}/RECORD +5 -5
- {sweatstack-0.56.0.dist-info → sweatstack-0.57.0.dist-info}/WHEEL +1 -1
- {sweatstack-0.56.0.dist-info → sweatstack-0.57.0.dist-info}/entry_points.txt +0 -0
sweatstack/streamlit.py
CHANGED
|
@@ -114,6 +114,9 @@ class StreamlitAuth:
|
|
|
114
114
|
|
|
115
115
|
self.redirect_uri = redirect_uri or os.environ.get("SWEATSTACK_REDIRECT_URI")
|
|
116
116
|
|
|
117
|
+
self._proxy_mode = False
|
|
118
|
+
self._logout_uri = None
|
|
119
|
+
|
|
117
120
|
self.api_key = st.session_state.get("sweatstack_api_key")
|
|
118
121
|
self.refresh_token = st.session_state.get("sweatstack_refresh_token")
|
|
119
122
|
self.client = Client(
|
|
@@ -124,13 +127,97 @@ class StreamlitAuth:
|
|
|
124
127
|
client_secret=self.client_secret,
|
|
125
128
|
)
|
|
126
129
|
|
|
130
|
+
@classmethod
|
|
131
|
+
def behind_proxy(
|
|
132
|
+
cls,
|
|
133
|
+
redirect_uri: str,
|
|
134
|
+
header_name: str = "X-SweatStack-Token",
|
|
135
|
+
logout_uri: str = "/logout",
|
|
136
|
+
) -> "StreamlitAuth":
|
|
137
|
+
"""Create a StreamlitAuth instance for use behind a proxy.
|
|
138
|
+
|
|
139
|
+
Use this method when your Streamlit app runs behind a proxy that handles
|
|
140
|
+
authentication and passes the SweatStack access token via an HTTP header.
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
redirect_uri: The URI to redirect to after login (used by proxy).
|
|
144
|
+
header_name: The HTTP header name containing the access token.
|
|
145
|
+
Defaults to "X-SweatStack-Token".
|
|
146
|
+
logout_uri: The URI to redirect to for logout.
|
|
147
|
+
Defaults to "/logout".
|
|
148
|
+
|
|
149
|
+
Returns:
|
|
150
|
+
StreamlitAuth: An instance configured for proxy mode.
|
|
151
|
+
|
|
152
|
+
Example:
|
|
153
|
+
auth = StreamlitAuth.behind_proxy(
|
|
154
|
+
redirect_uri="https://myapp.example.com/app",
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
if not auth.is_authenticated():
|
|
158
|
+
st.error("Missing authentication header")
|
|
159
|
+
st.stop()
|
|
160
|
+
|
|
161
|
+
activities = auth.client.get_activities()
|
|
162
|
+
"""
|
|
163
|
+
instance = cls(redirect_uri=redirect_uri)
|
|
164
|
+
instance._proxy_mode = True
|
|
165
|
+
instance._logout_uri = logout_uri
|
|
166
|
+
|
|
167
|
+
token = st.context.headers.get(header_name)
|
|
168
|
+
if token:
|
|
169
|
+
instance.api_key = token
|
|
170
|
+
instance.client = Client(token, streamlit_compatible=True)
|
|
171
|
+
|
|
172
|
+
return instance
|
|
173
|
+
|
|
174
|
+
def _show_styled_link_button(self, label: str, url: str):
|
|
175
|
+
"""Displays a styled link button with hover effects.
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
label: Text to display on the button.
|
|
179
|
+
url: The URL to navigate to when clicked.
|
|
180
|
+
"""
|
|
181
|
+
st.markdown(
|
|
182
|
+
f"""
|
|
183
|
+
<style>
|
|
184
|
+
.animated-button {{
|
|
185
|
+
}}
|
|
186
|
+
.animated-button:hover {{
|
|
187
|
+
transform: scale(1.05);
|
|
188
|
+
}}
|
|
189
|
+
.animated-button:active {{
|
|
190
|
+
transform: scale(1);
|
|
191
|
+
}}
|
|
192
|
+
</style>
|
|
193
|
+
<a href="{url}"
|
|
194
|
+
target="_top"
|
|
195
|
+
class="animated-button"
|
|
196
|
+
style="display: inline-block;
|
|
197
|
+
padding: 10px 20px;
|
|
198
|
+
background-color: #EF2B2D;
|
|
199
|
+
color: white;
|
|
200
|
+
text-decoration: none;
|
|
201
|
+
border-radius: 6px;
|
|
202
|
+
border: none;
|
|
203
|
+
transition: all 0.3s ease;
|
|
204
|
+
cursor: pointer;"
|
|
205
|
+
>{label}</a>
|
|
206
|
+
""",
|
|
207
|
+
unsafe_allow_html=True,
|
|
208
|
+
)
|
|
209
|
+
|
|
127
210
|
def logout_button(self):
|
|
128
211
|
"""Displays a logout button and handles user logout.
|
|
129
212
|
|
|
130
|
-
|
|
131
|
-
resets the client, and triggers a Streamlit rerun
|
|
213
|
+
In standard mode, clears the stored API key from session state,
|
|
214
|
+
resets the client, and triggers a Streamlit rerun.
|
|
215
|
+
|
|
216
|
+
In proxy mode, displays a styled link that redirects to the logout URI.
|
|
132
217
|
"""
|
|
133
|
-
if
|
|
218
|
+
if self._proxy_mode:
|
|
219
|
+
self._show_styled_link_button("Logout", self._logout_uri)
|
|
220
|
+
elif st.button("Logout"):
|
|
134
221
|
self.api_key = None
|
|
135
222
|
self.refresh_token = None
|
|
136
223
|
self.client = Client(streamlit_compatible=True)
|
|
@@ -151,34 +238,7 @@ class StreamlitAuth:
|
|
|
151
238
|
authorization_url = self.get_authorization_url()
|
|
152
239
|
login_label = login_label or "Connect with SweatStack"
|
|
153
240
|
if not self._running_on_streamlit_cloud():
|
|
154
|
-
|
|
155
|
-
f"""
|
|
156
|
-
<style>
|
|
157
|
-
.animated-button {{
|
|
158
|
-
}}
|
|
159
|
-
.animated-button:hover {{
|
|
160
|
-
transform: scale(1.05);
|
|
161
|
-
}}
|
|
162
|
-
.animated-button:active {{
|
|
163
|
-
transform: scale(1);
|
|
164
|
-
}}
|
|
165
|
-
</style>
|
|
166
|
-
<a href="{authorization_url}"
|
|
167
|
-
target="_top"
|
|
168
|
-
class="animated-button"
|
|
169
|
-
style="display: inline-block;
|
|
170
|
-
padding: 10px 20px;
|
|
171
|
-
background-color: #EF2B2D;
|
|
172
|
-
color: white;
|
|
173
|
-
text-decoration: none;
|
|
174
|
-
border-radius: 6px;
|
|
175
|
-
border: none;
|
|
176
|
-
transition: all 0.3s ease;
|
|
177
|
-
cursor: pointer;"
|
|
178
|
-
>{login_label}</a>
|
|
179
|
-
""",
|
|
180
|
-
unsafe_allow_html=True,
|
|
181
|
-
)
|
|
241
|
+
self._show_styled_link_button(login_label, authorization_url)
|
|
182
242
|
else:
|
|
183
243
|
st.link_button(login_label, authorization_url)
|
|
184
244
|
|
|
@@ -275,12 +335,23 @@ class StreamlitAuth:
|
|
|
275
335
|
to the Streamlit app with an authorization code, which is exchanged for an
|
|
276
336
|
access token.
|
|
277
337
|
|
|
338
|
+
In proxy mode, this method only shows the login button if not authenticated.
|
|
339
|
+
The proxy handles the OAuth callback and token exchange.
|
|
340
|
+
|
|
278
341
|
Args:
|
|
279
342
|
login_label: The label to display on the login button. Defaults to "Login with SweatStack".
|
|
280
343
|
|
|
281
344
|
Returns:
|
|
282
345
|
None
|
|
283
346
|
"""
|
|
347
|
+
if self._proxy_mode:
|
|
348
|
+
if self.is_authenticated():
|
|
349
|
+
if show_logout:
|
|
350
|
+
self.logout_button()
|
|
351
|
+
else:
|
|
352
|
+
self._show_sweatstack_login(login_label)
|
|
353
|
+
return
|
|
354
|
+
|
|
284
355
|
if self.is_authenticated():
|
|
285
356
|
if not st.session_state.get("sweatstack_auth_toast_shown", False):
|
|
286
357
|
st.toast("SweatStack authentication successful!", icon="✅")
|
|
@@ -7,11 +7,11 @@ sweatstack/jupyterlab_oauth2_startup.py,sha256=YcjXvzeZ459vL_dCkFi1IxX_RNAu80ZX9
|
|
|
7
7
|
sweatstack/openapi_schemas.py,sha256=VvquBdbssdB9D1KeJYQCx51hy1Df4SS0PjzGWXcUaew,46221
|
|
8
8
|
sweatstack/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
9
|
sweatstack/schemas.py,sha256=Xh9E8DjFx5NIEBnVqS6ixFVb0E06ANZbdOlnMofCpZw,4481
|
|
10
|
-
sweatstack/streamlit.py,sha256=
|
|
10
|
+
sweatstack/streamlit.py,sha256=wnabWhife9eMAdkECPjRKkzE82KZoi_H8YzucZl_m9s,19604
|
|
11
11
|
sweatstack/sweatshell.py,sha256=MYLNcWbOdceqKJ3S0Pe8dwHXEeYsGJNjQoYUXpMTftA,333
|
|
12
12
|
sweatstack/utils.py,sha256=AwHRdC1ziOZ5o9RBIB21Uxm-DoClVRAJSVvgsmSmvps,1801
|
|
13
13
|
sweatstack/Sweat Stack examples/Getting started.ipynb,sha256=k2hiSffWecoQ0VxjdpDcgFzBXDQiYEebhnAYlu8cgX8,6335204
|
|
14
|
-
sweatstack-0.
|
|
15
|
-
sweatstack-0.
|
|
16
|
-
sweatstack-0.
|
|
17
|
-
sweatstack-0.
|
|
14
|
+
sweatstack-0.57.0.dist-info/METADATA,sha256=0amcxzS2bzmC9qy3v_9wZ9_DH2BBAkqfvN8gECa7BZ0,852
|
|
15
|
+
sweatstack-0.57.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
16
|
+
sweatstack-0.57.0.dist-info/entry_points.txt,sha256=kCzOUQI3dqbTpEYqtgYDeiKFaqaA7BMlV6D24BMzCFU,208
|
|
17
|
+
sweatstack-0.57.0.dist-info/RECORD,,
|
|
File without changes
|