fhudi commited on
Commit
83d2c0a
·
1 Parent(s): 7d76671

update app.py

Browse files
Files changed (1) hide show
  1. app.py +41 -139
app.py CHANGED
@@ -1,5 +1,5 @@
 
1
  import os
2
-
3
  # os.environ.setdefault("GRADIO_SERVER_PORT", "1080")
4
  # os.environ.setdefault("TEXTGAMES_SHOW_HIDDEN_LEVEL", "1")
5
  os.environ.setdefault("TEXTGAMES_LOADGAME_DIR", "problemsets")
@@ -9,163 +9,64 @@ os.environ.setdefault("TEXTGAMES_OUTPUT_DIR", "user_outputs")
9
  favicon_path = "textgames-scrabble-black2-ss.png"
10
 
11
  #%%
12
- from textgames import GAME_NAMES, LEVELS
13
- from play_helper import declare_components, start_new_game, check_to_start_new_game,\
14
- session_state_change_fn, js_solved_games_df_and_remove_footers, js_remove_input_helper, solved_games_change_fn, check_played_game
15
- from typing import Optional
16
- import hashlib
17
-
18
-
19
- #%%
20
- import uvicorn
21
- from fastapi import FastAPI, Depends, Request
22
- from starlette.config import Config
23
- from starlette.responses import RedirectResponse, FileResponse
24
- from starlette.middleware.sessions import SessionMiddleware
25
- from authlib.integrations.starlette_client import OAuth, OAuthError
26
  import gradio as gr
27
 
28
- app = FastAPI()
29
-
30
- # Replace these with your own OAuth settings
31
- GOOGLE_CLIENT_ID = os.environ.get("GOOGLE_CLIENT_ID")
32
- GOOGLE_CLIENT_SECRET = os.environ.get("GOOGLE_CLIENT_SECRET")
33
- SECRET_KEY = os.environ.get("SECRET_KEY", "a_very_secret_key")
34
-
35
- # Set up OAuth
36
- config_data = {'GOOGLE_CLIENT_ID': GOOGLE_CLIENT_ID, 'GOOGLE_CLIENT_SECRET': GOOGLE_CLIENT_SECRET}
37
- starlette_config = Config(environ=config_data)
38
- oauth = OAuth(starlette_config)
39
- oauth.register(
40
- name='google',
41
- server_metadata_url='https://accounts.google.com/.well-known/openid-configuration',
42
- client_kwargs={'scope': 'openid email profile'},
43
- )
44
-
45
- app.add_middleware(SessionMiddleware, secret_key=SECRET_KEY)
46
-
47
- _HASHER = (hashlib.blake2b, {"digest_size": 16, "key": SECRET_KEY.encode('utf-8')})
48
-
49
-
50
- def _hash_msg(msg):
51
- return msg
52
- # if isinstance(msg, str):
53
- # msg = msg.encode('utf-8')
54
- # m = _HASHER[0](**_HASHER[1])
55
- # m.update(msg)
56
- # return m.hexdigest()
57
-
58
-
59
- # Dependency to get the current user
60
- def get_user(request: Request) -> Optional[dict]:
61
- if user := request.session.get('user'):
62
- return user
63
- elif username := os.getenv("TEXTGAMES_MOCKUSER", ""):
64
- return {'name': username, 'email': username, 'email_verified': False}
65
- else:
66
- return
67
-
68
-
69
- def get_username(request: Request):
70
- user = get_user(request)
71
- if user:
72
- return user['email']
73
- return None
74
-
75
 
76
- @app.get('/favicon.ico', include_in_schema=False)
77
- async def favicon():
78
- return FileResponse(favicon_path)
79
-
80
-
81
- @app.get('/')
82
- def public(user: str = Depends(get_username)):
83
- if user:
84
- return RedirectResponse(url='/TextGames')
85
- else:
86
- return RedirectResponse(url='/login')
87
 
88
 
