Chris Addis commited on
Commit
9e37410
·
1 Parent(s): 4d38d62
Files changed (2) hide show
  1. app.py +129 -0
  2. requirements.txt +6 -0
app.py ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+
4
+ # --- Configuration ---
5
+ # In your Hugging Face Space settings, add a Secret named `AUTHORIZED_USER_IDS`.
6
+ # The value should be a comma-separated string of the Hugging Face User IDs
7
+ # that you want to grant "full access" to (e.g., "user_id_123,user_id_456").
8
+ # You can find your Hugging Face User ID in your profile URL or settings.
9
+
10
+ # IMPORTANT: This secret should be set in the Hugging Face Space settings, NOT hardcoded here.
11
+ # We retrieve it using os.environ.get() which accesses the Space's environment variables/secrets.
12
+ # Provide a default empty string for local testing where the secret won't exist.
13
+ authorized_users_str = os.environ.get("AUTHORIZED_USER_IDS", "")
14
+ AUTHORIZED_USER_IDS = set(authorized_users_str.split(','))
15
+
16
+ # --- Application Logic ---
17
+
18
+ def get_user_access_level(request: gr.Request):
19
+ """
20
+ Checks the request object to determine if a user is logged in via HF OAuth
21
+ and their access level based on the AUTHORIZED_USER_IDS list.
22
+ Includes a check to prevent AssertionError if request.auth is not available.
23
+ """
24
+ user_info = None
25
+ # Defensive check: Only try to access request.auth if the 'auth' attribute exists
26
+ # and is not None. This prevents the AssertionError if the middleware hasn't run
27
+ # or request.auth isn't populated in this context.
28
+ if hasattr(request, 'auth') and request.auth is not None:
29
+ user_info = request.auth
30
+ # print(f"Accessed request.auth: {user_info}") # Debugging line
31
+ else:
32
+ # print("request.auth not available or is None.") # Debugging line
33
+ pass # Keep print statements minimal in final deployed code
34
+
35
+ if user_info is None:
36
+ # User is not logged in or auth info is not available in the request context
37
+ print("User not logged in or auth info not retrieved via request.auth.")
38
+ return {
39
+ "status_message": "Please sign in with Hugging Face to check your access.",
40
+ "user_identity": "Not Logged In or Auth Info Unavailable",
41
+ "show_login_prompt": gr.update(visible=True),
42
+ "show_limited_content": gr.update(visible=True),
43
+ "show_full_content": gr.update(visible=False)
44
+ }
45
+ else:
46
+ # User info is available (presumably logged in via HF OAuth)
47
+ user_id = user_info.get('sub') # 'sub' is the standard claim for user ID
48
+ username = user_info.get('preferred_username', user_id) # Use username or ID as fallback
49
+
50
+ print(f"Logged in user: Username={username}, ID={user_id}") # Log for debugging
51
+
52
+ # Check if user_id is in the authorized set and is not just an empty string from split(",")
53
+ if user_id in AUTHORIZED_USER_IDS and user_id != "":
54
+ # User is authorized for full access
55
+ print(f"User {user_id} is authorized for full access.")
56
+ return {
57
+ "status_message": f"Welcome, {username}! You have Full Access.",
58
+ "user_identity": f"Logged in as: {username} (ID: {user_id})",
59
+ "show_login_prompt": gr.update(visible=False),
60
+ "show_limited_content": gr.update(visible=False), # Hide limited content for full users
61
+ "show_full_content": gr.update(visible=True)
62
+ }
63
+ else:
64
+ # User is logged in but not authorized for full access
65
+ print(f"User {user_id} is logged in but not authorized.")
66
+ return {
67
+ "status_message": f"Welcome, {username}. You have Limited Access.",
68
+ "user_identity": f"Logged in as: {username} (ID: {user_id})",
69
+ "show_login_prompt": gr.update(visible=False),
70
+ "show_limited_content": gr.update(visible=True),
71
+ "show_full_content": gr.update(visible=False)
72
+ }
73
+
74
+ # --- Gradio Interface ---
75
+
76
+ with gr.Blocks() as demo:
77
+ gr.Markdown("# Hugging Face Spaces Tiered Access Example")
78
+
79
+ # Components to display status and user identity
80
+ status_message = gr.Markdown("Click 'Check My Access Level' after signing in.")
81
+ user_identity_text = gr.Textbox(label="Logged In User Info", interactive=False)
82
+
83
+ # Placeholder for the Login Prompt (visible by default)
84
+ with gr.Column(visible=True) as login_prompt_column:
85
+ gr.Markdown("### Please Sign in with Hugging Face")
86
+ gr.Markdown("*(A 'Sign in with Hugging Face' button will appear automatically above this section when deployed on HF Spaces with OAuth enabled)*")
87
+ # The actual login button is added by Hugging Face Spaces when hf_oauth: true is set in README.md
88
+
89
+ # Content for users with Limited Access (visible by default)
90
+ with gr.Column(visible=True) as limited_content_column:
91
+ gr.Markdown("## Limited Access Content")
92
+ gr.Textbox(value="This is content visible to everyone or users with limited access.", interactive=False)
93
+ gr.Markdown("*(Sign in with Hugging Face and click 'Check My Access Level' to see your status and potentially unlock full features!)*")
94
+ # Add other limited features here
95
+
96
+ # Content for users with Full Access (hidden by default)
97
+ with gr.Column(visible=False) as full_content_column:
98
+ gr.Markdown("## Full Access Content")
99
+ gr.Textbox(value="🥳 Congratulations! You have unlocked the full version! 🥳", interactive=False)
100
+ gr.Markdown("*(This content is only for authorized accounts)*")
101
+ # Add other full features here
102
+
103
+ # This button triggers the check_access_level function.
104
+ # The user should click this *after* potentially signing in via the HF button.
105
+ check_button = gr.Button("Check My Access Level")
106
+
107
+ # Link the button click to the access check function
108
+ # The outputs will update the visibility and text components
109
+ check_button.click(
110
+ fn=get_user_access_level,
111
+ inputs=None, # Request object is implicitly passed by Gradio
112
+ outputs=[
113
+ status_message,
114
+ user_identity_text,
115
+ login_prompt_column,
116
+ limited_content_column,
117
+ full_content_column
118
+ ]
119
+ )
120
+
121
+ # Removed the demo.load() call again, as it seems problematic with request.auth
122
+ # The initial state is controlled by component 'visible' attributes.
123
+
124
+ # --- Launch the App ---
125
+ # For local testing, hf_oauth won't work, request.auth will not be available,
126
+ # but the app should now run without the AssertionError on button click due to the check.
127
+ # It will show the login prompt and limited content.
128
+ # For deployment on HF Spaces, configure README.md and Secrets.
129
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ gradio==5.24.0
2
+ numpy>=1.24.0
3
+ Pillow>=10.0.0
4
+ requests>=2.28.0
5
+ python-dotenv>=1.0.0
6
+ openai>=1.0.0