-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgraphql_api.py
100 lines (88 loc) · 3.51 KB
/
graphql_api.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
from ariadne import QueryType, make_executable_schema, graphql_sync, load_schema_from_path
from flask import jsonify, request
from knowledge_graph.db import init_kg
import json
type_defs = load_schema_from_path("schema.graphql")
query = QueryType()
def process_paper_record(paper, references=None, incomingReferencesCount=None):
"""Process a single paper record to standardize its structure."""
if references is None:
references = []
if incomingReferencesCount is None:
incomingReferencesCount = 0
paper_node = {
"id": paper['arxiv_id'],
"title": paper['title'],
"publicationDate": paper['published'],
"summary": paper['summary'],
"authors": paper['authors'],
"source": paper['source'],
"references": [ref['arxiv_id'] for ref in references],
"incomingReferencesCount": incomingReferencesCount
}
return paper_node
def process_query_results(results):
papers_dict = {}
for record in results:
# Process main paper with its references and incoming references count
paper_node = process_paper_record(
record['paper'],
record['references'],
record['incomingReferencesCount'])
# Always overwrite the paper node because it is always richer
papers_dict[paper_node['id']] = paper_node
# Process each reference and add to dictionary, avoiding duplicates
for ref in record['references']:
ref_node = process_paper_record(ref)
# Only add if not already present to avoid overwriting richer data
if ref_node['id'] not in papers_dict:
papers_dict[ref_node['id']] = ref_node
return {"papers": list(papers_dict.values())}
@query.field("getAllData")
def resolve_get_all_data(*_):
kg = init_kg()
cypher = """
MATCH (p:Paper)
OPTIONAL MATCH (ref:Paper)-[:REFERENCES]->(p)
WITH p, COUNT(ref) AS incomingReferencesCount
OPTIONAL MATCH (p)-[:REFERENCES]->(outRef:Paper)
RETURN p AS paper, collect(outRef) AS references, incomingReferencesCount
"""
results = kg.query(cypher)
return process_query_results(results)
@query.field("getPapersByDate")
def resolve_get_papers_by_date(_, info, date='20240425'):
print('Resolving papers by date', date)
kg = init_kg()
cypher = f"""
MATCH (p:Paper)
OPTIONAL MATCH (ref:Paper {{published: '{date}'}})-[:REFERENCES]->(p)
WITH p, COUNT(ref) AS incomingReferencesCount
OPTIONAL MATCH (p)-[:REFERENCES]->(outRef:Paper)
RETURN p AS paper, collect(outRef) AS references, incomingReferencesCount
"""
print('Cypher query:', cypher)
results = kg.query(cypher)
# print('Results:', results)
return process_query_results(results)
@query.field("getAvailableDates")
def resolve_get_available_dates(*_, min_papers=10):
kg = init_kg() # Initialize or get your knowledge graph or database connection
cypher = f"""
MATCH (p:Paper)
WITH p.published AS availableDate, COUNT(p) AS paperCount
WHERE paperCount > {min_papers}
RETURN availableDate
ORDER BY availableDate DESC
"""
results = kg.query(cypher)
dates = [record['availableDate'] for record in results]
return dates
# Create executable schema
schema = make_executable_schema(type_defs, query)
# Function to handle GraphQL requests
def handle_graphql_request():
data = request.get_json()
success, result = graphql_sync(schema, data, context_value=request)
status_code = 200 if success else 400
return jsonify(result), status_code