delta commited on
Commit
d33032c
·
1 Parent(s): ec30ef9

fix: remove nest_asyncio, use thread for async

Browse files
Files changed (2) hide show
  1. app.py +68 -84
  2. requirements.txt +0 -1
app.py CHANGED
@@ -1,17 +1,13 @@
1
  """
2
  Maya Token Getter v3
3
  Playwright Google OAuth -> Firebase token -> saves to HF bridge
4
- One button. No fuss.
5
  """
6
- import os, json, uuid, asyncio, datetime
7
- import urllib.request, urllib.parse
8
- import nest_asyncio
9
  import gradio as gr
10
  from huggingface_hub import HfApi
11
  from playwright.async_api import async_playwright
12
 
13
- nest_asyncio.apply()
14
-
15
  EMAIL = os.environ.get("SESAME_EMAIL", "mail4444@post.com")
16
  PASSWORD = os.environ.get("SESAME_GOOGLE_PASS", "")
17
  FIREBASE_KEY = "AIzaSyDtC7Uwb5pGAsdmrH2T4Gqdk5Mga07jYPM"
@@ -50,8 +46,19 @@ def exchange_refresh_token(rt):
50
  return body.get("id_token", ""), body.get("refresh_token", rt)
51
 
52
 
53
- async def browser_auth():
54
- """Google OAuth via Playwright -> Firebase token"""
 
 
 
 
 
 
 
 
 
 
 
55
  log = []
56
  id_token = refresh_token = ""
57
 
@@ -67,7 +74,6 @@ async def browser_auth():
67
  user_agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36"
68
  )
69
 
70
- # Intercept Firebase token exchange responses
71
  async def on_resp(r):
72
  nonlocal id_token, refresh_token
73
  if "securetoken.googleapis.com/v1/token" in r.url:
@@ -77,9 +83,7 @@ async def browser_auth():
77
  id_token = b["id_token"]
78
  refresh_token = b.get("refresh_token", "")
79
  log.append(f"TOKEN INTERCEPTED ({len(id_token)} chars)")
80
- except:
81
- pass
82
- # Also catch signInWithIdp responses
83
  if "identitytoolkit.googleapis.com" in r.url and "signInWithIdp" in r.url:
84
  try:
85
  b = await r.json()
@@ -87,53 +91,46 @@ async def browser_auth():
87
  id_token = b["idToken"]
88
  refresh_token = b.get("refreshToken", "")
89
  log.append(f"TOKEN FROM signInWithIdp ({len(id_token)} chars)")
90
- except:
91
- pass
92
 
93
  page = await ctx.new_page()
94
  page.on("response", on_resp)
95
 
96
- # Navigate to Sesame login
97
- log.append("navigating to sesame login...")
98
  try:
99
  await page.goto("https://sesameai.app", wait_until="domcontentloaded", timeout=30000)
100
  await asyncio.sleep(3)
101
- log.append(f"page loaded: {page.url}")
102
  except Exception as e:
103
  log.append(f"nav error: {e}")
104
- # Try alternative URL
105
  try:
106
  await page.goto("https://app.sesame.com/login", wait_until="domcontentloaded", timeout=30000)
107
  await asyncio.sleep(3)
108
- log.append(f"alt page loaded: {page.url}")
109
  except Exception as e2:
110
  log.append(f"alt nav error: {e2}")
111
  await browser.close()
112
  return "", "", log
113
 
114
- # Click Google sign-in button
115
- try:
116
- # Try multiple selectors for the Google button
117
- for selector in [
118
- "text=Continue with Google",
119
- "text=Sign in with Google",
120
- "[data-provider-id='google.com']",
121
- "button:has-text('Google')",
122
- "a:has-text('Google')",
123
- ]:
124
- try:
125
- el = page.locator(selector).first
126
- if await el.count() > 0:
127
- await el.click()
128
- log.append(f"clicked: {selector}")
129
- break
130
- except:
131
- continue
132
- await asyncio.sleep(5)
133
- except Exception as e:
134
- log.append(f"google button error: {e}")
135
 
136
- # Enter email in Google sign-in
137
  try:
138
  await page.wait_for_selector("input[type='email']", timeout=15000)
