Spaces:
Sleeping
Sleeping
Nur Arifin Akbar commited on
Commit ·
9c12608
1
Parent(s): 9a4a0bb
Add rate limiting and API key management
Browse files- Add Semantic Scholar API key support in environment variables
- Implement 1 req/sec rate limiting for both LLM and Semantic Scholar APIs
- Sequential processing to avoid concurrency issues
- Load environment variables using python-dotenv
- Update README with rate limiting information and security notes
- Ensure .env is in .gitignore (already present)
.env.example
CHANGED
|
@@ -3,6 +3,9 @@ OPENAI_API_KEY=your-api-key-here
|
|
| 3 |
OPENAI_BASE_URL=https://api.openai.com/v1
|
| 4 |
MODEL_NAME=gpt-4
|
| 5 |
|
|
|
|
|
|
|
|
|
|
| 6 |
# Alternative configurations:
|
| 7 |
# For Azure OpenAI:
|
| 8 |
# OPENAI_BASE_URL=https://your-resource.openai.azure.com/
|
|
|
|
| 3 |
OPENAI_BASE_URL=https://api.openai.com/v1
|
| 4 |
MODEL_NAME=gpt-4
|
| 5 |
|
| 6 |
+
# Semantic Scholar API Configuration
|
| 7 |
+
SEMANTIC_SCHOLAR_API_KEY=your-semantic-scholar-api-key-here
|
| 8 |
+
|
| 9 |
# Alternative configurations:
|
| 10 |
# For Azure OpenAI:
|
| 11 |
# OPENAI_BASE_URL=https://your-resource.openai.azure.com/
|
README.md
CHANGED
|
Binary files a/README.md and b/README.md differ
|
|
|
agents.py
CHANGED
|
@@ -3,6 +3,7 @@
|
|
| 3 |
import json
|
| 4 |
import re
|
| 5 |
import os
|
|
|
|
| 6 |
from typing import Any, Optional, Dict, Tuple
|
| 7 |
from openai import OpenAI
|
| 8 |
|
|
@@ -35,8 +36,11 @@ def extract_json_between_markers(llm_output: str) -> Optional[Dict[str, Any]]:
|
|
| 35 |
|
| 36 |
|
| 37 |
def query_model(system_prompt: str, prompt: str, client: OpenAI, model: str) -> Optional[str]:
|
| 38 |
-
"""Query the model with the given prompts using OpenAI-compatible API."""
|
| 39 |
try:
|
|
|
|
|
|
|
|
|
|
| 40 |
response = client.chat.completions.create(
|
| 41 |
model=model,
|
| 42 |
messages=[
|
|
@@ -49,6 +53,8 @@ def query_model(system_prompt: str, prompt: str, client: OpenAI, model: str) ->
|
|
| 49 |
return response.choices[0].message.content
|
| 50 |
except Exception as e:
|
| 51 |
print(f"Error querying model: {e}")
|
|
|
|
|
|
|
| 52 |
return None
|
| 53 |
|
| 54 |
|
|
|
|
| 3 |
import json
|
| 4 |
import re
|
| 5 |
import os
|
| 6 |
+
import time
|
| 7 |
from typing import Any, Optional, Dict, Tuple
|
| 8 |
from openai import OpenAI
|
| 9 |
|
|
|
|
| 36 |
|
| 37 |
|
| 38 |
def query_model(system_prompt: str, prompt: str, client: OpenAI, model: str) -> Optional[str]:
|
| 39 |
+
"""Query the model with the given prompts using OpenAI-compatible API with rate limiting."""
|
| 40 |
try:
|
| 41 |
+
# Rate limiting: 1 request per second to avoid concurrency issues
|
| 42 |
+
time.sleep(1)
|
| 43 |
+
|
| 44 |
response = client.chat.completions.create(
|
| 45 |
model=model,
|
| 46 |
messages=[
|
|
|
|
| 53 |
return response.choices[0].message.content
|
| 54 |
except Exception as e:
|
| 55 |
print(f"Error querying model: {e}")
|
| 56 |
+
# Wait before retry
|
| 57 |
+
time.sleep(2)
|
| 58 |
return None
|
| 59 |
|
| 60 |
|
app.py
CHANGED
|
@@ -7,6 +7,10 @@ from markitdown import MarkItDown
|
|
| 7 |
from agents import MultiReviewerSystem
|
| 8 |
import requests
|
| 9 |
import time
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
|
| 11 |
|
| 12 |
def extract_text_from_pdf(pdf_file) -> str:
|
|
@@ -23,8 +27,8 @@ def extract_text_from_pdf(pdf_file) -> str:
|
|
| 23 |
return f"Error extracting text from PDF: {str(e)}"
|
| 24 |
|
| 25 |
|
| 26 |
-
def search_semantic_scholar(query: str, limit: int = 5) -> List[Dict]:
|
| 27 |
-
"""Search for related papers on Semantic Scholar."""
|
| 28 |
try:
|
| 29 |
url = "https://api.semanticscholar.org/graph/v1/paper/search"
|
| 30 |
params = {
|
|
@@ -33,7 +37,14 @@ def search_semantic_scholar(query: str, limit: int = 5) -> List[Dict]:
|
|
| 33 |
"fields": "title,authors,year,abstract,citationCount,url,openAccessPdf"
|
| 34 |
}
|
| 35 |
|
| 36 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
response.raise_for_status()
|
| 38 |
|
| 39 |
data = response.json()
|
|
@@ -122,9 +133,9 @@ def review_paper(
|
|
| 122 |
if search_related:
|
| 123 |
progress(0.2, desc="Searching for related papers...")
|
| 124 |
paper_title = extract_paper_title_from_text(paper_text)
|
| 125 |
-
|
|
|
|
| 126 |
related_papers_md = format_semantic_scholar_results(related_papers)
|
| 127 |
-
time.sleep(1) # Rate limiting
|
| 128 |
|
| 129 |
# Initialize multi-reviewer system
|
| 130 |
progress(0.3, desc="Initializing reviewers...")
|
|
|
|
| 7 |
from agents import MultiReviewerSystem
|
| 8 |
import requests
|
| 9 |
import time
|
| 10 |
+
from dotenv import load_dotenv
|
| 11 |
+
|
| 12 |
+
# Load environment variables from .env file
|
| 13 |
+
load_dotenv()
|
| 14 |
|
| 15 |
|
| 16 |
def extract_text_from_pdf(pdf_file) -> str:
|
|
|
|
| 27 |
return f"Error extracting text from PDF: {str(e)}"
|
| 28 |
|
| 29 |
|
| 30 |
+
def search_semantic_scholar(query: str, limit: int = 5, api_key: str = None) -> List[Dict]:
|
| 31 |
+
"""Search for related papers on Semantic Scholar with rate limiting."""
|
| 32 |
try:
|
| 33 |
url = "https://api.semanticscholar.org/graph/v1/paper/search"
|
| 34 |
params = {
|
|
|
|
| 37 |
"fields": "title,authors,year,abstract,citationCount,url,openAccessPdf"
|
| 38 |
}
|
| 39 |
|
| 40 |
+
headers = {}
|
| 41 |
+
if api_key:
|
| 42 |
+
headers["x-api-key"] = api_key
|
| 43 |
+
|
| 44 |
+
# Rate limiting: 1 request per second
|
| 45 |
+
time.sleep(1)
|
| 46 |
+
|
| 47 |
+
response = requests.get(url, params=params, headers=headers, timeout=10)
|
| 48 |
response.raise_for_status()
|
| 49 |
|
| 50 |
data = response.json()
|
|
|
|
| 133 |
if search_related:
|
| 134 |
progress(0.2, desc="Searching for related papers...")
|
| 135 |
paper_title = extract_paper_title_from_text(paper_text)
|
| 136 |
+
semantic_scholar_key = os.getenv("SEMANTIC_SCHOLAR_API_KEY", "")
|
| 137 |
+
related_papers = search_semantic_scholar(paper_title, limit=5, api_key=semantic_scholar_key)
|
| 138 |
related_papers_md = format_semantic_scholar_results(related_papers)
|
|
|
|
| 139 |
|
| 140 |
# Initialize multi-reviewer system
|
| 141 |
progress(0.3, desc="Initializing reviewers...")
|