openfree commited on
Commit
cae054e
·
verified ·
1 Parent(s): 8c1efe0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +75 -187
app.py CHANGED
@@ -1,205 +1,93 @@
1
  import os
2
  import gradio as gr
3
- from authlib.integrations.starlette_client import OAuth, OAuthError
4
- from starlette.config import Config
5
- from starlette.middleware.sessions import SessionMiddleware
6
- import secrets
7
- import json
8
 
9
- # 환경 변수에서 Google OAuth 정보 가져오기
10
  GOOGLE_CLIENT_ID = os.environ.get("GOOGLE_CLIENT_ID", "your-client-id")
11
  GOOGLE_CLIENT_SECRET = os.environ.get("GOOGLE_CLIENT_SECRET", "your-secret")
12
 
13
- # Hugging Face Space URL (환경변수로 설정 가능)
14
- SPACE_HOST = os.environ.get("SPACE_HOST", "http://localhost:7860")
15
-
16
- # 세션을 위한 비밀 키
17
- SECRET_KEY = os.environ.get("SECRET_KEY", secrets.token_urlsafe(32))
18
-
19
- # OAuth 설정
20
- config = Config(environ={
21
- 'GOOGLE_CLIENT_ID': GOOGLE_CLIENT_ID,
22
- 'GOOGLE_CLIENT_SECRET': GOOGLE_CLIENT_SECRET
23
- })
24
-
25
- oauth = OAuth(config)
26
- oauth.register(
27
- name='google',
28
- server_metadata_url='https://accounts.google.com/.well-known/openid-configuration',
29
- client_kwargs={'scope': 'openid email profile'}
30
- )
31
-
32
- # 전역 변수로 사용자 정보 저장 (실제 프로덕션에서는 세션 사용 권장)
33
- current_user = None
34
-
35
- def get_login_url():
36
- """Google 로그인 URL 생성"""
37
- redirect_uri = f"{SPACE_HOST}/auth/callback"
38
- return oauth.google.authorize_redirect(redirect_uri).headers['Location']
39
-
40
- def handle_user_info(info):
41
- """사용자 정보 처리"""
42
- global current_user
43
- current_user = info
44
- return info
45
-
46
- def logout():
47
- """로그아웃 처리"""
48
- global current_user
49
- current_user = None
50
- return None, gr.update(visible=True), gr.update(visible=False)
51
-
52
- def create_oauth_app():
53
- with gr.Blocks(title="Google OAuth Gradio 앱") as demo:
54
- gr.Markdown("# Google OAuth 통합 Gradio 앱")
55
-
56
- # 상태 관리를 위한 State
57
- user_info_state = gr.State(value=None)
58
-
59
- # 로그인 전 화면
60
- with gr.Column(visible=True) as login_section:
61
- gr.Markdown("### 환경 설정 상태")
62
- gr.Markdown(f"✅ Client ID 설정됨" if GOOGLE_CLIENT_ID != "your-client-id" else "❌ Client ID 미설정")
63
- gr.Markdown(f"✅ Client Secret 설정됨" if GOOGLE_CLIENT_SECRET != "your-secret" else "❌ Client Secret 미설정")
64
-
65
- gr.Markdown("---")
66
- gr.Markdown("### Google 로그인이 필요합니다")
67
-
68
- if GOOGLE_CLIENT_ID != "your-client-id" and GOOGLE_CLIENT_SECRET != "your-secret":
69
- login_btn = gr.Button("🔐 Google로 로그인", variant="primary", size="lg")
70
- gr.Markdown("""
71
- **참고:** Hugging Face Spaces에서는 OAuth 리다이렉트가 제한적일 수 있습니다.
72
-
73
- OAuth 설정 방법:
74
- 1. [Google Cloud Console](https://console.cloud.google.com/)에서 OAuth 2.0 클라이언트 생성
75
- 2. 승인된 리다이렉트 URI에 추가:
76
- - `https://[space-name].hf.space/auth/callback`
77
- - `http://localhost:7860/auth/callback` (로컬 테스트용)
78
- 3. Hugging Face Space Settings에서 환경변수 설정
79
- """)
80
- else:
81
- gr.Markdown("""
82
- ⚠️ **OAuth 설정이 필요합니다**
83
-
84
- 1. 환경변수 `GOOGLE_CLIENT_ID`와 `GOOGLE_CLIENT_SECRET` 설정
85
- 2. Hugging Face Space Settings > Variables and secrets에서 추가
86
- """)
87
-
88
- # 로그인 후 화면
89
- with gr.Column(visible=False) as user_section:
90
- gr.Markdown("### 👤 로그인된 사용자 정보")
91
-
92
- with gr.Row():
93
- user_name = gr.Textbox(label="이름", interactive=False)
94
- user_email = gr.Textbox(label="이메일", interactive=False)
95
-
96
- user_picture = gr.Image(label="프로필 사진", type="filepath", interactive=False, height=100)
97
-
98
- logout_btn = gr.Button("로그아웃", variant="secondary")
99
-
100
- gr.Markdown("---")
101
- gr.Markdown("### 🎉 환영합니다! 이제 앱을 사용할 수 있습니다.")
102
-
103
- # 로그인 후 사용 가능한 기능들
104
- with gr.Row():
105
- name_input = gr.Textbox(label="인사할 이름", placeholder="친구 이름")
106
- greeting_output = gr.Textbox(label="개인화된 인사말")
107
-
108
- greet_btn = gr.Button("인사하기")
109
-
110
- def personalized_greet(name, user_info):
111
- if user_info and name:
112
- user_name = user_info.get('name', '사용자')
113
- return f"안녕하세요 {name}님! {user_name}님이 인사드립니다! 😊"
114
- return "이름을 입력해주세요."
115
-
116
- greet_btn.click(
117
- fn=personalized_greet,
118
- inputs=[name_input, user_info_state],
119
- outputs=greeting_output
120
- )
121
 