139
  await page.fill("input[type='email']", EMAIL)
@@ -141,23 +138,22 @@ async def browser_auth():
141
  await asyncio.sleep(4)
142
  log.append("email entered")
143
  except Exception as e:
144
- log.append(f"email step error: {e}")
145
 
146
- # Enter password
147
  try:
148
  await page.wait_for_selector("input[type='password']", timeout=15000)
149
  await page.fill("input[type='password']", PASSWORD)
150
  await page.keyboard.press("Enter")
151
  await asyncio.sleep(10)
152
- log.append("password entered, waiting for redirect...")
153
  except Exception as e:
154
- log.append(f"password step error: {e}")
155
 
156
- # Wait for redirect back
157
  await asyncio.sleep(5)
158
  log.append(f"final URL: {page.url}")
159
 
160
- # Fallback: try IndexedDB extraction
161
  if not id_token:
162
  try:
163
  data = await page.evaluate("""async () => {
@@ -185,65 +181,56 @@ async def browser_auth():
185
  log.append(f"token from IndexedDB ({len(id_token)} chars)")
186
  break
187
  except Exception as e:
188
- log.append(f"IndexedDB fallback error: {e}")
189
-
190
- # Screenshot for debug
191
- try:
192
- await page.screenshot(path="/tmp/auth_result.png")
193
- log.append("screenshot saved")
194
- except:
195
- pass
196
 
197
  await browser.close()
198
 
199
  return id_token, refresh_token, log
200
 
201
 
202
- def test_ws_connection(id_token):
203
- """Quick test: can this token connect to Maya's WebSocket?"""
204
- import base64
205
- try:
206
- payload = id_token.split('.')[1] + '==='
207
- claims = json.loads(base64.b64decode(payload))
208
- provider = claims.get("firebase", {}).get("sign_in_provider", "unknown")
209
- uid = claims.get("sub", "unknown")
210
- email = claims.get("email", "unknown")
211
- return f"provider: {provider} | uid: {uid} | email: {email}"
212
- except:
213
- return "could not decode token"
 
 
214
 
215
 
216
  def run_auth():
217
- """Main auth flow: try refresh first, then browser"""
218
  log = []
219
  state = read_state()
220
  stored_rt = state.get("refresh_token", "")
221
 
222
- # Try refresh token first
223
  if stored_rt:
224
  log.append("trying stored refresh token...")
225
  try:
226
  id_token, new_rt = exchange_refresh_token(stored_rt)
227
  if id_token:
228
- log.append(f"REFRESH SUCCESS ({len(id_token)} chars)")
229
- claims = test_ws_connection(id_token)
230
  log.append(claims)
231
  state["refresh_token"] = new_rt
232
  state["last_id_token"] = id_token[:40] + "..."
233
  state["last_updated"] = datetime.datetime.utcnow().isoformat()
234
  write_state(state)
235
- return "TOKEN READY (from refresh)", "\n".join(log), id_token[:80] + "..."
236
  except Exception as e:
237
  log.append(f"refresh failed: {e}")
238
 
239
- # Browser auth
240
  log.append("starting browser auth...")
241
- loop = asyncio.get_event_loop()
242
- id_token, refresh_token, auth_log = loop.run_until_complete(browser_auth())
243
  log.extend(auth_log)
244
 
245
  if id_token:
246
- claims = test_ws_connection(id_token)
247
  log.append(claims)
248
  state["refresh_token"] = refresh_token
249
  state["last_id_token"] = id_token[:40] + "..."
@@ -252,18 +239,15 @@ def run_auth():
252
  log.append("SAVED TO HF BRIDGE")
253
  return "TOKEN READY", "\n".join(log), id_token[:80] + "..."
254
  else:
255
- return "FAILED - check log", "\n".join(log), ""
256
 
257
 
258
- # Gradio UI
259
  with gr.Blocks(title="Maya Token Getter", theme=gr.themes.Monochrome()) as app:
260
- gr.Markdown("# Maya Token Getter v3\nOne button. Gets Google OAuth Firebase token for Sesame.")
261
-
262
  btn = gr.Button("GET TOKEN", variant="primary", size="lg")
263
  status = gr.Textbox(label="Status", interactive=False)
264
- log_output = gr.Textbox(label="Log", interactive=False, lines=15)
265
- token_preview = gr.Textbox(label="Token Preview", interactive=False)
266
-
267
- btn.click(fn=run_auth, outputs=[status, log_output, token_preview])
268
 
269
  app.launch(server_name="0.0.0.0", server_port=7860)
 
1
  """
2
  Maya Token Getter v3
3
  Playwright Google OAuth -> Firebase token -> saves to HF bridge
 
4
  """
5
+ import os, json, uuid, asyncio, datetime, threading
6
+ import urllib.request, urllib.parse, base64
 
7
  import gradio as gr
8
  from huggingface_hub import HfApi
9
  from playwright.async_api import async_playwright
10
 
 
 
11
  EMAIL = os.environ.get("SESAME_EMAIL", "mail4444@post.com")
12
  PASSWORD = os.environ.get("SESAME_GOOGLE_PASS", "")
13
  FIREBASE_KEY = "AIzaSyDtC7Uwb5pGAsdmrH2T4Gqdk5Mga07jYPM"
 
46
  return body.get("id_token", ""), body.get("refresh_token", rt)
47
 
48
 
49
+ def decode_token(id_token):
50
+ try:
51
+ payload = id_token.split('.')[1] + '==='
52
+ claims = json.loads(base64.b64decode(payload))
53
+ provider = claims.get("firebase", {}).get("sign_in_provider", "unknown")
54
+ uid = claims.get("sub", "unknown")
55
+ email = claims.get("email", "unknown")
56
+ return f"provider: {provider} | uid: {uid} | email: {email}"
57
+ except:
58
+ return "could not decode"
59
+
60
+
61
+ async def _browser_auth():
62
  log = []
63
  id_token = refresh_token = ""
64
 
 
74
  user_agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36"
75
  )
