Spaces:
Sleeping
Sleeping
internomega-terrablue commited on
Commit ·
8547fff
1
Parent(s): d308d8e
Enabling login for oauth changes
Browse files- Dockerfile +21 -0
- README.md +2 -3
- auth.py +9 -26
- entrypoint.sh +24 -0
- requirements.txt +2 -1
Dockerfile
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM python:3.12-slim
|
| 2 |
+
|
| 3 |
+
WORKDIR /app
|
| 4 |
+
|
| 5 |
+
RUN apt-get update && apt-get install -y \
|
| 6 |
+
build-essential \
|
| 7 |
+
curl \
|
| 8 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 9 |
+
|
| 10 |
+
COPY requirements.txt ./
|
| 11 |
+
RUN pip install --no-cache-dir -r requirements.txt
|
| 12 |
+
|
| 13 |
+
COPY . .
|
| 14 |
+
|
| 15 |
+
RUN chmod +x /app/entrypoint.sh
|
| 16 |
+
|
| 17 |
+
EXPOSE 8501
|
| 18 |
+
|
| 19 |
+
HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
|
| 20 |
+
|
| 21 |
+
ENTRYPOINT ["/app/entrypoint.sh"]
|
README.md
CHANGED
|
@@ -3,9 +3,8 @@ title: NotebookLM
|
|
| 3 |
emoji: 🚀
|
| 4 |
colorFrom: red
|
| 5 |
colorTo: red
|
| 6 |
-
sdk:
|
| 7 |
-
|
| 8 |
-
app_file: app.py
|
| 9 |
hf_oauth: true
|
| 10 |
hf_oauth_expiration_minutes: 480
|
| 11 |
tags:
|
|
|
|
| 3 |
emoji: 🚀
|
| 4 |
colorFrom: red
|
| 5 |
colorTo: red
|
| 6 |
+
sdk: docker
|
| 7 |
+
app_port: 8501
|
|
|
|
| 8 |
hf_oauth: true
|
| 9 |
hf_oauth_expiration_minutes: 480
|
| 10 |
tags:
|
auth.py
CHANGED
|
@@ -2,23 +2,12 @@ import streamlit as st
|
|
| 2 |
import os
|
| 3 |
|
| 4 |
|
| 5 |
-
def _get_hf_user_info():
|
| 6 |
-
"""Try available Streamlit user APIs (handles version differences)."""
|
| 7 |
-
# HF Streamlit SDK injects st.experimental_user with OAuth info
|
| 8 |
-
if hasattr(st, "experimental_user"):
|
| 9 |
-
return st.experimental_user
|
| 10 |
-
# Newer Streamlit versions may use st.user
|
| 11 |
-
if hasattr(st, "user") and callable(getattr(st.user, "get", None)):
|
| 12 |
-
return st.user
|
| 13 |
-
return None
|
| 14 |
-
|
| 15 |
-
|
| 16 |
def get_current_user() -> dict | None:
|
| 17 |
"""
|
| 18 |
-
Get the currently logged-in user.
|
| 19 |
|
| 20 |
-
On HF Spaces
|
| 21 |
-
|
| 22 |
Locally: uses a dev user so the app is testable without OAuth.
|
| 23 |
|
| 24 |
Returns dict with 'id' and 'name', or None if not authenticated.
|
|
@@ -26,15 +15,13 @@ def get_current_user() -> dict | None:
|
|
| 26 |
is_hf_space = os.environ.get("SPACE_ID") is not None
|
| 27 |
|
| 28 |
if is_hf_space:
|
| 29 |
-
|
| 30 |
-
if user_info and user_info.get("is_logged_in"):
|
| 31 |
return {
|
| 32 |
-
"id":
|
| 33 |
-
"name":
|
| 34 |
}
|
| 35 |
return None
|
| 36 |
else:
|
| 37 |
-
# Local development — use a mock user
|
| 38 |
return {
|
| 39 |
"id": "dev_user",
|
| 40 |
"name": "Dev User (local)",
|
|
@@ -52,18 +39,14 @@ def require_auth() -> dict:
|
|
| 52 |
st.markdown(
|
| 53 |
'<div style="text-align:center; padding:60px 20px;">'
|
| 54 |
'<h1>NotebookLM</h1>'
|
| 55 |
-
'<p style="color:#888; font-size:1.1rem;">
|
| 56 |
"</div>",
|
| 57 |
unsafe_allow_html=True,
|
| 58 |
)
|
| 59 |
_col1, col2, _col3 = st.columns([1, 1, 1])
|
| 60 |
with col2:
|
| 61 |
-
st.
|
| 62 |
-
|
| 63 |
-
"/oauth/login",
|
| 64 |
-
use_container_width=True,
|
| 65 |
-
type="primary",
|
| 66 |
-
)
|
| 67 |
st.stop()
|
| 68 |
|
| 69 |
return user
|
|
|
|
| 2 |
import os
|
| 3 |
|
| 4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
def get_current_user() -> dict | None:
|
| 6 |
"""
|
| 7 |
+
Get the currently logged-in user via Streamlit's native auth (st.user).
|
| 8 |
|
| 9 |
+
On HF Spaces: secrets.toml is auto-generated from HF OAuth env vars
|
| 10 |
+
by entrypoint.sh, so st.login()/st.user just works.
|
| 11 |
Locally: uses a dev user so the app is testable without OAuth.
|
| 12 |
|
| 13 |
Returns dict with 'id' and 'name', or None if not authenticated.
|
|
|
|
| 15 |
is_hf_space = os.environ.get("SPACE_ID") is not None
|
| 16 |
|
| 17 |
if is_hf_space:
|
| 18 |
+
if st.user.is_logged_in:
|
|
|
|
| 19 |
return {
|
| 20 |
+
"id": st.user.get("sub", st.user.get("name", "unknown")),
|
| 21 |
+
"name": st.user.get("name", st.user.get("preferred_username", "User")),
|
| 22 |
}
|
| 23 |
return None
|
| 24 |
else:
|
|
|
|
| 25 |
return {
|
| 26 |
"id": "dev_user",
|
| 27 |
"name": "Dev User (local)",
|
|
|
|
| 39 |
st.markdown(
|
| 40 |
'<div style="text-align:center; padding:60px 20px;">'
|
| 41 |
'<h1>NotebookLM</h1>'
|
| 42 |
+
'<p style="color:#888; font-size:1.1rem;">Sign in with your Hugging Face account to continue.</p>'
|
| 43 |
"</div>",
|
| 44 |
unsafe_allow_html=True,
|
| 45 |
)
|
| 46 |
_col1, col2, _col3 = st.columns([1, 1, 1])
|
| 47 |
with col2:
|
| 48 |
+
if st.button("Sign in with Hugging Face", use_container_width=True, type="primary"):
|
| 49 |
+
st.login()
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
st.stop()
|
| 51 |
|
| 52 |
return user
|
entrypoint.sh
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
set -e
|
| 3 |
+
|
| 4 |
+
# Generate .streamlit/secrets.toml from HF OAuth environment variables
|
| 5 |
+
mkdir -p /app/.streamlit
|
| 6 |
+
|
| 7 |
+
REDIRECT="https://${SPACE_HOST}/oauth2callback"
|
| 8 |
+
|
| 9 |
+
cat > /app/.streamlit/secrets.toml <<EOF
|
| 10 |
+
[auth]
|
| 11 |
+
redirect_uri = "${REDIRECT}"
|
| 12 |
+
cookie_secret = "$(python3 -c 'import secrets; print(secrets.token_hex(32))')"
|
| 13 |
+
client_id = "${OAUTH_CLIENT_ID}"
|
| 14 |
+
client_secret = "${OAUTH_CLIENT_SECRET}"
|
| 15 |
+
server_metadata_url = "${OPENID_PROVIDER_URL}/.well-known/openid-configuration"
|
| 16 |
+
EOF
|
| 17 |
+
|
| 18 |
+
echo "Generated secrets.toml with redirect_uri=${REDIRECT}"
|
| 19 |
+
|
| 20 |
+
exec streamlit run app.py \
|
| 21 |
+
--server.port=8501 \
|
| 22 |
+
--server.address=0.0.0.0 \
|
| 23 |
+
--server.enableCORS=false \
|
| 24 |
+
--server.enableXsrfProtection=false
|
requirements.txt
CHANGED
|
@@ -1 +1,2 @@
|
|
| 1 |
-
streamlit>=1.
|
|
|
|
|
|
| 1 |
+
streamlit>=1.42.0
|
| 2 |
+
authlib>=1.3.2
|