1313import uvicorn
1414import redis .asyncio as redis
1515
16- port = int (os .getenv ("SERVER_PORT" , 8098 ))
17-
1816# Load environment variables from .env file
1917dotenv .load_dotenv ()
2018
21- logging = utils .get_logger ("rest-server " )
19+ logger = utils .get_logger ("restapi " )
2220
21+ port = int (os .getenv ("SERVER_PORT" , 8098 ))
2322SYNC_INTERVAL = int (os .getenv ('SYNC_INTERVAL' , 21600 )) # 6 hours by default
2423ACCEPTANCE_THRESHOLD = float (os .getenv ('ACCEPTANCE_THRESHOLD' , float (0.75 ))) # > 75% by default
2524REJECTION_THRESHOLD = float (os .getenv ('REJECTION_THRESHOLD' , float (0.3 ))) # < 40% by default
2625MIN_COUNT_FOR_EVAL = int (os .getenv ('MIN_COUNT_FOR_EVAL' , int (3 ))) # 3 by default
27- PERCENT_CHANGE_FOR_EVAL = float (os .getenv ('PERCENT_CHANGE_FOR_EVAL' , float (0.1 ))) # 10% by default
28- MAX_CONCURRENT_PROCESSING = int (os .getenv ('MAX_CONCURRENT_PROCESSING' , int (30 ))) # 30 by default
29- MAX_CONCURRENT_EVALUATION = int (os .getenv ('MAX_CONCURRENT_EVALUATION' , int (5 ))) # 5 by default
26+ COUNT_CHANGE_THRESHOLD_RATIO = float (os .getenv ('COUNT_CHANGE_THRESHOLD_RATIO' , float (0.1 ))) # 10% by default
27+ MAX_CONCURRENT_PROCESSING = int (os .getenv ('MAX_CONCURRENT_PROCESSING' , int (40 ))) # 40 by default
28+ MAX_CONCURRENT_EVALUATION = int (os .getenv ('MAX_CONCURRENT_EVALUATION' , int (10 ))) # 10 by default
29+
30+ GRAPH_DB_CLIENT_NAME = "web_manual"
3031
3132scheduler = AsyncIOScheduler ()
3233
3334# Initialize dependencies
34- logging .info ("Initializing data graph database..." )
35+ logger .info ("Initializing data graph database..." )
3536graph_db : GraphDB = Neo4jDB ()
3637
37- logging .info ("Initializing ontology graph database..." )
38+ logger .info ("Initializing ontology graph database..." )
3839ontology_graph_db : GraphDB = Neo4jDB (uri = os .getenv ("NEO4J_ONTOLOGY_ADDR" , "bolt://localhost:7688" ))
3940
40- logging .info ("Initializing key-value store..." )
41+ logger .info ("Initializing key-value store..." )
4142redis_client = redis .from_url (os .getenv ("REDIS_URL" , "redis://localhost:6379" ))
4243
43- logging .info ("Initializing ontology agent..." )
44+ logger .info ("Initializing ontology agent..." )
45+ logger .info ("Config:\n Acceptance threshold: %s\n Rejection threshold: %s\n Max concurrent processing: %s\n Max concurrent evaluation: %s\n Count change threshold ratio: %s\n Min count for eval: %s" ,
46+ ACCEPTANCE_THRESHOLD , REJECTION_THRESHOLD , MAX_CONCURRENT_PROCESSING , MAX_CONCURRENT_EVALUATION , COUNT_CHANGE_THRESHOLD_RATIO , MIN_COUNT_FOR_EVAL )
4447agent : OntologyAgent = OntologyAgent (graph_db = graph_db ,
4548 ontology_graph_db = ontology_graph_db ,
4649 redis = redis_client ,
4750 acceptance_threshold = ACCEPTANCE_THRESHOLD ,
4851 rejection_threshold = REJECTION_THRESHOLD ,
4952 min_count_for_eval = MIN_COUNT_FOR_EVAL ,
50- percent_change_for_eval = PERCENT_CHANGE_FOR_EVAL ,
53+ count_change_threshold_ratio = COUNT_CHANGE_THRESHOLD_RATIO ,
5154 max_concurrent_processing = MAX_CONCURRENT_PROCESSING ,
5255 max_concurrent_evaluation = MAX_CONCURRENT_EVALUATION ,
5356 )
5457
5558
5659@asynccontextmanager
5760async def lifespan (_ : FastAPI ):
58- logging .info ("Setting up key-value store with heuristics version" )
61+ logger .info ("Setting up key-value store with heuristics version" )
5962
6063 # Fetch latest heuristics version
6164 heuristics_version_id = await redis_client .get (constants .KV_HEURISTICS_VERSION_ID_KEY )
6265 if heuristics_version_id is None : # if no heuristics version is found, create one
6366 heuristics_version_id = utils .get_uuid ()
6467 await redis_client .set (constants .KV_HEURISTICS_VERSION_ID_KEY , heuristics_version_id )
6568
66- logging .info ("Running the ontology agent periodically every %s seconds ..." , SYNC_INTERVAL )
69+ logger .info ("Running the ontology agent periodically every %s seconds ..." , SYNC_INTERVAL )
6770 scheduler .add_job (agent .process_and_evaluate_all , trigger = IntervalTrigger (seconds = SYNC_INTERVAL ))
6871 scheduler .start ()
6972
@@ -86,9 +89,9 @@ async def accept_relation(relation_id: str):
8689 """
8790 Accepts a foreign key relation
8891 """
89- logging .warning ("Accepting foreign key relation %s" , relation_id )
92+ logger .warning ("Accepting foreign key relation %s" , relation_id )
9093 rc_manager = await get_rc_manager_with_latest_heuristics ()
91- await rc_manager .apply_relation ("web" , relation_id , manual = True )
94+ await rc_manager .apply_relation (GRAPH_DB_CLIENT_NAME , relation_id , manual = True ) # TODO: change client name to something more meaningful
9295
9396 return JSONResponse (status_code = 200 , content = {"message" : "Foreign key relation accepted" })
9497
@@ -97,7 +100,7 @@ async def reject_relation(relation_id: str):
97100 """
98101 Reject a foreign key relation
99102 """
100- logging .warning ("Rejecting foreign key relation %s" , relation_id )
103+ logger .warning ("Rejecting foreign key relation %s" , relation_id )
101104 rc_manager = await get_rc_manager_with_latest_heuristics ()
102105 await rc_manager .unapply_relation (relation_id , manual = True ) # setting manual=True will explicitly reject the relation
103106 return JSONResponse (status_code = 200 , content = {"message" : "Foreign key relation rejected" })
@@ -107,7 +110,7 @@ async def unreject_relation(relation_id: str):
107110 """
108111 Undo an accepted or rejected foreign key relation
109112 """
110- logging .warning ("Un-rejecting foreign key relation %s" , relation_id )
113+ logger .warning ("Un-rejecting foreign key relation %s" , relation_id )
111114 rc_manager = await get_rc_manager_with_latest_heuristics ()
112115 await rc_manager .unapply_relation (relation_id ) # manual=False by default, so it will be undone without explicitly rejecting
113116 return JSONResponse (status_code = 200 , content = {"message" : "Foreign key relation un-rejected" })
@@ -117,7 +120,7 @@ async def evaluate_relation(relation_id: str):
117120 """
118121 Asks the agent to reevaluate a single foreign key relation
119122 """
120- logging .warning ("Re-evaluating foreign key relation %s" , relation_id )
123+ logger .warning ("Re-evaluating foreign key relation %s" , relation_id )
121124 rc_manager = await get_rc_manager_with_latest_heuristics ()
122125 await agent .evaluate (rc_manager = rc_manager , relation_id = relation_id )
123126 return JSONResponse (status_code = 200 , content = {"message" : "Submitted" })
@@ -128,9 +131,9 @@ async def sync_relation(relation_id: str):
128131 """
129132 Syncs a single foreign key relation with the graph database
130133 """
131- logging .warning ("Syncing foreign key relation %s" , relation_id )
134+ logger .warning ("Syncing foreign key relation %s" , relation_id )
132135 rc_manager = await get_rc_manager_with_latest_heuristics ()
133- await rc_manager .sync_relation ("web" , relation_id )
136+ await rc_manager .sync_relation (GRAPH_DB_CLIENT_NAME , relation_id )
134137 return JSONResponse (status_code = 200 , content = {"message" : "Submitted" })
135138
136139
@@ -139,7 +142,7 @@ async def regenerate_ontology(background_tasks: BackgroundTasks):
139142 """
140143 Asks the agent to regenerate the ontology graph based on current foreign key relations in the data graph
141144 """
142- logging .warning ("Regenerating ontology graph" )
145+ logger .warning ("Regenerating ontology graph" )
143146 if agent .is_processing or agent .is_evaluating :
144147 return JSONResponse (status_code = 400 , content = {"message" : "Heuristics processing is in progress" })
145148 background_tasks .add_task (agent .process_and_evaluate_all )
@@ -150,7 +153,7 @@ async def clear_ontology():
150153 """
151154 Clears all foreign key relations and the ontology graph
152155 """
153- logging .warning ("Clearing all foreign key relations and the ontology graph" )
156+ logger .warning ("Clearing all foreign key relations and the ontology graph" )
154157 if agent .is_processing or agent .is_evaluating :
155158 return JSONResponse (status_code = 400 , content = {"message" : "Heuristics processing is in progress" })
156159 heuristics_version_id = await redis_client .get (constants .KV_HEURISTICS_VERSION_ID_KEY )
@@ -178,7 +181,7 @@ async def process_entity(entity_type: str, primary_key_value: str):
178181 Asks the agent to process a specific entity for heuristics, this is used for debugging
179182 For debugging purposes
180183 """
181- logging .warning ("Processing entity %s:%s for heuristics" , entity_type , primary_key_value )
184+ logger .warning ("Processing entity %s:%s for heuristics" , entity_type , primary_key_value )
182185 rc_manager = await get_rc_manager_with_latest_heuristics ()
183186 await agent .process (rc_manager , entity_type , primary_key_value )
184187 return JSONResponse (status_code = 200 , content = {"message" : "Submitted for processing" })
@@ -190,7 +193,7 @@ async def process_all(background_tasks: BackgroundTasks):
190193 Asks the agent to process all foreign key relations
191194 For debugging purposes
192195 """
193- logging .warning ("Processing all heuristics" )
196+ logger .warning ("Processing all heuristics" )
194197 if agent .is_processing :
195198 return JSONResponse (status_code = 400 , content = {"message" : "Heuristics processing is already in progress" })
196199
@@ -206,7 +209,7 @@ async def evaluate_all(background_tasks: BackgroundTasks):
206209 Asks the agent to reevaluate all heuristics
207210 For debugging purposes
208211 """
209- logging .warning ("Re-evaluating all heuristics" )
212+ logger .warning ("Re-evaluating all heuristics" )
210213 if agent .is_processing :
211214 return JSONResponse (status_code = 400 , content = {"message" : "Heuristics processing is in progress" })
212215 rc_manager = await get_rc_manager_with_latest_heuristics ()
@@ -221,7 +224,7 @@ async def cleanup():
221224 For debugging purposes
222225 """
223226 rc_manager = await get_rc_manager_with_latest_heuristics ()
224- await rc_manager .cleanup () # This will remove all relations that are no longer candidates, but still exist in the graph database
227+ await rc_manager .cleanup () # This will remove all relations that are no longer candidates, as well as applied relations
225228 return JSONResponse (status_code = 200 , content = {"message" : "Submitted" })
226229
227230#####
@@ -238,8 +241,10 @@ async def status():
238241 "evaluated_tasks_count" : agent .evaluated_tasks_count ,
239242 "candidate_acceptance_threshold" : ACCEPTANCE_THRESHOLD ,
240243 "candidate_rejection_threshold" : REJECTION_THRESHOLD ,
244+ "max_concurrent_processing" : MAX_CONCURRENT_PROCESSING ,
245+ "max_concurrent_evaluation" : MAX_CONCURRENT_EVALUATION ,
241246 "min_count_for_eval" : MIN_COUNT_FOR_EVAL ,
242- "percent_change_for_eval " : PERCENT_CHANGE_FOR_EVAL }
247+ "count_change_threshold_ratio " : COUNT_CHANGE_THRESHOLD_RATIO , }
243248
244249if __name__ == "__main__" :
245250 uvicorn .run (app , host = "0.0.0.0" , port = port )
0 commit comments