SeaWolf-AI commited on
Commit
52fd4ca
·
verified ·
1 Parent(s): cbc9da9

Fix the OAuth callback path and stop a failed sign-in from taking the page down

Browse files

The platform registers the callback at /auth/callback; serving it at /auth made the token exchange fail and the exception surfaced as a 500 for the whole space. The callback now answers on the registered path, keeps the old one as an alias, and renders a readable message instead of raising. Also adds resident reference-tool results.

Files changed (2) hide show
  1. app.py +58 -22
  2. data/reference_entries.json +328 -0
app.py CHANGED
@@ -25,6 +25,7 @@ import os
25
  import re
26
  import secrets
27
  import time
 
28
  import urllib.parse
29
  import urllib.request
30
 
@@ -131,9 +132,9 @@ def boards():
131
  def _load_references():
132
  """현업 도구를 이 부문 훈련 자료로 재학습해 얻은 성적.
133
 
134
- 기존 모델을 그대로 옮겨 재면 훈련 자료의 차이가 방법의 차이로 읽힌다. 실제로 그렇게
135
- 나왔었다 - 523 화합물로 학습한 모델8,450 화합물로 학습한 무튜닝 기준선졌다.
136
- 그래서 **방법만 가져오고 데터는것을 다.**
137
  """
138
  p = os.path.join(DATA, "reference_entries.json")
139
  if not os.path.exists(p):
@@ -343,8 +344,8 @@ def api_leaderboard(name: str):
343
  # ------------------------------------------------------------------ 로그인
344
  @app.get("/login")
345
  def login(request: Request):
346
- if not OAUTH_ID:
347
- raise HTTPException(503, "로그인이 구성되지 않았다")
348
  nxt = request.query_params.get("next", "/")
349
  st = base64.urlsafe_b64encode(json.dumps({"n": nxt, "r": secrets.token_hex(8)}).encode()).decode()
