async def build_profile_report(self) -> None: """ Build a pandas profile report. This is done in a separate process because it can be quite slow. """ try: if not fs.profile_report_exists(self.data_id): await self.get_data() await execute_profile_report_builder( data_path=fs.data_path(self.data_id), output_path=fs.profile_report_path(self.data_id), title=f"{self.source.name} - {self.path}", ) if not fs.profile_report_exists(self.data_id): raise Exception( "The profile report failed to build for some reason") except Exception as e: raise HTTPException(status_code=500, detail=str(e))
async def node_watch_profile_report_builder(data_id: str): """ Allows the front-end to update the display information once a profile report builds successfully. Necessary because the profile report entails opening a separate tab. """ time_waited = 0 while time_waited < 600: if fs.profile_report_exists(data_id): return UpdateNode(node=get_node_by_data_id(data_id)) await asyncio.sleep(5) time_waited += 5 raise HTTPException( status_code=400, detail="The report either failed to generate or took too long")
async def noad_profile_report_loading_page(data_id: str): """ This one is a bit weird because it is being opened in a new tab. We do this because building a profile report can take a LONG time, and we don't want to block the main app. If the profile report output already exists, it's simple -- we just redirect you to the page for viewing it. If it does not exist, however, we return a static loading page which will make display a loading indicator and shoot off a request to /node/build-profile-report/{data_id}/. Once the report is built, the response will provide a url for viewing it. The promise resolves by redirecting the user to that URL. """ if fs.profile_report_exists(data_id): return RedirectResponse(url=f"/node/view-profile-report/{data_id}/") else: with open( os.path.join(settings.TEMPLATES_DIR, "loading_profile_report.html"), encoding="utf-8", ) as f: return f.read()