Ippo987 commited on
Commit
99e927a
·
verified ·
1 Parent(s): e134de0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +184 -77
app.py CHANGED
@@ -1,77 +1,184 @@
1
- from fastapi import FastAPI, HTTPException, APIRouter, Request
2
- from fastapi.responses import HTMLResponse
3
- import uvicorn
4
- from dataApi import router as dataAPI_router
5
- from TrendAnalysis import router as trend_analysis_process
6
- from datacite import router as citation_analysis_process
7
- from fastapi.middleware.cors import CORSMiddleware
8
- from dbconnect import db_Connect
9
- from fastapi.templating import Jinja2Templates
10
- from fastapi.staticfiles import StaticFiles
11
- from venuAnalysis import router as venue_analysis_process
12
- from venuedata import router as venuedata_router
13
-
14
-
15
-
16
- # Initialize FastAPI app
17
- app = FastAPI()
18
-
19
- app.mount("/static", StaticFiles(directory="static"), name="static")
20
- app.mount("/assets", StaticFiles(directory="assets"), name="assets")
21
-
22
- templates = Jinja2Templates(directory="templates")
23
- templates.env.auto_reload = True
24
-
25
- app.add_middleware(
26
- CORSMiddleware,
27
- allow_origins=["*"], # For development - restrict this in production
28
- allow_credentials=True,
29
- allow_methods=["*"],
30
- allow_headers=["*"],
31
- )
32
-
33
-
34
-
35
-
36
- # # Include routers
37
- app.include_router(dataAPI_router)
38
- app.include_router(trend_analysis_process)
39
- app.include_router(citation_analysis_process)
40
- app.include_router(venue_analysis_process)
41
- app.include_router(venuedata_router)
42
-
43
-
44
- collection,collection1,collection2 = db_Connect()
45
- app.state.collection = collection
46
- app.state.collection1 = collection1
47
- app.state.collection2 = collection2
48
-
49
-
50
-
51
-
52
- # Root endpoint
53
- @app.get("/")
54
- async def root():
55
- return {"message": "Welcome to the Science Mapping Tool!"}
56
-
57
-
58
-
59
- @app.get("/home", response_class=HTMLResponse)
60
- async def home(request: Request):
61
- return templates.TemplateResponse("homepage.html", {"request": request})
62
-
63
- @app.get("/login", response_class=HTMLResponse)
64
- async def login(request: Request):
65
- return templates.TemplateResponse("loginpage.html", {"request": request})
66
-
67
- @app.get("/contact", response_class=HTMLResponse)
68
- async def login(request: Request):
69
- return templates.TemplateResponse("contactBoard.html", {"request": request})
70
-
71
- @app.get("/feedback", response_class=HTMLResponse)
72
- async def login(request: Request):
73
- return templates.TemplateResponse("feedback.html", {"request": request})
74
-
75
-
76
- # uvicorn app:app --host 0.0.0.0 --port 3000 --reload
77
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException, APIRouter, Request
2
+ from fastapi.responses import HTMLResponse, RedirectResponse
3
+ import uvicorn
4
+ from dataApi import router as dataAPI_router
5
+ from TrendAnalysis import router as trend_analysis_process
6
+ from datacite import router as citation_analysis_process
7
+ from fastapi.middleware.cors import CORSMiddleware
8
+ from dbconnect import db_Connect
9
+ from fastapi.templating import Jinja2Templates
10
+ from fastapi.staticfiles import StaticFiles
11
+ from venuAnalysis import router as venue_analysis_process
12
+ from venuedata import router as venuedata_router
13
+ import os
14
+ from starlette.middleware.wsgi import WSGIMiddleware
15
+ import dash_bootstrap_components as dbc
16
+ import dash
17
+ from dash import html
18
+ import webbrowser
19
+ import threading
20
+
21
+ # Initialize FastAPI app
22
+ app = FastAPI()
23
+
24
+ # Global dash app instances
25
+ dash_app = None
26
+ venue_dash_app = None
27
+
28
+ # Define a function to get or create the trend analysis dash app
29
+ def get_or_create_dash_app():
30
+ global dash_app
31
+ if dash_app is None:
32
+ dash_app = dash.Dash(__name__,
33
+ external_stylesheets=[dbc.themes.DARKLY],
34
+ requests_pathname_prefix='/dash/')
35
+ dash_app.layout = html.Div("Dashboard is loading...")
36
+ return dash_app
37
+
38
+ # Define a function to get or create the venue dash app
39
+ def get_or_create_venue_dash_app():
40
+ global venue_dash_app
41
+ if venue_dash_app is None:
42
+ venue_dash_app = dash.Dash(__name__,
43
+ external_stylesheets=[dbc.themes.DARKLY],
44
+ requests_pathname_prefix='/venues/')
45
+ venue_dash_app.layout = html.Div("Venue Dashboard is loading. Please start an analysis first.")
46
+ return venue_dash_app
47
+
48
+ # Initialize and mount dash apps
49
+ dash_app = get_or_create_dash_app()
50
+ app.mount("/dash", WSGIMiddleware(dash_app.server))
51
+
52
+ venue_dash_app = get_or_create_venue_dash_app()
53
+ app.mount("/venues", WSGIMiddleware(venue_dash_app.server))
54
+
55
+ # Function to safely open browser
56
+ def open_browser_safely(url, delay=1.5):
57
+ def _open():
58
+ try:
59
+ webbrowser.open(url, new=2)
60
+ except Exception as e:
61
+ print(f"Error opening browser: {e}")
62
+
63
+ # Start a thread to open the browser after a delay
64
+ threading.Timer(delay, _open).start()
65
+
66
+ @app.get("/update-dashboard/{userId}/{topic}/{year}")
67
+ @app.get("/update-dashboard/{userId}/{topic}")
68
+ async def update_dashboard(request: Request, userId: str, topic: str, year: str = None):
69
+ # Import necessary components
70
+ from TrendAnalysis import fetch_papers_with_pagination, perform_trend_analysis, build_dashboard
71
+
72
+ # Convert to a TrendAnalysisRequest-like structure
73
+ class TempRequest:
74
+ def __init__(self, userId, topic, year=None, page=0):
75
+ self.userId = userId
76
+ self.topic = topic
77
+ self.year = year
78
+ self.page = page
79
+
80
+ data_request = TempRequest(userId, topic, year)
81
+
82
+ # Fetch and process data
83
+ df, current_page, total_pages, papers_count, total_papers = await fetch_papers_with_pagination(
84
+ request, data_request.userId, data_request.topic, data_request.year, data_request.page
85
+ )
86
+
87
+ if df.empty:
88
+ return {"error": "No data found"}
89
+
90
+ # Perform the trend analysis
91
+ df, topic_labels = perform_trend_analysis(df)
92
+
93
+ if df.empty:
94
+ return {"error": "Failed to process embeddings"}
95
+
96
+ # Update the global dash app
97
+ global dash_app
98
+ dash_app = build_dashboard(df, data_request.topic, data_request.year if data_request.year else "", existing_app=dash_app)
99
+
100
+ # Get the base URL from the request
101
+ base_url = str(request.base_url)
102
+ dashboard_url = f"{base_url}dash"
103
+
104
+ # Open the dashboard in a new browser tab
105
+ open_browser_safely(dashboard_url)
106
+
107
+ # Return a redirect to the dash app
108
+ return RedirectResponse(url="/dash")
109
+
110
+
111
+ # Fix for venue_redirect endpoint
112
+ @app.get("/venue_redirect/{userId}/{topic}/{year}")
113
+ @app.get("/venue_redirect/{userId}/{topic}")
114
+ async def venue_redirect(request: Request, userId: str, topic: str, year: int = None):
115
+ """
116
+ A centralized endpoint that redirects to the venue dashboard and opens it in a browser
117
+ """
118
+ try:
119
+ # Reset the global venue_dash_app to ensure a fresh instance
120
+ global venue_dash_app
121
+ venue_dash_app = None
122
+
123
+ # Re-initialize and mount the Dash app
124
+ venue_dash_app = get_or_create_venue_dash_app()
125
+ app.mount("/venues", WSGIMiddleware(venue_dash_app.server))
126
+
127
+ base_url = str(request.base_url).rstrip('/')
128
+ dashboard_url = f"{base_url}/venues/"
129
+ open_browser_safely(dashboard_url)
130
+ print(f"Redirecting to {dashboard_url}")
131
+ return RedirectResponse(url="/venues/")
132
+ except Exception as e:
133
+ print(f"Error in venue_redirect: {e}")
134
+ raise HTTPException(status_code=500, detail=f"Failed to redirect to venue dashboard: {str(e)}")
135
+
136
+
137
+ app.mount("/static", StaticFiles(directory="static"), name="static")
138
+ app.mount("/assets", StaticFiles(directory="assets"), name="assets")
139
+
140
+ templates = Jinja2Templates(directory="templates")
141
+ templates.env.auto_reload = True
142
+
143
+ app.add_middleware(
144
+ CORSMiddleware,
145
+ allow_origins=["*"], # For development - restrict this in production
146
+ allow_credentials=True,
147
+ allow_methods=["*"],
148
+ allow_headers=["*"],
149
+ )
150
+
151
+ # Include routers
152
+ app.include_router(dataAPI_router)
153
+ app.include_router(trend_analysis_process)
154
+ app.include_router(citation_analysis_process)
155
+ app.include_router(venue_analysis_process)
156
+ app.include_router(venuedata_router)
157
+
158
+ collection, collection1, collection2 = db_Connect()
159
+ app.state.collection = collection
160
+ app.state.collection1 = collection1
161
+ app.state.collection2 = collection2
162
+
163
+ # Root endpoint
164
+ @app.get("/")
165
+ async def root():
166
+ return {"message": "Welcome to the Science Mapping Tool!"}
167
+
168
+ @app.get("/home", response_class=HTMLResponse)
169
+ async def home(request: Request):
170
+ return templates.TemplateResponse("homepage.html", {"request": request})
171
+
172
+ @app.get("/login", response_class=HTMLResponse)
173
+ async def login(request: Request):
174
+ return templates.TemplateResponse("loginpage.html", {"request": request})
175
+
176
+ @app.get("/contact", response_class=HTMLResponse)
177
+ async def login(request: Request):
178
+ return templates.TemplateResponse("contactBoard.html", {"request": request})
179
+
180
+ @app.get("/feedback", response_class=HTMLResponse)
181
+ async def login(request: Request):
182
+ return templates.TemplateResponse("feedback.html", {"request": request})
183
+
184
+ # uvicorn app:app --host 0.0.0.0 --port 7000 --reload