# Semantic_Scholar.py # Description: This file contains the functions to interact with the Semantic Scholar API # # Imports from typing import List, Dict, Any import requests # #################################################################################################### # # Functions # Constants FIELDS_OF_STUDY = [ "Computer Science", "Medicine", "Chemistry", "Biology", "Materials Science", "Physics", "Geology", "Psychology", "Art", "History", "Geography", "Sociology", "Business", "Political Science", "Economics", "Philosophy", "Mathematics", "Engineering", "Environmental Science", "Agricultural and Food Sciences", "Education", "Law", "Linguistics" ] PUBLICATION_TYPES = [ "Review", "JournalArticle", "CaseReport", "ClinicalTrial", "Conference", "Dataset", "Editorial", "LettersAndComments", "MetaAnalysis", "News", "Study", "Book", "BookSection" ] def search_papers( query: str, page: int, fields_of_study: List[str], publication_types: List[str], year_range: str, venue: str, min_citations: int, open_access_only: bool, limit: int = 10 ) -> Dict[str, Any]: """Search for papers using the Semantic Scholar API with all available filters""" if not query.strip(): return {"total": 0, "offset": 0, "next": 0, "data": []} try: url = "https://api.semanticscholar.org/graph/v1/paper/search" params = { "query": query, "offset": page * limit, "limit": limit, "fields": "title,abstract,year,citationCount,authors,venue,openAccessPdf,url,publicationTypes,publicationDate" } # Add optional filters if fields_of_study: params["fieldsOfStudy"] = ",".join(fields_of_study) if publication_types: params["publicationTypes"] = ",".join(publication_types) if venue: params["venue"] = venue if min_citations: params["minCitationCount"] = str(min_citations) if open_access_only: params["openAccessPdf"] = "" if year_range: try: if "-" in year_range: start_year, end_year = year_range.split("-") params["year"] = f"{start_year.strip()}-{end_year.strip()}" else: params["year"] = year_range.strip() except ValueError: pass response = requests.get(url, params=params) response.raise_for_status() return response.json() except requests.exceptions.RequestException as e: return {"error": f"API Error: {str(e)}", "total": 0, "offset": 0, "data": []} def get_paper_details(paper_id): """Get detailed information about a specific paper""" try: url = f"https://api.semanticscholar.org/graph/v1/paper/{paper_id}" params = { "fields": "title,abstract,year,citationCount,authors,venue,openAccessPdf,url,references,citations" } response = requests.get(url, params=params) response.raise_for_status() return response.json() except requests.exceptions.RequestException as e: return {"error": f"API Error: {str(e)}"} def format_paper_info(paper: Dict[str, Any]) -> str: """Format paper information for display""" authors = ", ".join([author["name"] for author in paper.get("authors", [])]) year = f"Year: {paper.get('year', 'N/A')}" venue = f"Venue: {paper.get('venue', 'N/A')}" citations = f"Citations: {paper.get('citationCount', 0)}" pub_types = f"Types: {', '.join(paper.get('publicationTypes', ['N/A']))}" pdf_link = "" if paper.get("openAccessPdf"): pdf_link = f"\nPDF: {paper['openAccessPdf']['url']}" s2_link = f"\nSemantic Scholar: {paper.get('url', '')}" formatted = f"""# {paper.get('title', 'No Title')} Authors: {authors} {year} | {venue} | {citations} {pub_types} Abstract: {paper.get('abstract', 'No abstract available')} Links:{pdf_link}{s2_link} """ return formatted def search_and_display( query: str, page: int, fields_of_study: List[str], publication_types: List[str], year_range: str, venue: str, min_citations: int, open_access_only: bool ) -> tuple[str, int, int, str]: """Search for papers and return formatted results with pagination info""" result = search_papers( query, page, fields_of_study, publication_types, year_range, venue, min_citations, open_access_only ) if "error" in result: return result["error"], 0, 0, "0" if not result["data"]: return "No results found.", 0, 0, "0" papers = result["data"] total_results = int(result.get("total", "0")) max_pages = (total_results + 9) // 10 # Ceiling division results = [] for paper in papers: results.append(format_paper_info(paper)) formatted_results = "\n\n---\n\n".join(results) # Add pagination information pagination_info = f"\n\n---\n\nShowing results {result['offset'] + 1}-{result['offset'] + len(papers)} of {total_results}" return formatted_results + pagination_info, page, max_pages - 1, str(total_results) # # End of Semantic_Scholar.py ####################################################################################################