From b94e998d8c355eb19153b2d8af5527c3fa17ff14 Mon Sep 17 00:00:00 2001 From: anishamahuli Date: Fri, 20 Feb 2026 15:33:35 -0500 Subject: [PATCH 1/4] Fix error 1, added unit tests and more logging --- server/api/views/uploadFile/test_title.py | 30 +++++++++++++++++++++++ server/api/views/uploadFile/title.py | 3 ++- server/api/views/uploadFile/views.py | 4 +++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/server/api/views/uploadFile/test_title.py b/server/api/views/uploadFile/test_title.py index 69979620..5391ed05 100644 --- a/server/api/views/uploadFile/test_title.py +++ b/server/api/views/uploadFile/test_title.py @@ -67,3 +67,33 @@ def test_falls_back_to_chatgpt_if_no_title_found(self, mock_openAI): title.generate_title(doc) self.assertTrue(mock_openAI.called) + + @patch("api.services.openai_services.openAIServices.openAI") + def test_strips_quotes_from_openai_title(self, mock_openAI): + doc = MagicMock() + doc.metadata = {"title": None} + doc.get_text.return_value = [] + + mock_response = MagicMock() + mock_response.choices = [MagicMock()] + mock_response.choices[0].message.content = '"Updated CANMAT/ISBD Guidelines for Treating Mixed Features in Bipolar Disorder"' + mock_openAI.return_value = mock_response + + result = title.generate_title(doc) + + self.assertEqual(result, "Updated CANMAT/ISBD Guidelines for Treating Mixed Features in Bipolar Disorder") + + @patch("api.services.openai_services.openAIServices.openAI") + def test_truncates_long_openai_title(self, mock_openAI): + doc = MagicMock() + doc.metadata = {"title": None} + doc.get_text.return_value = [] + + mock_response = MagicMock() + mock_response.choices = [MagicMock()] + mock_response.choices[0].message.content = "A" * 300 + mock_openAI.return_value = mock_response + + result = title.generate_title(doc) + + self.assertLessEqual(len(result), 255) diff --git a/server/api/views/uploadFile/title.py b/server/api/views/uploadFile/title.py index 06e0ce0c..b3f8aded 100644 --- a/server/api/views/uploadFile/title.py +++ b/server/api/views/uploadFile/title.py @@ -58,4 +58,5 @@ def summarize_pdf(pdf: fitz.Document) -> str: prompt = "Please provide a title for this document. The title should be less than 256 characters and will be displayed on a webpage." response = openAIServices.openAI( first_page_content, prompt, model='gpt-4o', temp=0.0) - return response.choices[0].message.content + title = response.choices[0].message.content.strip().strip('"').strip("'") + return title[:255] diff --git a/server/api/views/uploadFile/views.py b/server/api/views/uploadFile/views.py index 69dfb996..58bd8752 100644 --- a/server/api/views/uploadFile/views.py +++ b/server/api/views/uploadFile/views.py @@ -12,6 +12,9 @@ import fitz from django.db import transaction from .title import generate_title +import logging + +logger = logging.getLogger(__name__) class UploadFileView(APIView): @@ -124,6 +127,7 @@ def post(self, request, format=None): ) except Exception as e: # Handle potential errors + logger.exception("File upload failed for '%s': %s", uploaded_file.name, e) return Response({"message": f"Error processing file and embeddings: {str(e)}"}, status=status.HTTP_400_BAD_REQUEST) From 7085aa0c71f210bbe450034deb5ae5af1ef6cbef Mon Sep 17 00:00:00 2001 From: anishamahuli Date: Mon, 2 Mar 2026 11:59:48 -0500 Subject: [PATCH 2/4] Requested changes: fix patch decorators to point to where openAI is used, not where it's defined --- server/api/views/uploadFile/test_title.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/api/views/uploadFile/test_title.py b/server/api/views/uploadFile/test_title.py index 5391ed05..07e1b1ba 100644 --- a/server/api/views/uploadFile/test_title.py +++ b/server/api/views/uploadFile/test_title.py @@ -53,7 +53,7 @@ def test_falls_back_to_first_page_text_if_metadata_title_does_not_match_regex(se expected_title = "Advances in Mood Disorder Pharmacotherapy: Evaluating New Antipsychotics and Mood Stabilizers for Bipolar Disorder and Schizophrenia" self.assertEqual(expected_title, title.generate_title(doc)) - @patch("api.services.openai_services.openAIServices.openAI") + @patch("api.views.uploadFile.title.openAIServices.openAI") def test_falls_back_to_chatgpt_if_no_title_found(self, mock_openAI): doc = MagicMock() doc.metadata = {"title": None} @@ -68,7 +68,7 @@ def test_falls_back_to_chatgpt_if_no_title_found(self, mock_openAI): self.assertTrue(mock_openAI.called) - @patch("api.services.openai_services.openAIServices.openAI") + @patch("api.views.uploadFile.title.openAIServices.openAI") def test_strips_quotes_from_openai_title(self, mock_openAI): doc = MagicMock() doc.metadata = {"title": None} @@ -83,7 +83,7 @@ def test_strips_quotes_from_openai_title(self, mock_openAI): self.assertEqual(result, "Updated CANMAT/ISBD Guidelines for Treating Mixed Features in Bipolar Disorder") - @patch("api.services.openai_services.openAIServices.openAI") + @patch("api.views.uploadFile.title.openAIServices.openAI") def test_truncates_long_openai_title(self, mock_openAI): doc = MagicMock() doc.metadata = {"title": None} From e6754df366d1762a1b2028f0ec296c2bbd5eb3b6 Mon Sep 17 00:00:00 2001 From: anishamahuli Date: Mon, 2 Mar 2026 12:07:57 -0500 Subject: [PATCH 3/4] Requested changes: added comments explaining title truncation --- server/api/views/uploadFile/test_title.py | 1 + server/api/views/uploadFile/title.py | 1 + 2 files changed, 2 insertions(+) diff --git a/server/api/views/uploadFile/test_title.py b/server/api/views/uploadFile/test_title.py index 07e1b1ba..d5945da8 100644 --- a/server/api/views/uploadFile/test_title.py +++ b/server/api/views/uploadFile/test_title.py @@ -96,4 +96,5 @@ def test_truncates_long_openai_title(self, mock_openAI): result = title.generate_title(doc) + # Ensure the title is truncated to fit the UploadFile model's title field (max_length=255), since OpenAI responses may exceed this limit self.assertLessEqual(len(result), 255) diff --git a/server/api/views/uploadFile/title.py b/server/api/views/uploadFile/title.py index b3f8aded..17f52a74 100644 --- a/server/api/views/uploadFile/title.py +++ b/server/api/views/uploadFile/title.py @@ -59,4 +59,5 @@ def summarize_pdf(pdf: fitz.Document) -> str: response = openAIServices.openAI( first_page_content, prompt, model='gpt-4o', temp=0.0) title = response.choices[0].message.content.strip().strip('"').strip("'") + # Truncate to fit UploadFile model's max_length=255 title field as a final safeguard return title[:255] From 4b4d7275ed7d580c9ee7b7d51287cdb99a78b9bc Mon Sep 17 00:00:00 2001 From: anishamahuli Date: Mon, 2 Mar 2026 12:15:32 -0500 Subject: [PATCH 4/4] Fix mock setups to match how generate_title accesses title --- server/api/views/uploadFile/test_title.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/api/views/uploadFile/test_title.py b/server/api/views/uploadFile/test_title.py index d5945da8..0ec9e1bc 100644 --- a/server/api/views/uploadFile/test_title.py +++ b/server/api/views/uploadFile/test_title.py @@ -57,7 +57,7 @@ def test_falls_back_to_first_page_text_if_metadata_title_does_not_match_regex(se def test_falls_back_to_chatgpt_if_no_title_found(self, mock_openAI): doc = MagicMock() doc.metadata = {"title": None} - doc.get_text.return_value = [] + doc[0].get_text.return_value = [] mock_response = MagicMock() mock_response.choices = [MagicMock()] @@ -72,7 +72,7 @@ def test_falls_back_to_chatgpt_if_no_title_found(self, mock_openAI): def test_strips_quotes_from_openai_title(self, mock_openAI): doc = MagicMock() doc.metadata = {"title": None} - doc.get_text.return_value = [] + doc[0].get_text.return_value = [] mock_response = MagicMock() mock_response.choices = [MagicMock()] @@ -87,7 +87,7 @@ def test_strips_quotes_from_openai_title(self, mock_openAI): def test_truncates_long_openai_title(self, mock_openAI): doc = MagicMock() doc.metadata = {"title": None} - doc.get_text.return_value = [] + doc[0].get_text.return_value = [] mock_response = MagicMock() mock_response.choices = [MagicMock()]