350
  q = urllib.parse.urlencode({
@@ -354,12 +355,32 @@ def login(request: Request):
354
 
355
 
356
  def _redirect(request: Request):
357
- if SPACE_HOST:
358
- return "https://%s/auth" % SPACE_HOST
359
- return str(request.base_url).rstrip("/") + "/auth"
360
-
361
 
362
- @app.get("/auth")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
363
  def auth(request: Request):
364
  code = request.query_params.get("code")
365
  st = request.query_params.get("state") or ""
@@ -370,24 +391,39 @@ def auth(request: Request):
370
  pass
371
  if not code:
372
  return RedirectResponse(nxt)
373
- body = urllib.parse.urlencode({
374
- "client_id": OAUTH_ID, "client_secret": OAUTH_SECRET,
375
- "grant_type": "authorization_code", "code": code,
376
- "redirect_uri": _redirect(request)}).encode()
377
- with urllib.request.urlopen(urllib.request.Request(
378
- OAUTH_ISS + "/oauth/token", data=body,
379
- headers={"Content-Type": "application/x-www-form-urlencoded"}), timeout=60) as r:
380
- tok = json.loads(r.read())
381
- with urllib.request.urlopen(urllib.request.Request(
382
- OAUTH_ISS + "/oauth/userinfo",
383
- headers={"Authorization": "Bearer " + tok["access_token"]}), timeout=60) as r:
384
- ui = json.loads(r.read())
 
 
 
 
 
 
 
 
 
385
  resp = RedirectResponse(nxt)
386
  set_session(resp, {"user": ui.get("preferred_username") or ui.get("sub"),
387
  "name": ui.get("name", ""), "pic": ui.get("picture", "")})
388
  return resp
389
 
390
 
 
 
 
 
 
 
391
  @app.get("/logout")
392
  def logout():
393
  r = RedirectResponse("/")
 
25
  import re
26
  import secrets
27
  import time
28
+ import urllib.error
29
  import urllib.parse
30
  import urllib.request
31
 
 
132
  def _load_references():
133
  """현업 도구를 이 부문 훈련 자료로 재학습해 얻은 성적.
134
 
135
+ 다른 자료로 학습한 모델을 그대로 옮겨 재면, 훈련 자료의 차이가 방법의 차이로 읽힌다.
136
+ 그래서 **방법만 가져오고 데이터는부문 것을 쓴다.** 그래야 오른 숫자가
137
+ "이 방법이 이 문제에서 어디까지 가는가"를 뜻한다.
138
  """
139
  p = os.path.join(DATA, "reference_entries.json")
140
  if not os.path.exists(p):
 
344
  # ------------------------------------------------------------------ 로그인
345
  @app.get("/login")
346
  def login(request: Request):
347
+ if not (OAUTH_ID and OAUTH_SECRET):
348
+ return _err_page("이 시험대에 로그인이 아직 구성되지 않았습니.")
349
  nxt = request.query_params.get("next", "/")
350
  st = base64.urlsafe_b64encode(json.dumps({"n": nxt, "r": secrets.token_hex(8)}).encode()).decode()
351
  q = urllib.parse.urlencode({
 
355
 
356
 
357
  def _redirect(request: Request):
358
+ """플랫폼이 등록해 주는 콜백 주소는 **/auth/callback** 이다.
 
 
 
359
 
360
+ 여기를 /auth 로 두면 토큰 교환에서 redirect_uri 불일치로 거부되고, 그 예외가
361
+ 그대로 500 이 되어 화면 전체가 죽는다. 로그인 한 번 눌렀다가 사이트가 사라진다.
362
+ """
363
+ if SPACE_HOST:
364
+ return "https://%s/auth/callback" % SPACE_HOST
365
+ return str(request.base_url).rstrip("/") + "/auth/callback"
366
+
367
+
368
+ def _err_page(msg, detail=""):
369
+ """로그인이 실패해도 화면은 살아 있어야 한다. 흰 배경에 Internal Server Error 만
370
+ 남으면 이용자는 사이트가 죽은 줄 안다."""
371
+ return Response(
372
+ "<!doctype html><html lang=ko><head><meta charset=utf-8>"
373
+ "<title>로그인 실패</title><style>body{font-family:system-ui,sans-serif;"
374
+ "max-width:38em;margin:14vh auto;padding:0 24px;line-height:1.7;color:#15171c}"
375
+ "code{background:#f0f3f7;padding:2px 6px;border-radius:5px;font-size:13px}"
376
+ "a{color:#1f4fa3}</style></head><body>"
377
+ "<h2>로그인을 마치지 못했습니다</h2><p>%s</p>%s"
378
+ "<p><a href='/'>← 시험대로 돌아가기</a></p></body></html>"
379
+ % (msg, ("<p><code>%s</code></p>" % detail[:300]) if detail else ""),
380
+ media_type="text/html; charset=utf-8", status_code=200)
381
+
382
+
383
+ @app.get("/auth/callback")
384
  def auth(request: Request):
385
  code = request.query_params.get("code")
386
  st = request.query_params.get("state") or ""
 
391
  pass
392
  if not code:
393
  return RedirectResponse(nxt)
394
+ try:
395
+ body = urllib.parse.urlencode({
396
+ "client_id": OAUTH_ID, "client_secret": OAUTH_SECRET,
397
+ "grant_type": "authorization_code", "code": code,
398
+ "redirect_uri": _redirect(request)}).encode()
399
+ with urllib.request.urlopen(urllib.request.Request(
400
+ OAUTH_ISS + "/oauth/token", data=body,
401
+ headers={"Content-Type": "application/x-www-form-urlencoded"}),
402
+ timeout=60) as r:
403
+ tok = json.loads(r.read())
404
+ with urllib.request.urlopen(urllib.request.Request(
405
+ OAUTH_ISS + "/oauth/userinfo",
406
+ headers={"Authorization": "Bearer " + tok["access_token"]}),
407
+ timeout=60) as r:
408
+ ui = json.loads(r.read())
409
+ except urllib.error.HTTPError as e:
410
+ return _err_page("인증 제공자가 요청을 거부했습니다. 다시 시도해 주십시오.",
411
+ "%d %s" % (e.code, e.read().decode("utf-8", "replace")))
412
+ except Exception as e:
413
+ return _err_page("인증 중 통신에 실패했습니다. 잠시 후 다시 시도해 주십시오.",
414
+ "%s: %s" % (type(e).__name__, e))
415
  resp = RedirectResponse(nxt)
416
  set_session(resp, {"user": ui.get("preferred_username") or ui.get("sub"),
417
  "name": ui.get("name", ""), "pic": ui.get("picture", "")})
418
  return resp
419
 
420
 
421
+ @app.get("/auth")
422
+ def auth_legacy(request: Request):
423
+ """예전 주소로 들어온 콜백도 받아 준다. 링크가 어딘가 남아 있을 수 있다."""
424
+ return auth(request)
425
+
426
+
427
  @app.get("/logout")
428
  def logout():
429
  r = RedirectResponse("/")
data/reference_entries.json ADDED
@@ -0,0 +1,328 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "method": "PharmaOS (재학습)",
3
+ "method_en": "PharmaOS (retrained)",
4
+ "entries": [
5
+ {
6
+ "board": "ABL1",
7
+ "n_train": 1952,
8
+ "n_test": 199,
9
+ "mae": 1.0225884766675557,
10
+ "tabpfn_reg": true,
11
+ "auroc": 0.5425824175824175,
12
+ "prauc": 0.39926475852782806,
13
+ "tabpfn_cls": true,
14
+ "exact_hits": 0,
15
+ "exact_rate": 0.0,
16
+ "leak": "clean",
17
+ "baseline_best_mae": 0.7779393745231502,
18
+ "baseline_best_auroc": 0.8191808191808192,
19
+ "noise_floor": 0.4588912458471183,
20
+ "secs": 70.0
21
+ },
22
+ {
23
+ "board": "AChE",
24
+ "n_train": 5357,
25
+ "n_test": 904,
26
+ "mae": 0.8442791152929728,
27
+ "tabpfn_reg": true,
28
+ "auroc": 0.7343206807340933,
29
+ "prauc": 0.6809792654292656,
30
+ "tabpfn_cls": true,
31
+ "exact_hits": 7,
32
+ "exact_rate": 0.007743362831858407,
33
+ "leak": "clean",
34
+ "baseline_best_mae": 0.8050872164791483,
35
+ "baseline_best_auroc": 0.7328022677661897,
36
+ "noise_floor": 0.46187469497191214,
37
+ "secs": 83.3
38
+ },
39
+ {
40
+ "board": "ALK",
41
+ "n_train": 2020,
42
+ "n_test": 153,
43
+ "mae": 0.7807908480743736,
44
+ "tabpfn_reg": true,
45
+ "auroc": 0.878763440860215,
46
+ "prauc": 0.9329935752080366,
47
+ "tabpfn_cls": true,
48
+ "exact_hits": 1,
49
+ "exact_rate": 0.006535947712418301,
50
+ "leak": "clean",
51
+ "baseline_best_mae": 0.8582590736344116,
52
+ "baseline_best_auroc": 0.814247311827957,
53
+ "noise_floor": 0.742835624347912,
54
+ "secs": 46.0
55
+ },
56
+ {
57
+ "board": "BRAF",
58
+ "n_train": 5201,
59
+ "n_test": 183,
60
+ "mae": 0.7975919419264598,
61
+ "tabpfn_reg": true,
62
+ "auroc": 0.801650269755633,
63
+ "prauc": 0.8789148071354913,
64
+ "tabpfn_cls": true,
65
+ "exact_hits": 2,
66
+ "exact_rate": 0.01092896174863388,
67
+ "leak": "clean",
68
+ "baseline_best_mae": 0.8570106284643041,
69
+ "baseline_best_auroc": 0.7719771501110758,
70
+ "noise_floor": 0.3133348834362967,
71
+ "secs": 84.0
72
+ },
73
+ {
74
+ "board": "CDK2",
75
+ "n_train": 1794,
76
+ "n_test": 321,
77
+ "mae": 0.7934575185428231,
78
+ "tabpfn_reg": true,
79
+ "auroc": 0.6108409470478435,
80
+ "prauc": 0.40142716185283467,
81
+ "tabpfn_cls": true,
82
+ "exact_hits": 2,
83
+ "exact_rate": 0.006230529595015576,
84
+ "leak": "clean",
85
+ "baseline_best_mae": 0.8165537848180889,
86
+ "baseline_best_auroc": 0.6097111700559977,
87
+ "noise_floor": 0.29309743262056304,
88
+ "secs": 89.8
89
+ },
90
+ {
91
+ "board": "COX2",
92
+ "n_train": 4024,
93
+ "n_test": 491,
94
+ "mae": 0.978391315623745,
95
+ "tabpfn_reg": true,
96
+ "auroc": 0.570387886647088,
97
+ "prauc": 0.7375222888571707,
98
+ "tabpfn_cls": true,
99
+ "exact_hits": 3,
100
+ "exact_rate": 0.006109979633401222,
101
+ "leak": "clean",
102
+ "baseline_best_mae": 0.9269477494249706,
103
+ "baseline_best_auroc": 0.6051336816812234,
104
+ "noise_floor": 0.7671300598249152,
105
+ "secs": 62.4
106
+ },
107
+ {
108
+ "board": "CYP2C9",
109
+ "n_train": 2435,
110
+ "n_test": 371,
111
+ "mae": 0.48261192303231587,
112
+ "tabpfn_reg": true,
113
+ "auroc": 0.6377483443708609,
114
+ "prauc": 0.7373126205902567,
115
+ "tabpfn_cls": true,
116
+ "exact_hits": 5,
117
+ "exact_rate": 0.013477088948787063,
118
+ "leak": "clean",
119
+ "baseline_best_mae": 0.4743088526790385,
120
+ "baseline_best_auroc": 0.5966586393738711,
121
+ "noise_floor": 0.3504820192518295,
122
+ "secs": 49.1
123
+ },
124
+ {
125
+ "board": "CYP2D6",
126
+ "n_train": 2676,
127
+ "n_test": 268,
128
+ "mae": 0.6066116802160365,
129
+ "tabpfn_reg": true,
130
+ "auroc": 0.527542372881356,
131
+ "prauc": 0.4607589892244653,
132
+ "tabpfn_cls": true,
133
+ "exact_hits": 4,
134
+ "exact_rate": 0.014925373134328358,
135
+ "leak": "clean",
136
+ "baseline_best_mae": 0.596600795371179,
137
+ "baseline_best_auroc": 0.570225988700565,
138
+ "noise_floor": 0.65903687863192,
139
+ "secs": 75.4
140
+ },
141
+ {
142
+ "board": "CYP3A4",
143
+ "n_train": 4814,
144
+ "n_test": 600,
145
+ "mae": 0.5603310599241302,
146
+ "tabpfn_reg": true,
147
+ "auroc": 0.61359375,
148
+ "prauc": 0.7857618469985579,
149
+ "tabpfn_cls": true,
150
+ "exact_hits": 4,
151
+ "exact_rate": 0.006666666666666667,
152
+ "leak": "clean",
153
+ "baseline_best_mae": 0.5737513093544662,
154
+ "baseline_best_auroc": 0.5716875000000001,
155
+ "noise_floor": 0.6276473051863152,
156
+ "secs": 187.9
157
+ },
158
+ {
159
+ "board": "EGFR",
160
+ "n_train": 9231,
161
+ "n_test": 1565,
162
+ "mae": 1.0073031841568407,
163
+ "tabpfn_reg": true,
164
+ "auroc": 0.6044200348825833,
165
+ "prauc": 0.6922003665231697,
166
+ "tabpfn_cls": true,
167
+ "exact_hits": 11,
168
+ "exact_rate": 0.007028753993610224,
169
+ "leak": "clean",
170
+ "baseline_best_mae": 0.9960533038964834,
171
+ "baseline_best_auroc": 0.5653230349871636,
172
+ "noise_floor": 0.8881466464306685,
173
+ "secs": 155.8
174
+ },
175
+ {
176
+ "board": "FLT3",
177
+ "n_train": 2913,
178
+ "n_test": 853,
179
+ "mae": 0.9910920022429478,
180
+ "tabpfn_reg": true,
181
+ "auroc": 0.651502219187436,
182
+ "prauc": 0.7520078617551165,
183
+ "tabpfn_cls": true,
184
+ "exact_hits": 9,
185
+ "exact_rate": 0.010550996483001172,
186
+ "leak": "clean",
187
+ "baseline_best_mae": 0.9858170086772374,
188
+ "baseline_best_auroc": 0.6213980880846706,
189
+ "noise_floor": 0.6601522287378142,
190
+ "secs": 67.4
191
+ },
192
+ {
193
+ "board": "HER2",
194
+ "n_train": 2262,
195
+ "n_test": 236,
196
+ "mae": 0.8614050015726017,
197
+ "tabpfn_reg": true,
198
+ "auroc": 0.8487300435413643,
199
+ "prauc": 0.8743434829296226,
200
+ "tabpfn_cls": true,
201
+ "exact_hits": 1,
202
+ "exact_rate": 0.00423728813559322,
203
+ "leak": "clean",
204
+ "baseline_best_mae": 0.9163787230821009,
205
+ "baseline_best_auroc": 0.7604136429608127,
206
+ "noise_floor": 0.4979961818213226,
207
+ "secs": 50.2
208
+ },
209
+ {
210
+ "board": "hERG",
211
+ "n_train": 8450,
212
+ "n_test": 1338,
213
+ "mae": 0.5745173440987656,
214
+ "tabpfn_reg": true,
215
+ "auroc": 0.6553969737714581,
216
+ "prauc": 0.7055356549215994,
217
+ "tabpfn_cls": true,
218
+ "exact_hits": 17,
219
+ "exact_rate": 0.012705530642750373,
220
+ "leak": "clean",
221
+ "baseline_best_mae": 0.5887837936811489,
222
+ "baseline_best_auroc": 0.6063324246666175,
223
+ "noise_floor": 0.4210538663630575,
224
+ "secs": 193.3
225
+ },
226
+ {
227
+ "board": "JAK2",
228
+ "n_train": 9012,
229
+ "n_test": 1288,
230
+ "mae": 1.0818229169586282,
231
+ "tabpfn_reg": true,
232
+ "auroc": 0.5803116466486234,
233
+ "prauc": 0.61593880320513,
234
+ "tabpfn_cls": true,
235
+ "exact_hits": 9,
236
+ "exact_rate": 0.006987577639751553,
237
+ "leak": "clean",
238
+ "baseline_best_mae": 0.9194816993033287,
239
+ "baseline_best_auroc": 0.7303318787238527,
240
+ "noise_floor": 0.6345000139527338,
241
+ "secs": 136.7
242
+ },
243
+ {
244
+ "board": "KIT",
245
+ "n_train": 1788,
246
+ "n_test": 158,
247
+ "mae": 0.882323390899274,
248
+ "tabpfn_reg": true,
249
+ "auroc": 0.6347741622146672,
250
+ "prauc": 0.6737596830228373,
251
+ "tabpfn_cls": true,
252
+ "exact_hits": 0,
253
+ "exact_rate": 0.0,
254
+ "leak": "clean",
255
+ "baseline_best_mae": 0.9250771660303996,
256
+ "baseline_best_auroc": 0.6422211429496519,
257
+ "noise_floor": 0.4273138205482797,
258
+ "secs": 40.5
259
+ },
260
+ {
261
+ "board": "MAOB",
262
+ "n_train": 3857,
263
+ "n_test": 877,
264
+ "mae": 0.9263366112325823,
265
+ "tabpfn_reg": true,
266
+ "auroc": 0.7159423078923552,
267
+ "prauc": 0.7268052560577757,
268
+ "tabpfn_cls": true,
269
+ "exact_hits": 7,
270
+ "exact_rate": 0.00798175598631699,
271
+ "leak": "clean",
272
+ "baseline_best_mae": 1.0279754487195185,
273
+ "baseline_best_auroc": 0.7043747594428436,
274
+ "noise_floor": 0.6256612894840171,
275
+ "secs": 64.6
276
+ },
277
+ {
278
+ "board": "PI3Ka",
279
+ "n_train": 5387,
280
+ "n_test": 1078,
281
+ "mae": 0.7688265800729167,
282
+ "tabpfn_reg": true,
283
+ "auroc": 0.8188078400558756,
284
+ "prauc": 0.7625155072318662,
285
+ "tabpfn_cls": true,
286
+ "exact_hits": 15,
287
+ "exact_rate": 0.013914656771799629,
288
+ "leak": "clean",
289
+ "baseline_best_mae": 0.8713868648365752,
290
+ "baseline_best_auroc": 0.7185662941621558,
291
+ "noise_floor": 0.3741289502909002,
292
+ "secs": 112.6
293
+ },
294
+ {
295
+ "board": "Solubility",
296
+ "n_train": 15957,
297
+ "n_test": 4635,
298
+ "mae": 0.6008277144281021,
299
+ "tabpfn_reg": true,
300
+ "auroc": null,
301
+ "prauc": null,
302
+ "exact_hits": 51,
303
+ "exact_rate": 0.011003236245954692,
304
+ "leak": "clean",
305
+ "baseline_best_mae": 0.711774820802794,
306
+ "baseline_best_auroc": 0.6932688073415427,
307
+ "noise_floor": 0.5751407196134256,
308
+ "secs": 286.7
309
+ },
310
+ {
311
+ "board": "VEGFR2",
312
+ "n_train": 9125,
313
+ "n_test": 637,
314
+ "mae": 0.8660788723514213,
315
+ "tabpfn_reg": true,
316
+ "auroc": 0.6841249084632284,
317
+ "prauc": 0.5927051957181371,
318
+ "tabpfn_cls": true,
319
+ "exact_hits": 4,
320
+ "exact_rate": 0.006279434850863423,
321
+ "leak": "clean",
322
+ "baseline_best_mae": 0.8203045097805136,
323
+ "baseline_best_auroc": 0.7233654147923423,
324
+ "noise_floor": 0.7622042646013418,
325
+ "secs": 143.4
326
+ }
327
+ ]
328
+ }