[docs]asyncdefget_arxiv_paper_by_arxiv_id(arxiv_id:str)->Optional[ArxivPaper]:"""Get ArXiv paper by ArXiv ID. :param arxiv_id: ArXiv ID :returns: ArxivPaper instance or None """asyncwithSessionLocal()assession:result=awaitsession.execute(select(ArxivPaper).where(ArxivPaper.arxiv_id==arxiv_id))returnresult.scalar_one_or_none()
[docs]asyncdefcreate_arxiv_paper(data:dict[str,Any])->ArxivPaper:"""Create an ArXiv paper. :param data: Paper data :returns: ArxivPaper instance """asyncwithSessionLocal()assession:paper=ArxivPaper(**data)session.add(paper)awaitsession.commit()awaitsession.refresh(paper)returnpaper
[docs]asyncdefhas_paper_analysis(paper_id:int,topic_id:int)->bool:"""Check if paper analysis exists. :param paper_id: Paper ID :param topic_id: Topic ID :returns: True if analysis exists """asyncwithSessionLocal()assession:result=awaitsession.execute(select(func.count(PaperAnalysis.id)).where(and_(PaperAnalysis.paper_id==paper_id,PaperAnalysis.topic_id==topic_id,)))count_val=result.scalar_one()returnbool(count_valandcount_val>0)
[docs]asyncdefcreate_paper_analysis(*,paper_id:int,topic_id:int,relevance:float,summary:Optional[str],status:str="analyzed",key_fragments:Optional[str]=None,contextual_reasoning:Optional[str]=None,)->PaperAnalysis:"""Create a paper analysis. :param paper_id: Paper ID :param topic_id: Topic ID :param relevance: Relevance score :param summary: Analysis summary :param status: Analysis status :param key_fragments: Key fragments :param contextual_reasoning: Contextual reasoning :returns: PaperAnalysis instance """asyncwithSessionLocal()assession:analysis=PaperAnalysis(paper_id=paper_id,topic_id=topic_id,relevance=relevance,summary=summary,status=status,key_fragments=key_fragments,contextual_reasoning=contextual_reasoning,)session.add(analysis)awaitsession.commit()awaitsession.refresh(analysis)returnanalysis
[docs]asyncdeflist_new_analyses_since(last_id:int,min_overall:float)->List[PaperAnalysis]:"""List new analyses since last ID. :param last_id: Last analysis ID :param min_overall: Minimum relevance score :returns: List of PaperAnalysis instances """asyncwithSessionLocal()assession:result=awaitsession.execute(select(PaperAnalysis).where(and_(PaperAnalysis.id>last_id,PaperAnalysis.status=="analyzed",PaperAnalysis.relevance>=min_overall,)).order_by(PaperAnalysis.created_at.asc()))returnlist(result.scalars().all())
[docs]asyncdefget_analysis_with_entities(analysis_id:int,)->Optional[Tuple[PaperAnalysis,ArxivPaper,ResearchTopic]]:"""Get analysis with related entities. :param analysis_id: Analysis ID :returns: Tuple of (PaperAnalysis, ArxivPaper, ResearchTopic) or None """asyncwithSessionLocal()assession:analysis=awaitsession.get(PaperAnalysis,analysis_id)ifanalysisisNone:returnNonepaper=awaitsession.get(ArxivPaper,analysis.paper_id)topic=awaitsession.get(ResearchTopic,analysis.topic_id)ifpaperisNoneortopicisNone:returnNonereturnanalysis,paper,topic
[docs]asyncdefmark_analysis_notified(analysis_id:int)->None:"""Mark analysis as notified. :param analysis_id: Analysis ID """asyncwithSessionLocal()assession:analysis=awaitsession.get(PaperAnalysis,analysis_id)ifanalysisisNone:returnanalysis.status="notified"analysis.updated_at=datetime.now()awaitsession.commit()
[docs]asyncdefmark_analysis_queued(analysis_id:int)->None:"""Mark analysis as queued. :param analysis_id: Analysis ID """asyncwithSessionLocal()assession:analysis=awaitsession.get(PaperAnalysis,analysis_id)ifanalysisisNone:returnanalysis.status="queued"analysis.updated_at=datetime.now()awaitsession.commit()