Skip to content

Commit 2a2a0e9

Browse files
committed
added mlflow tracing
1 parent db604b8 commit 2a2a0e9

File tree

4 files changed

+80
-0
lines changed

4 files changed

+80
-0
lines changed

src/fundus_murag/agent/chat_assistant.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
from typing import Any, Iterable
55

66
import google.auth.transport.requests
7+
import mlflow
78
import openai
89
import pandas as pd
910
from google.auth import default
1011
from loguru import logger
12+
from mlflow.entities import SpanType
1113
from openai.types.chat import ChatCompletionMessageParam
1214
from openai.types.chat.chat_completion import ChatCompletion
1315
from openai.types.chat.chat_completion_assistant_message_param import (
@@ -268,6 +270,7 @@ def _create_chat_completion_from_history(self) -> ChatCompletion:
268270
logger.error(f"[{self.assistant_name}] Unexpected Error of Type {type(e)}: {e}")
269271
raise e
270272

273+
@mlflow.trace(span_type=SpanType.AGENT)
271274
def _run_agentic_loop(self) -> str:
272275
# 1. Send the messages in the chat history to the model
273276
response = self._create_chat_completion_from_history()

src/fundus_murag/agent/tools/image_analyzer.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import json
22
from enum import Enum
33

4+
import mlflow
45
from loguru import logger
6+
from mlflow.entities import SpanType
57

68
from fundus_murag.agent.chat_assistant import ChatAssistant
79
from fundus_murag.agent.chat_assistant_factory import ChatAssistantFactory
@@ -49,6 +51,9 @@ def _get_image_analysis_assistant(self, task: ImageAnalysisTask) -> ChatAssistan
4951
)
5052
return assistant
5153

