{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":52324,"databundleVersionId":6229904,"sourceType":"competition"},{"sourceId":11438857,"sourceType":"datasetVersion","datasetId":7165372},{"sourceId":11440070,"sourceType":"datasetVersion","datasetId":7166320},{"sourceId":11440106,"sourceType":"datasetVersion","datasetId":7166352}],"dockerImageVersionId":31012,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"\n# Multilingual Medical Transcription & Report Generator\n\n**Purpose:** This notebook acts as a powerful AI assistant for physicians dealing with patients speaking different languages. It addresses the critical challenge of language barriers in healthcare, particularly prevalent in multilingual regions like South Asia.\n**How it Works**: It takes an audio recording of a patient consultation (in languages like English, Hindi, Gujarati, Bangla, Marathi, Tamil, or Telugu), transcribes the speech to text, translates it into English if necessary, and then uses a sophisticated AI (Google's Gemini) to generate a structured, professional medical report. This allows clinicians to quickly understand patient complaints, review potential diagnoses, and access key information regardless of the original language spoken.\nUsage: Follow the steps below. You'll need an audio file of a patient consultation and a Google AI API key (ensure you use Kaggle Secrets to store your key securely!).\n.","metadata":{}},{"cell_type":"markdown","source":"# 📦Step 0: Install Required Libraries\n**Purpose:** This first code block sets up the necessary software toolkit for our AI assistant. Before we can process audio, transcribe, translate, or generate reports, we need to install the specific Python libraries that provide these functionalities.\nDetails:\n**pydub & ffmpeg-python:** Essential for handling various audio file formats (.mp3, .m4a, .wav). ffmpeg is the underlying powerhouse for audio processing.\n**git+https://github.com/openai/whisper.git:** Installs OpenAI's Whisper model directly from its source. Whisper is the state-of-the-art AI model we use for accurate speech-to-text transcription across multiple languages. The -q flag keeps the installation output tidy.\n**translate:** A Python library used to translate the transcribed text into English, creating a common language base for the report generation step.\n**google-generativeai:** The official Google library to interact with powerful generative models like Gemini, which will analyze the transcript and create the structured report. The -U flag ensures we have the latest version.\n**reportlab:** A library used in the final step to create professional-looking PDF documents from the generated report text.\n","metadata":{}},{"cell_type":"code","source":"# Install required libraries \n!pip install -q pydub ffmpeg-python git+https://github.com/openai/whisper.git\n!pip install translate\n!pip install -U google-generativeai\n!pip install reportlab","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 🌐 Step 1: Select the Spoken Language\n**Purpose:** To maximize transcription accuracy, we need to tell the Whisper model which language is being spoken in the audio file. This step allows the user (e.g., the physician or assistant) to specify the language.\nDetails:\n**language_options:** A Python dictionary maps easy-to-select numbers (1, 2, 3...) to language names (English, Hindi, Gujarati...) and their corresponding standard language codes (en, hi, gu...) that Whisper understands.\n**User Interaction:** The code prints the available language options and prompts the user to enter the number corresponding to the language in the audio file.\n**Input Handling:** It captures the user's choice, retrieves the language name and code, and confirms the selection. If invalid input is given, it defaults to English ('en'). Specifying the correct language significantly improves the quality of the transcription in Step 3.\n","metadata":{}},{"cell_type":"markdown","source":"# 📁 Step 2: Load Audio File\n**Purpose:** This step locates and selects the specific audio recording of the patient consultation that needs to be processed.\nDetails:\n**import os:** Imports the 'os' module, which provides functions for interacting with the operating system, like listing files in a directory.\n**input_dir:** Specifies the directory where Kaggle notebooks typically expect input files (/kaggle/input/). You should upload your audio files (e.g., in a dataset linked to the notebook) so they appear here, perhaps in a subdirectory like sample-audios.\n**File Discovery:** The code lists all files within the specified input_dir that have common audio extensions (.mp3, .m4a, .wav).\n**Error Handling:** It checks if any audio files were found and raises an error if the directory is empty or contains no valid files.\n**User Selection:** It displays the list of found audio files with numbers and prompts the user to select the specific file they want to process for this run.\n**File Path Construction:** It creates the full path to the selected audio file, ready for the transcription step.","metadata":{}},{"cell_type":"markdown","source":"# 🔊 Step 3: Transcribe Audio using Whisper\n**Purpose:** This is the core speech-to-text conversion step. It takes the selected audio file and uses the powerful Whisper AI model to generate a written transcript of the spoken words in the language identified in Step 1.\nDetails:\n**import whisper:** Imports the Whisper library installed in Step 0.\n**model** = whisper.load_model(\"large-v3\"): Loads the specific version of the Whisper model. We use large-v3, which is computationally intensive but offers the highest accuracy, especially crucial for handling various accents, dialects, and potentially noisy clinical recordings across multiple languages.\n**result** = model.transcribe(...): This is the command that performs the transcription.\n**input_file**: The path to the audio file selected in Step 2.\n**language**=lang_code: Critically passes the language code (e.g., 'gu' for Gujarati) selected in Step 1 to guide the model.\n**task**=\"transcribe\": Explicitly tells Whisper to perform speech-to-text, not speech-to-English translation (which it can also do).\n**final_transcription** = result[\"text\"].strip(): Extracts the actual text content from the complex result object returned by Whisper and removes any leading/trailing whitespace. The variable final_transcription now holds the raw text of the consultation in its original language.\n","metadata":{}},{"cell_type":"markdown","source":"# 🌍 Step 4: Translate to English (if necessary)\n**Purpose:** To enable the use of a powerful English-based generative AI (Gemini) for report creation in the next step, we need the consultation text in English. This step translates the transcript obtained in Step 3 only if the original language was not English.\n**Details:**\n**from translate import Translator:** Imports the necessary class from the translation library.\n**translate_to_english(text, from_lang_code) function:**\nChecks if from_lang_code is already 'en'. If yes, it returns the text untranslated.\nIf translation is needed, it initializes the Translator specifying the source language (from_lang=from_lang_code) and target language (to_lang=\"en\").\n**max_chars** = 500: Breaks the text into smaller chunks (e.g., 500 characters) because many translation APIs have limits on the amount of text per request. This prevents errors with long transcripts.\nIt iterates through the chunks, translates each one, and handles potential errors during the API call (e.g., network issues, API limits).\nFinally, it joins the translated chunks back together with spaces.\n**translated_english = translate_to_english(...):** Calls the function with the final_transcription and lang_code to get the English version. If the original was English, translated_english will be identical to final_transcription.\n","metadata":{}},{"cell_type":"code","source":"# 📍 Step 1: Ask user to select spoken language (number-based)\nlanguage_options = {\n    \"1\": (\"English\", \"en\"),\n    \"2\": (\"Hindi\", \"hi\"),\n    \"3\": (\"Gujarati\", \"gu\"),\n    \"4\": (\"Bangla\", \"bn\"),\n    \"5\": (\"Marathi\", \"mr\"),\n    \"6\": (\"Tamil\", \"ta\"),\n    \"7\": (\"Telugu\", \"te\")\n}\n\nprint(\"\\n🌐 Select the language spoken in the audio:\")\nfor num, (lang, _) in language_options.items():\n    print(f\"{num}. {lang}\")\n\nselected_number = input(\"\\n🔢 Enter the number for your language: \").strip()\nselected_language, lang_code = language_options.get(selected_number, (\"English\", \"en\"))\nprint(f\"\\n✅ You selected: {selected_language} ({lang_code})\")\n\n# 📁 Step 2: Use audio files from Kaggle input directory\nimport os\n\ninput_dir = \"/kaggle/input/bangla-test-2\"\naudio_files = [f for f in os.listdir(input_dir) if f.endswith(('.mp3', '.m4a', '.wav'))]\n\nif not audio_files:\n    raise FileNotFoundError(\"❌ No audio files found in the input directory!\")\n\nprint(\"\\n🎧 Available audio files:\")\nfor idx, file in enumerate(audio_files, 1):\n    print(f\"{idx}. {file}\")\n\nselected_idx = int(input(\"\\n🔢 Select the file number to transcribe: \").strip()) - 1\ninput_file = os.path.join(input_dir, audio_files[selected_idx])\n\nprint(f\"\\n🎯 Using file: {audio_files[selected_idx]}\")\n\n# 🔊 Step 3: Transcribe using Whisper with language code\nimport whisper\n\nmodel = whisper.load_model(\"large-v3\")\nresult = model.transcribe(input_file, language=lang_code, task=\"transcribe\")\nfinal_transcription = result[\"text\"].strip()\n\nprint(\"\\n📝 Transcribed Text:\\n\", final_transcription)\n\n# 🌍 Step 4: Translate if needed\nfrom translate import Translator\n\ndef translate_to_english(text, from_lang_code):\n    if from_lang_code == \"en\":\n        return text\n    translator = Translator(from_lang=from_lang_code, to_lang=\"en\")\n    max_chars = 500\n    chunks = [text[i:i+max_chars] for i in range(0, len(text), max_chars)]\n    translated_chunks = []\n    for idx, chunk in enumerate(chunks):\n        try:\n            translated = translator.translate(chunk)\n            translated_chunks.append(translated)\n        except Exception as e:\n            translated_chunks.append(f\"[Error in chunk {idx + 1}: {e}]\")\n    return ' '.join(translated_chunks)\n\ntranslated_english = translate_to_english(final_transcription, lang_code)\n\nprint(\"\\n🔁 Translated to English:\\n\", translated_english)\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 🤖 Step 5: Generate Structured Medical Report using Gemini\n**Purpose:** This is where the AI Physician Assistant truly shines. Taking the standardized English transcript, this step uses Google's powerful Gemini generative AI model to analyze the text and create a well-structured, professional medical report.\nDetails:\n**import google.generativeai as genai:** Imports the Google AI library.\n**genai.configure(api_key=\"...\"): IMPORTANT:** Configures the library with your unique Google AI API key. Never paste your key directly into the notebook. Use Kaggle Secrets (from kaggle_secrets import UserSecretsClient) to securely access your key. The placeholder key AIza... will not work.\ngenerate_medical_report(text) function:\nmodel = genai.GenerativeModel('gemini-1.5-pro'): Specifies the Gemini model to use. gemini-1.5-pro is a highly capable model suitable for complex understanding and generation tasks like this.\n**prompt** = f\"\"\"...\"\"\": This defines the instructions given to the Gemini model. It's carefully crafted (\"prompt engineering\") to tell the AI:\n**Its role:** \"You are a medical expert AI assistant.\"\n**The input**: The text variable containing the English transcript.\nThe desired output: A \"well-structured, detailed medical report\" with specific sections (Patient Complaints, Diagnosis, Medications, etc.) in paragraph format.\n**Constraints:** \"Ensure the report is comprehensive and professional.\"\n**response** = model.generate_content(prompt): Sends the prompt and the transcript text to the Gemini API.\n**return response.text.strip():** Extracts the generated report text from the AI's response.\n**medical_report** = generate_medical_report(translated_english): Calls the function, feeding it the English transcript to generate the report.\nThe final print statement displays the AI-generated report.\n","metadata":{}},{"cell_type":"code","source":"# 🔐 Configure Gemini with your API key\nimport google.generativeai as genai\ngenai.configure(api_key=\"AIzaSyAWUNcaRpMV3g6rKDQBe4ezbJFVHUJ73q8\")  # 🔑 Replace with your actual API key\n\n# 📑 Function to generate structured medical report\ndef generate_medical_report(text):\n    model = genai.GenerativeModel('gemini-1.5-pro')\n    prompt = f\"\"\"\nYou are a medical expert AI assistant.\n\nGiven the following unstructured medical note in English, generate a **well-structured, detailed medical report**. \nIt must include the following sections in paragraph format (avoid using any ** or markdown symbols):\n\n1. Patient Complaints  \n2. Diagnosis  \n3. Medications  \n4. Suggested Tests or Follow-ups  \n5. Additional Notes or Observations\n\nMedical Note:  \n{text}\n\nEnsure the report is comprehensive and professional.\n\"\"\"\n    response = model.generate_content(prompt)\n    return response.text.strip()\n  \n# 🔁 Generate the report using the translated English text\nmedical_report = generate_medical_report(translated_english)\n\n# 🖨️ Print the result\nprint(\"\\n📝 Medical Report:\\n\")\nprint(medical_report)\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 📄 Step 6: Save the Report as a PDF\n**Purpose:** To provide the generated medical report in a standard, easily shareable, and printable format, this step saves the report text into a PDF document.\n**Details:**\nImports necessary components from the reportlab library (canvas for drawing, A4 for page size, inch for units) and textwrap for handling long lines of text.\n**save_report_to_pdf(report_text, filename) function:**\n**cleaned_text = report_text.replace(\"**\", \"\").strip():** Removes any potential markdown bold formatting that Gemini might have included, ensuring clean text in the PDF.\n**c = canvas.Canvas(filename, pagesize=A4):** Creates a new PDF file canvas with the specified filename and standard A4 page size.\nSets up margins (x_margin, y_margin), line height, and the starting Y position for drawing text near the top of the page.\nSets the font to Helvetica, size 12.\nIterates through each paragraph of the cleaned report text.\n**wrapped_lines = wrap(paragraph, width=95):** Uses textwrap to automatically break long lines within a paragraph to fit within the defined page width (preventing text from running off the edge).\nDraws each wrapped line onto the PDF page using c.drawString(), decrementing the Y position for each line.\n**Handles page breaks automatically:** If the Y position gets too close to the bottom margin, it finalizes the current page (c.showPage()) and starts a new one, resetting the Y position to the top margin.\nAdds a little extra space between paragraphs for readability.\n**c.save()**:Finalizes and saves the PDF file.\n","metadata":{}},{"cell_type":"code","source":"from reportlab.lib.pagesizes import A4\nfrom reportlab.pdfgen import canvas\nfrom reportlab.lib.units import inch\nfrom textwrap import wrap\nimport os\n\ndef save_report_to_pdf(report_text, filename=\"medical_report.pdf\"):\n    cleaned_text = report_text.replace(\"**\", \"\").strip()\n\n    c = canvas.Canvas(filename, pagesize=A4)\n    width, height = A4\n    x_margin, y_margin = 50, 50\n    max_width = width - 2 * x_margin\n    line_height = 15\n    y_position = height - y_margin\n\n    c.setFont(\"Helvetica\", 12)\n\n    for paragraph in cleaned_text.split(\"\\n\"):\n        paragraph = paragraph.strip()\n        if not paragraph:\n            y_position -= line_height\n            continue\n\n        # Wrap paragraph text\n        wrapped_lines = wrap(paragraph, width=95)\n\n        for line in wrapped_lines:\n            if y_position <= y_margin:\n                c.showPage()\n                c.setFont(\"Helvetica\", 12)\n                y_position = height - y_margin\n            c.drawString(x_margin, y_position, line)\n            y_position -= line_height\n\n        y_position -= line_height  # Extra space between paragraphs\n\n    c.save()\n\n    # ✅ For Kaggle: inform user where the file is saved\n    if os.path.exists(filename):\n        print(f\"✅ PDF saved: {filename}\")\n        print(\"📥 Go to the 'Output' tab on the right sidebar to download the file.\")\n    else:\n        print(\"⚠️ File not found. Something went wrong.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-16T20:39:52.598155Z","iopub.execute_input":"2025-04-16T20:39:52.598596Z","iopub.status.idle":"2025-04-16T20:39:52.650718Z","shell.execute_reply.started":"2025-04-16T20:39:52.59856Z","shell.execute_reply":"2025-04-16T20:39:52.64966Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"save_report_to_pdf(medical_report, \"medical_report.pdf\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-16T20:40:00.38296Z","iopub.execute_input":"2025-04-16T20:40:00.383306Z","iopub.status.idle":"2025-04-16T20:40:00.395772Z","shell.execute_reply.started":"2025-04-16T20:40:00.383283Z","shell.execute_reply":"2025-04-16T20:40:00.39481Z"}},"outputs":[],"execution_count":null}]}