11from typing import List , Optional
22
3+ import requests
34from fastapi import APIRouter
45
5- import matcher
6+ import model
67import service_model
78
89
910class SemanticMatchingService :
1011 """
1112 Todo
1213 """
13- def __init__ (self , semantic_matcher : matcher . SemanticMatcher ):
14+ def __init__ (self , equivalences : model . EquivalenceTable ):
1415 self .router = APIRouter ()
1516 self .router .add_api_route (
1617 "/get_match" ,
1718 self .get_matches ,
1819 methods = ["GET" ]
1920 )
20- self .semantic_matcher : matcher . SemanticMatcher = semantic_matcher
21+ self .equivalence_table : model . EquivalenceTable = equivalences
2122
2223 def get_matches (
2324 self ,
@@ -29,14 +30,44 @@ def get_matches(
2930 Returns a matching score
3031 """
3132 # Try first local matching
32- matches : Optional [List [matcher .SemanticMatch ]] = self .semantic_matcher .get_matches (request_body .semantic_id )
33- if matches is None :
34- matches = []
33+ matches : List [model .SemanticMatch ] = self .equivalence_table .get_local_matches (
34+ semantic_id = request_body .semantic_id ,
35+ score_limit = request_body .score_limit
36+ )
3537 # If the request asks us to only locally look, we're done already
3638 if request_body .local_only :
3739 return service_model .MatchResponse (matches = matches )
40+ # Now look for remote matches:
41+ additional_remote_matches : List [model .SemanticMatch ] = []
42+ for match in matches :
43+ remote_matching_service = self ._get_matcher_from_semantic_id (match .match_semantic_id )
44+ remote_matching_request = service_model .MatchRequest (
45+ semantic_id = match .match_semantic_id ,
46+ # This is a simple "Ungleichung"
47+ # Unified score is multiplied: score(A->B) * score(B->C)
48+ # This score should be larger or equal than the requested score_limit:
49+ # score(A->B) * score(B->C) >= score_limit
50+ # score(A->B) is well known, as it is the `match.score`
51+ # => score(B->C) >= (score_limit/score(A->B))
52+ score_limit = float (request_body .score_limit / match .score ),
53+ # If we already request a remote score, it does not make sense to choose `local_only`
54+ local_only = False ,
55+ name = request_body .name ,
56+ definition = request_body .definition
57+ )
58+ new_matches_response = requests .get (remote_matching_service , data = remote_matching_request )
59+ match_response : service_model .MatchResponse = service_model .MatchResponse .model_dump_json (
60+ new_matches_response .json ()
61+ )
62+ additional_remote_matches .extend (match_response .matches )
63+ # Finally, put all matches together and return
64+ matches .extend (additional_remote_matches )
65+ return service_model .MatchResponse (matches = matches )
3866
39- # Todo: There is a difference between searching and matching two given semantic IDs
67+ def _get_matcher_from_semantic_id (self , semantic_id : str ) -> str :
68+ """
69+ Finds the suiting `SemanticMatchingService` for the given `semantic_id`.
4070
41- def _get_matcher_from_semantic_id (self , semantic_id : str ):
42- pass
71+ :returns: The endpoint with which the `SemanticMatchingService` can be accessed
72+ """
73+ return "Todo" # todo
0 commit comments