davidepanza commited on
Commit
8fa1db6
·
verified ·
1 Parent(s): f6191d3

Upload 6 files

Browse files
app.py ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException
2
+ from fastapi.staticfiles import StaticFiles
3
+ from fastapi.responses import FileResponse
4
+ from pydantic import BaseModel
5
+ from fastapi.middleware.cors import CORSMiddleware
6
+ from sentence_transformers import SentenceTransformer
7
+ import lancedb
8
+ import os
9
+
10
+ # For local testing
11
+ from dotenv import load_dotenv
12
+ load_dotenv()
13
+
14
+ app = FastAPI()
15
+
16
+ # Enable CORS for React frontend
17
+ app.add_middleware(
18
+ CORSMiddleware,
19
+ allow_origins=["*"], # HF Spaces handles security
20
+ allow_methods=["*"],
21
+ allow_headers=["*"],
22
+ )
23
+
24
+ class BookRequest(BaseModel):
25
+ query: str
26
+ limit: int = 5
27
+
28
+ model = SentenceTransformer("all-MiniLM-L6-v2")
29
+
30
+ db = lancedb.connect(
31
+ uri=os.getenv("LANCEDB_URI", "your-lancedb-uri"),
32
+ api_key=os.getenv("LANCEDB_API_KEY", "your-api-key"),
33
+ region="us-east-1"
34
+ )
35
+
36
+ # API Routes
37
+ @app.get("/health")
38
+ def health_check():
39
+ return {"status": "healthy"}
40
+
41
+ @app.get("/tables")
42
+ def list_tables():
43
+ """Debug endpoint to see available tables"""
44
+ try:
45
+ tables = db.table_names()
46
+ return {"tables": tables}
47
+ except Exception as e:
48
+ return {"error": str(e)}
49
+
50
+ @app.post("/api/search")
51
+ def search_books(book_request: BookRequest):
52
+ if not book_request.query:
53
+ raise HTTPException(status_code=400, detail="Query string is required")
54
+
55
+ # Get query embeddings
56
+ query_embedding = model.encode(book_request.query)
57
+
58
+ table = db.open_table(os.getenv("LANCEDB_TABLE", "book_db"))
59
+ results = (table.search(query_embedding)
60
+ .select([
61
+ "id", "title", "primary_author", "description",
62
+ "publisher", "published_date", "page_count",
63
+ "primary_category", "avg_rating", "ratings_count",
64
+ "thumbnail_url", "preview_link", "list_price", "buy_link",
65
+ "_distance"
66
+ ])
67
+ .limit(book_request.limit)
68
+ .to_list())
69
+
70
+ return {"results": results}
71
+
72
+ # Serve React static files (add this section)
73
+ # Mount static assets (CSS, JS, images)
74
+ app.mount("/assets", StaticFiles(directory="dist/assets"), name="assets")
75
+
76
+ # Serve React app for all other routes (this should be last)
77
+ @app.get("/{full_path:path}")
78
+ async def serve_react_app(full_path: str):
79
+ # Don't serve React for API routes
80
+ if full_path.startswith("api/") or full_path in ["health", "tables", "docs", "redoc"]:
81
+ raise HTTPException(status_code=404, detail="Not found")
82
+ return FileResponse('dist/index.html')
dist/assets/index-BrcDu5PP.js ADDED
The diff for this file is too large to render. See raw diff
 
dist/assets/index-RZxuottz.css ADDED
@@ -0,0 +1 @@
 
 
1
+ *{margin:0;padding:0;box-sizing:border-box}body{font-family:Avenir,sans-serif;background-color:#f5f5f5}
dist/index.html ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Vite + React</title>
8
+ <script type="module" crossorigin src="/assets/index-BrcDu5PP.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-RZxuottz.css">
10
+ </head>
11
+ <body>
12
+ <div id="root"></div>
13
+ </body>
14
+ </html>
dist/vite.svg ADDED
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ fastapi==0.104.1
2
+ uvicorn[standard]==0.24.0
3
+ pydantic==2.5.0
4
+ sentence-transformers==2.2.2
5
+ lancedb==0.3.4
6
+ python-dotenv==1.0.0
7
+ torch==2.1.0
8
+ transformers==4.35.0
9
+ numpy==1.24.3