Spaces:
Sleeping
Sleeping
deploy at 2024-08-24 15:14:26.631580
Browse files
main.py
CHANGED
|
@@ -57,8 +57,9 @@ import tempfile
|
|
| 57 |
from enum import Enum
|
| 58 |
from typing import Tuple as T
|
| 59 |
from urllib.parse import quote
|
|
|
|
| 60 |
|
| 61 |
-
DEV_MODE =
|
| 62 |
|
| 63 |
if DEV_MODE:
|
| 64 |
print("Running in DEV_MODE - Hot reload enabled")
|
|
@@ -170,7 +171,7 @@ middlewares = [
|
|
| 170 |
SessionMiddleware,
|
| 171 |
secret_key=get_key(fname=sess_key_path),
|
| 172 |
max_age=3600,
|
| 173 |
-
same_site=
|
| 174 |
),
|
| 175 |
Middleware(XFrameOptionsMiddleware),
|
| 176 |
]
|
|
@@ -202,8 +203,7 @@ app, rt = fast_app(
|
|
| 202 |
|
| 203 |
|
| 204 |
sesskey = get_key(fname=sess_key_path)
|
| 205 |
-
|
| 206 |
-
print(f"Session key: {sesskey}")
|
| 207 |
|
| 208 |
|
| 209 |
# enum class for rank profiles
|
|
@@ -299,6 +299,7 @@ def get(sess):
|
|
| 299 |
"Treating Asthma With Plants vs. Pills",
|
| 300 |
"Alkylphenol Endocrine Disruptors",
|
| 301 |
"Testing Turmeric on Smokers",
|
|
|
|
| 302 |
]
|
| 303 |
return (
|
| 304 |
Title("Vespa demo"),
|
|
@@ -453,9 +454,23 @@ def replace_hi_with_strong(text):
|
|
| 453 |
|
| 454 |
|
| 455 |
def log_query_to_db(query, ranking, sess):
|
| 456 |
-
|
| 457 |
-
|
| 458 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 459 |
|
| 460 |
|
| 461 |
def parse_results(records):
|
|
@@ -544,15 +559,8 @@ def get_yql(ranking: RankProfile, userquery: str) -> T[str, dict]:
|
|
| 544 |
|
| 545 |
@app.get("/search")
|
| 546 |
async def search(userquery: str, ranking: str, sess):
|
| 547 |
-
print(
|
| 548 |
-
print(f"Session: {sess}")
|
| 549 |
-
if "queries" not in sess:
|
| 550 |
-
print("Creating queries list")
|
| 551 |
-
sess["queries"] = []
|
| 552 |
quoted = quote(userquery) + "&ranking=" + ranking
|
| 553 |
-
sess["queries"].append(quoted)
|
| 554 |
-
print(f"Searching for: {userquery}")
|
| 555 |
-
print(f"Ranking: {ranking}")
|
| 556 |
log_query_to_db(userquery, ranking, sess)
|
| 557 |
yql, body = get_yql(ranking, userquery)
|
| 558 |
async with vespa_app.asyncio() as session:
|
|
@@ -593,16 +601,23 @@ async def search(userquery: str, ranking: str, sess):
|
|
| 593 |
|
| 594 |
|
| 595 |
@app.get("/download_csv")
|
| 596 |
-
def download_csv(auth):
|
| 597 |
-
|
| 598 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 599 |
|
| 600 |
# Create CSV in memory
|
| 601 |
csv_file = StringIO()
|
| 602 |
csv_writer = csv.writer(csv_file)
|
| 603 |
-
csv_writer.writerow(["Query", "
|
| 604 |
-
for query in
|
| 605 |
-
csv_writer.writerow([query
|
| 606 |
|
| 607 |
# Move to the beginning of the StringIO object
|
| 608 |
csv_file.seek(0)
|
|
@@ -621,21 +636,27 @@ def download_csv(auth):
|
|
| 621 |
|
| 622 |
|
| 623 |
@app.get("/admin")
|
| 624 |
-
def get_admin(auth, page: int = 1):
|
|
|
|
|
|
|
|
|
|
| 625 |
limit = 15
|
| 626 |
offset = (page - 1) * limit
|
| 627 |
-
total_queries_result = list(
|
| 628 |
-
db.query("SELECT COUNT(*) AS count FROM queries ORDER BY timestamp DESC")
|
| 629 |
-
)
|
| 630 |
-
total_queries = total_queries_result[0]["count"]
|
| 631 |
-
queries_dict = list(
|
| 632 |
-
db.query(f"SELECT * FROM queries LIMIT {limit} OFFSET {offset}")
|
| 633 |
-
)
|
| 634 |
-
queries = [Query(**query) for query in queries_dict]
|
| 635 |
|
| 636 |
-
|
| 637 |
-
|
| 638 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 639 |
|
| 640 |
# Define the range of pages to display
|
| 641 |
page_window = 5 # Number of pages to display at once
|
|
@@ -715,16 +736,16 @@ def get_admin(auth, page: int = 1):
|
|
| 715 |
Thead(
|
| 716 |
Tr(
|
| 717 |
Th("Query"),
|
| 718 |
-
Th("
|
| 719 |
Th("Datetime"),
|
| 720 |
)
|
| 721 |
),
|
| 722 |
Tbody(
|
| 723 |
*[
|
| 724 |
Tr(
|
| 725 |
-
Td(query
|
| 726 |
-
Td(query
|
| 727 |
-
Td(
|
| 728 |
)
|
| 729 |
for query in queries
|
| 730 |
],
|
|
@@ -806,8 +827,6 @@ def get_about(auth, sess):
|
|
| 806 |
|
| 807 |
@app.get("/document/{docid}")
|
| 808 |
def get_document(docid: str, sess):
|
| 809 |
-
print(f"Getting document {docid}")
|
| 810 |
-
print(f"Session: {sess}")
|
| 811 |
resp = vespa_app.get_data(data_id=docid, schema="doc", namespace="tutorial")
|
| 812 |
doc = resp.json
|
| 813 |
# Link with Back to search results at top of page
|
|
@@ -831,4 +850,17 @@ if not DEV_MODE:
|
|
| 831 |
setup_hf_backup(app)
|
| 832 |
except Exception as e:
|
| 833 |
print(f"Error setting up hf backup: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 834 |
serve()
|
|
|
|
| 57 |
from enum import Enum
|
| 58 |
from typing import Tuple as T
|
| 59 |
from urllib.parse import quote
|
| 60 |
+
import uuid
|
| 61 |
|
| 62 |
+
DEV_MODE = True
|
| 63 |
|
| 64 |
if DEV_MODE:
|
| 65 |
print("Running in DEV_MODE - Hot reload enabled")
|
|
|
|
| 171 |
SessionMiddleware,
|
| 172 |
secret_key=get_key(fname=sess_key_path),
|
| 173 |
max_age=3600,
|
| 174 |
+
same_site='lax', # This allows cookies to be sent in top-level navigations
|
| 175 |
),
|
| 176 |
Middleware(XFrameOptionsMiddleware),
|
| 177 |
]
|
|
|
|
| 203 |
|
| 204 |
|
| 205 |
sesskey = get_key(fname=sess_key_path)
|
| 206 |
+
print(f"Session key: {sesskey}")
|
|
|
|
| 207 |
|
| 208 |
|
| 209 |
# enum class for rank profiles
|
|
|
|
| 299 |
"Treating Asthma With Plants vs. Pills",
|
| 300 |
"Alkylphenol Endocrine Disruptors",
|
| 301 |
"Testing Turmeric on Smokers",
|
| 302 |
+
"The Role of Pesticides in Parkinson's Disease",
|
| 303 |
]
|
| 304 |
return (
|
| 305 |
Title("Vespa demo"),
|
|
|
|
| 454 |
|
| 455 |
|
| 456 |
def log_query_to_db(query, ranking, sess):
|
| 457 |
+
if 'user_id' not in sess:
|
| 458 |
+
sess['user_id'] = str(uuid.uuid4())
|
| 459 |
+
|
| 460 |
+
if 'queries' not in sess:
|
| 461 |
+
sess['queries'] = []
|
| 462 |
+
|
| 463 |
+
query_data = {
|
| 464 |
+
'query': query,
|
| 465 |
+
'ranking': ranking,
|
| 466 |
+
'timestamp': int(time.time())
|
| 467 |
+
}
|
| 468 |
+
sess['queries'].append(query_data)
|
| 469 |
+
|
| 470 |
+
# Limit the number of queries stored in the session to prevent it from growing too large
|
| 471 |
+
sess['queries'] = sess['queries'][-100:] # Keep only the last 100 queries
|
| 472 |
+
|
| 473 |
+
return query_data
|
| 474 |
|
| 475 |
|
| 476 |
def parse_results(records):
|
|
|
|
| 559 |
|
| 560 |
@app.get("/search")
|
| 561 |
async def search(userquery: str, ranking: str, sess):
|
| 562 |
+
print(sess)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 563 |
quoted = quote(userquery) + "&ranking=" + ranking
|
|
|
|
|
|
|
|
|
|
| 564 |
log_query_to_db(userquery, ranking, sess)
|
| 565 |
yql, body = get_yql(ranking, userquery)
|
| 566 |
async with vespa_app.asyncio() as session:
|
|
|
|
| 601 |
|
| 602 |
|
| 603 |
@app.get("/download_csv")
|
| 604 |
+
def download_csv(auth, sess):
|
| 605 |
+
if not auth:
|
| 606 |
+
return RedirectResponse("/login", status_code=303)
|
| 607 |
+
|
| 608 |
+
all_queries = []
|
| 609 |
+
for user_id, user_sess in app.state.sessions.items():
|
| 610 |
+
user_queries = user_sess.get('queries', [])
|
| 611 |
+
for query in user_queries:
|
| 612 |
+
query['user_id'] = user_id
|
| 613 |
+
all_queries.extend(user_queries)
|
| 614 |
|
| 615 |
# Create CSV in memory
|
| 616 |
csv_file = StringIO()
|
| 617 |
csv_writer = csv.writer(csv_file)
|
| 618 |
+
csv_writer.writerow(["Query", "User ID", "Timestamp", "Ranking"])
|
| 619 |
+
for query in all_queries:
|
| 620 |
+
csv_writer.writerow([query['query'], query['user_id'], query['timestamp'], query['ranking']])
|
| 621 |
|
| 622 |
# Move to the beginning of the StringIO object
|
| 623 |
csv_file.seek(0)
|
|
|
|
| 636 |
|
| 637 |
|
| 638 |
@app.get("/admin")
|
| 639 |
+
def get_admin(auth, sess, page: int = 1):
|
| 640 |
+
if not auth:
|
| 641 |
+
return RedirectResponse("/login", status_code=303)
|
| 642 |
+
|
| 643 |
limit = 15
|
| 644 |
offset = (page - 1) * limit
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 645 |
|
| 646 |
+
all_queries = []
|
| 647 |
+
for user_id, user_sess in app.state.sessions.items():
|
| 648 |
+
user_queries = user_sess.get('queries', [])
|
| 649 |
+
for query in user_queries:
|
| 650 |
+
query['user_id'] = user_id
|
| 651 |
+
all_queries.extend(user_queries)
|
| 652 |
+
|
| 653 |
+
# Sort queries by timestamp in descending order
|
| 654 |
+
all_queries.sort(key=lambda x: x['timestamp'], reverse=True)
|
| 655 |
+
|
| 656 |
+
total_queries = len(all_queries)
|
| 657 |
+
queries = all_queries[offset:offset+limit]
|
| 658 |
+
|
| 659 |
+
total_pages = (total_queries + limit - 1) // limit
|
| 660 |
|
| 661 |
# Define the range of pages to display
|
| 662 |
page_window = 5 # Number of pages to display at once
|
|
|
|
| 736 |
Thead(
|
| 737 |
Tr(
|
| 738 |
Th("Query"),
|
| 739 |
+
Th("User ID"),
|
| 740 |
Th("Datetime"),
|
| 741 |
)
|
| 742 |
),
|
| 743 |
Tbody(
|
| 744 |
*[
|
| 745 |
Tr(
|
| 746 |
+
Td(query['query']),
|
| 747 |
+
Td(query['user_id']),
|
| 748 |
+
Td(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(query['timestamp']))),
|
| 749 |
)
|
| 750 |
for query in queries
|
| 751 |
],
|
|
|
|
| 827 |
|
| 828 |
@app.get("/document/{docid}")
|
| 829 |
def get_document(docid: str, sess):
|
|
|
|
|
|
|
| 830 |
resp = vespa_app.get_data(data_id=docid, schema="doc", namespace="tutorial")
|
| 831 |
doc = resp.json
|
| 832 |
# Link with Back to search results at top of page
|
|
|
|
| 850 |
setup_hf_backup(app)
|
| 851 |
except Exception as e:
|
| 852 |
print(f"Error setting up hf backup: {e}")
|
| 853 |
+
|
| 854 |
+
# Add this at the end of your file, before serve()
|
| 855 |
+
app.state.sessions = {}
|
| 856 |
+
|
| 857 |
+
@app.middleware("http")
|
| 858 |
+
async def add_session_to_app_state(request, call_next):
|
| 859 |
+
response = await call_next(request)
|
| 860 |
+
if 'session' in request.scope:
|
| 861 |
+
session = request.scope['session']
|
| 862 |
+
if 'user_id' in session:
|
| 863 |
+
app.state.sessions[session['user_id']] = session
|
| 864 |
+
return response
|
| 865 |
+
|
| 866 |
serve()
|