89
- @app.route('/logout')
90
- async def logout(request: Request):
91
- request.session.pop('user', None)
92
  if os.getenv('TEXTGAMES_MOCKUSER', ''):
93
- os.environ['TEXTGAMES_MOCKUSER'] = ''
94
- return RedirectResponse(url='/')
95
-
 
96
 
97
- @app.route('/do-login')
98
- async def login(request: Request):
99
- redirect_uri = request.url_for('auth')
100
- # If your app is running on https, you should ensure that the
101
- # `redirect_uri` is https, e.g. uncomment the following lines:
102
- #
103
- # from urllib.parse import urlparse, urlunparse
104
- # redirect_uri = urlunparse(urlparse(str(redirect_uri))._replace(scheme='https'))
105
- return await oauth.google.authorize_redirect(request, redirect_uri)
106
 
 
 
 
 
 
 
 
 
 
 
 
 
107
 
108
- @app.route('/auth')
109
- async def auth(request: Request):
110
- try:
111
- access_token = await oauth.google.authorize_access_token(request)
112
- except OAuthError:
113
- return RedirectResponse(url='/')
114
- request.session['user'] = dict(access_token)["userinfo"]
115
- return RedirectResponse(url='/')
116
 
117
 
118
- def greet(request: gr.Request):
119
- user = get_user(request.request)
120
- # uid = ('1' if user['email_verified'] else '0') + f"{int(time.time()*10):x}_"[-8:] + _hash_msg(user['email'])
121
- uid = _hash_msg(user['email'])
122
- return f"""
123
- Welcome to TextGames, {user['name']}!<br />
124
- <{user['email'].replace('@', '{at}')}> ({'' if user['email_verified'] else 'NON-'}verified email)
125
- """, user, uid
126
-
127
-
128
- with gr.Blocks(title="TextGames") as login_demo:
129
- gr.Markdown("Welcome to TextGames!")
130
- # gr.Button("Login", link="/do-login")
131
- gr.Button("🚪\tLogin", link="/do-login", icon=None)
132
-
133
- app = gr.mount_gradio_app(app, login_demo, path="/login")
134
-
135
- with gr.Blocks(title="TextGames", delete_cache=(3600, 3600)) as demo:
136
- m, logout_btn, solved_games_df, game_radio, level_radio, new_game_btn, render_toggle = declare_components()
137
-
138
- # cur_game_start = gr.BrowserState()
139
- session_state = gr.State(0) # 0: menu selection, 1: game is ongoing, 2: game is solved.
140
- is_solved = gr.State(0)
141
- solved_games = gr.State({g: [] for _, g in game_radio.choices})
142
- user_state = gr.State()
143
- uid_state = gr.State()
144
-
145
- session_state.change(
146
- lambda s: session_state_change_fn(s, 2, 0, 2, 0),
147
- [session_state], [game_radio, level_radio, new_game_btn, logout_btn], js=js_remove_input_helper,
148
- )
149
- new_game_btn.click(check_to_start_new_game, [game_radio, level_radio, user_state, uid_state], [session_state])
150
- solved_games.change(solved_games_change_fn, solved_games, solved_games_df)
151
- session_state.change(lambda s, r: (not r if s in [0, 1] else r), [session_state, render_toggle], [render_toggle])
152
-
153
- demo.load(
154
- greet, None, [m, user_state, uid_state], js=js_solved_games_df_and_remove_footers
155
- ).then(
156
- check_played_game, [solved_games, uid_state], [solved_games]
157
- )
158
 
159
  @gr.render(inputs=[game_radio, level_radio, user_state, session_state, uid_state], triggers=[render_toggle.change])
160
  def _start_new_game(game_name, level, user, _session_state, _uid_state):
161
  if _session_state in [1, 2]:
162
  start_new_game(game_name, level, session_state, is_solved, solved_games, user=user, uid=_uid_state)
163
 
 
 
 
 
 
164
 
165
- app = gr.mount_gradio_app(app, demo, path="/TextGames", auth_dependency=get_username)
166
 