76
 
 
77
  async def on_resp(r):
78
  nonlocal id_token, refresh_token
79
  if "securetoken.googleapis.com/v1/token" in r.url:
 
83
  id_token = b["id_token"]
84
  refresh_token = b.get("refresh_token", "")
85
  log.append(f"TOKEN INTERCEPTED ({len(id_token)} chars)")
86
+ except: pass
 
 
87
  if "identitytoolkit.googleapis.com" in r.url and "signInWithIdp" in r.url:
88
  try:
89
  b = await r.json()
 
91
  id_token = b["idToken"]
92
  refresh_token = b.get("refreshToken", "")
93
  log.append(f"TOKEN FROM signInWithIdp ({len(id_token)} chars)")
94
+ except: pass
 
95
 
96
  page = await ctx.new_page()
97
  page.on("response", on_resp)
98
 
99
+ log.append("navigating to sesame...")
 
100
  try:
101
  await page.goto("https://sesameai.app", wait_until="domcontentloaded", timeout=30000)
102
  await asyncio.sleep(3)
103
+ log.append(f"loaded: {page.url}")
104
  except Exception as e:
105
  log.append(f"nav error: {e}")
 
106
  try:
107
  await page.goto("https://app.sesame.com/login", wait_until="domcontentloaded", timeout=30000)
108
  await asyncio.sleep(3)
109
+ log.append(f"alt loaded: {page.url}")
110
  except Exception as e2:
111
  log.append(f"alt nav error: {e2}")
112
  await browser.close()
113
  return "", "", log
114
 
115
+ # Click Google sign-in
116
+ for selector in [
117
+ "text=Continue with Google",
118
+ "text=Sign in with Google",
119
+ "[data-provider-id='google.com']",
120
+ "button:has-text('Google')",
121
+ "a:has-text('Google')",
122
+ ]:
123
+ try:
124
+ el = page.locator(selector).first
125
+ if await el.count() > 0:
126
+ await el.click()
127
+ log.append(f"clicked: {selector}")
128
+ break
129
+ except:
130
+ continue
131
+ await asyncio.sleep(5)
 
 
 
 
132
 
133
+ # Email
134
  try:
135
  await page.wait_for_selector("input[type='email']", timeout=15000)
136
  await page.fill("input[type='email']", EMAIL)
 
