Spaces:
Sleeping
Sleeping
Update genesis/providers.py
Browse files- genesis/providers.py +47 -49
genesis/providers.py
CHANGED
@@ -1,28 +1,21 @@
|
|
1 |
-
# genesis/providers.py
|
2 |
"""
|
3 |
Providers module for GENESIS-AI
|
4 |
-
Handles:
|
5 |
-
1. Medical/Biological APIs (PubMed, ChEMBL, BioPortal, UMLS, NCBI)
|
6 |
-
2. AI Text Generation (Gemini, OpenAI, Claude, DeepSeek)
|
7 |
-
3. Image Generation (Gemini Vision, OpenAI DALLΒ·E, Hugging Face Diffusion)
|
8 |
-
4. Text-to-Speech (ElevenLabs + fallback)
|
9 |
-
5. Graph DB Integration (Neo4j for pathways/funding)
|
10 |
"""
|
11 |
|
12 |
import os
|
13 |
import json
|
14 |
import requests
|
15 |
import logging
|
16 |
-
from neo4j import GraphDatabase
|
17 |
from dotenv import load_dotenv
|
|
|
18 |
|
19 |
# ========================
|
20 |
-
#
|
21 |
# ========================
|
22 |
load_dotenv()
|
23 |
logging.basicConfig(level=logging.INFO)
|
24 |
|
25 |
-
# API KEYS
|
26 |
PUBMED_API_KEY = os.getenv("PUBMED_API_KEY")
|
27 |
CHEMBL_API_KEY = os.getenv("CHEMBL_API_KEY")
|
28 |
BIOPORTAL_API_KEY = os.getenv("BIOPORTAL_API_KEY")
|
@@ -40,10 +33,22 @@ NEO4J_URI = os.getenv("NEO4J_URI")
|
|
40 |
NEO4J_USER = os.getenv("NEO4J_USER")
|
41 |
NEO4J_PASSWORD = os.getenv("NEO4J_PASSWORD")
|
42 |
|
43 |
-
#
|
44 |
-
|
45 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
|
|
|
|
|
|
|
47 |
def safe_request(url, headers=None, params=None, data=None, method="GET", json_data=None):
|
48 |
try:
|
49 |
if method == "GET":
|
@@ -57,11 +62,10 @@ def safe_request(url, headers=None, params=None, data=None, method="GET", json_d
|
|
57 |
return None
|
58 |
|
59 |
# ========================
|
60 |
-
#
|
61 |
# ========================
|
62 |
-
|
63 |
def run_pubmed_literature(query, max_results=5):
|
64 |
-
url =
|
65 |
params = {
|
66 |
"db": "pubmed",
|
67 |
"term": query,
|
@@ -82,35 +86,33 @@ def run_pubmed_literature(query, max_results=5):
|
|
82 |
results.append(summary)
|
83 |
return results
|
84 |
|
85 |
-
|
86 |
def run_chembl_search(molecule_name):
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
|
92 |
def run_bioportal_ontology(term):
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
|
98 |
def run_umls_search(term):
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
|
104 |
def run_ncbi_gene_lookup(gene_id):
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
|
110 |
# ========================
|
111 |
-
#
|
112 |
# ========================
|
113 |
-
|
114 |
def ai_generate_text(prompt, model="gemini"):
|
115 |
"""Fallback order: Gemini β OpenAI β Claude β DeepSeek"""
|
116 |
if model == "gemini" and GEMINI_API_KEY:
|
@@ -156,11 +158,9 @@ def ai_generate_text(prompt, model="gemini"):
|
|
156 |
|
157 |
return "No AI provider available or all failed."
|
158 |
|
159 |
-
|
160 |
# ========================
|
161 |
-
#
|
162 |
# ========================
|
163 |
-
|
164 |
def ai_generate_image(prompt):
|
165 |
"""Fallback: Gemini Vision β OpenAI β Hugging Face"""
|
166 |
if GEMINI_API_KEY:
|
@@ -181,7 +181,6 @@ def ai_generate_image(prompt):
|
|
181 |
except Exception as e:
|
182 |
logging.error(f"OpenAI Image error: {e}")
|
183 |
|
184 |
-
# Hugging Face fallback
|
185 |
HF_TOKEN = os.getenv("HF_TOKEN")
|
186 |
if HF_TOKEN:
|
187 |
resp = safe_request(
|
@@ -195,11 +194,9 @@ def ai_generate_image(prompt):
|
|
195 |
|
196 |
return None
|
197 |
|
198 |
-
|
199 |
# ========================
|
200 |
-
#
|
201 |
# ========================
|
202 |
-
|
203 |
def run_tts(text, voice="Rachel"):
|
204 |
if ELEVENLABS_API_KEY:
|
205 |
url = f"https://api.elevenlabs.io/v1/text-to-speech/{voice}"
|
@@ -209,12 +206,13 @@ def run_tts(text, voice="Rachel"):
|
|
209 |
return resp.content
|
210 |
return None
|
211 |
|
212 |
-
|
213 |
# ========================
|
214 |
-
#
|
215 |
# ========================
|
216 |
-
|
217 |
def query_funding_network(keyword):
|
|
|
|
|
|
|
218 |
with neo4j_driver.session() as session:
|
219 |
result = session.run(
|
220 |
"""
|
@@ -226,8 +224,10 @@ def query_funding_network(keyword):
|
|
226 |
)
|
227 |
return [dict(record) for record in result]
|
228 |
|
229 |
-
|
230 |
def query_pathway_graph(pathway):
|
|
|
|
|
|
|
231 |
with neo4j_driver.session() as session:
|
232 |
result = session.run(
|
233 |
"""
|
@@ -238,11 +238,9 @@ def query_pathway_graph(pathway):
|
|
238 |
)
|
239 |
return [dict(record) for record in result]
|
240 |
|
241 |
-
|
242 |
# ========================
|
243 |
-
#
|
244 |
# ========================
|
245 |
-
|
246 |
__all__ = [
|
247 |
"run_pubmed_literature",
|
248 |
"run_chembl_search",
|
|
|
|
|
1 |
"""
|
2 |
Providers module for GENESIS-AI
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
"""
|
4 |
|
5 |
import os
|
6 |
import json
|
7 |
import requests
|
8 |
import logging
|
|
|
9 |
from dotenv import load_dotenv
|
10 |
+
from neo4j import GraphDatabase
|
11 |
|
12 |
# ========================
|
13 |
+
# SETUP & LOGGING
|
14 |
# ========================
|
15 |
load_dotenv()
|
16 |
logging.basicConfig(level=logging.INFO)
|
17 |
|
18 |
+
# API KEYS
|
19 |
PUBMED_API_KEY = os.getenv("PUBMED_API_KEY")
|
20 |
CHEMBL_API_KEY = os.getenv("CHEMBL_API_KEY")
|
21 |
BIOPORTAL_API_KEY = os.getenv("BIOPORTAL_API_KEY")
|
|
|
33 |
NEO4J_USER = os.getenv("NEO4J_USER")
|
34 |
NEO4J_PASSWORD = os.getenv("NEO4J_PASSWORD")
|
35 |
|
36 |
+
# ========================
|
37 |
+
# OPTIONAL NEO4J CONNECTION
|
38 |
+
# ========================
|
39 |
+
neo4j_driver = None
|
40 |
+
if NEO4J_URI and NEO4J_USER and NEO4J_PASSWORD:
|
41 |
+
try:
|
42 |
+
neo4j_driver = GraphDatabase.driver(NEO4J_URI, auth=(NEO4J_USER, NEO4J_PASSWORD))
|
43 |
+
logging.info("[Neo4j] Connected successfully.")
|
44 |
+
except Exception as e:
|
45 |
+
logging.error(f"[Neo4j] Connection failed: {e}")
|
46 |
+
else:
|
47 |
+
logging.info("[Neo4j] No URI/user/password set β skipping connection.")
|
48 |
|
49 |
+
# ========================
|
50 |
+
# SAFE REQUEST WRAPPER
|
51 |
+
# ========================
|
52 |
def safe_request(url, headers=None, params=None, data=None, method="GET", json_data=None):
|
53 |
try:
|
54 |
if method == "GET":
|
|
|
62 |
return None
|
63 |
|
64 |
# ========================
|
65 |
+
# MEDICAL & BIOLOGY API CLIENTS
|
66 |
# ========================
|
|
|
67 |
def run_pubmed_literature(query, max_results=5):
|
68 |
+
url = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi"
|
69 |
params = {
|
70 |
"db": "pubmed",
|
71 |
"term": query,
|
|
|
86 |
results.append(summary)
|
87 |
return results
|
88 |
|
|
|
89 |
def run_chembl_search(molecule_name):
|
90 |
+
return safe_request(
|
91 |
+
"https://www.ebi.ac.uk/chembl/api/data/molecule",
|
92 |
+
params={"molecule_synonyms__icontains": molecule_name, "format": "json"}
|
93 |
+
)
|
94 |
|
95 |
def run_bioportal_ontology(term):
|
96 |
+
return safe_request(
|
97 |
+
"https://data.bioontology.org/search",
|
98 |
+
params={"q": term, "apikey": BIOPORTAL_API_KEY}
|
99 |
+
)
|
100 |
|
101 |
def run_umls_search(term):
|
102 |
+
return safe_request(
|
103 |
+
"https://uts-ws.nlm.nih.gov/rest/search/current",
|
104 |
+
params={"string": term, "apiKey": UMLS_API_KEY}
|
105 |
+
)
|
106 |
|
107 |
def run_ncbi_gene_lookup(gene_id):
|
108 |
+
return safe_request(
|
109 |
+
f"https://api.ncbi.nlm.nih.gov/gene/{gene_id}",
|
110 |
+
headers={"api-key": NCBI_API_KEY}
|
111 |
+
)
|
112 |
|
113 |
# ========================
|
114 |
+
# AI TEXT GENERATION
|
115 |
# ========================
|
|
|
116 |
def ai_generate_text(prompt, model="gemini"):
|
117 |
"""Fallback order: Gemini β OpenAI β Claude β DeepSeek"""
|
118 |
if model == "gemini" and GEMINI_API_KEY:
|
|
|
158 |
|
159 |
return "No AI provider available or all failed."
|
160 |
|
|
|
161 |
# ========================
|
162 |
+
# IMAGE GENERATION
|
163 |
# ========================
|
|
|
164 |
def ai_generate_image(prompt):
|
165 |
"""Fallback: Gemini Vision β OpenAI β Hugging Face"""
|
166 |
if GEMINI_API_KEY:
|
|
|
181 |
except Exception as e:
|
182 |
logging.error(f"OpenAI Image error: {e}")
|
183 |
|
|
|
184 |
HF_TOKEN = os.getenv("HF_TOKEN")
|
185 |
if HF_TOKEN:
|
186 |
resp = safe_request(
|
|
|
194 |
|
195 |
return None
|
196 |
|
|
|
197 |
# ========================
|
198 |
+
# TEXT-TO-SPEECH
|
199 |
# ========================
|
|
|
200 |
def run_tts(text, voice="Rachel"):
|
201 |
if ELEVENLABS_API_KEY:
|
202 |
url = f"https://api.elevenlabs.io/v1/text-to-speech/{voice}"
|
|
|
206 |
return resp.content
|
207 |
return None
|
208 |
|
|
|
209 |
# ========================
|
210 |
+
# GRAPH DB QUERIES (Optional)
|
211 |
# ========================
|
|
|
212 |
def query_funding_network(keyword):
|
213 |
+
if not neo4j_driver:
|
214 |
+
logging.warning("[Neo4j] Skipping query β no connection.")
|
215 |
+
return []
|
216 |
with neo4j_driver.session() as session:
|
217 |
result = session.run(
|
218 |
"""
|
|
|
224 |
)
|
225 |
return [dict(record) for record in result]
|
226 |
|
|
|
227 |
def query_pathway_graph(pathway):
|
228 |
+
if not neo4j_driver:
|
229 |
+
logging.warning("[Neo4j] Skipping query β no connection.")
|
230 |
+
return []
|
231 |
with neo4j_driver.session() as session:
|
232 |
result = session.run(
|
233 |
"""
|
|
|
238 |
)
|
239 |
return [dict(record) for record in result]
|
240 |
|
|
|
241 |
# ========================
|
242 |
+
# EXPORTS
|
243 |
# ========================
|
|
|
244 |
__all__ = [
|
245 |
"run_pubmed_literature",
|
246 |
"run_chembl_search",
|