SarahXia0405 commited on
Commit
fe4fa70
·
verified ·
1 Parent(s): 179b1ef

Update api/server.py

Browse files
Files changed (1) hide show
  1. api/server.py +25 -76
api/server.py CHANGED
@@ -2,7 +2,7 @@
2
  import os
3
  import time
4
  import threading
5
- from typing import Dict, List, Optional, Any
6
 
7
  from fastapi import FastAPI, UploadFile, File, Form, Request
8
  from fastapi.responses import FileResponse, JSONResponse
@@ -37,29 +37,9 @@ API_DIR = os.path.dirname(__file__)
37
  MODULE10_PATH = os.path.join(API_DIR, "module10_responsible_ai.pdf")
38
  MODULE10_DOC_TYPE = "Literature Review / Paper"
39
 
40
- # ----------------------------
41
- # Static hosting (SPA build)
42
- # Prefer CRA web/build then Vite web/dist
43
- # ----------------------------
44
- WEB_BUILD = os.path.abspath(os.path.join(API_DIR, "..", "web", "build"))
45
- WEB_DIST2 = os.path.abspath(os.path.join(API_DIR, "..", "web", "dist"))
46
-
47
- def _pick_web_root() -> str:
48
- build_index = os.path.join(WEB_BUILD, "index.html")
49
- dist_index = os.path.join(WEB_DIST2, "index.html")
50
- if os.path.exists(build_index):
51
- return WEB_BUILD
52
- if os.path.exists(dist_index):
53
- return WEB_DIST2
54
- # fallback: prefer build path, but may not exist yet
55
- return WEB_BUILD
56
-
57
- WEB_ROOT = _pick_web_root()
58
- WEB_INDEX = os.path.join(WEB_ROOT, "index.html")
59
-
60
- WEB_ASSETS_DIR = os.path.join(WEB_ROOT, "assets") # Vite
61
- WEB_STATIC_DIR = os.path.join(WEB_ROOT, "static") # CRA
62
- # Some builds also place misc files at root (favicon, manifest, etc.)
63
 
64
  LS_DATASET_NAME = os.getenv("LS_DATASET_NAME", "clare_user_events").strip()
65
  LS_PROJECT = os.getenv("LANGSMITH_PROJECT", os.getenv("LANGCHAIN_PROJECT", "")).strip()
@@ -95,58 +75,25 @@ app.add_middleware(
95
  )
96
 
97
  # ----------------------------
98
- # Static hosting mounts
99
  # ----------------------------
100
- # If Vite build: /assets exists
101
- if os.path.isdir(WEB_ASSETS_DIR):
102
- app.mount("/assets", StaticFiles(directory=WEB_ASSETS_DIR), name="assets")
103
-
104
- # If CRA build: /static exists
105
- if os.path.isdir(WEB_STATIC_DIR):
106
- app.mount("/static", StaticFiles(directory=WEB_STATIC_DIR), name="static")
107
 
108
- # Mount the full root to serve favicon/manifest/robots.txt, etc.
109
- if os.path.isdir(WEB_ROOT):
110
- app.mount("/_app", StaticFiles(directory=WEB_ROOT), name="app_root")
111
 
112
 
113
  @app.get("/")
114
  def index():
115
- # Re-pick on each request in case build output changed after container start
116
- global WEB_ROOT, WEB_INDEX, WEB_ASSETS_DIR, WEB_STATIC_DIR
117
- WEB_ROOT = _pick_web_root()
118
- WEB_INDEX = os.path.join(WEB_ROOT, "index.html")
119
- WEB_ASSETS_DIR = os.path.join(WEB_ROOT, "assets")
120
- WEB_STATIC_DIR = os.path.join(WEB_ROOT, "static")
121
-
122
  if os.path.exists(WEB_INDEX):
123
  return FileResponse(WEB_INDEX)
124
  return JSONResponse(
125
- {"detail": "web build not found. Expected web/build/index.html or web/dist/index.html."},
126
  status_code=500,
127
  )
128
 
129
 
130
- # ----------------------------
131
- # Debug endpoint (verify deployment / static root)
132
- # ----------------------------
133
- @app.get("/__debug__")
134
- def __debug__():
135
- root = _pick_web_root()
136
- return {
137
- "ok": True,
138
- "ts": int(time.time()),
139
- "web_build": WEB_BUILD,
140
- "web_dist": WEB_DIST2,
141
- "web_root_selected": root,
142
- "index_path": os.path.join(root, "index.html"),
143
- "has_index": os.path.exists(os.path.join(root, "index.html")),
144
- "has_assets_dir": os.path.isdir(os.path.join(root, "assets")),
145
- "has_static_dir": os.path.isdir(os.path.join(root, "static")),
146
- "uptime_s": round(time.time() - APP_START_TS, 3),
147
- }
148
-
149
-
150
  # ----------------------------
151
  # In-memory session store (MVP)
152
  # ----------------------------
@@ -426,7 +373,10 @@ def chat(req: ChatReq):
426
 
427
  sess["history"] = new_history
428
 
429
- refs = [{"source_file": c.get("source_file"), "section": c.get("section")} for c in (rag_used_chunks or [])]
 
 
 
430
 
431
  rag_context_chars = len(rag_context_text or "")
432
  rag_used_chunks_count = len(rag_used_chunks or [])