138
  await asyncio.sleep(4)
139
  log.append("email entered")
140
  except Exception as e:
141
+ log.append(f"email error: {e}")
142
 
143
+ # Password
144
  try:
145
  await page.wait_for_selector("input[type='password']", timeout=15000)
146
  await page.fill("input[type='password']", PASSWORD)
147
  await page.keyboard.press("Enter")
148
  await asyncio.sleep(10)
149
+ log.append("password entered")
150
  except Exception as e:
151
+ log.append(f"password error: {e}")
152
 
 
153
  await asyncio.sleep(5)
154
  log.append(f"final URL: {page.url}")
155
 
156
+ # IndexedDB fallback
157
  if not id_token:
158
  try:
159
  data = await page.evaluate("""async () => {
 
181
  log.append(f"token from IndexedDB ({len(id_token)} chars)")
182
  break
183
  except Exception as e:
184
+ log.append(f"IndexedDB error: {e}")
 
 
 
 
 
 
 
185
 
186
  await browser.close()
187
 
188
  return id_token, refresh_token, log
189
 
190
 
191
+ def browser_auth():
192
+ """Run async browser auth in a new event loop in a thread"""
193
+ result = [None]
194
+ def run():
195
+ loop = asyncio.new_event_loop()
196
+ asyncio.set_event_loop(loop)
197
+ result[0] = loop.run_until_complete(_browser_auth())
198
+ loop.close()
199
+ t = threading.Thread(target=run)
200
+ t.start()
201
+ t.join(timeout=120)
202
+ if result[0] is None:
203
+ return "", "", ["TIMEOUT: browser auth took >120s"]
204
+ return result[0]
205
 
206
 
207
  def run_auth():
 
208
  log = []
209
  state = read_state()
210
  stored_rt = state.get("refresh_token", "")
211
 
 
212
  if stored_rt:
213
  log.append("trying stored refresh token...")
214
  try:
215
  id_token, new_rt = exchange_refresh_token(stored_rt)
216
  if id_token:
217
+ claims = decode_token(id_token)
218
+ log.append(f"REFRESH OK ({len(id_token)} chars)")
219
  log.append(claims)
220
  state["refresh_token"] = new_rt
221
  state["last_id_token"] = id_token[:40] + "..."
222
  state["last_updated"] = datetime.datetime.utcnow().isoformat()
223
  write_state(state)
224
+ return "TOKEN READY (refresh)", "\n".join(log), id_token[:80] + "..."
225
  except Exception as e:
226
  log.append(f"refresh failed: {e}")
227
 
 
228
  log.append("starting browser auth...")
229
+ id_token, refresh_token, auth_log = browser_auth()
 
230
  log.extend(auth_log)
231
 
232
  if id_token:
233
+ claims = decode_token(id_token)
234
  log.append(claims)
235
  state["refresh_token"] = refresh_token
236
  state["last_id_token"] = id_token[:40] + "..."
 
239
  log.append("SAVED TO HF BRIDGE")
240
  return "TOKEN READY", "\n".join(log), id_token[:80] + "..."
241
  else:
242
+ return "FAILED", "\n".join(log), ""
243
 
244
 
 
245
  with gr.Blocks(title="Maya Token Getter", theme=gr.themes.Monochrome()) as app:
246
+ gr.Markdown("# Maya Token Getter v3\nOne button. Gets Google OAuth Firebase token.")
 
247
  btn = gr.Button("GET TOKEN", variant="primary", size="lg")
248
  status = gr.Textbox(label="Status", interactive=False)
249
+ log_out = gr.Textbox(label="Log", interactive=False, lines=15)
250
+ tok_prev = gr.Textbox(label="Token Preview", interactive=False)
251
+ btn.click(fn=run_auth, outputs=[status, log_out, tok_prev])
 
252
 
253
  app.launch(server_name="0.0.0.0", server_port=7860)
requirements.txt CHANGED
@@ -1,4 +1,3 @@
1
  gradio>=4.0
2
  playwright==1.50.0
3
- nest_asyncio
4
  huggingface_hub
 
1
  gradio>=4.0
2
  playwright==1.50.0
 
3
  huggingface_hub