167
- if __name__ == '__main__':
168
- uvicorn.run(app, port=int(os.environ.get("GRADIO_SERVER_PORT", "7860")), host="0.0.0.0")
169
 
170
 
171
  #%%
@@ -173,3 +74,4 @@ if __name__ == '__main__':
173
 
174
  #%%
175
 
 
 
1
+ #%%
2
  import os
 
3
  # os.environ.setdefault("GRADIO_SERVER_PORT", "1080")
4
  # os.environ.setdefault("TEXTGAMES_SHOW_HIDDEN_LEVEL", "1")
5
  os.environ.setdefault("TEXTGAMES_LOADGAME_DIR", "problemsets")
 
9
  favicon_path = "textgames-scrabble-black2-ss.png"
10
 
11
  #%%
12
+ from play_helper import css, declare_components, start_new_game, download_from_drive
13
+ import pandas as pd
 
 
 
 
 
 
 
 
 
 
 
 
14
  import gradio as gr
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
+ #%%
18
+ fp_user_auth = f"{os.getenv('TEXTGAMES_OUTPUT_DIR')}/textgames_userauth.tsv"
19
+ # fp_user_auth_id = "13RLyxV3ys5DGgRIJt5_tO-ILllJ1LDPGasobagZyVLU"
20
+ fp_user_auth_mime_type = "text/tab-separated-values"
 
 
 
 
 
 
 
21
 
22
 
23
+ #%%
24
+ def file_based_auth(username, password):
 
25
  if os.getenv('TEXTGAMES_MOCKUSER', ''):
26
+ return True
27
+ download_from_drive(fp_user_auth, mime_type=fp_user_auth_mime_type)
28
+ df_auth = pd.read_csv(fp_user_auth, sep="\t").dropna(how="any")
29
+ return len(df_auth.loc[(df_auth.EMAIL == username) & (df_auth.PASSWORD == password)]) > 0
30
 
 
 
 
 
 
 
 
 
 
31
 
32
+ #%%
33
+ def greet(request: gr.Request):
34
+ email = os.getenv('TEXTGAMES_MOCKUSER', '')
35
+ if email:
36
+ user = {'email': email, 'name': "mockuser"}
37
+ else:
38
+ df_auth = pd.read_csv(fp_user_auth, sep="\t").dropna(how="any").drop_duplicates(subset=['EMAIL'])
39
+ r = df_auth.loc[df_auth.EMAIL == request.username].iloc[0]
40
+ user = {'email': r.EMAIL, 'name': r.NAME}
41
+ return f"""
42
+ Welcome to TextGames, {user['name']}!<br/><{user['email'].replace('@', '{at}')}>
43
+ """, user, user['email']
44
 
45
+ # return f"""
46
+ # Welcome to TextGames, {user['name']}!<br />
47
+ # <{user['email'].replace('@', '{at}')}> ({'' if user['email_verified'] else 'NON-'}verified email)
48
+ # """, None, None
 
 
 
 
49
 
50
 
51
+ #%%
52
+ with gr.Blocks(title="TextGames", css=css, delete_cache=(3600, 3600)) as demo:
53
+ ((m, logout_btn, solved_games_df, game_radio, level_radio, new_game_btn, render_toggle),
54
+ (session_state, is_solved, solved_games, user_state, uid_state),
55
+ ) = declare_components(demo, greet)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
  @gr.render(inputs=[game_radio, level_radio, user_state, session_state, uid_state], triggers=[render_toggle.change])
58
  def _start_new_game(game_name, level, user, _session_state, _uid_state):
59
  if _session_state in [1, 2]:
60
  start_new_game(game_name, level, session_state, is_solved, solved_games, user=user, uid=_uid_state)
61
 
62
+ demo.launch(
63
+ auth=file_based_auth,
64
+ favicon_path=favicon_path if os.path.exists(favicon_path) else None,
65
+ share=True,
66
+ )
67
 
 
68
 
69
+ #%%
 
70
 
71
 
72
  #%%
 
74
 
75
  #%%
76
 
77
+