@@ -537,6 +487,7 @@ def api_feedback(req: FeedbackReq):
537
  if rating not in ("helpful", "not_helpful"):
538
  return JSONResponse({"ok": False, "error": "Invalid rating"}, status_code=400)
539
 
 
540
  assistant_text = (req.assistant_text or "").strip()
541
  user_text = (req.user_text or "").strip()
542
  comment = (req.comment or "").strip()
@@ -554,8 +505,12 @@ def api_feedback(req: FeedbackReq):
554
  "timestamp_ms": timestamp_ms,
555
  "rating": rating,
556
  "assistant_message_id": req.assistant_message_id,
557
- "question": user_text,
558
- "answer": assistant_text,
 
 
 
 
559
  "comment": comment,
560
  "tags": tags,
561
  "refs": refs,
@@ -613,23 +568,17 @@ def memoryline(user_id: str):
613
  # ----------------------------
614
  @app.get("/{full_path:path}")
615
  def spa_fallback(full_path: str, request: Request):
616
- # allow API and static mounts to 404 normally
617
  if (
618
  full_path.startswith("api/")
619
  or full_path.startswith("assets/")
620
  or full_path.startswith("static/")
621
- or full_path.startswith("_app/")
622
- or full_path in ("__debug__", "health", "ready")
623
  ):
624
  return JSONResponse({"detail": "Not Found"}, status_code=404)
625
 
626
- root = _pick_web_root()
627
- idx = os.path.join(root, "index.html")
628
-
629
- if os.path.exists(idx):
630
- return FileResponse(idx)
631
 
632
  return JSONResponse(
633
- {"detail": "web build not found. Expected web/build/index.html or web/dist/index.html."},
634
  status_code=500,
635
- )
 
2
  import os
3
  import time
4
  import threading
5
+ from typing import Dict, List, Optional, Any, Tuple
6
 
7
  from fastapi import FastAPI, UploadFile, File, Form, Request
8
  from fastapi.responses import FileResponse, JSONResponse
 
37
  MODULE10_PATH = os.path.join(API_DIR, "module10_responsible_ai.pdf")
38
  MODULE10_DOC_TYPE = "Literature Review / Paper"
39
 
40
+ WEB_DIST = os.path.abspath(os.path.join(API_DIR, "..", "web", "build"))
41
+ WEB_INDEX = os.path.join(WEB_DIST, "index.html")
42
+ WEB_ASSETS = os.path.join(WEB_DIST, "assets")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
  LS_DATASET_NAME = os.getenv("LS_DATASET_NAME", "clare_user_events").strip()
45
  LS_PROJECT = os.getenv("LANGSMITH_PROJECT", os.getenv("LANGCHAIN_PROJECT", "")).strip()
 
75
  )
76
 
77
  # ----------------------------
78
+ # Static hosting (Vite build)
79
  # ----------------------------
80
+ if os.path.isdir(WEB_ASSETS):
81
+ app.mount("/assets", StaticFiles(directory=WEB_ASSETS), name="assets")
 
 
 
 
 
82
 
83
+ if os.path.isdir(WEB_DIST):
84
+ app.mount("/static", StaticFiles(directory=WEB_DIST), name="static")
 
85
 
86
 
87
  @app.get("/")
88
  def index():
 
 
 
 
 
 
 
89
  if os.path.exists(WEB_INDEX):
90
  return FileResponse(WEB_INDEX)
91
  return JSONResponse(
92
+ {"detail": "web/build not found. Build frontend first (web/build/index.html)."},
93
  status_code=500,
94
  )
95
 
96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  # ----------------------------
98
  # In-memory session store (MVP)
99
  # ----------------------------
 
373
 
374
  sess["history"] = new_history
375
 
376
+ refs = [
377
+ {"source_file": c.get("source_file"), "section": c.get("section")}
378
+ for c in (rag_used_chunks or [])
379
+ ]
380
 
381
  rag_context_chars = len(rag_context_text or "")
382
  rag_used_chunks_count = len(rag_used_chunks or [])
 
487
  if rating not in ("helpful", "not_helpful"):
488
  return JSONResponse({"ok": False, "error": "Invalid rating"}, status_code=400)
489
 
490
+ # normalize fields
491
  assistant_text = (req.assistant_text or "").strip()
492
  user_text = (req.user_text or "").strip()
493
  comment = (req.comment or "").strip()
 
505
  "timestamp_ms": timestamp_ms,
506
  "rating": rating,
507
  "assistant_message_id": req.assistant_message_id,
508
+
509
+ # Keep the Example readable:
510
+ "question": user_text, # what user asked (optional)
511
+ "answer": assistant_text, # the assistant response being rated
512
+
513
+ # metadata
514
  "comment": comment,
515
  "tags": tags,
516
  "refs": refs,
 
568
  # ----------------------------
569
  @app.get("/{full_path:path}")
570
  def spa_fallback(full_path: str, request: Request):
 
571
  if (
572
  full_path.startswith("api/")
573
  or full_path.startswith("assets/")
574
  or full_path.startswith("static/")
 
 
575
  ):
576
  return JSONResponse({"detail": "Not Found"}, status_code=404)
577
 
578
+ if os.path.exists(WEB_INDEX):
579
+ return FileResponse(WEB_INDEX)
 
 
 
580
 
581
  return JSONResponse(
582
+ {"detail": "web/build not found. Build frontend first (web/build/index.html)."},
583
  status_code=500,
584
+ )