122
- # 임시 로그인 시뮬레이션 (실제로는 OAuth 콜백 처리 필요)
123
- def simulate_login():
124
- # 실제로는 OAuth 콜백에서 받은 정보를 사용
125
- fake_user_info = {
126
- 'name': '테스트 사용자',
127
- 'email': 'test@example.com',
128
- 'picture': 'https://via.placeholder.com/100'
129
- }
130
- return (
131
- fake_user_info, # user_info_state
132
- gr.update(visible=False), # login_section
133
- gr.update(visible=True), # user_section
134
- fake_user_info.get('name', ''), # user_name
135
- fake_user_info.get('email', ''), # user_email
136
- fake_user_info.get('picture', '') # user_picture
137
- )
138
 
139
- def handle_logout():
140
- return (
141
- None, # user_info_state
142
- gr.update(visible=True), # login_section
143
- gr.update(visible=False), # user_section
144
- '', # user_name
145
- '', # user_email
146
- None # user_picture
147
- )
148
 
149
- if GOOGLE_CLIENT_ID != "your-client-id" and GOOGLE_CLIENT_SECRET != "your-secret":
150
- login_btn.click(
151
- fn=simulate_login,
152
- inputs=[],
153
- outputs=[user_info_state, login_section, user_section, user_name, user_email, user_picture]
 
 
 
 
154
  )
 
 
 
 
 
 
 
 
155
 
