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