54+
@mlflow.trace(
55+
span_type=SpanType.TOOL,
56+
)
5257
def answer_question_about_fundus_record_image(self, question: str, murag_id: str) -> str:
5358
"""
5459
Generates an answer to the given question about the image of a `FundusRecord` specified by the given `murag_id`.
@@ -75,6 +80,9 @@ def answer_question_about_fundus_record_image(self, question: str, murag_id: str
7580
logger.error(msg)
7681
return msg
7782

83+
@mlflow.trace(
84+
span_type=SpanType.TOOL,
85+
)
7886
def generate_caption_for_fundus_record_image(self, murag_id: str, detailed: bool = False) -> str:
7987
"""
8088
Generates a caption for the image of a `FundusRecord` specified by the given `murag_id`.
@@ -100,6 +108,9 @@ def generate_caption_for_fundus_record_image(self, murag_id: str, detailed: bool
100108
logger.error(msg)
101109
return msg
102110

111+
@mlflow.trace(
112+
span_type=SpanType.TOOL,
113+
)
103114
def extract_text_from_fundus_record_image(self, murag_id: str) -> str:
104115
"""
105116
Perform OCR on the image of a `FundusRecord` specified by the given `murag_id`.
@@ -124,6 +135,9 @@ def extract_text_from_fundus_record_image(self, murag_id: str) -> str:
124135
logger.error(msg)
125136
return msg
126137

138+
@mlflow.trace(
139+
span_type=SpanType.TOOL,
140+
)
127141
def detect_objects_in_fundus_record_image(self, murag_id: str) -> str:
128142
"""
129143
Perform object detection on the image of a `FundusRecord` specified by the given `murag_id`.

src/fundus_murag/api/lifespan.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from contextlib import asynccontextmanager
22

3+
import mlflow
34
from fastapi import FastAPI
45
from loguru import logger
56

@@ -12,6 +13,9 @@
1213
@asynccontextmanager
1314
async def api_lifespan(app: FastAPI):
1415
# Startup
16+
mlflow.set_tracking_uri("http://localhost:58058")
17+
mlflow.set_experiment("/fundus")
18+
mlflow.openai.autolog()
1519
logger.info("Starting FUNDus! Data API")
1620
chat_assistant_factory = ChatAssistantFactory()
1721
fundus_agent_factory = FundusMultiAgentSystemFactory()

src/fundus_murag/data/vector_db.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
from functools import reduce
44
from typing import Any, Literal
55

6+
import mlflow
67
import pandas as pd
78
import weaviate
89
from loguru import logger
10+
from mlflow.entities import SpanType
911
from tqdm import tqdm
1012
from weaviate.classes.query import Filter, MetadataQuery, QueryNested, QueryReference
1113

@@ -359,6 +361,9 @@ def _create_fundus_record_from_query_results(self, res: Any) -> list[FundusRecor
359361

360362
return records
361363

364+
@mlflow.trace(
365+
span_type=SpanType.TOOL,
366+
)
362367
def get_total_number_of_fundus_records(self) -> int:
363368
"""
364369
Get the total number of FUNDus! records in the database.
@@ -375,6 +380,9 @@ def get_total_number_of_fundus_records(self) -> int:
375380
except Exception:
376381
return 0
377382

383+
@mlflow.trace(
384+
span_type=SpanType.TOOL,
385+
)
378386
def get_total_number_of_fundus_collections(self) -> int:
379387
"""
380388
Get the total number of FUNDus! collections in the database.
@@ -391,6 +399,9 @@ def get_total_number_of_fundus_collections(self) -> int:
391399
except Exception:
392400
return 0
393401

402+
@mlflow.trace(
403+
span_type=SpanType.TOOL,
404+
)
394405
def list_all_fundus_collections(self) -> list[FundusCollection]:
395406
"""
396407
List all `FundusCollection`s in the FUNDus! database.
@@ -403,6 +414,9 @@ def list_all_fundus_collections(self) -> list[FundusCollection]:
403414
results = self._create_fundus_collection_from_query_results(res)
404415
return results
405416

417+
@mlflow.trace(
418+
span_type=SpanType.TOOL,
419+
)
406420
def get_fundus_collection_by_murag_id(
407421
self,
408422
murag_id: str,
@@ -478,6 +492,9 @@ def _resolve_collection_name(self, collection_name: str) -> str:
478492
results = matches[0][0]
479493
return results
480494

495+
@mlflow.trace(
496+
span_type=SpanType.TOOL,
497+
)
481498
def get_fundus_collection_by_name(
482499
self,
483500
collection_name: str,
@@ -504,6 +521,9 @@ def get_fundus_collection_by_name(
504521
results = self._create_fundus_collection_from_query_results(res)
505522
return results[0]
506523

524+
@mlflow.trace(
525+
span_type=SpanType.TOOL,
526+
)
507527
def get_random_fundus_collection(
508528
self,
509529
n: int = 1,
@@ -525,6 +545,9 @@ def get_random_fundus_collection(
525545
results = [self.get_fundus_collection_by_name(collection_name=cn) for cn in collection_names]
526546
return results
527547

548+
@mlflow.trace(
549+
span_type=SpanType.TOOL,
550+
)
528551
def get_random_fundus_records(
529552
self,
530553
n: int = 1,
@@ -557,6 +580,9 @@ def get_random_fundus_records(
557580
results = [self.get_fundus_record_by_murag_id(murag_id=murag_id) for murag_id in murag_ids]
558581
return results
559582

583+
@mlflow.trace(
584+
span_type=SpanType.TOOL,
585+
)
560586
def get_fundus_record_by_murag_id(
561587
self,
562588
murag_id: str,
@@ -612,6 +638,9 @@ def get_fundus_record_image_by_murag_id(
612638
)
613639
return result
614640

641+
@mlflow.trace(
642+
span_type=SpanType.TOOL,
643+
)
615644
def get_fundus_records_by_fundus_id(
616645
self,
617646
fundus_id: int,
@@ -636,6 +665,9 @@ def get_fundus_records_by_fundus_id(
636665
results = self._create_fundus_record_from_query_results(res)
637666
return results
638667

668+
@mlflow.trace(
669+
span_type=SpanType.TOOL,
670+
)
639671
def find_fundus_records_with_similar_image(
640672
self,
641673
murag_id: str,
@@ -664,6 +696,9 @@ def find_fundus_records_with_similar_image(
664696
)
665697
return results
666698

699+
@mlflow.trace(
700+
span_type=SpanType.TOOL,
701+
)
667702
def find_fundus_records_with_images_similar_to_the_text_query(
668703
self,
669704
query: str,
@@ -692,6 +727,9 @@ def find_fundus_records_with_images_similar_to_the_text_query(
692727
)
693728
return results
694729

730+
@mlflow.trace(
731+
span_type=SpanType.TOOL,
732+
)
695733
def find_fundus_records_with_images_similar_to_the_user_provided_image(
696734
self,
697735
user_image_id: str,
@@ -723,6 +761,9 @@ def find_fundus_records_with_images_similar_to_the_user_provided_image(
723761
)
724762
return results
725763

764+
@mlflow.trace(
765+
span_type=SpanType.TOOL,
766+
)
726767
def find_fundus_records_with_titles_similar_to_the_text_query(
727768
self,
728769
query: str,
@@ -920,6 +961,9 @@ def get_fundus_record_internal_by_murag_id(
920961

921962
return rec[0]
922963

964+
@mlflow.trace(
965+
span_type=SpanType.TOOL,
966+
)
923967
def fundus_record_title_lexical_search(
924968
self,
925969
query: str,
@@ -992,6 +1036,9 @@ def _fundus_record_lexical_search(
9921036
results = self._create_fundus_record_from_query_results(results)
9931037
return results
9941038

1039+
@mlflow.trace(
1040+
span_type=SpanType.TOOL,
1041+
)
9951042
def fundus_collection_lexical_search(
9961043
self,
9971044
query: str,
@@ -1073,6 +1120,9 @@ def _fundus_collection_lexical_search(
10731120
results = self._create_fundus_collection_from_query_results(res)
10741121
return results
10751122

1123+
@mlflow.trace(
1124+
span_type=SpanType.TOOL,
1125+
)
10761126
def fundus_collection_description_similarity_search(
10771127
self,
10781128
query_embedding: list[float],
@@ -1095,6 +1145,9 @@ def fundus_collection_description_similarity_search(
10951145
)
10961146
return results
10971147

1148+
@mlflow.trace(
1149+
span_type=SpanType.TOOL,
1150+
)
10981151
def fundus_collection_title_similarity_search(
10991152
self,
11001153
query_embedding: list[float],
@@ -1152,6 +1205,9 @@ def _fundus_collection_similarity_search(
11521205
results = simsearch_results
11531206
return results
11541207

1208+
@mlflow.trace(
1209+
span_type=SpanType.TOOL,
1210+
)
11551211
def get_number_of_records_per_collection(self) -> dict[str, int]:
11561212
"""
11571213
Get the number of records in each collection.
@@ -1162,6 +1218,9 @@ def get_number_of_records_per_collection(self) -> dict[str, int]:
11621218
results = self._records_df.groupby("collection_name").size().to_dict() # type: ignore
11631219
return results
11641220

1221+
@mlflow.trace(
1222+
span_type=SpanType.TOOL,
1223+
)
11651224
def get_number_of_records_in_collection(self, collection_name: str) -> int:
11661225
"""
11671226
Get the number of records in the specified collection.

0 commit comments

Comments
 (0)