156
- logout_btn.click(
157
- fn=handle_logout,
158
- inputs=[],
159
- outputs=[user_info_state, login_section, user_section, user_name, user_email, user_picture]
160
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
 
162
- # OAuth 콜백 처리를 위한 숨겨진 컴포넌트
163
  gr.Markdown("""
164
- <script>
165
- // OAuth 콜백 처리를 위한 JavaScript
166
- if (window.location.search.includes('code=')) {
167
- console.log('OAuth callback detected');
168
- // 실제 구현시 여기서 토큰 교환 및 사용자 정보 가져오기
169
- }
170
- </script>
171
- """, visible=False)
172
 
173
  return demo
174
 
175
- # Gradio 앱 ��성
176
- demo = create_oauth_app()
177
-
178
- # 미들웨어 추가 (세션 관리)
179
- demo.app.add_middleware(SessionMiddleware, secret_key=SECRET_KEY)
180
-
181
- # OAuth 라우트 추가 (Gradio 앱에 커스텀 라우트 추가)
182
- @demo.app.get("/auth/google")
183
- async def auth_google(request):
184
- redirect_uri = f"{SPACE_HOST}/auth/callback"
185
- return await oauth.google.authorize_redirect(request, redirect_uri)
186
-
187
- @demo.app.get("/auth/callback")
188
- async def auth_callback(request):
189
- try:
190
- token = await oauth.google.authorize_access_token(request)
191
- user = token.get('userinfo')
192
- if user:
193
- request.session['user'] = user
194
- return {"status": "success", "user": user}
195
- except OAuthError as e:
196
- return {"status": "error", "message": str(e)}
197
-
198
- # requirements.txt에 추가 필요:
199
- # gradio
200
- # authlib
201
- # httpx
202
- # starlette
203
 
204
  if __name__ == "__main__":
205
- demo.launch(server_name="0.0.0.0", server_port=7860)
 
1
  import os
2
  import gradio as gr
 
 
 
 
 
3
 
4
+ # 환경 변수에서 설정 가져오기
5
  GOOGLE_CLIENT_ID = os.environ.get("GOOGLE_CLIENT_ID", "your-client-id")
6
  GOOGLE_CLIENT_SECRET = os.environ.get("GOOGLE_CLIENT_SECRET", "your-secret")
7
 
8
+ # Gradio의 기본 인증 사용 (OAuth 대신)
9
+ USERS = os.environ.get("USERS", "user1:pass1,user2:pass2").split(",")
10
+ auth_dict = {}
11
+ for user in USERS:
12
+ if ":" in user:
13
+ username, password = user.split(":", 1)
14
+ auth_dict[username] = password
15
+
16
+ def create_app():
17
+ with gr.Blocks(title="Google 로그인 스타일 앱") as demo:
18
+ gr.Markdown("# 🔐 로그인이 필요한 Gradio 앱")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
+ # 환경 설정 상태
21
+ gr.Markdown("### 환경 설정 상태")
22
+ gr.Markdown(f"✅ Client ID 설정됨" if GOOGLE_CLIENT_ID != "your-client-id" else "❌ Client ID 미설정")
23
+ gr.Markdown(f"✅ Client Secret 설정됨" if GOOGLE_CLIENT_SECRET != "your-secret" else "❌ Client Secret 미설정")
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
+ gr.Markdown("---")
 
 
 
 
 
 
 
 
26
 
27
+ # 메인 기능
28
+ gr.Markdown("### 👋 환영합니다!")
29
+ gr.Markdown("이 앱은 로그인된 사용자만 사용할 수 있습니다.")
30
+
31
+ with gr.Row():
32
+ name_input = gr.Textbox(
33
+ label="이름을 입력하세요",
34
+ placeholder="홍길동",
35
+ info="인사받을 이름을 입력하세요"
36
  )
37
+ output = gr.Textbox(label="인사말")
38
+
39
+ greet_btn = gr.Button("인사하기", variant="primary")
40
+
41
+ def greet(name):
42
+ if name:
43
+ return f"안녕하세요, {name}님! 로그인해주셔서 감사합니다! 😊"
44
+ return "이름을 입력해주세요."
45
 
46
+ greet_btn.click(fn=greet, inputs=name_input, outputs=output)
47
+
48
+ gr.Markdown("---")
49
+
50
+ # Google OAuth 안내
51
+ gr.Markdown("""
52
+ ### 📝 Google OAuth 통합 안내
53
+
54
+ Hugging Face Spaces는 서버사이드 OAuth를 완전히 지원하지 않습니다.
55
+
56
+ **대안:**
57
+ 1. **Gradio 기본 인증 사용** (현재 적용됨)
58
+ - Space Settings에서 `USERS` 환경변수 설정
59
+ - 예: `USERS=admin:password123,user:pass456`
60
+
61
+ 2. **Google OAuth 버튼 (외부 링크)**
62
+ - 아래 버튼을 클릭하면 Google 로그인 페이지로 이동합니다
63
+ """)
64
+
65
+ # Google OAuth URL 생성 (클라이언트 사이드)
66
+ if GOOGLE_CLIENT_ID != "your-client-id":
67
+ oauth_url = f"https://accounts.google.com/o/oauth2/v2/auth?client_id={GOOGLE_CLIENT_ID}&redirect_uri=https://your-space.hf.space&response_type=token&scope=email%20profile"
68
+ gr.Markdown(f"[🔗 Google로 로그인]({oauth_url})")
69
 
 
70
  gr.Markdown("""
71
+ ### 🔧 설정 방법
72
+
73
+ 1. **Hugging Face Space Settings > Variables**에서:
74
+ - `USERS`: 사용자명:비밀번호 형식으로 설정
75
+ - 예: `admin:mypassword,john:doe123`
76
+
77
+ 2. **앱 재시작 후 로그인 창이 표시됩니다**
78
+ """)
79
 
80
  return demo
81
 
82
+ # 인증이 있는 앱 생성
83
+ if auth_dict:
84
+ # 사용자 인증이 설정된 경우
85
+ demo = create_app()
86
+ demo.auth = list(auth_dict.items())
87
+ demo.auth_message = "Google 계정 대신 설정된 사용자명/비밀번호를 사용하세요"
88
+ else:
89
+ # 인증이 설정되지 않은 경우
90
+ demo = create_app()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
 
92
  if __name__ == "__main__":
93
+ demo.launch(server_name="0.0.0.0", server_port=786