Repository: satvik314/educhain (language: python)

Issue:
Added generate_flashcards function
Generates flashcards as front back and explainations


Discussion / hints:

Fix patch:
diff --git a/archive/content_engine_converter.py b/archive/content_engine_converter.py
new file mode 100644
index 0000000..55ac58a
--- /dev/null
+++ b/archive/content_engine_converter.py
@@ -0,0 +1,220 @@
+from typing import Optional, Any
+import json
+import csv
+from datetime import datetime
+from reportlab.lib.pagesizes import letter
+from reportlab.lib import colors
+from reportlab.lib.styles import getSampleStyleSheet
+from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
+
+
+class ContentExporter:
+    def export_lesson_plan_to_pdf(self, lesson_plan: Any, output_path: Optional[str] = None) -> str:
+        """Export lesson plan to PDF format using ReportLab"""
+        if output_path is None:
+            output_path = f"lesson_plan_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf"
+        
+        # Create PDF document
+        doc = SimpleDocTemplate(output_path, pagesize=letter)
+        story = []
+        styles = getSampleStyleSheet()
+        
+        # Title
+        title = getattr(lesson_plan, 'title', 'Untitled Lesson Plan')
+        story.append(Paragraph(f"Lesson Plan: {title}", styles['Title']))
+        story.append(Spacer(1, 12))
+        
+        # Subject Area
+        subject = getattr(lesson_plan, 'subject', 'N/A')
+        story.append(Paragraph(f"Subject Area: {subject}", styles['Heading2']))
+        story.append(Spacer(1, 12))
+        
+        # Learning Objectives
+        learning_objectives = getattr(lesson_plan, 'learning_objectives', [])
+        story.append(Paragraph("Learning Objectives:", styles['Heading2']))
+        for obj in learning_objectives:
+            story.append(Paragraph(f"- {obj}", styles['Normal']))
+        story.append(Spacer(1, 12))
+        
+        # Main Topics
+        for topic in getattr(lesson_plan, 'main_topics', []):
+            topic_title = getattr(topic, 'title', 'Untitled Topic')
+            story.append(Paragraph(f"Topic: {topic_title}", styles['Heading2']))
+            story.append(Spacer(1, 12))
+            
+            for subtopic in getattr(topic, 'subtopics', []):
+                subtopic_title = getattr(subtopic, 'title', 'Untitled Subtopic')
+                story.append(Paragraph(f"Subtopic: {subtopic_title}", styles['Heading3']))
+                story.append(Spacer(1, 12))
+                
+                # Add Key Concepts, Discussion Questions, and Activities
+                story.append(Paragraph(f"Key Concepts: {getattr(subtopic, 'key_concepts', 'N/A')}", styles['Normal']))
+                discussion_questions = getattr(subtopic, 'discussion_questions', [])
+                story.append(Paragraph(f"Discussion Questions: {', '.join(str(q) for q in discussion_questions)}", styles['Normal']))
+                story.append(Paragraph(f"Activities: {getattr(subtopic, 'activities', 'N/A')}", styles['Normal']))
+                story.append(Spacer(1, 12))
+        
+        # Build the PDF
+        doc.build(story)
+        print(f"PDF generated successfully: {output_path}")  # Debugging output
+        return output_path
+
+    def export_lesson_plan_to_csv(self, lesson_plan: Any, output_path: Optional[str] = None) -> str:
+        """Export lesson plan to CSV format."""
+        if output_path is None:
+            output_path = f"lesson_plan_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv"
+
+        with open(output_path, 'w', newline='', encoding='utf-8') as file:
+            writer = csv.writer(file)
+            writer.writerow(['Section', 'Content'])
+
+            writer.writerow(['Title', getattr(lesson_plan, 'title', 'Untitled Lesson Plan')])
+            writer.writerow(['Subject', getattr(lesson_plan, 'subject', 'N/A')])
+            learning_objectives = getattr(lesson_plan, 'learning_objectives', [])
+            writer.writerow(['Learning Objectives', '\n'.join(learning_objectives) if learning_objectives else 'N/A'])
+
+            for topic in getattr(lesson_plan, 'main_topics', []):
+                writer.writerow(['Topic', getattr(topic, 'title', 'Untitled Topic')])
+                for subtopic in getattr(topic, 'subtopics', []):
+                    writer.writerow(['Subtopic', getattr(subtopic, 'title', 'Untitled Subtopic')])
+                    writer.writerow(['Key Concepts', getattr(subtopic, 'key_concepts', 'N/A')])
+                    discussion_questions = getattr(subtopic, 'discussion_questions', [])
+                    writer.writerow(['Discussion Questions', '\n'.join(str(q) for q in discussion_questions)])  # Convert to string
+                    writer.writerow(['Activities', getattr(subtopic, 'activities', 'N/A')])
+
+        return output_path
+
+    def export_study_guide_to_pdf(self, study_guide: Any, output_path: Optional[str] = None) -> str:
+        """Export study guide to PDF format using ReportLab."""
+        if output_path is None:
+            output_path = f"study_guide_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf"
+
+        # Create PDF document
+        doc = SimpleDocTemplate(output_path, pagesize=letter)
+        story = []
+        styles = getSampleStyleSheet()
+        
+        # Title
+        topic = getattr(study_guide, 'topic', 'N/A')
+        story.append(Paragraph(f"Study Guide: {topic}", styles['Title']))
+        story.append(Spacer(1, 12))
+
+        # Overview
+        overview = getattr(study_guide, 'overview', 'N/A')
+        story.append(Paragraph("Overview", styles['Heading2']))
+        story.append(Paragraph(overview, styles['Normal']))
+        story.append(Spacer(1, 12))
+
+        # Key Concepts
+        story.append(Paragraph("Key Concepts", styles['Heading2']))
+        for concept, description in getattr(study_guide, 'key_concepts', {}).items():
+            story.append(Paragraph(f"{concept}: {description}", styles['Normal']))
+        
+        # Practice Exercises
+        story.append(Paragraph("Practice Exercises", styles['Heading2']))
+        for exercise in getattr(study_guide, 'practice_exercises', []):
+            title = getattr(exercise, 'title', 'N/A')
+            difficulty = getattr(exercise, 'difficulty', 'N/A')
+            problem = getattr(exercise, 'problem', 'N/A')
+            solution = getattr(exercise, 'solution', 'N/A')
+            story.append(Paragraph(f"Exercise: {title} (Difficulty: {difficulty})", styles['Normal']))
+            story.append(Paragraph(f"Problem: {problem}", styles['Normal']))
+            story.append(Paragraph(f"Solution: {solution}", styles['Normal']))
+            story.append(Spacer(1, 12))
+
+        # Case Studies
+        story.append(Paragraph("Case Studies", styles['Heading2']))
+        for case in getattr(study_guide, 'case_studies', []):
+            case_title = getattr(case, 'title', 'N/A')
+            scenario = getattr(case, 'scenario', 'N/A')
+            challenge = getattr(case, 'challenge', 'N/A')
+            story.append(Paragraph(f"Case Study: {case_title}", styles['Normal']))
+            story.append(Paragraph(f"Scenario: {scenario}", styles['Normal']))
+            story.append(Paragraph(f"Challenge: {challenge}", styles['Normal']))
+            story.append(Spacer(1, 12))
+
+        # Build the PDF
+        doc.build(story)
+        print(f"PDF generated successfully: {output_path}")  # Debugging output
+        return output_path
+
+    def export_study_guide_to_csv(self, study_guide: Any, output_path: Optional[str] = None) -> str:
+        """Export study guide to CSV format."""
+        if output_path is None:
+            output_path = f"study_guide_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv"
+
+        with open(output_path, 'w', newline='', encoding='utf-8') as file:
+            writer = csv.writer(file)
+            writer.writerow(['Section', 'Content'])
+
+            writer.writerow(['Topic', getattr(study_guide, 'topic', 'N/A')])
+            writer.writerow(['Overview', getattr(study_guide, 'overview', 'N/A')])
+
+            for concept, description in getattr(study_guide, 'key_concepts', {}).items():
+                writer.writerow(['Key Concept', f"{concept}: {description}"])
+            for exercise in getattr(study_guide, 'practice_exercises', []):
+                writer.writerow(['Practice Exercise', f"{getattr(exercise, 'title', 'N/A')}: {getattr(exercise, 'problem', 'N/A')}"])
+
+            for case in getattr(study_guide, 'case_studies', []):
+                writer.writerow(['Case Study', f"{getattr(case, 'title', 'N/A')}: {getattr(case, 'scenario', 'N/A')}"])
+
+        return output_path
+
+    def export_career_connections_to_pdf(self, career_connections: Any, output_path: Optional[str] = None) -> str:
+        """Export career connections to PDF format using ReportLab."""
+        if output_path is None:
+            output_path = f"career_connections_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf"
+
+        # Create PDF document
+        doc = SimpleDocTemplate(output_path, pagesize=letter)
+        story = []
+        styles = getSampleStyleSheet()
+        
+        # Title
+        career_field = getattr(career_connections, 'career_field', 'N/A')
+        story.append(Paragraph(f"Career Connections: {career_field}", styles['Title']))
+        story.append(Spacer(1, 12))
+
+        # Description
+        description = getattr(career_connections, 'description', 'N/A')
+        story.append(Paragraph("Description", styles['Heading2']))
+        story.append(Paragraph(description, styles['Normal']))
+        story.append(Spacer(1, 12))
+
+        # Required Skills
+        story.append(Paragraph("Required Skills", styles['Heading2']))
+        for skill in getattr(career_connections, 'required_skills', []):
+            story.append(Paragraph(f"- {skill}", styles['Normal']))
+        
+        # Career Pathways
+        story.append(Paragraph("Career Pathways", styles['Heading2']))
+        for pathway in getattr(career_connections, 'career_pathways', []):
+            pathway_name = getattr(pathway, 'name', 'N/A')
+            pathway_description = getattr(pathway, 'description', 'N/A')
+            story.append(Paragraph(f"Pathway: {pathway_name}", styles['Normal']))
+            story.append(Paragraph(f"Description: {pathway_description}", styles['Normal']))
+            story.append(Spacer(1, 12))
+
+        # Build the PDF
+        doc.build(story)
+        print(f"PDF generated successfully: {output_path}")  # Debugging output
+        return output_path
+
+    def export_career_connections_to_csv(self, career_connections: Any, output_path: Optional[str] = None) -> str:
+        """Export career connections to CSV format."""
+        if output_path is None:
+            output_path = f"career_connections_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv"
+
+        with open(output_path, 'w', newline='', encoding='utf-8') as file:
+            writer = csv.writer(file)
+            writer.writerow(['Section', 'Content'])
+
+            writer.writerow(['Career Field', getattr(career_connections, 'career_field', 'N/A')])
+            writer.writerow(['Description', getattr(career_connections, 'description', 'N/A')])
+
+            for skill in getattr(career_connections, 'required_skills', []):
+                writer.writerow(['Required Skill', skill])
+            for pathway in getattr(career_connections, 'career_pathways', []):
+                writer.writerow(['Career Pathway', f"{getattr(pathway, 'name', 'N/A')}: {getattr(pathway, 'description', 'N/A')}"])
+
+        return output_path
diff --git a/cookbook/Convert_any_webpage_to_quiz.ipynb b/cookbook/Convert_any_webpage_to_quiz.ipynb
index d3a6de4..c516e21 100644
--- a/cookbook/Convert_any_webpage_to_quiz.ipynb
+++ b/cookbook/Convert_any_webpage_to_quiz.ipynb
@@ -17,7 +17,7 @@
     {
       "cell_type": "markdown",
       "source": [
-        "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1i-K3mdWfyApCuUx7t_uSRTczZ-B4qpdI?usp=sharing)"
+        "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/185Py9FXMLspaEqwmUAx0I1p-IeCa67zH?usp=sharing)"
       ],
       "metadata": {
         "id": "ScXuwxJl9uTo"
@@ -43,7 +43,7 @@
     },
     {
       "cell_type": "code",
-      "execution_count": 1,
+      "execution_count": null,
       "metadata": {
         "colab": {
           "base_uri": "https://localhost:8080/"
@@ -89,17 +89,19 @@
       "metadata": {
         "id": "e5R2skFs6wCq"
       },
-      "execution_count": 2,
+      "execution_count": null,
       "outputs": []
     },
     {
       "cell_type": "code",
       "source": [
-        "from educhain import qna_engine\n",
+        "from educhain import Educhain\n",
         "from langchain_openai import ChatOpenAI\n",
         "\n",
         "gpt_4o_mini = ChatOpenAI(model = \"gpt-4o-mini\")\n",
         "\n",
+        "client = Educhain()\n",
+        "\n",
         "url_mcqs = qna_engine.generate_mcqs_from_data(\n",
         "        source=\"https://en.wikipedia.org/wiki/Butterfly_effect\",\n",
         "        source_type=\"url\",\n",
@@ -116,7 +118,7 @@
         "id": "-GIvZQuO6zKH",
         "outputId": "230790b6-50b9-4eb3-cb16-289024245d6a"
       },
-      "execution_count": 4,
+      "execution_count": null,
       "outputs": [
         {
           "output_type": "stream",
diff --git a/cookbook/Generate_flashcards_basics.ipynb b/cookbook/Generate_flashcards_basics.ipynb
new file mode 100644
index 0000000..9f64a36
--- /dev/null
+++ b/cookbook/Generate_flashcards_basics.ipynb
@@ -0,0 +1,248 @@
+{
+  "nbformat": 4,
+  "nbformat_minor": 0,
+  "metadata": {
+    "colab": {
+      "provenance": []
+    },
+    "kernelspec": {
+      "name": "python3",
+      "display_name": "Python 3"
+    },
+    "language_info": {
+      "name": "python"
+    }
+  },
+  "cells": [
+    {
+      "cell_type": "markdown",
+      "source": [
+        "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1kUqNA-VCznoS6d1T7-IyZXfaQs-c-2M0?usp=sharing)"
+      ],
+      "metadata": {
+        "id": "QZY7KgxpkwIP"
+      }
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "#Flashcard Generator Function\n",
+        "\n",
+        "A simple tool that creates educational flashcards on any topic you choose. 📚\n",
+        "\n",
+        "What it Does\n",
+        "\n",
+        "1.Creates study flashcards based on your chosen topic\n",
+        "\n",
+        "2.Let's you pick how many cards you want\n",
+        "\n",
+        "3.Can customize content style and difficulty"
+      ],
+      "metadata": {
+        "id": "U2L0HzzUkJ2V"
+      }
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 1,
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "rYs8Szr1nuJL",
+        "outputId": "4af0b96b-aa9b-4723-ead3-710821645a2b"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "\u001b[?25l     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/67.3 kB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m67.3/67.3 kB\u001b[0m \u001b[31m3.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25h  Installing build dependencies ... \u001b[?25l\u001b[?25hdone\n",
+            "  Getting requirements to build wheel ... \u001b[?25l\u001b[?25hdone\n",
+            "  Preparing metadata (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n",
+            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m50.6/50.6 kB\u001b[0m \u001b[31m1.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m607.0/607.0 kB\u001b[0m \u001b[31m15.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.4/2.4 MB\u001b[0m \u001b[31m52.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.0/1.0 MB\u001b[0m \u001b[31m53.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.4/2.4 MB\u001b[0m \u001b[31m78.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.9/49.9 kB\u001b[0m \u001b[31m4.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m386.9/386.9 kB\u001b[0m \u001b[31m28.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m232.6/232.6 kB\u001b[0m \u001b[31m17.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.9/1.9 MB\u001b[0m \u001b[31m73.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m273.8/273.8 kB\u001b[0m \u001b[31m22.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m94.7/94.7 kB\u001b[0m \u001b[31m8.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m76.4/76.4 kB\u001b[0m \u001b[31m6.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m78.0/78.0 kB\u001b[0m \u001b[31m6.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m325.2/325.2 kB\u001b[0m \u001b[31m23.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.9/1.9 MB\u001b[0m \u001b[31m66.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m408.0/408.0 kB\u001b[0m \u001b[31m30.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m296.9/296.9 kB\u001b[0m \u001b[31m25.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m93.2/93.2 kB\u001b[0m \u001b[31m8.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m13.2/13.2 MB\u001b[0m \u001b[31m81.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m52.5/52.5 kB\u001b[0m \u001b[31m4.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m149.7/149.7 kB\u001b[0m \u001b[31m13.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m64.0/64.0 kB\u001b[0m \u001b[31m5.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m110.5/110.5 kB\u001b[0m \u001b[31m9.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m144.5/144.5 kB\u001b[0m \u001b[31m13.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m54.4/54.4 kB\u001b[0m \u001b[31m3.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.2/1.2 MB\u001b[0m \u001b[31m58.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m63.7/63.7 kB\u001b[0m \u001b[31m5.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.3/58.3 kB\u001b[0m \u001b[31m5.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m442.1/442.1 kB\u001b[0m \u001b[31m23.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.5/49.5 kB\u001b[0m \u001b[31m4.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m54.5/54.5 kB\u001b[0m \u001b[31m5.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m73.3/73.3 kB\u001b[0m \u001b[31m6.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.8/3.8 MB\u001b[0m \u001b[31m90.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m425.7/425.7 kB\u001b[0m \u001b[31m31.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m164.1/164.1 kB\u001b[0m \u001b[31m14.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m46.0/46.0 kB\u001b[0m \u001b[31m3.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m86.8/86.8 kB\u001b[0m \u001b[31m7.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25h  Building wheel for pypika (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n"
+          ]
+        }
+      ],
+      "source": [
+        "!pip install -U educhain --quiet"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "from langchain_openai import ChatOpenAI\n",
+        "import os\n",
+        "from google.colab import userdata\n",
+        "os.environ[\"OPENAI_API_KEY\"] = userdata.get('OPENAI_API_KEY')\n"
+      ],
+      "metadata": {
+        "id": "V4DRv7Udn1ZS"
+      },
+      "execution_count": null,
+      "outputs": []
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "## Use Cases 🧰\n",
+        "\n",
+        "- Students studying for tests\n",
+        "- Teachers making lesson materials\n",
+        "- Self-study on any topic\n",
+        "- Corporate training materials"
+      ],
+      "metadata": {
+        "id": "SIr7-NmwkSTs"
+      }
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "from educhain import Educhain\n",
+        "\n",
+        "client = Educhain()\n",
+        "\n",
+        "\n",
+        "# content_engine = ContentEngine()\n",
+        "flashcard_set = client.content_engine.generate_flashcards(\"Python Basics\")\n",
+        "  # This will display the flashcards in a formatted way"
+      ],
+      "metadata": {
+        "id": "l5Z-SAQgn4UF"
+      },
+      "execution_count": null,
+      "outputs": []
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "flashcard_set"
+      ],
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "P2SNbu0XoIuN",
+        "outputId": "2036061a-40b8-4fa3-aba2-ca01cb3be6d5"
+      },
+      "execution_count": null,
+      "outputs": [
+        {
+          "output_type": "execute_result",
+          "data": {
+            "text/plain": [
+              "FlashcardSet(title='Python Basics', flashcards=[Flashcard(front='What is Python?', back='Python is a high-level, interpreted programming language known for its readability and versatility.', explanation='Python is widely used for web development, data analysis, artificial intelligence, scientific computing, and more.'), Flashcard(front='What are variables in Python?', back='Variables are used to store data values in Python.', explanation='In Python, you do not need to declare the type of a variable explicitly; it is determined dynamically.'), Flashcard(front='What does \\'if __name__ == \"__main__\":\\' do?', back=\"This construct allows a Python script to determine if it's being run as the main program or being imported as a module.\", explanation='Code within this block will only execute if the script is run directly, allowing for better module organization.'), Flashcard(front='What are lists in Python?', back='Lists are mutable, ordered collections of items in Python.', explanation='You can store multiple items in a single variable and access them using indices.'), Flashcard(front='What is a dictionary in Python?', back='A dictionary is an unordered collection of key-value pairs.', explanation='Dictionaries are useful for storing data that is associated with unique keys, enabling fast access.'), Flashcard(front='What are functions in Python?', back='Functions are reusable blocks of code that perform a specific task.', explanation=\"You can define functions using the 'def' keyword and call them to execute their code.\"), Flashcard(front='What is a loop in Python?', back='A loop is a control structure that enables repeated execution of a block of code.', explanation=\"Python has 'for' loops and 'while' loops to iterate over sequences and execute code based on conditions.\"), Flashcard(front='What is a module in Python?', back='A module is a file containing Python code that can define functions, classes, and variables.', explanation='Modules promote code reusability and organization by allowing you to separate functionality into different files.'), Flashcard(front='What is a class in Python?', back='A class is a blueprint for creating objects that encapsulate data and functionality.', explanation='Python supports object-oriented programming, allowing you to define classes and create instances (objects) of those classes.'), Flashcard(front='What is list comprehension?', back='List comprehension is a concise way to create lists in Python using a single line of code.', explanation='It allows for more readable and efficient code by combining loops and conditional statements.')])"
+            ]
+          },
+          "metadata": {},
+          "execution_count": 4
+        }
+      ]
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "\n",
+        "# Loop through each flashcard and print the 'front' and 'back' attributes\n",
+        "for flashcard in flashcard_set.flashcards:\n",
+        "    print(\"Front:\", flashcard.front)\n",
+        "    print(\"Back:\", flashcard.back)\n",
+        "    print()  # Blank line for better readability\n"
+      ],
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "uLtpGhlajYLL",
+        "outputId": "9d2c8e57-b998-448f-ec6d-40ebe660c287"
+      },
+      "execution_count": null,
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "Front: What is Python?\n",
+            "Back: Python is a high-level, interpreted programming language known for its readability and versatility.\n",
+            "\n",
+            "Front: What are variables in Python?\n",
+            "Back: Variables are used to store data values in Python.\n",
+            "\n",
+            "Front: What does 'if __name__ == \"__main__\":' do?\n",
+            "Back: This construct allows a Python script to determine if it's being run as the main program or being imported as a module.\n",
+            "\n",
+            "Front: What are lists in Python?\n",
+            "Back: Lists are mutable, ordered collections of items in Python.\n",
+            "\n",
+            "Front: What is a dictionary in Python?\n",
+            "Back: A dictionary is an unordered collection of key-value pairs.\n",
+            "\n",
+            "Front: What are functions in Python?\n",
+            "Back: Functions are reusable blocks of code that perform a specific task.\n",
+            "\n",
+            "Front: What is a loop in Python?\n",
+            "Back: A loop is a control structure that enables repeated execution of a block of code.\n",
+            "\n",
+            "Front: What is a module in Python?\n",
+            "Back: A module is a file containing Python code that can define functions, classes, and variables.\n",
+            "\n",
+            "Front: What is a class in Python?\n",
+            "Back: A class is a blueprint for creating objects that encapsulate data and functionality.\n",
+            "\n",
+            "Front: What is list comprehension?\n",
+            "Back: List comprehension is a concise way to create lists in Python using a single line of code.\n",
+            "\n"
+          ]
+        }
+      ]
+    },
+    {
+      "cell_type": "code",
+      "source": [],
+      "metadata": {
+        "id": "NfewjoaDjb0A"
+      },
+      "execution_count": null,
+      "outputs": []
+    }
+  ]
+}
\ No newline at end of file
diff --git a/cookbook/educhain_career_connection.ipynb b/cookbook/educhain_career_connection.ipynb
new file mode 100644
index 0000000..f630ef1
--- /dev/null
+++ b/cookbook/educhain_career_connection.ipynb
@@ -0,0 +1,706 @@
+{
+  "nbformat": 4,
+  "nbformat_minor": 0,
+  "metadata": {
+    "colab": {
+      "provenance": []
+    },
+    "kernelspec": {
+      "name": "python3",
+      "display_name": "Python 3"
+    },
+    "language_info": {
+      "name": "python"
+    }
+  },
+  "cells": [
+    {
+      "cell_type": "markdown",
+      "source": [
+        "## Generate Study Guide using [Educhain](https://github.com/satvik314/educhain)"
+      ],
+      "metadata": {
+        "id": "WSqlGy_wSmwu"
+      }
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "Explore the power of AI-driven education with Educhain! This notebook demonstrates how to view carrer connection of various subjects/topics using the Educhain package.\n",
+        "\n",
+        "Key Features:\n",
+        "- Customize output according to the Industry you are focusing on\n",
+        "- Leverage advanced language models for carrer connection generation\n",
+        "\n",
+        "Perfect for educators, students, and e-learning developers looking for the possibility of jobs/internship in their field/subject and enhance their career plan. Dive in to revolutionize your approach to educational content generation!"
+      ],
+      "metadata": {
+        "id": "-hL4ioiWSrDH"
+      }
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 1,
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "6sTmhfmySfQO",
+        "outputId": "3f6b72b4-43cd-4108-b21c-d035d642334b"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "Collecting git+https://github.com/lunatic-7/educhain.git@main\n",
+            "  Cloning https://github.com/lunatic-7/educhain.git (to revision main) to /tmp/pip-req-build-l9molyzi\n",
+            "  Running command git clone --filter=blob:none --quiet https://github.com/lunatic-7/educhain.git /tmp/pip-req-build-l9molyzi\n",
+            "  Resolved https://github.com/lunatic-7/educhain.git to commit 39fec93ecaf5c4ebe78a391840f6e7e98645db6c\n",
+            "  Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
+            "Collecting langchain (from educhain==0.3.2)\n",
+            "  Downloading langchain-0.3.4-py3-none-any.whl.metadata (7.1 kB)\n",
+            "Collecting langchain-community (from educhain==0.3.2)\n",
+            "  Downloading langchain_community-0.3.3-py3-none-any.whl.metadata (2.8 kB)\n",
+            "Collecting langchain-openai (from educhain==0.3.2)\n",
+            "  Downloading langchain_openai-0.2.3-py3-none-any.whl.metadata (2.6 kB)\n",
+            "Collecting openai (from educhain==0.3.2)\n",
+            "  Downloading openai-1.52.2-py3-none-any.whl.metadata (24 kB)\n",
+            "Collecting python-dotenv (from educhain==0.3.2)\n",
+            "  Downloading python_dotenv-1.0.1-py3-none-any.whl.metadata (23 kB)\n",
+            "Requirement already satisfied: pandas in /usr/local/lib/python3.10/dist-packages (from educhain==0.3.2) (2.2.2)\n",
+            "Collecting reportlab (from educhain==0.3.2)\n",
+            "  Downloading reportlab-4.2.5-py3-none-any.whl.metadata (1.5 kB)\n",
+            "Collecting PyPDF2 (from educhain==0.3.2)\n",
+            "  Downloading pypdf2-3.0.1-py3-none-any.whl.metadata (6.8 kB)\n",
+            "Requirement already satisfied: beautifulsoup4 in /usr/local/lib/python3.10/dist-packages (from educhain==0.3.2) (4.12.3)\n",
+            "Collecting youtube_transcript_api (from educhain==0.3.2)\n",
+            "  Downloading youtube_transcript_api-0.6.2-py3-none-any.whl.metadata (15 kB)\n",
+            "Requirement already satisfied: pydantic in /usr/local/lib/python3.10/dist-packages (from educhain==0.3.2) (2.9.2)\n",
+            "Requirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (from educhain==0.3.2) (2.32.3)\n",
+            "Collecting chromadb (from educhain==0.3.2)\n",
+            "  Downloading chromadb-0.5.15-py3-none-any.whl.metadata (6.8 kB)\n",
+            "Requirement already satisfied: soupsieve>1.2 in /usr/local/lib/python3.10/dist-packages (from beautifulsoup4->educhain==0.3.2) (2.6)\n",
+            "Collecting build>=1.0.3 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading build-1.2.2.post1-py3-none-any.whl.metadata (6.5 kB)\n",
+            "Collecting chroma-hnswlib==0.7.6 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading chroma_hnswlib-0.7.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (252 bytes)\n",
+            "Collecting fastapi>=0.95.2 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading fastapi-0.115.3-py3-none-any.whl.metadata (27 kB)\n",
+            "Collecting uvicorn>=0.18.3 (from uvicorn[standard]>=0.18.3->chromadb->educhain==0.3.2)\n",
+            "  Downloading uvicorn-0.32.0-py3-none-any.whl.metadata (6.6 kB)\n",
+            "Requirement already satisfied: numpy>=1.22.5 in /usr/local/lib/python3.10/dist-packages (from chromadb->educhain==0.3.2) (1.26.4)\n",
+            "Collecting posthog>=2.4.0 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading posthog-3.7.0-py2.py3-none-any.whl.metadata (2.0 kB)\n",
+            "Requirement already satisfied: typing-extensions>=4.5.0 in /usr/local/lib/python3.10/dist-packages (from chromadb->educhain==0.3.2) (4.12.2)\n",
+            "Collecting onnxruntime>=1.14.1 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading onnxruntime-1.19.2-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.metadata (4.5 kB)\n",
+            "Requirement already satisfied: opentelemetry-api>=1.2.0 in /usr/local/lib/python3.10/dist-packages (from chromadb->educhain==0.3.2) (1.16.0)\n",
+            "Collecting opentelemetry-exporter-otlp-proto-grpc>=1.2.0 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading opentelemetry_exporter_otlp_proto_grpc-1.27.0-py3-none-any.whl.metadata (2.3 kB)\n",
+            "Collecting opentelemetry-instrumentation-fastapi>=0.41b0 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading opentelemetry_instrumentation_fastapi-0.48b0-py3-none-any.whl.metadata (2.1 kB)\n",
+            "Requirement already satisfied: opentelemetry-sdk>=1.2.0 in /usr/local/lib/python3.10/dist-packages (from chromadb->educhain==0.3.2) (1.16.0)\n",
+            "Requirement already satisfied: tokenizers>=0.13.2 in /usr/local/lib/python3.10/dist-packages (from chromadb->educhain==0.3.2) (0.19.1)\n",
+            "Collecting pypika>=0.48.9 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading PyPika-0.48.9.tar.gz (67 kB)\n",
+            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m67.3/67.3 kB\u001b[0m \u001b[31m3.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25h  Installing build dependencies ... \u001b[?25l\u001b[?25hdone\n",
+            "  Getting requirements to build wheel ... \u001b[?25l\u001b[?25hdone\n",
+            "  Preparing metadata (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n",
+            "Requirement already satisfied: tqdm>=4.65.0 in /usr/local/lib/python3.10/dist-packages (from chromadb->educhain==0.3.2) (4.66.5)\n",
+            "Collecting overrides>=7.3.1 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading overrides-7.7.0-py3-none-any.whl.metadata (5.8 kB)\n",
+            "Requirement already satisfied: importlib-resources in /usr/local/lib/python3.10/dist-packages (from chromadb->educhain==0.3.2) (6.4.5)\n",
+            "Requirement already satisfied: grpcio>=1.58.0 in /usr/local/lib/python3.10/dist-packages (from chromadb->educhain==0.3.2) (1.64.1)\n",
+            "Collecting bcrypt>=4.0.1 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading bcrypt-4.2.0-cp39-abi3-manylinux_2_28_x86_64.whl.metadata (9.6 kB)\n",
+            "Requirement already satisfied: typer>=0.9.0 in /usr/local/lib/python3.10/dist-packages (from chromadb->educhain==0.3.2) (0.12.5)\n",
+            "Collecting kubernetes>=28.1.0 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading kubernetes-31.0.0-py2.py3-none-any.whl.metadata (1.5 kB)\n",
+            "Requirement already satisfied: tenacity>=8.2.3 in /usr/local/lib/python3.10/dist-packages (from chromadb->educhain==0.3.2) (9.0.0)\n",
+            "Requirement already satisfied: PyYAML>=6.0.0 in /usr/local/lib/python3.10/dist-packages (from chromadb->educhain==0.3.2) (6.0.2)\n",
+            "Collecting mmh3>=4.0.1 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading mmh3-5.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (14 kB)\n",
+            "Collecting orjson>=3.9.12 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (50 kB)\n",
+            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m50.6/50.6 kB\u001b[0m \u001b[31m1.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hCollecting httpx>=0.27.0 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading httpx-0.27.2-py3-none-any.whl.metadata (7.1 kB)\n",
+            "Requirement already satisfied: rich>=10.11.0 in /usr/local/lib/python3.10/dist-packages (from chromadb->educhain==0.3.2) (13.9.3)\n",
+            "Requirement already satisfied: annotated-types>=0.6.0 in /usr/local/lib/python3.10/dist-packages (from pydantic->educhain==0.3.2) (0.7.0)\n",
+            "Requirement already satisfied: pydantic-core==2.23.4 in /usr/local/lib/python3.10/dist-packages (from pydantic->educhain==0.3.2) (2.23.4)\n",
+            "Requirement already satisfied: SQLAlchemy<3,>=1.4 in /usr/local/lib/python3.10/dist-packages (from langchain->educhain==0.3.2) (2.0.36)\n",
+            "Requirement already satisfied: aiohttp<4.0.0,>=3.8.3 in /usr/local/lib/python3.10/dist-packages (from langchain->educhain==0.3.2) (3.10.10)\n",
+            "Requirement already satisfied: async-timeout<5.0.0,>=4.0.0 in /usr/local/lib/python3.10/dist-packages (from langchain->educhain==0.3.2) (4.0.3)\n",
+            "Collecting langchain-core<0.4.0,>=0.3.12 (from langchain->educhain==0.3.2)\n",
+            "  Downloading langchain_core-0.3.13-py3-none-any.whl.metadata (6.3 kB)\n",
+            "Collecting langchain-text-splitters<0.4.0,>=0.3.0 (from langchain->educhain==0.3.2)\n",
+            "  Downloading langchain_text_splitters-0.3.0-py3-none-any.whl.metadata (2.3 kB)\n",
+            "Collecting langsmith<0.2.0,>=0.1.17 (from langchain->educhain==0.3.2)\n",
+            "  Downloading langsmith-0.1.137-py3-none-any.whl.metadata (13 kB)\n",
+            "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests->educhain==0.3.2) (3.4.0)\n",
+            "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests->educhain==0.3.2) (3.10)\n",
+            "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests->educhain==0.3.2) (2.2.3)\n",
+            "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests->educhain==0.3.2) (2024.8.30)\n",
+            "Collecting dataclasses-json<0.7,>=0.5.7 (from langchain-community->educhain==0.3.2)\n",
+            "  Downloading dataclasses_json-0.6.7-py3-none-any.whl.metadata (25 kB)\n",
+            "Collecting pydantic-settings<3.0.0,>=2.4.0 (from langchain-community->educhain==0.3.2)\n",
+            "  Downloading pydantic_settings-2.6.0-py3-none-any.whl.metadata (3.5 kB)\n",
+            "Collecting tiktoken<1,>=0.7 (from langchain-openai->educhain==0.3.2)\n",
+            "  Downloading tiktoken-0.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (6.6 kB)\n",
+            "Requirement already satisfied: anyio<5,>=3.5.0 in /usr/local/lib/python3.10/dist-packages (from openai->educhain==0.3.2) (3.7.1)\n",
+            "Requirement already satisfied: distro<2,>=1.7.0 in /usr/lib/python3/dist-packages (from openai->educhain==0.3.2) (1.7.0)\n",
+            "Collecting jiter<1,>=0.4.0 (from openai->educhain==0.3.2)\n",
+            "  Downloading jiter-0.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (5.2 kB)\n",
+            "Requirement already satisfied: sniffio in /usr/local/lib/python3.10/dist-packages (from openai->educhain==0.3.2) (1.3.1)\n",
+            "Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.10/dist-packages (from pandas->educhain==0.3.2) (2.8.2)\n",
+            "Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas->educhain==0.3.2) (2024.2)\n",
+            "Requirement already satisfied: tzdata>=2022.7 in /usr/local/lib/python3.10/dist-packages (from pandas->educhain==0.3.2) (2024.2)\n",
+            "Requirement already satisfied: pillow>=9.0.0 in /usr/local/lib/python3.10/dist-packages (from reportlab->educhain==0.3.2) (10.4.0)\n",
+            "Requirement already satisfied: chardet in /usr/local/lib/python3.10/dist-packages (from reportlab->educhain==0.3.2) (5.2.0)\n",
+            "Requirement already satisfied: aiohappyeyeballs>=2.3.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain->educhain==0.3.2) (2.4.3)\n",
+            "Requirement already satisfied: aiosignal>=1.1.2 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain->educhain==0.3.2) (1.3.1)\n",
+            "Requirement already satisfied: attrs>=17.3.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain->educhain==0.3.2) (24.2.0)\n",
+            "Requirement already satisfied: frozenlist>=1.1.1 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain->educhain==0.3.2) (1.4.1)\n",
+            "Requirement already satisfied: multidict<7.0,>=4.5 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain->educhain==0.3.2) (6.1.0)\n",
+            "Requirement already satisfied: yarl<2.0,>=1.12.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain->educhain==0.3.2) (1.16.0)\n",
+            "Requirement already satisfied: exceptiongroup in /usr/local/lib/python3.10/dist-packages (from anyio<5,>=3.5.0->openai->educhain==0.3.2) (1.2.2)\n",
+            "Requirement already satisfied: packaging>=19.1 in /usr/local/lib/python3.10/dist-packages (from build>=1.0.3->chromadb->educhain==0.3.2) (24.1)\n",
+            "Collecting pyproject_hooks (from build>=1.0.3->chromadb->educhain==0.3.2)\n",
+            "  Downloading pyproject_hooks-1.2.0-py3-none-any.whl.metadata (1.3 kB)\n",
+            "Requirement already satisfied: tomli>=1.1.0 in /usr/local/lib/python3.10/dist-packages (from build>=1.0.3->chromadb->educhain==0.3.2) (2.0.2)\n",
+            "Collecting marshmallow<4.0.0,>=3.18.0 (from dataclasses-json<0.7,>=0.5.7->langchain-community->educhain==0.3.2)\n",
+            "  Downloading marshmallow-3.23.0-py3-none-any.whl.metadata (7.6 kB)\n",
+            "Collecting typing-inspect<1,>=0.4.0 (from dataclasses-json<0.7,>=0.5.7->langchain-community->educhain==0.3.2)\n",
+            "  Downloading typing_inspect-0.9.0-py3-none-any.whl.metadata (1.5 kB)\n",
+            "Collecting starlette<0.42.0,>=0.40.0 (from fastapi>=0.95.2->chromadb->educhain==0.3.2)\n",
+            "  Downloading starlette-0.41.2-py3-none-any.whl.metadata (6.0 kB)\n",
+            "Collecting httpcore==1.* (from httpx>=0.27.0->chromadb->educhain==0.3.2)\n",
+            "  Downloading httpcore-1.0.6-py3-none-any.whl.metadata (21 kB)\n",
+            "Collecting h11<0.15,>=0.13 (from httpcore==1.*->httpx>=0.27.0->chromadb->educhain==0.3.2)\n",
+            "  Downloading h11-0.14.0-py3-none-any.whl.metadata (8.2 kB)\n",
+            "Requirement already satisfied: six>=1.9.0 in /usr/local/lib/python3.10/dist-packages (from kubernetes>=28.1.0->chromadb->educhain==0.3.2) (1.16.0)\n",
+            "Requirement already satisfied: google-auth>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from kubernetes>=28.1.0->chromadb->educhain==0.3.2) (2.27.0)\n",
+            "Requirement already satisfied: websocket-client!=0.40.0,!=0.41.*,!=0.42.*,>=0.32.0 in /usr/local/lib/python3.10/dist-packages (from kubernetes>=28.1.0->chromadb->educhain==0.3.2) (1.8.0)\n",
+            "Requirement already satisfied: requests-oauthlib in /usr/local/lib/python3.10/dist-packages (from kubernetes>=28.1.0->chromadb->educhain==0.3.2) (1.3.1)\n",
+            "Requirement already satisfied: oauthlib>=3.2.2 in /usr/local/lib/python3.10/dist-packages (from kubernetes>=28.1.0->chromadb->educhain==0.3.2) (3.2.2)\n",
+            "Collecting durationpy>=0.7 (from kubernetes>=28.1.0->chromadb->educhain==0.3.2)\n",
+            "  Downloading durationpy-0.9-py3-none-any.whl.metadata (338 bytes)\n",
+            "Collecting jsonpatch<2.0,>=1.33 (from langchain-core<0.4.0,>=0.3.12->langchain->educhain==0.3.2)\n",
+            "  Downloading jsonpatch-1.33-py2.py3-none-any.whl.metadata (3.0 kB)\n",
+            "Collecting requests-toolbelt<2.0.0,>=1.0.0 (from langsmith<0.2.0,>=0.1.17->langchain->educhain==0.3.2)\n",
+            "  Downloading requests_toolbelt-1.0.0-py2.py3-none-any.whl.metadata (14 kB)\n",
+            "Collecting coloredlogs (from onnxruntime>=1.14.1->chromadb->educhain==0.3.2)\n",
+            "  Downloading coloredlogs-15.0.1-py2.py3-none-any.whl.metadata (12 kB)\n",
+            "Requirement already satisfied: flatbuffers in /usr/local/lib/python3.10/dist-packages (from onnxruntime>=1.14.1->chromadb->educhain==0.3.2) (24.3.25)\n",
+            "Requirement already satisfied: protobuf in /usr/local/lib/python3.10/dist-packages (from onnxruntime>=1.14.1->chromadb->educhain==0.3.2) (3.20.3)\n",
+            "Requirement already satisfied: sympy in /usr/local/lib/python3.10/dist-packages (from onnxruntime>=1.14.1->chromadb->educhain==0.3.2) (1.13.1)\n",
+            "Requirement already satisfied: deprecated>=1.2.6 in /usr/local/lib/python3.10/dist-packages (from opentelemetry-api>=1.2.0->chromadb->educhain==0.3.2) (1.2.14)\n",
+            "Requirement already satisfied: setuptools>=16.0 in /usr/local/lib/python3.10/dist-packages (from opentelemetry-api>=1.2.0->chromadb->educhain==0.3.2) (75.1.0)\n",
+            "Requirement already satisfied: googleapis-common-protos~=1.52 in /usr/local/lib/python3.10/dist-packages (from opentelemetry-exporter-otlp-proto-grpc>=1.2.0->chromadb->educhain==0.3.2) (1.65.0)\n",
+            "Collecting opentelemetry-exporter-otlp-proto-common==1.27.0 (from opentelemetry-exporter-otlp-proto-grpc>=1.2.0->chromadb->educhain==0.3.2)\n",
+            "  Downloading opentelemetry_exporter_otlp_proto_common-1.27.0-py3-none-any.whl.metadata (1.8 kB)\n",
+            "Collecting opentelemetry-proto==1.27.0 (from opentelemetry-exporter-otlp-proto-grpc>=1.2.0->chromadb->educhain==0.3.2)\n",
+            "  Downloading opentelemetry_proto-1.27.0-py3-none-any.whl.metadata (2.3 kB)\n",
+            "Collecting opentelemetry-sdk>=1.2.0 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading opentelemetry_sdk-1.27.0-py3-none-any.whl.metadata (1.5 kB)\n",
+            "Collecting opentelemetry-instrumentation-asgi==0.48b0 (from opentelemetry-instrumentation-fastapi>=0.41b0->chromadb->educhain==0.3.2)\n",
+            "  Downloading opentelemetry_instrumentation_asgi-0.48b0-py3-none-any.whl.metadata (2.0 kB)\n",
+            "Collecting opentelemetry-instrumentation==0.48b0 (from opentelemetry-instrumentation-fastapi>=0.41b0->chromadb->educhain==0.3.2)\n",
+            "  Downloading opentelemetry_instrumentation-0.48b0-py3-none-any.whl.metadata (6.1 kB)\n",
+            "Collecting opentelemetry-semantic-conventions==0.48b0 (from opentelemetry-instrumentation-fastapi>=0.41b0->chromadb->educhain==0.3.2)\n",
+            "  Downloading opentelemetry_semantic_conventions-0.48b0-py3-none-any.whl.metadata (2.4 kB)\n",
+            "Collecting opentelemetry-util-http==0.48b0 (from opentelemetry-instrumentation-fastapi>=0.41b0->chromadb->educhain==0.3.2)\n",
+            "  Downloading opentelemetry_util_http-0.48b0-py3-none-any.whl.metadata (2.5 kB)\n",
+            "Requirement already satisfied: wrapt<2.0.0,>=1.0.0 in /usr/local/lib/python3.10/dist-packages (from opentelemetry-instrumentation==0.48b0->opentelemetry-instrumentation-fastapi>=0.41b0->chromadb->educhain==0.3.2) (1.16.0)\n",
+            "Collecting asgiref~=3.0 (from opentelemetry-instrumentation-asgi==0.48b0->opentelemetry-instrumentation-fastapi>=0.41b0->chromadb->educhain==0.3.2)\n",
+            "  Downloading asgiref-3.8.1-py3-none-any.whl.metadata (9.3 kB)\n",
+            "Collecting opentelemetry-api>=1.2.0 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading opentelemetry_api-1.27.0-py3-none-any.whl.metadata (1.4 kB)\n",
+            "Collecting importlib-metadata<=8.4.0,>=6.0 (from opentelemetry-api>=1.2.0->chromadb->educhain==0.3.2)\n",
+            "  Downloading importlib_metadata-8.4.0-py3-none-any.whl.metadata (4.7 kB)\n",
+            "Collecting monotonic>=1.5 (from posthog>=2.4.0->chromadb->educhain==0.3.2)\n",
+            "  Downloading monotonic-1.6-py2.py3-none-any.whl.metadata (1.5 kB)\n",
+            "Collecting backoff>=1.10.0 (from posthog>=2.4.0->chromadb->educhain==0.3.2)\n",
+            "  Downloading backoff-2.2.1-py3-none-any.whl.metadata (14 kB)\n",
+            "Requirement already satisfied: markdown-it-py>=2.2.0 in /usr/local/lib/python3.10/dist-packages (from rich>=10.11.0->chromadb->educhain==0.3.2) (3.0.0)\n",
+            "Requirement already satisfied: pygments<3.0.0,>=2.13.0 in /usr/local/lib/python3.10/dist-packages (from rich>=10.11.0->chromadb->educhain==0.3.2) (2.18.0)\n",
+            "Requirement already satisfied: greenlet!=0.4.17 in /usr/local/lib/python3.10/dist-packages (from SQLAlchemy<3,>=1.4->langchain->educhain==0.3.2) (3.1.1)\n",
+            "Requirement already satisfied: regex>=2022.1.18 in /usr/local/lib/python3.10/dist-packages (from tiktoken<1,>=0.7->langchain-openai->educhain==0.3.2) (2024.9.11)\n",
+            "Requirement already satisfied: huggingface-hub<1.0,>=0.16.4 in /usr/local/lib/python3.10/dist-packages (from tokenizers>=0.13.2->chromadb->educhain==0.3.2) (0.24.7)\n",
+            "Requirement already satisfied: click>=8.0.0 in /usr/local/lib/python3.10/dist-packages (from typer>=0.9.0->chromadb->educhain==0.3.2) (8.1.7)\n",
+            "Requirement already satisfied: shellingham>=1.3.0 in /usr/local/lib/python3.10/dist-packages (from typer>=0.9.0->chromadb->educhain==0.3.2) (1.5.4)\n",
+            "Collecting httptools>=0.5.0 (from uvicorn[standard]>=0.18.3->chromadb->educhain==0.3.2)\n",
+            "  Downloading httptools-0.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (3.6 kB)\n",
+            "Collecting uvloop!=0.15.0,!=0.15.1,>=0.14.0 (from uvicorn[standard]>=0.18.3->chromadb->educhain==0.3.2)\n",
+            "  Downloading uvloop-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.9 kB)\n",
+            "Collecting watchfiles>=0.13 (from uvicorn[standard]>=0.18.3->chromadb->educhain==0.3.2)\n",
+            "  Downloading watchfiles-0.24.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.9 kB)\n",
+            "Collecting websockets>=10.4 (from uvicorn[standard]>=0.18.3->chromadb->educhain==0.3.2)\n",
+            "  Downloading websockets-13.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (6.8 kB)\n",
+            "Requirement already satisfied: cachetools<6.0,>=2.0.0 in /usr/local/lib/python3.10/dist-packages (from google-auth>=1.0.1->kubernetes>=28.1.0->chromadb->educhain==0.3.2) (5.5.0)\n",
+            "Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.10/dist-packages (from google-auth>=1.0.1->kubernetes>=28.1.0->chromadb->educhain==0.3.2) (0.4.1)\n",
+            "Requirement already satisfied: rsa<5,>=3.1.4 in /usr/local/lib/python3.10/dist-packages (from google-auth>=1.0.1->kubernetes>=28.1.0->chromadb->educhain==0.3.2) (4.9)\n",
+            "Requirement already satisfied: filelock in /usr/local/lib/python3.10/dist-packages (from huggingface-hub<1.0,>=0.16.4->tokenizers>=0.13.2->chromadb->educhain==0.3.2) (3.16.1)\n",
+            "Requirement already satisfied: fsspec>=2023.5.0 in /usr/local/lib/python3.10/dist-packages (from huggingface-hub<1.0,>=0.16.4->tokenizers>=0.13.2->chromadb->educhain==0.3.2) (2024.6.1)\n",
+            "Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.10/dist-packages (from importlib-metadata<=8.4.0,>=6.0->opentelemetry-api>=1.2.0->chromadb->educhain==0.3.2) (3.20.2)\n",
+            "Collecting jsonpointer>=1.9 (from jsonpatch<2.0,>=1.33->langchain-core<0.4.0,>=0.3.12->langchain->educhain==0.3.2)\n",
+            "  Downloading jsonpointer-3.0.0-py2.py3-none-any.whl.metadata (2.3 kB)\n",
+            "Requirement already satisfied: mdurl~=0.1 in /usr/local/lib/python3.10/dist-packages (from markdown-it-py>=2.2.0->rich>=10.11.0->chromadb->educhain==0.3.2) (0.1.2)\n",
+            "Collecting mypy-extensions>=0.3.0 (from typing-inspect<1,>=0.4.0->dataclasses-json<0.7,>=0.5.7->langchain-community->educhain==0.3.2)\n",
+            "  Downloading mypy_extensions-1.0.0-py3-none-any.whl.metadata (1.1 kB)\n",
+            "Requirement already satisfied: propcache>=0.2.0 in /usr/local/lib/python3.10/dist-packages (from yarl<2.0,>=1.12.0->aiohttp<4.0.0,>=3.8.3->langchain->educhain==0.3.2) (0.2.0)\n",
+            "Collecting humanfriendly>=9.1 (from coloredlogs->onnxruntime>=1.14.1->chromadb->educhain==0.3.2)\n",
+            "  Downloading humanfriendly-10.0-py2.py3-none-any.whl.metadata (9.2 kB)\n",
+            "Requirement already satisfied: mpmath<1.4,>=1.1.0 in /usr/local/lib/python3.10/dist-packages (from sympy->onnxruntime>=1.14.1->chromadb->educhain==0.3.2) (1.3.0)\n",
+            "Requirement already satisfied: pyasn1<0.7.0,>=0.4.6 in /usr/local/lib/python3.10/dist-packages (from pyasn1-modules>=0.2.1->google-auth>=1.0.1->kubernetes>=28.1.0->chromadb->educhain==0.3.2) (0.6.1)\n",
+            "Downloading chromadb-0.5.15-py3-none-any.whl (607 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m607.0/607.0 kB\u001b[0m \u001b[31m14.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading chroma_hnswlib-0.7.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.4 MB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.4/2.4 MB\u001b[0m \u001b[31m51.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading langchain-0.3.4-py3-none-any.whl (1.0 MB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.0/1.0 MB\u001b[0m \u001b[31m56.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading langchain_community-0.3.3-py3-none-any.whl (2.4 MB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.4/2.4 MB\u001b[0m \u001b[31m82.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading langchain_openai-0.2.3-py3-none-any.whl (49 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.9/49.9 kB\u001b[0m \u001b[31m5.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading openai-1.52.2-py3-none-any.whl (386 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m386.9/386.9 kB\u001b[0m \u001b[31m27.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading pypdf2-3.0.1-py3-none-any.whl (232 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m232.6/232.6 kB\u001b[0m \u001b[31m20.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading python_dotenv-1.0.1-py3-none-any.whl (19 kB)\n",
+            "Downloading reportlab-4.2.5-py3-none-any.whl (1.9 MB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.9/1.9 MB\u001b[0m \u001b[31m66.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading youtube_transcript_api-0.6.2-py3-none-any.whl (24 kB)\n",
+            "Downloading bcrypt-4.2.0-cp39-abi3-manylinux_2_28_x86_64.whl (273 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m273.8/273.8 kB\u001b[0m \u001b[31m26.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading build-1.2.2.post1-py3-none-any.whl (22 kB)\n",
+            "Downloading dataclasses_json-0.6.7-py3-none-any.whl (28 kB)\n",
+            "Downloading fastapi-0.115.3-py3-none-any.whl (94 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m94.6/94.6 kB\u001b[0m \u001b[31m9.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading httpx-0.27.2-py3-none-any.whl (76 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m76.4/76.4 kB\u001b[0m \u001b[31m8.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading httpcore-1.0.6-py3-none-any.whl (78 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m78.0/78.0 kB\u001b[0m \u001b[31m8.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading jiter-0.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (325 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m325.2/325.2 kB\u001b[0m \u001b[31m28.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading kubernetes-31.0.0-py2.py3-none-any.whl (1.9 MB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.9/1.9 MB\u001b[0m \u001b[31m76.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading langchain_core-0.3.13-py3-none-any.whl (408 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m408.0/408.0 kB\u001b[0m \u001b[31m32.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading langchain_text_splitters-0.3.0-py3-none-any.whl (25 kB)\n",
+            "Downloading langsmith-0.1.137-py3-none-any.whl (296 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m296.9/296.9 kB\u001b[0m \u001b[31m23.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading mmh3-5.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (93 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m93.2/93.2 kB\u001b[0m \u001b[31m8.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading onnxruntime-1.19.2-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (13.2 MB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m13.2/13.2 MB\u001b[0m \u001b[31m88.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading opentelemetry_exporter_otlp_proto_grpc-1.27.0-py3-none-any.whl (18 kB)\n",
+            "Downloading opentelemetry_exporter_otlp_proto_common-1.27.0-py3-none-any.whl (17 kB)\n",
+            "Downloading opentelemetry_proto-1.27.0-py3-none-any.whl (52 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m52.5/52.5 kB\u001b[0m \u001b[31m4.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading opentelemetry_instrumentation_fastapi-0.48b0-py3-none-any.whl (11 kB)\n",
+            "Downloading opentelemetry_instrumentation-0.48b0-py3-none-any.whl (29 kB)\n",
+            "Downloading opentelemetry_instrumentation_asgi-0.48b0-py3-none-any.whl (15 kB)\n",
+            "Downloading opentelemetry_semantic_conventions-0.48b0-py3-none-any.whl (149 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m149.7/149.7 kB\u001b[0m \u001b[31m15.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading opentelemetry_api-1.27.0-py3-none-any.whl (63 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m64.0/64.0 kB\u001b[0m \u001b[31m7.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading opentelemetry_util_http-0.48b0-py3-none-any.whl (6.9 kB)\n",
+            "Downloading opentelemetry_sdk-1.27.0-py3-none-any.whl (110 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m110.5/110.5 kB\u001b[0m \u001b[31m11.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (144 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m144.5/144.5 kB\u001b[0m \u001b[31m15.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading overrides-7.7.0-py3-none-any.whl (17 kB)\n",
+            "Downloading posthog-3.7.0-py2.py3-none-any.whl (54 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m54.4/54.4 kB\u001b[0m \u001b[31m5.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading pydantic_settings-2.6.0-py3-none-any.whl (28 kB)\n",
+            "Downloading tiktoken-0.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.2 MB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.2/1.2 MB\u001b[0m \u001b[31m58.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading uvicorn-0.32.0-py3-none-any.whl (63 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m63.7/63.7 kB\u001b[0m \u001b[31m6.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading backoff-2.2.1-py3-none-any.whl (15 kB)\n",
+            "Downloading durationpy-0.9-py3-none-any.whl (3.5 kB)\n",
+            "Downloading h11-0.14.0-py3-none-any.whl (58 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.3/58.3 kB\u001b[0m \u001b[31m6.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading httptools-0.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (442 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m442.1/442.1 kB\u001b[0m \u001b[31m36.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading importlib_metadata-8.4.0-py3-none-any.whl (26 kB)\n",
+            "Downloading jsonpatch-1.33-py2.py3-none-any.whl (12 kB)\n",
+            "Downloading marshmallow-3.23.0-py3-none-any.whl (49 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.5/49.5 kB\u001b[0m \u001b[31m4.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading monotonic-1.6-py2.py3-none-any.whl (8.2 kB)\n",
+            "Downloading requests_toolbelt-1.0.0-py2.py3-none-any.whl (54 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m54.5/54.5 kB\u001b[0m \u001b[31m5.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading starlette-0.41.2-py3-none-any.whl (73 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m73.3/73.3 kB\u001b[0m \u001b[31m6.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading typing_inspect-0.9.0-py3-none-any.whl (8.8 kB)\n",
+            "Downloading uvloop-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.8 MB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.8/3.8 MB\u001b[0m \u001b[31m67.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading watchfiles-0.24.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (425 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m425.7/425.7 kB\u001b[0m \u001b[31m34.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading websockets-13.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (164 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m164.1/164.1 kB\u001b[0m \u001b[31m15.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading coloredlogs-15.0.1-py2.py3-none-any.whl (46 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m46.0/46.0 kB\u001b[0m \u001b[31m4.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading pyproject_hooks-1.2.0-py3-none-any.whl (10 kB)\n",
+            "Downloading asgiref-3.8.1-py3-none-any.whl (23 kB)\n",
+            "Downloading humanfriendly-10.0-py2.py3-none-any.whl (86 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m86.8/86.8 kB\u001b[0m \u001b[31m8.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading jsonpointer-3.0.0-py2.py3-none-any.whl (7.6 kB)\n",
+            "Downloading mypy_extensions-1.0.0-py3-none-any.whl (4.7 kB)\n",
+            "Building wheels for collected packages: educhain, pypika\n",
+            "  Building wheel for educhain (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
+            "  Created wheel for educhain: filename=educhain-0.3.2-py3-none-any.whl size=20719 sha256=0bf5ea4fcfe437b0a6dcec0002590d476d304ac11b78b48c28f974366a8240da\n",
+            "  Stored in directory: /tmp/pip-ephem-wheel-cache-7nu1wrn_/wheels/cf/37/1a/d1708e678c8679ecce8ee35b17f42fc00df5e425b1ef60b913\n",
+            "  Building wheel for pypika (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n",
+            "  Created wheel for pypika: filename=PyPika-0.48.9-py2.py3-none-any.whl size=53725 sha256=c62ff4cb1da83c72e6d3e285f45c6976b7867f93d68a9ce6261bc7c5292dc475\n",
+            "  Stored in directory: /root/.cache/pip/wheels/e1/26/51/d0bffb3d2fd82256676d7ad3003faea3bd6dddc9577af665f4\n",
+            "Successfully built educhain pypika\n",
+            "Installing collected packages: pypika, monotonic, durationpy, websockets, uvloop, reportlab, python-dotenv, pyproject_hooks, PyPDF2, overrides, orjson, opentelemetry-util-http, opentelemetry-proto, mypy-extensions, mmh3, marshmallow, jsonpointer, jiter, importlib-metadata, humanfriendly, httptools, h11, chroma-hnswlib, bcrypt, backoff, asgiref, youtube_transcript_api, watchfiles, uvicorn, typing-inspect, tiktoken, starlette, requests-toolbelt, posthog, opentelemetry-exporter-otlp-proto-common, opentelemetry-api, jsonpatch, httpcore, coloredlogs, build, pydantic-settings, opentelemetry-semantic-conventions, opentelemetry-instrumentation, onnxruntime, kubernetes, httpx, fastapi, dataclasses-json, opentelemetry-sdk, opentelemetry-instrumentation-asgi, openai, langsmith, opentelemetry-instrumentation-fastapi, opentelemetry-exporter-otlp-proto-grpc, langchain-core, langchain-text-splitters, langchain-openai, chromadb, langchain, langchain-community, educhain\n",
+            "  Attempting uninstall: importlib-metadata\n",
+            "    Found existing installation: importlib_metadata 8.5.0\n",
+            "    Uninstalling importlib_metadata-8.5.0:\n",
+            "      Successfully uninstalled importlib_metadata-8.5.0\n",
+            "  Attempting uninstall: opentelemetry-api\n",
+            "    Found existing installation: opentelemetry-api 1.16.0\n",
+            "    Uninstalling opentelemetry-api-1.16.0:\n",
+            "      Successfully uninstalled opentelemetry-api-1.16.0\n",
+            "  Attempting uninstall: opentelemetry-semantic-conventions\n",
+            "    Found existing installation: opentelemetry-semantic-conventions 0.37b0\n",
+            "    Uninstalling opentelemetry-semantic-conventions-0.37b0:\n",
+            "      Successfully uninstalled opentelemetry-semantic-conventions-0.37b0\n",
+            "  Attempting uninstall: opentelemetry-sdk\n",
+            "    Found existing installation: opentelemetry-sdk 1.16.0\n",
+            "    Uninstalling opentelemetry-sdk-1.16.0:\n",
+            "      Successfully uninstalled opentelemetry-sdk-1.16.0\n",
+            "Successfully installed PyPDF2-3.0.1 asgiref-3.8.1 backoff-2.2.1 bcrypt-4.2.0 build-1.2.2.post1 chroma-hnswlib-0.7.6 chromadb-0.5.15 coloredlogs-15.0.1 dataclasses-json-0.6.7 durationpy-0.9 educhain-0.3.2 fastapi-0.115.3 h11-0.14.0 httpcore-1.0.6 httptools-0.6.4 httpx-0.27.2 humanfriendly-10.0 importlib-metadata-8.4.0 jiter-0.6.1 jsonpatch-1.33 jsonpointer-3.0.0 kubernetes-31.0.0 langchain-0.3.4 langchain-community-0.3.3 langchain-core-0.3.13 langchain-openai-0.2.3 langchain-text-splitters-0.3.0 langsmith-0.1.137 marshmallow-3.23.0 mmh3-5.0.1 monotonic-1.6 mypy-extensions-1.0.0 onnxruntime-1.19.2 openai-1.52.2 opentelemetry-api-1.27.0 opentelemetry-exporter-otlp-proto-common-1.27.0 opentelemetry-exporter-otlp-proto-grpc-1.27.0 opentelemetry-instrumentation-0.48b0 opentelemetry-instrumentation-asgi-0.48b0 opentelemetry-instrumentation-fastapi-0.48b0 opentelemetry-proto-1.27.0 opentelemetry-sdk-1.27.0 opentelemetry-semantic-conventions-0.48b0 opentelemetry-util-http-0.48b0 orjson-3.10.10 overrides-7.7.0 posthog-3.7.0 pydantic-settings-2.6.0 pypika-0.48.9 pyproject_hooks-1.2.0 python-dotenv-1.0.1 reportlab-4.2.5 requests-toolbelt-1.0.0 starlette-0.41.2 tiktoken-0.8.0 typing-inspect-0.9.0 uvicorn-0.32.0 uvloop-0.21.0 watchfiles-0.24.0 websockets-13.1 youtube_transcript_api-0.6.2\n"
+          ]
+        }
+      ],
+      "source": [
+        "!pip install git+https://github.com/lunatic-7/educhain.git@main"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "# Set up your OpenAI API key\n",
+        "import os\n",
+        "from google.colab import userdata\n",
+        "\n",
+        "os.environ[\"OPENAI_API_KEY\"] = userdata.get('OPENAI_API_KEY')"
+      ],
+      "metadata": {
+        "id": "9oFbWTb5TXNe"
+      },
+      "execution_count": 6,
+      "outputs": []
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "### Generate Career Connection\n",
+        "\n",
+        "**NOTE** - \"Using better models is important here, models like *gpt-4o* will work fine, small models like *gpt-4o-mini* might give parsing errors...\""
+      ],
+      "metadata": {
+        "id": "-q2Y-XKdTehw"
+      }
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "from langchain_openai import ChatOpenAI\n",
+        "from educhain import Educhain, LLMConfig\n",
+        "\n",
+        "openai_4o = ChatOpenAI(\n",
+        "    model=\"gpt-4o\",\n",
+        "    openai_api_key=userdata.get(\"OPENAI_API_KEY\"))\n",
+        "\n",
+        "openai_config = LLMConfig(custom_model=openai_4o)\n",
+        "\n",
+        "client = Educhain(openai_config) #using better model\n",
+        "\n",
+        "plan = client.content_engine.generate_career_connections(\n",
+        "    topic = \"Data Science\"\n",
+        "    )\n",
+        "\n",
+        "plan.show()"
+      ],
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "WDrG2lTOTZ0v",
+        "outputId": "50776c36-d399-4069-c25f-6095ae5bbe7c"
+      },
+      "execution_count": 20,
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "================================================================================\n",
+            "Career Connections: Data Science\n",
+            "================================================================================\n",
+            "\n",
+            "Industry Overview:\n",
+            "The data science industry is experiencing rapid growth as organizations across all sectors seek to leverage data-driven insights to drive decision-making and innovation. Current advancements in machine learning, artificial intelligence, and big data analytics are propelling the industry forward. The future outlook is promising, with an increasing demand for skilled professionals who can harness data to solve complex problems. Key trends include the rise of automated machine learning (AutoML), the integration of AI in data analytics, and the growing importance of data ethics and governance.\n",
+            "\n",
+            "Career Paths:\n",
+            "\n",
+            "1. Data Scientist\n",
+            "   Description: Data Scientists analyze and interpret complex data to help organizations make informed decisions.\n",
+            "   Responsibilities:\n",
+            "   - Developing algorithms and models to extract insights from data\n",
+            "   - Collaborating with cross-functional teams to implement data-driven solutions\n",
+            "   - Communicating findings to stakeholders through reports and visualizations\n",
+            "   Education: Bachelor's degree in Computer Science, Statistics, or a related field; Master's or PhD preferred\n",
+            "   Salary Range: $80,000 - $150,000\n",
+            "   Growth Potential: High; opportunities to advance to senior roles or specialized fields like AI or machine learning\n",
+            "   Required Skills:\n",
+            "   - Statistical Analysis (Essential)\n",
+            "   - Programming (Essential)\n",
+            "\n",
+            "2. Data Analyst\n",
+            "   Description: Data Analysts collect, process, and perform statistical analyses on data sets.\n",
+            "   Responsibilities:\n",
+            "   - Interpreting data and analyzing results\n",
+            "   - Developing data collection systems and strategies\n",
+            "   - Creating data visualizations to present findings\n",
+            "   Education: Bachelor's degree in Mathematics, Economics, Computer Science, or related field\n",
+            "   Salary Range: $60,000 - $90,000\n",
+            "   Growth Potential: Moderate; potential to transition into data science or business intelligence roles\n",
+            "   Required Skills:\n",
+            "   - Data Visualization (Important)\n",
+            "   - Data Cleaning (Essential)\n",
+            "\n",
+            "Industry Trends:\n",
+            "\n",
+            "- Automated Machine Learning (AutoML)\n",
+            "  Impact: Increases efficiency and accessibility of machine learning applications.\n",
+            "  Timeframe: Current and ongoing\n",
+            "\n",
+            "- Data Ethics and Governance\n",
+            "  Impact: Shapes policies and practices for responsible data management.\n",
+            "  Timeframe: Current and increasing in importance\n",
+            "\n",
+            "Professional Insights:\n",
+            "\n",
+            "From Senior Data Scientist (10 years)\n",
+            "Key Insights:\n",
+            "- Data science is a collaborative field that requires effective communication.\n",
+            "- Continuous learning is crucial due to rapid technological advancements.\n",
+            "Advice for Students:\n",
+            "- Develop strong foundational skills in mathematics and programming.\n",
+            "- Engage in projects and internships to gain practical experience.\n",
+            "\n",
+            "Preparation Paths:\n",
+            "\n",
+            "Education\n",
+            "Requirements:\n",
+            "- Pursue a degree in a relevant field (e.g., Computer Science, Statistics)\n",
+            "- Take courses in machine learning, data analysis, and statistics\n",
+            "Duration: 4-6 years\n",
+            "\n",
+            "Early Career\n",
+            "Requirements:\n",
+            "- Gain experience through entry-level roles such as data analyst\n",
+            "- Develop a portfolio of data projects\n",
+            "Duration: 2-4 years\n",
+            "\n",
+            "Resources:\n",
+            "\n",
+            "- Kaggle (Platform)\n",
+            "  Description: An online community for data scientists to collaborate and compete on data science challenges.\n",
+            "  URL: https://www.kaggle.com\n",
+            "  Cost: Free\n",
+            "\n",
+            "- Coursera (Platform)\n",
+            "  Description: Provides a wide range of data science courses and certifications.\n",
+            "  URL: https://www.coursera.org\n",
+            "  Cost: Varies; some courses free or with financial aid\n",
+            "\n",
+            "- Data Science Association (Organization)\n",
+            "  Description: A professional organization that provides resources and networking opportunities for data scientists.\n",
+            "  URL: http://datascienceassn.org\n",
+            "  Cost: Membership fees vary\n",
+            "\n",
+            "Skill Categories:\n",
+            "\n",
+            "Technical Skills:\n",
+            "- Machine Learning: Ability to design and implement machine learning algorithms\n",
+            "- Data Visualization Tools: Proficiency in tools like Tableau, Power BI, or D3.js\n",
+            "\n",
+            "Soft Skills:\n",
+            "- Communication: Ability to effectively convey complex information to non-technical stakeholders\n",
+            "- Problem Solving: Strong analytical and critical thinking skills to tackle challenging data problems\n",
+            "\n",
+            "Industry-specific Skills:\n",
+            "- Data Governance: Knowledge of policies and procedures for managing data assets\n",
+            "\n",
+            "Future Skills Needed:\n",
+            "- AI Ethics: Understanding of ethical implications in AI and machine learning\n"
+          ]
+        }
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "### Generate Study Guide with **Industry you are focusing on**"
+      ],
+      "metadata": {
+        "id": "L1VZaA7NUNQF"
+      }
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "from langchain_openai import ChatOpenAI\n",
+        "from educhain import Educhain, LLMConfig\n",
+        "\n",
+        "openai_4o = ChatOpenAI(\n",
+        "    model=\"gpt-4o\",\n",
+        "    openai_api_key=userdata.get(\"OPENAI_API_KEY\"))\n",
+        "\n",
+        "openai_config = LLMConfig(custom_model=openai_4o)\n",
+        "\n",
+        "client = Educhain(openai_config) #using better model\n",
+        "\n",
+        "plan = client.content_engine.generate_career_connections(\n",
+        "    topic = \"Data Science\",\n",
+        "    industry_focus = \"Finance\"\n",
+        "    )\n",
+        "\n",
+        "plan.show()"
+      ],
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "z06-wGHET09G",
+        "outputId": "bf9fe930-b40e-4b89-c7e4-43bc08f53aed"
+      },
+      "execution_count": 21,
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "================================================================================\n",
+            "Career Connections: Data Science\n",
+            "================================================================================\n",
+            "\n",
+            "Industry Overview:\n",
+            "The finance industry is undergoing a significant transformation driven by advancements in data science. With the proliferation of big data, financial institutions are leveraging data science to gain insights, improve decision-making, and enhance customer experiences. The integration of machine learning, artificial intelligence, and predictive analytics is becoming commonplace. The future outlook for data science in finance is promising, with increased demand for skilled professionals who can navigate complex data landscapes and drive innovation. Key trends include the rise of fintech, the adoption of blockchain, and the use of AI for risk management and fraud detection.\n",
+            "\n",
+            "Career Paths:\n",
+            "\n",
+            "1. Financial Data Scientist\n",
+            "   Description: A Financial Data Scientist analyzes complex financial data to identify trends, forecast future outcomes, and make data-driven decisions.\n",
+            "   Responsibilities:\n",
+            "   - Analyze financial datasets to identify trends and patterns.\n",
+            "   - Develop predictive models for financial forecasting.\n",
+            "   - Collaborate with stakeholders to optimize financial strategies.\n",
+            "   Education: Bachelor's degree in Data Science, Finance, or related field; Master's preferred.\n",
+            "   Salary Range: $90,000 - $130,000\n",
+            "   Growth Potential: High growth potential with opportunities to advance to senior data scientist or managerial roles.\n",
+            "   Required Skills:\n",
+            "   - Statistical Analysis (Essential)\n",
+            "   - Machine Learning (Essential)\n",
+            "\n",
+            "2. Quantitative Analyst\n",
+            "   Description: Quantitative Analysts use mathematical models to evaluate financial securities and manage risk.\n",
+            "   Responsibilities:\n",
+            "   - Develop quantitative models for pricing and risk assessment.\n",
+            "   - Analyze market trends to inform trading strategies.\n",
+            "   - Collaborate with traders and risk managers.\n",
+            "   Education: Bachelor's degree in Mathematics, Finance, or related field; PhD preferred.\n",
+            "   Salary Range: $100,000 - $150,000\n",
+            "   Growth Potential: Strong demand in investment banks, hedge funds, and asset management firms.\n",
+            "   Required Skills:\n",
+            "   - Mathematical Modeling (Essential)\n",
+            "   - Programming (Important)\n",
+            "\n",
+            "Industry Trends:\n",
+            "\n",
+            "- Rise of Fintech\n",
+            "  Impact: Increased demand for data-driven solutions and adaptable financial strategies.\n",
+            "  Timeframe: Current and ongoing\n",
+            "\n",
+            "- AI in Risk Management\n",
+            "  Impact: Improved accuracy in risk assessment and fraud detection.\n",
+            "  Timeframe: Next 5-10 years\n",
+            "\n",
+            "Professional Insights:\n",
+            "\n",
+            "From Senior Data Scientist (10 years)\n",
+            "Key Insights:\n",
+            "- Data science is integral to strategic decision-making in finance.\n",
+            "- Continuous learning and adaptation are crucial due to rapid technological advancements.\n",
+            "Advice for Students:\n",
+            "- Build a strong foundation in both finance and data science.\n",
+            "- Gain practical experience through internships and projects.\n",
+            "\n",
+            "Preparation Paths:\n",
+            "\n",
+            "Education\n",
+            "Requirements:\n",
+            "- Bachelor's degree in Data Science, Finance, or related field\n",
+            "Duration: 4 years\n",
+            "\n",
+            "Early Career\n",
+            "Requirements:\n",
+            "- Entry-level data analyst or financial analyst position\n",
+            "Duration: 2-3 years\n",
+            "\n",
+            "Resources:\n",
+            "\n",
+            "- Kaggle (Platform)\n",
+            "  Description: An online community for data scientists and machine learning enthusiasts.\n",
+            "  URL: https://www.kaggle.com\n",
+            "\n",
+            "- Financial Data Professional Institute (Organization)\n",
+            "  Description: Offers certifications and resources for finance professionals specializing in data science.\n",
+            "  URL: https://fdpinstitute.org\n",
+            "  Cost: Certification fees apply\n",
+            "\n",
+            "- Journal of Financial Data Science (Publication)\n",
+            "  Description: Provides insights and research on data science applications in finance.\n",
+            "  Cost: Subscription fees apply\n",
+            "\n",
+            "Skill Categories:\n",
+            "\n",
+            "Technical Skills:\n",
+            "- Statistical Analysis: Ability to analyze data using statistical methods.\n",
+            "- Machine Learning: Knowledge of machine learning techniques and algorithms.\n",
+            "\n",
+            "Soft Skills:\n",
+            "- Communication: Effective communication of complex data insights to non-technical stakeholders.\n",
+            "- Problem-Solving: Ability to address complex financial challenges using data-driven approaches.\n",
+            "\n",
+            "Industry-Specific Skills:\n",
+            "- Financial Modeling: Creation of mathematical models to represent financial scenarios.\n",
+            "- Risk Management: Understanding of risk assessment and mitigation strategies.\n",
+            "\n",
+            "Future Skills Needed:\n",
+            "- Blockchain Technology: Understanding of blockchain and its applications in finance.\n",
+            "- AI Development: Ability to develop AI-driven solutions for financial applications.\n"
+          ]
+        }
+      ]
+    },
+    {
+      "cell_type": "code",
+      "source": [],
+      "metadata": {
+        "id": "lUo6MIabVY27"
+      },
+      "execution_count": null,
+      "outputs": []
+    }
+  ]
+}
\ No newline at end of file
diff --git a/cookbook/educhain_generate_study_guide.ipynb b/cookbook/educhain_generate_study_guide.ipynb
new file mode 100644
index 0000000..454a872
--- /dev/null
+++ b/cookbook/educhain_generate_study_guide.ipynb
@@ -0,0 +1,663 @@
+{
+  "nbformat": 4,
+  "nbformat_minor": 0,
+  "metadata": {
+    "colab": {
+      "provenance": []
+    },
+    "kernelspec": {
+      "name": "python3",
+      "display_name": "Python 3"
+    },
+    "language_info": {
+      "name": "python"
+    }
+  },
+  "cells": [
+    {
+      "cell_type": "markdown",
+      "source": [
+        "## Generate Study Guide using [Educhain](https://github.com/satvik314/educhain)"
+      ],
+      "metadata": {
+        "id": "2yuOXx718YJT"
+      }
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "Explore the power of AI-driven education with Educhain! This notebook demonstrates how to create high-quality Study Guide of various topics using the Educhain package.\n",
+        "\n",
+        "Key Features:\n",
+        "- Customize difficulty level according to you\n",
+        "- Leverage advanced language models for study guide generation\n",
+        "\n",
+        "Perfect for educators, students, and e-learning developers looking to automate and enhance their study guide plan. Dive in to revolutionize your approach to educational content generation!"
+      ],
+      "metadata": {
+        "id": "Vdyr-nkg8fBI"
+      }
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 1,
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "IM2f9yVg73iO",
+        "outputId": "b8a060a2-792d-4b03-9d6c-c8cf18625f8b"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "Collecting git+https://github.com/lunatic-7/educhain.git@main\n",
+            "  Cloning https://github.com/lunatic-7/educhain.git (to revision main) to /tmp/pip-req-build-6bihe9wx\n",
+            "  Running command git clone --filter=blob:none --quiet https://github.com/lunatic-7/educhain.git /tmp/pip-req-build-6bihe9wx\n",
+            "  Resolved https://github.com/lunatic-7/educhain.git to commit 2d0d94a5ac83c31075a08ad220e11a892b0edbe2\n",
+            "  Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
+            "Collecting langchain (from educhain==0.3.2)\n",
+            "  Downloading langchain-0.3.4-py3-none-any.whl.metadata (7.1 kB)\n",
+            "Collecting langchain-community (from educhain==0.3.2)\n",
+            "  Downloading langchain_community-0.3.3-py3-none-any.whl.metadata (2.8 kB)\n",
+            "Collecting langchain-openai (from educhain==0.3.2)\n",
+            "  Downloading langchain_openai-0.2.3-py3-none-any.whl.metadata (2.6 kB)\n",
+            "Collecting openai (from educhain==0.3.2)\n",
+            "  Downloading openai-1.52.2-py3-none-any.whl.metadata (24 kB)\n",
+            "Collecting python-dotenv (from educhain==0.3.2)\n",
+            "  Downloading python_dotenv-1.0.1-py3-none-any.whl.metadata (23 kB)\n",
+            "Requirement already satisfied: pandas in /usr/local/lib/python3.10/dist-packages (from educhain==0.3.2) (2.2.2)\n",
+            "Collecting reportlab (from educhain==0.3.2)\n",
+            "  Downloading reportlab-4.2.5-py3-none-any.whl.metadata (1.5 kB)\n",
+            "Collecting PyPDF2 (from educhain==0.3.2)\n",
+            "  Downloading pypdf2-3.0.1-py3-none-any.whl.metadata (6.8 kB)\n",
+            "Requirement already satisfied: beautifulsoup4 in /usr/local/lib/python3.10/dist-packages (from educhain==0.3.2) (4.12.3)\n",
+            "Collecting youtube_transcript_api (from educhain==0.3.2)\n",
+            "  Downloading youtube_transcript_api-0.6.2-py3-none-any.whl.metadata (15 kB)\n",
+            "Requirement already satisfied: pydantic in /usr/local/lib/python3.10/dist-packages (from educhain==0.3.2) (2.9.2)\n",
+            "Requirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (from educhain==0.3.2) (2.32.3)\n",
+            "Collecting chromadb (from educhain==0.3.2)\n",
+            "  Downloading chromadb-0.5.15-py3-none-any.whl.metadata (6.8 kB)\n",
+            "Requirement already satisfied: soupsieve>1.2 in /usr/local/lib/python3.10/dist-packages (from beautifulsoup4->educhain==0.3.2) (2.6)\n",
+            "Collecting build>=1.0.3 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading build-1.2.2.post1-py3-none-any.whl.metadata (6.5 kB)\n",
+            "Collecting chroma-hnswlib==0.7.6 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading chroma_hnswlib-0.7.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (252 bytes)\n",
+            "Collecting fastapi>=0.95.2 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading fastapi-0.115.3-py3-none-any.whl.metadata (27 kB)\n",
+            "Collecting uvicorn>=0.18.3 (from uvicorn[standard]>=0.18.3->chromadb->educhain==0.3.2)\n",
+            "  Downloading uvicorn-0.32.0-py3-none-any.whl.metadata (6.6 kB)\n",
+            "Requirement already satisfied: numpy>=1.22.5 in /usr/local/lib/python3.10/dist-packages (from chromadb->educhain==0.3.2) (1.26.4)\n",
+            "Collecting posthog>=2.4.0 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading posthog-3.7.0-py2.py3-none-any.whl.metadata (2.0 kB)\n",
+            "Requirement already satisfied: typing-extensions>=4.5.0 in /usr/local/lib/python3.10/dist-packages (from chromadb->educhain==0.3.2) (4.12.2)\n",
+            "Collecting onnxruntime>=1.14.1 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading onnxruntime-1.19.2-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.metadata (4.5 kB)\n",
+            "Requirement already satisfied: opentelemetry-api>=1.2.0 in /usr/local/lib/python3.10/dist-packages (from chromadb->educhain==0.3.2) (1.16.0)\n",
+            "Collecting opentelemetry-exporter-otlp-proto-grpc>=1.2.0 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading opentelemetry_exporter_otlp_proto_grpc-1.27.0-py3-none-any.whl.metadata (2.3 kB)\n",
+            "Collecting opentelemetry-instrumentation-fastapi>=0.41b0 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading opentelemetry_instrumentation_fastapi-0.48b0-py3-none-any.whl.metadata (2.1 kB)\n",
+            "Requirement already satisfied: opentelemetry-sdk>=1.2.0 in /usr/local/lib/python3.10/dist-packages (from chromadb->educhain==0.3.2) (1.16.0)\n",
+            "Requirement already satisfied: tokenizers>=0.13.2 in /usr/local/lib/python3.10/dist-packages (from chromadb->educhain==0.3.2) (0.19.1)\n",
+            "Collecting pypika>=0.48.9 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading PyPika-0.48.9.tar.gz (67 kB)\n",
+            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m67.3/67.3 kB\u001b[0m \u001b[31m3.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25h  Installing build dependencies ... \u001b[?25l\u001b[?25hdone\n",
+            "  Getting requirements to build wheel ... \u001b[?25l\u001b[?25hdone\n",
+            "  Preparing metadata (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n",
+            "Requirement already satisfied: tqdm>=4.65.0 in /usr/local/lib/python3.10/dist-packages (from chromadb->educhain==0.3.2) (4.66.5)\n",
+            "Collecting overrides>=7.3.1 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading overrides-7.7.0-py3-none-any.whl.metadata (5.8 kB)\n",
+            "Requirement already satisfied: importlib-resources in /usr/local/lib/python3.10/dist-packages (from chromadb->educhain==0.3.2) (6.4.5)\n",
+            "Requirement already satisfied: grpcio>=1.58.0 in /usr/local/lib/python3.10/dist-packages (from chromadb->educhain==0.3.2) (1.64.1)\n",
+            "Collecting bcrypt>=4.0.1 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading bcrypt-4.2.0-cp39-abi3-manylinux_2_28_x86_64.whl.metadata (9.6 kB)\n",
+            "Requirement already satisfied: typer>=0.9.0 in /usr/local/lib/python3.10/dist-packages (from chromadb->educhain==0.3.2) (0.12.5)\n",
+            "Collecting kubernetes>=28.1.0 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading kubernetes-31.0.0-py2.py3-none-any.whl.metadata (1.5 kB)\n",
+            "Requirement already satisfied: tenacity>=8.2.3 in /usr/local/lib/python3.10/dist-packages (from chromadb->educhain==0.3.2) (9.0.0)\n",
+            "Requirement already satisfied: PyYAML>=6.0.0 in /usr/local/lib/python3.10/dist-packages (from chromadb->educhain==0.3.2) (6.0.2)\n",
+            "Collecting mmh3>=4.0.1 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading mmh3-5.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (14 kB)\n",
+            "Collecting orjson>=3.9.12 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (50 kB)\n",
+            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m50.6/50.6 kB\u001b[0m \u001b[31m3.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hCollecting httpx>=0.27.0 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading httpx-0.27.2-py3-none-any.whl.metadata (7.1 kB)\n",
+            "Requirement already satisfied: rich>=10.11.0 in /usr/local/lib/python3.10/dist-packages (from chromadb->educhain==0.3.2) (13.9.3)\n",
+            "Requirement already satisfied: annotated-types>=0.6.0 in /usr/local/lib/python3.10/dist-packages (from pydantic->educhain==0.3.2) (0.7.0)\n",
+            "Requirement already satisfied: pydantic-core==2.23.4 in /usr/local/lib/python3.10/dist-packages (from pydantic->educhain==0.3.2) (2.23.4)\n",
+            "Requirement already satisfied: SQLAlchemy<3,>=1.4 in /usr/local/lib/python3.10/dist-packages (from langchain->educhain==0.3.2) (2.0.36)\n",
+            "Requirement already satisfied: aiohttp<4.0.0,>=3.8.3 in /usr/local/lib/python3.10/dist-packages (from langchain->educhain==0.3.2) (3.10.10)\n",
+            "Requirement already satisfied: async-timeout<5.0.0,>=4.0.0 in /usr/local/lib/python3.10/dist-packages (from langchain->educhain==0.3.2) (4.0.3)\n",
+            "Collecting langchain-core<0.4.0,>=0.3.12 (from langchain->educhain==0.3.2)\n",
+            "  Downloading langchain_core-0.3.12-py3-none-any.whl.metadata (6.3 kB)\n",
+            "Collecting langchain-text-splitters<0.4.0,>=0.3.0 (from langchain->educhain==0.3.2)\n",
+            "  Downloading langchain_text_splitters-0.3.0-py3-none-any.whl.metadata (2.3 kB)\n",
+            "Collecting langsmith<0.2.0,>=0.1.17 (from langchain->educhain==0.3.2)\n",
+            "  Downloading langsmith-0.1.137-py3-none-any.whl.metadata (13 kB)\n",
+            "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests->educhain==0.3.2) (3.4.0)\n",
+            "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests->educhain==0.3.2) (3.10)\n",
+            "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests->educhain==0.3.2) (2.2.3)\n",
+            "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests->educhain==0.3.2) (2024.8.30)\n",
+            "Collecting dataclasses-json<0.7,>=0.5.7 (from langchain-community->educhain==0.3.2)\n",
+            "  Downloading dataclasses_json-0.6.7-py3-none-any.whl.metadata (25 kB)\n",
+            "Collecting pydantic-settings<3.0.0,>=2.4.0 (from langchain-community->educhain==0.3.2)\n",
+            "  Downloading pydantic_settings-2.6.0-py3-none-any.whl.metadata (3.5 kB)\n",
+            "Collecting tiktoken<1,>=0.7 (from langchain-openai->educhain==0.3.2)\n",
+            "  Downloading tiktoken-0.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (6.6 kB)\n",
+            "Requirement already satisfied: anyio<5,>=3.5.0 in /usr/local/lib/python3.10/dist-packages (from openai->educhain==0.3.2) (3.7.1)\n",
+            "Requirement already satisfied: distro<2,>=1.7.0 in /usr/lib/python3/dist-packages (from openai->educhain==0.3.2) (1.7.0)\n",
+            "Collecting jiter<1,>=0.4.0 (from openai->educhain==0.3.2)\n",
+            "  Downloading jiter-0.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (5.2 kB)\n",
+            "Requirement already satisfied: sniffio in /usr/local/lib/python3.10/dist-packages (from openai->educhain==0.3.2) (1.3.1)\n",
+            "Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.10/dist-packages (from pandas->educhain==0.3.2) (2.8.2)\n",
+            "Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas->educhain==0.3.2) (2024.2)\n",
+            "Requirement already satisfied: tzdata>=2022.7 in /usr/local/lib/python3.10/dist-packages (from pandas->educhain==0.3.2) (2024.2)\n",
+            "Requirement already satisfied: pillow>=9.0.0 in /usr/local/lib/python3.10/dist-packages (from reportlab->educhain==0.3.2) (10.4.0)\n",
+            "Requirement already satisfied: chardet in /usr/local/lib/python3.10/dist-packages (from reportlab->educhain==0.3.2) (5.2.0)\n",
+            "Requirement already satisfied: aiohappyeyeballs>=2.3.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain->educhain==0.3.2) (2.4.3)\n",
+            "Requirement already satisfied: aiosignal>=1.1.2 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain->educhain==0.3.2) (1.3.1)\n",
+            "Requirement already satisfied: attrs>=17.3.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain->educhain==0.3.2) (24.2.0)\n",
+            "Requirement already satisfied: frozenlist>=1.1.1 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain->educhain==0.3.2) (1.4.1)\n",
+            "Requirement already satisfied: multidict<7.0,>=4.5 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain->educhain==0.3.2) (6.1.0)\n",
+            "Requirement already satisfied: yarl<2.0,>=1.12.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain->educhain==0.3.2) (1.16.0)\n",
+            "Requirement already satisfied: exceptiongroup in /usr/local/lib/python3.10/dist-packages (from anyio<5,>=3.5.0->openai->educhain==0.3.2) (1.2.2)\n",
+            "Requirement already satisfied: packaging>=19.1 in /usr/local/lib/python3.10/dist-packages (from build>=1.0.3->chromadb->educhain==0.3.2) (24.1)\n",
+            "Collecting pyproject_hooks (from build>=1.0.3->chromadb->educhain==0.3.2)\n",
+            "  Downloading pyproject_hooks-1.2.0-py3-none-any.whl.metadata (1.3 kB)\n",
+            "Requirement already satisfied: tomli>=1.1.0 in /usr/local/lib/python3.10/dist-packages (from build>=1.0.3->chromadb->educhain==0.3.2) (2.0.2)\n",
+            "Collecting marshmallow<4.0.0,>=3.18.0 (from dataclasses-json<0.7,>=0.5.7->langchain-community->educhain==0.3.2)\n",
+            "  Downloading marshmallow-3.23.0-py3-none-any.whl.metadata (7.6 kB)\n",
+            "Collecting typing-inspect<1,>=0.4.0 (from dataclasses-json<0.7,>=0.5.7->langchain-community->educhain==0.3.2)\n",
+            "  Downloading typing_inspect-0.9.0-py3-none-any.whl.metadata (1.5 kB)\n",
+            "Collecting starlette<0.42.0,>=0.40.0 (from fastapi>=0.95.2->chromadb->educhain==0.3.2)\n",
+            "  Downloading starlette-0.41.0-py3-none-any.whl.metadata (6.0 kB)\n",
+            "Collecting httpcore==1.* (from httpx>=0.27.0->chromadb->educhain==0.3.2)\n",
+            "  Downloading httpcore-1.0.6-py3-none-any.whl.metadata (21 kB)\n",
+            "Collecting h11<0.15,>=0.13 (from httpcore==1.*->httpx>=0.27.0->chromadb->educhain==0.3.2)\n",
+            "  Downloading h11-0.14.0-py3-none-any.whl.metadata (8.2 kB)\n",
+            "Requirement already satisfied: six>=1.9.0 in /usr/local/lib/python3.10/dist-packages (from kubernetes>=28.1.0->chromadb->educhain==0.3.2) (1.16.0)\n",
+            "Requirement already satisfied: google-auth>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from kubernetes>=28.1.0->chromadb->educhain==0.3.2) (2.27.0)\n",
+            "Requirement already satisfied: websocket-client!=0.40.0,!=0.41.*,!=0.42.*,>=0.32.0 in /usr/local/lib/python3.10/dist-packages (from kubernetes>=28.1.0->chromadb->educhain==0.3.2) (1.8.0)\n",
+            "Requirement already satisfied: requests-oauthlib in /usr/local/lib/python3.10/dist-packages (from kubernetes>=28.1.0->chromadb->educhain==0.3.2) (1.3.1)\n",
+            "Requirement already satisfied: oauthlib>=3.2.2 in /usr/local/lib/python3.10/dist-packages (from kubernetes>=28.1.0->chromadb->educhain==0.3.2) (3.2.2)\n",
+            "Collecting durationpy>=0.7 (from kubernetes>=28.1.0->chromadb->educhain==0.3.2)\n",
+            "  Downloading durationpy-0.9-py3-none-any.whl.metadata (338 bytes)\n",
+            "Collecting jsonpatch<2.0,>=1.33 (from langchain-core<0.4.0,>=0.3.12->langchain->educhain==0.3.2)\n",
+            "  Downloading jsonpatch-1.33-py2.py3-none-any.whl.metadata (3.0 kB)\n",
+            "Collecting requests-toolbelt<2.0.0,>=1.0.0 (from langsmith<0.2.0,>=0.1.17->langchain->educhain==0.3.2)\n",
+            "  Downloading requests_toolbelt-1.0.0-py2.py3-none-any.whl.metadata (14 kB)\n",
+            "Collecting coloredlogs (from onnxruntime>=1.14.1->chromadb->educhain==0.3.2)\n",
+            "  Downloading coloredlogs-15.0.1-py2.py3-none-any.whl.metadata (12 kB)\n",
+            "Requirement already satisfied: flatbuffers in /usr/local/lib/python3.10/dist-packages (from onnxruntime>=1.14.1->chromadb->educhain==0.3.2) (24.3.25)\n",
+            "Requirement already satisfied: protobuf in /usr/local/lib/python3.10/dist-packages (from onnxruntime>=1.14.1->chromadb->educhain==0.3.2) (3.20.3)\n",
+            "Requirement already satisfied: sympy in /usr/local/lib/python3.10/dist-packages (from onnxruntime>=1.14.1->chromadb->educhain==0.3.2) (1.13.1)\n",
+            "Requirement already satisfied: deprecated>=1.2.6 in /usr/local/lib/python3.10/dist-packages (from opentelemetry-api>=1.2.0->chromadb->educhain==0.3.2) (1.2.14)\n",
+            "Requirement already satisfied: setuptools>=16.0 in /usr/local/lib/python3.10/dist-packages (from opentelemetry-api>=1.2.0->chromadb->educhain==0.3.2) (75.1.0)\n",
+            "Requirement already satisfied: googleapis-common-protos~=1.52 in /usr/local/lib/python3.10/dist-packages (from opentelemetry-exporter-otlp-proto-grpc>=1.2.0->chromadb->educhain==0.3.2) (1.65.0)\n",
+            "Collecting opentelemetry-exporter-otlp-proto-common==1.27.0 (from opentelemetry-exporter-otlp-proto-grpc>=1.2.0->chromadb->educhain==0.3.2)\n",
+            "  Downloading opentelemetry_exporter_otlp_proto_common-1.27.0-py3-none-any.whl.metadata (1.8 kB)\n",
+            "Collecting opentelemetry-proto==1.27.0 (from opentelemetry-exporter-otlp-proto-grpc>=1.2.0->chromadb->educhain==0.3.2)\n",
+            "  Downloading opentelemetry_proto-1.27.0-py3-none-any.whl.metadata (2.3 kB)\n",
+            "Collecting opentelemetry-sdk>=1.2.0 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading opentelemetry_sdk-1.27.0-py3-none-any.whl.metadata (1.5 kB)\n",
+            "Collecting opentelemetry-instrumentation-asgi==0.48b0 (from opentelemetry-instrumentation-fastapi>=0.41b0->chromadb->educhain==0.3.2)\n",
+            "  Downloading opentelemetry_instrumentation_asgi-0.48b0-py3-none-any.whl.metadata (2.0 kB)\n",
+            "Collecting opentelemetry-instrumentation==0.48b0 (from opentelemetry-instrumentation-fastapi>=0.41b0->chromadb->educhain==0.3.2)\n",
+            "  Downloading opentelemetry_instrumentation-0.48b0-py3-none-any.whl.metadata (6.1 kB)\n",
+            "Collecting opentelemetry-semantic-conventions==0.48b0 (from opentelemetry-instrumentation-fastapi>=0.41b0->chromadb->educhain==0.3.2)\n",
+            "  Downloading opentelemetry_semantic_conventions-0.48b0-py3-none-any.whl.metadata (2.4 kB)\n",
+            "Collecting opentelemetry-util-http==0.48b0 (from opentelemetry-instrumentation-fastapi>=0.41b0->chromadb->educhain==0.3.2)\n",
+            "  Downloading opentelemetry_util_http-0.48b0-py3-none-any.whl.metadata (2.5 kB)\n",
+            "Requirement already satisfied: wrapt<2.0.0,>=1.0.0 in /usr/local/lib/python3.10/dist-packages (from opentelemetry-instrumentation==0.48b0->opentelemetry-instrumentation-fastapi>=0.41b0->chromadb->educhain==0.3.2) (1.16.0)\n",
+            "Collecting asgiref~=3.0 (from opentelemetry-instrumentation-asgi==0.48b0->opentelemetry-instrumentation-fastapi>=0.41b0->chromadb->educhain==0.3.2)\n",
+            "  Downloading asgiref-3.8.1-py3-none-any.whl.metadata (9.3 kB)\n",
+            "Collecting opentelemetry-api>=1.2.0 (from chromadb->educhain==0.3.2)\n",
+            "  Downloading opentelemetry_api-1.27.0-py3-none-any.whl.metadata (1.4 kB)\n",
+            "Collecting importlib-metadata<=8.4.0,>=6.0 (from opentelemetry-api>=1.2.0->chromadb->educhain==0.3.2)\n",
+            "  Downloading importlib_metadata-8.4.0-py3-none-any.whl.metadata (4.7 kB)\n",
+            "Collecting monotonic>=1.5 (from posthog>=2.4.0->chromadb->educhain==0.3.2)\n",
+            "  Downloading monotonic-1.6-py2.py3-none-any.whl.metadata (1.5 kB)\n",
+            "Collecting backoff>=1.10.0 (from posthog>=2.4.0->chromadb->educhain==0.3.2)\n",
+            "  Downloading backoff-2.2.1-py3-none-any.whl.metadata (14 kB)\n",
+            "Requirement already satisfied: markdown-it-py>=2.2.0 in /usr/local/lib/python3.10/dist-packages (from rich>=10.11.0->chromadb->educhain==0.3.2) (3.0.0)\n",
+            "Requirement already satisfied: pygments<3.0.0,>=2.13.0 in /usr/local/lib/python3.10/dist-packages (from rich>=10.11.0->chromadb->educhain==0.3.2) (2.18.0)\n",
+            "Requirement already satisfied: greenlet!=0.4.17 in /usr/local/lib/python3.10/dist-packages (from SQLAlchemy<3,>=1.4->langchain->educhain==0.3.2) (3.1.1)\n",
+            "Requirement already satisfied: regex>=2022.1.18 in /usr/local/lib/python3.10/dist-packages (from tiktoken<1,>=0.7->langchain-openai->educhain==0.3.2) (2024.9.11)\n",
+            "Requirement already satisfied: huggingface-hub<1.0,>=0.16.4 in /usr/local/lib/python3.10/dist-packages (from tokenizers>=0.13.2->chromadb->educhain==0.3.2) (0.24.7)\n",
+            "Requirement already satisfied: click>=8.0.0 in /usr/local/lib/python3.10/dist-packages (from typer>=0.9.0->chromadb->educhain==0.3.2) (8.1.7)\n",
+            "Requirement already satisfied: shellingham>=1.3.0 in /usr/local/lib/python3.10/dist-packages (from typer>=0.9.0->chromadb->educhain==0.3.2) (1.5.4)\n",
+            "Collecting httptools>=0.5.0 (from uvicorn[standard]>=0.18.3->chromadb->educhain==0.3.2)\n",
+            "  Downloading httptools-0.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (3.6 kB)\n",
+            "Collecting uvloop!=0.15.0,!=0.15.1,>=0.14.0 (from uvicorn[standard]>=0.18.3->chromadb->educhain==0.3.2)\n",
+            "  Downloading uvloop-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.9 kB)\n",
+            "Collecting watchfiles>=0.13 (from uvicorn[standard]>=0.18.3->chromadb->educhain==0.3.2)\n",
+            "  Downloading watchfiles-0.24.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.9 kB)\n",
+            "Collecting websockets>=10.4 (from uvicorn[standard]>=0.18.3->chromadb->educhain==0.3.2)\n",
+            "  Downloading websockets-13.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (6.8 kB)\n",
+            "Requirement already satisfied: cachetools<6.0,>=2.0.0 in /usr/local/lib/python3.10/dist-packages (from google-auth>=1.0.1->kubernetes>=28.1.0->chromadb->educhain==0.3.2) (5.5.0)\n",
+            "Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.10/dist-packages (from google-auth>=1.0.1->kubernetes>=28.1.0->chromadb->educhain==0.3.2) (0.4.1)\n",
+            "Requirement already satisfied: rsa<5,>=3.1.4 in /usr/local/lib/python3.10/dist-packages (from google-auth>=1.0.1->kubernetes>=28.1.0->chromadb->educhain==0.3.2) (4.9)\n",
+            "Requirement already satisfied: filelock in /usr/local/lib/python3.10/dist-packages (from huggingface-hub<1.0,>=0.16.4->tokenizers>=0.13.2->chromadb->educhain==0.3.2) (3.16.1)\n",
+            "Requirement already satisfied: fsspec>=2023.5.0 in /usr/local/lib/python3.10/dist-packages (from huggingface-hub<1.0,>=0.16.4->tokenizers>=0.13.2->chromadb->educhain==0.3.2) (2024.6.1)\n",
+            "Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.10/dist-packages (from importlib-metadata<=8.4.0,>=6.0->opentelemetry-api>=1.2.0->chromadb->educhain==0.3.2) (3.20.2)\n",
+            "Collecting jsonpointer>=1.9 (from jsonpatch<2.0,>=1.33->langchain-core<0.4.0,>=0.3.12->langchain->educhain==0.3.2)\n",
+            "  Downloading jsonpointer-3.0.0-py2.py3-none-any.whl.metadata (2.3 kB)\n",
+            "Requirement already satisfied: mdurl~=0.1 in /usr/local/lib/python3.10/dist-packages (from markdown-it-py>=2.2.0->rich>=10.11.0->chromadb->educhain==0.3.2) (0.1.2)\n",
+            "Collecting mypy-extensions>=0.3.0 (from typing-inspect<1,>=0.4.0->dataclasses-json<0.7,>=0.5.7->langchain-community->educhain==0.3.2)\n",
+            "  Downloading mypy_extensions-1.0.0-py3-none-any.whl.metadata (1.1 kB)\n",
+            "Requirement already satisfied: propcache>=0.2.0 in /usr/local/lib/python3.10/dist-packages (from yarl<2.0,>=1.12.0->aiohttp<4.0.0,>=3.8.3->langchain->educhain==0.3.2) (0.2.0)\n",
+            "Collecting humanfriendly>=9.1 (from coloredlogs->onnxruntime>=1.14.1->chromadb->educhain==0.3.2)\n",
+            "  Downloading humanfriendly-10.0-py2.py3-none-any.whl.metadata (9.2 kB)\n",
+            "Requirement already satisfied: mpmath<1.4,>=1.1.0 in /usr/local/lib/python3.10/dist-packages (from sympy->onnxruntime>=1.14.1->chromadb->educhain==0.3.2) (1.3.0)\n",
+            "Requirement already satisfied: pyasn1<0.7.0,>=0.4.6 in /usr/local/lib/python3.10/dist-packages (from pyasn1-modules>=0.2.1->google-auth>=1.0.1->kubernetes>=28.1.0->chromadb->educhain==0.3.2) (0.6.1)\n",
+            "Downloading chromadb-0.5.15-py3-none-any.whl (607 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m607.0/607.0 kB\u001b[0m \u001b[31m24.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading chroma_hnswlib-0.7.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.4 MB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.4/2.4 MB\u001b[0m \u001b[31m25.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading langchain-0.3.4-py3-none-any.whl (1.0 MB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.0/1.0 MB\u001b[0m \u001b[31m32.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading langchain_community-0.3.3-py3-none-any.whl (2.4 MB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.4/2.4 MB\u001b[0m \u001b[31m60.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading langchain_openai-0.2.3-py3-none-any.whl (49 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.9/49.9 kB\u001b[0m \u001b[31m3.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading openai-1.52.2-py3-none-any.whl (386 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m386.9/386.9 kB\u001b[0m \u001b[31m20.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading pypdf2-3.0.1-py3-none-any.whl (232 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m232.6/232.6 kB\u001b[0m \u001b[31m15.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading python_dotenv-1.0.1-py3-none-any.whl (19 kB)\n",
+            "Downloading reportlab-4.2.5-py3-none-any.whl (1.9 MB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.9/1.9 MB\u001b[0m \u001b[31m57.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading youtube_transcript_api-0.6.2-py3-none-any.whl (24 kB)\n",
+            "Downloading bcrypt-4.2.0-cp39-abi3-manylinux_2_28_x86_64.whl (273 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m273.8/273.8 kB\u001b[0m \u001b[31m20.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading build-1.2.2.post1-py3-none-any.whl (22 kB)\n",
+            "Downloading dataclasses_json-0.6.7-py3-none-any.whl (28 kB)\n",
+            "Downloading fastapi-0.115.3-py3-none-any.whl (94 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m94.6/94.6 kB\u001b[0m \u001b[31m7.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading httpx-0.27.2-py3-none-any.whl (76 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m76.4/76.4 kB\u001b[0m \u001b[31m6.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading httpcore-1.0.6-py3-none-any.whl (78 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m78.0/78.0 kB\u001b[0m \u001b[31m6.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading jiter-0.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (325 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m325.2/325.2 kB\u001b[0m \u001b[31m20.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading kubernetes-31.0.0-py2.py3-none-any.whl (1.9 MB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.9/1.9 MB\u001b[0m \u001b[31m69.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading langchain_core-0.3.12-py3-none-any.whl (407 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m407.7/407.7 kB\u001b[0m \u001b[31m29.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading langchain_text_splitters-0.3.0-py3-none-any.whl (25 kB)\n",
+            "Downloading langsmith-0.1.137-py3-none-any.whl (296 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m296.9/296.9 kB\u001b[0m \u001b[31m18.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading mmh3-5.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (93 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m93.2/93.2 kB\u001b[0m \u001b[31m7.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading onnxruntime-1.19.2-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (13.2 MB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m13.2/13.2 MB\u001b[0m \u001b[31m85.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading opentelemetry_exporter_otlp_proto_grpc-1.27.0-py3-none-any.whl (18 kB)\n",
+            "Downloading opentelemetry_exporter_otlp_proto_common-1.27.0-py3-none-any.whl (17 kB)\n",
+            "Downloading opentelemetry_proto-1.27.0-py3-none-any.whl (52 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m52.5/52.5 kB\u001b[0m \u001b[31m3.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading opentelemetry_instrumentation_fastapi-0.48b0-py3-none-any.whl (11 kB)\n",
+            "Downloading opentelemetry_instrumentation-0.48b0-py3-none-any.whl (29 kB)\n",
+            "Downloading opentelemetry_instrumentation_asgi-0.48b0-py3-none-any.whl (15 kB)\n",
+            "Downloading opentelemetry_semantic_conventions-0.48b0-py3-none-any.whl (149 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m149.7/149.7 kB\u001b[0m \u001b[31m10.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading opentelemetry_api-1.27.0-py3-none-any.whl (63 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m64.0/64.0 kB\u001b[0m \u001b[31m4.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading opentelemetry_util_http-0.48b0-py3-none-any.whl (6.9 kB)\n",
+            "Downloading opentelemetry_sdk-1.27.0-py3-none-any.whl (110 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m110.5/110.5 kB\u001b[0m \u001b[31m8.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (144 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m144.5/144.5 kB\u001b[0m \u001b[31m11.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading overrides-7.7.0-py3-none-any.whl (17 kB)\n",
+            "Downloading posthog-3.7.0-py2.py3-none-any.whl (54 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m54.4/54.4 kB\u001b[0m \u001b[31m3.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading pydantic_settings-2.6.0-py3-none-any.whl (28 kB)\n",
+            "Downloading tiktoken-0.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.2 MB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.2/1.2 MB\u001b[0m \u001b[31m53.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading uvicorn-0.32.0-py3-none-any.whl (63 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m63.7/63.7 kB\u001b[0m \u001b[31m4.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading backoff-2.2.1-py3-none-any.whl (15 kB)\n",
+            "Downloading durationpy-0.9-py3-none-any.whl (3.5 kB)\n",
+            "Downloading h11-0.14.0-py3-none-any.whl (58 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.3/58.3 kB\u001b[0m \u001b[31m4.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading httptools-0.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (442 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m442.1/442.1 kB\u001b[0m \u001b[31m24.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading importlib_metadata-8.4.0-py3-none-any.whl (26 kB)\n",
+            "Downloading jsonpatch-1.33-py2.py3-none-any.whl (12 kB)\n",
+            "Downloading marshmallow-3.23.0-py3-none-any.whl (49 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.5/49.5 kB\u001b[0m \u001b[31m3.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading monotonic-1.6-py2.py3-none-any.whl (8.2 kB)\n",
+            "Downloading requests_toolbelt-1.0.0-py2.py3-none-any.whl (54 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m54.5/54.5 kB\u001b[0m \u001b[31m4.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading starlette-0.41.0-py3-none-any.whl (73 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m73.2/73.2 kB\u001b[0m \u001b[31m5.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading typing_inspect-0.9.0-py3-none-any.whl (8.8 kB)\n",
+            "Downloading uvloop-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.8 MB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.8/3.8 MB\u001b[0m \u001b[31m76.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading watchfiles-0.24.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (425 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m425.7/425.7 kB\u001b[0m \u001b[31m26.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading websockets-13.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (164 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m164.1/164.1 kB\u001b[0m \u001b[31m12.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading coloredlogs-15.0.1-py2.py3-none-any.whl (46 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m46.0/46.0 kB\u001b[0m \u001b[31m3.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading pyproject_hooks-1.2.0-py3-none-any.whl (10 kB)\n",
+            "Downloading asgiref-3.8.1-py3-none-any.whl (23 kB)\n",
+            "Downloading humanfriendly-10.0-py2.py3-none-any.whl (86 kB)\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m86.8/86.8 kB\u001b[0m \u001b[31m6.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25hDownloading jsonpointer-3.0.0-py2.py3-none-any.whl (7.6 kB)\n",
+            "Downloading mypy_extensions-1.0.0-py3-none-any.whl (4.7 kB)\n",
+            "Building wheels for collected packages: educhain, pypika\n",
+            "  Building wheel for educhain (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
+            "  Created wheel for educhain: filename=educhain-0.3.2-py3-none-any.whl size=18549 sha256=6ef98ea713c3b172d8589cc51e183acad5ceb623eaf8d2c1bda7e9b7f9b2bffa\n",
+            "  Stored in directory: /tmp/pip-ephem-wheel-cache-b9ci1szg/wheels/cf/37/1a/d1708e678c8679ecce8ee35b17f42fc00df5e425b1ef60b913\n",
+            "  Building wheel for pypika (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n",
+            "  Created wheel for pypika: filename=PyPika-0.48.9-py2.py3-none-any.whl size=53725 sha256=75dad2077afcd19b316b0c1cd2860f38a33cb75c2e95acae38cefe9d9cfab164\n",
+            "  Stored in directory: /root/.cache/pip/wheels/e1/26/51/d0bffb3d2fd82256676d7ad3003faea3bd6dddc9577af665f4\n",
+            "Successfully built educhain pypika\n",
+            "Installing collected packages: pypika, monotonic, durationpy, websockets, uvloop, reportlab, python-dotenv, pyproject_hooks, PyPDF2, overrides, orjson, opentelemetry-util-http, opentelemetry-proto, mypy-extensions, mmh3, marshmallow, jsonpointer, jiter, importlib-metadata, humanfriendly, httptools, h11, chroma-hnswlib, bcrypt, backoff, asgiref, youtube_transcript_api, watchfiles, uvicorn, typing-inspect, tiktoken, starlette, requests-toolbelt, posthog, opentelemetry-exporter-otlp-proto-common, opentelemetry-api, jsonpatch, httpcore, coloredlogs, build, pydantic-settings, opentelemetry-semantic-conventions, opentelemetry-instrumentation, onnxruntime, kubernetes, httpx, fastapi, dataclasses-json, opentelemetry-sdk, opentelemetry-instrumentation-asgi, openai, langsmith, opentelemetry-instrumentation-fastapi, opentelemetry-exporter-otlp-proto-grpc, langchain-core, langchain-text-splitters, langchain-openai, chromadb, langchain, langchain-community, educhain\n",
+            "  Attempting uninstall: importlib-metadata\n",
+            "    Found existing installation: importlib_metadata 8.5.0\n",
+            "    Uninstalling importlib_metadata-8.5.0:\n",
+            "      Successfully uninstalled importlib_metadata-8.5.0\n",
+            "  Attempting uninstall: opentelemetry-api\n",
+            "    Found existing installation: opentelemetry-api 1.16.0\n",
+            "    Uninstalling opentelemetry-api-1.16.0:\n",
+            "      Successfully uninstalled opentelemetry-api-1.16.0\n",
+            "  Attempting uninstall: opentelemetry-semantic-conventions\n",
+            "    Found existing installation: opentelemetry-semantic-conventions 0.37b0\n",
+            "    Uninstalling opentelemetry-semantic-conventions-0.37b0:\n",
+            "      Successfully uninstalled opentelemetry-semantic-conventions-0.37b0\n",
+            "  Attempting uninstall: opentelemetry-sdk\n",
+            "    Found existing installation: opentelemetry-sdk 1.16.0\n",
+            "    Uninstalling opentelemetry-sdk-1.16.0:\n",
+            "      Successfully uninstalled opentelemetry-sdk-1.16.0\n",
+            "Successfully installed PyPDF2-3.0.1 asgiref-3.8.1 backoff-2.2.1 bcrypt-4.2.0 build-1.2.2.post1 chroma-hnswlib-0.7.6 chromadb-0.5.15 coloredlogs-15.0.1 dataclasses-json-0.6.7 durationpy-0.9 educhain-0.3.2 fastapi-0.115.3 h11-0.14.0 httpcore-1.0.6 httptools-0.6.4 httpx-0.27.2 humanfriendly-10.0 importlib-metadata-8.4.0 jiter-0.6.1 jsonpatch-1.33 jsonpointer-3.0.0 kubernetes-31.0.0 langchain-0.3.4 langchain-community-0.3.3 langchain-core-0.3.12 langchain-openai-0.2.3 langchain-text-splitters-0.3.0 langsmith-0.1.137 marshmallow-3.23.0 mmh3-5.0.1 monotonic-1.6 mypy-extensions-1.0.0 onnxruntime-1.19.2 openai-1.52.2 opentelemetry-api-1.27.0 opentelemetry-exporter-otlp-proto-common-1.27.0 opentelemetry-exporter-otlp-proto-grpc-1.27.0 opentelemetry-instrumentation-0.48b0 opentelemetry-instrumentation-asgi-0.48b0 opentelemetry-instrumentation-fastapi-0.48b0 opentelemetry-proto-1.27.0 opentelemetry-sdk-1.27.0 opentelemetry-semantic-conventions-0.48b0 opentelemetry-util-http-0.48b0 orjson-3.10.10 overrides-7.7.0 posthog-3.7.0 pydantic-settings-2.6.0 pypika-0.48.9 pyproject_hooks-1.2.0 python-dotenv-1.0.1 reportlab-4.2.5 requests-toolbelt-1.0.0 starlette-0.41.0 tiktoken-0.8.0 typing-inspect-0.9.0 uvicorn-0.32.0 uvloop-0.21.0 watchfiles-0.24.0 websockets-13.1 youtube_transcript_api-0.6.2\n"
+          ]
+        }
+      ],
+      "source": [
+        "!pip install git+https://github.com/lunatic-7/educhain.git@main"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "# Set up your OpenAI API key\n",
+        "import os\n",
+        "from google.colab import userdata\n",
+        "\n",
+        "os.environ[\"OPENAI_API_KEY\"] = userdata.get('OPENAI_API_KEY')"
+      ],
+      "metadata": {
+        "id": "PVFWI_hi89i-"
+      },
+      "execution_count": 4,
+      "outputs": []
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "### Generate Study guide"
+      ],
+      "metadata": {
+        "id": "jZRJaa2p9Evq"
+      }
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "from educhain import Educhain\n",
+        "\n",
+        "client = Educhain()\n",
+        "\n",
+        "plan = client.content_engine.generate_study_guide(\n",
+        "    topic = \"Ethical Hacking\",\n",
+        "    difficulty_level = \"Beginner\",\n",
+        "    )\n",
+        "\n",
+        "plan.show(format=\"text\")"
+      ],
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "SYibPQr1-JOd",
+        "outputId": "b82ff18d-fb7e-4851-a7b6-053599facdd0"
+      },
+      "execution_count": 5,
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "=== Study Guide: Ethical Hacking ===\n",
+            "\n",
+            "Difficulty Level: Beginner\n",
+            "Estimated Study Time: 10 hours\n",
+            "\n",
+            "Prerequisites:\n",
+            "- Basic understanding of computer networks\n",
+            "- Familiarity with operating systems (especially Linux)\n",
+            "- Basic programming skills (Python or similar recommended)\n",
+            "\n",
+            "Learning Objectives:\n",
+            "- Define ethical hacking and its importance in cybersecurity.\n",
+            "- Identify different types of hackers and their motivations.\n",
+            "- Describe the ethical hacking process and methodologies.\n",
+            "- Recognize the legal implications and ethical considerations in hacking.\n",
+            "- Conduct basic penetration testing using common tools.\n",
+            "\n",
+            "Overview:\n",
+            "Ethical hacking involves legally breaking into systems to identify vulnerabilities. Unlike malicious hackers, ethical hackers work to improve security systems. This field is crucial for protecting sensitive information and maintaining trust in technology.\n",
+            "\n",
+            "Key Concepts:\n",
+            "\n",
+            "Ethical Hacking:\n",
+            "The practice of deliberately probing systems for vulnerabilities in order to improve security. Ethical hackers obtain permission to test systems legally.\n",
+            "\n",
+            "Types of Hackers:\n",
+            "Hackers can be categorized as white hat (ethical hackers), black hat (malicious hackers), and gray hat (mixed intentions). Understanding these types helps in identifying motivations behind hacking activities.\n",
+            "\n",
+            "Penetration Testing:\n",
+            "A simulated cyber attack against a system, conducted to evaluate its security. This process involves planning, scanning, gaining access, maintaining access, and analysis.\n",
+            "\n",
+            "Legal Aspects:\n",
+            "Ethical hackers must understand laws such as the Computer Fraud and Abuse Act (CFAA) and the importance of obtaining proper authorization before testing systems.\n",
+            "\n",
+            "Common Tools:\n",
+            "Tools like Metasploit, Nmap, Wireshark, and Burp Suite are essential for ethical hacking as they assist in scanning, exploiting vulnerabilities, and analyzing traffic.\n",
+            "\n",
+            "Important Dates:\n",
+            "- 1996: The formation of the first hacking ethics organization, which established guidelines for ethical hacking.\n",
+            "- 2000: The release of the first version of the Certified Ethical Hacker (CEH) certification.\n",
+            "\n",
+            "Practice Exercises:\n",
+            "\n",
+            "Exercise 1:\n",
+            "Problem: List and describe at least three types of hackers and their motivations.\n",
+            "Solution: 1. White Hat: Ethical hackers who find vulnerabilities to protect systems. 2. Black Hat: Malicious hackers who exploit vulnerabilities for personal gain. 3. Gray Hat: Individuals who may violate ethical standards but do not have malicious intent.\n",
+            "\n",
+            "Exercise 2:\n",
+            "Problem: Outline the five main steps in the penetration testing process.\n",
+            "Solution: 1. Planning: Define the scope and objectives. 2. Scanning: Identify open ports and services. 3. Gaining Access: Exploit identified vulnerabilities. 4. Maintaining Access: Ensure continued access for further testing. 5. Analysis: Document findings and provide recommendations.\n",
+            "\n",
+            "Real-World Case Studies:\n",
+            "\n",
+            "Case Study 1: Target Data Breach (2013)\n",
+            "Scenario: Target Corporation suffered a massive data breach affecting millions of customer credit and debit card accounts.\n",
+            "Challenge: The attackers gained access through a third-party vendor, highlighting the importance of supply chain security.\n",
+            "Solution: After the breach, Target implemented strict security measures, including enhanced monitoring and segmentation of networks to prevent unauthorized access.\n",
+            "Outcome: The breach resulted in significant financial loss and reputational damage, leading to a reevaluation of their cybersecurity practices.\n",
+            "\n",
+            "Key Lessons Learned:\n",
+            "- The importance of securing third-party vendors.\n",
+            "- Continuous monitoring and assessment of security protocols are essential.\n",
+            "\n",
+            "Related Concepts:\n",
+            "- Penetration Testing\n",
+            "- Legal Aspects of Ethical Hacking\n",
+            "--------------------------------------------------\n",
+            "\n",
+            "Study Tips:\n",
+            "- Use hands-on tools to practice ethical hacking techniques in a safe and legal environment.\n",
+            "- Join online forums or groups to discuss and learn from other aspiring ethical hackers.\n",
+            "- Take online courses that offer practical labs and exercises.\n",
+            "- Stay updated with the latest cybersecurity news and trends.\n",
+            "\n",
+            "Additional Resources:\n",
+            "- OWASP: The Open Web Application Security Project provides free tools and resources for web application security.\n",
+            "- Cybrary: An online platform offering courses in ethical hacking and cybersecurity.\n",
+            "- Kali Linux: A widely used Linux distribution for penetration testing and ethical hacking.\n",
+            "\n",
+            "Summary:\n",
+            "Ethical hacking is a vital field that helps organizations protect their systems from malicious attacks. By understanding the types of hackers, the ethical hacking process, and the legal implications, beginners can start their journey in cybersecurity, armed with the knowledge of essential tools and practices.\n"
+          ]
+        }
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "### Generate Study Guide with **custom instructions**"
+      ],
+      "metadata": {
+        "id": "EXAn-gUs-NEV"
+      }
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "from educhain import Educhain\n",
+        "\n",
+        "client = Educhain()\n",
+        "\n",
+        "plan = client.content_engine.generate_study_guide(\n",
+        "    topic = \"Ethical Hacking\",\n",
+        "    difficulty_level = \"Beginner\",\n",
+        "    # Optional\n",
+        "    custom_instructions = \"\"\"\n",
+        "        Include hands-on examples and some real-world techniques.\n",
+        "        Focus on practical applications and security best practices.\n",
+        "        \"\"\"\n",
+        "    )\n",
+        "\n",
+        "plan.show(format=\"text\")"
+      ],
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "9Nocv5yN9FSf",
+        "outputId": "b9cc93b8-c824-43e3-e78b-71db159f3c18"
+      },
+      "execution_count": 6,
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "=== Study Guide: Ethical Hacking ===\n",
+            "\n",
+            "Difficulty Level: Beginner\n",
+            "Estimated Study Time: 10-15 hours\n",
+            "\n",
+            "Prerequisites:\n",
+            "- Basic understanding of computer networks\n",
+            "- Familiarity with operating systems (Windows, Linux)\n",
+            "- Basic programming knowledge (Python or similar)\n",
+            "\n",
+            "Learning Objectives:\n",
+            "- Understand the role and importance of ethical hacking in cybersecurity.\n",
+            "- Identify common types of cyber attacks and their mechanisms.\n",
+            "- Learn the ethical and legal considerations in ethical hacking.\n",
+            "- Gain hands-on experience with basic tools and techniques used in ethical hacking.\n",
+            "- Develop problem-solving skills to address security vulnerabilities.\n",
+            "\n",
+            "Overview:\n",
+            "Ethical hacking involves legally breaking into computers and devices to test an organization's defenses. Unlike malicious hackers, ethical hackers have permission to access systems to identify vulnerabilities and strengthen security measures. This study guide covers essential concepts, practices, and tools necessary for aspiring ethical hackers.\n",
+            "\n",
+            "Key Concepts:\n",
+            "\n",
+            "Ethical Hacking:\n",
+            "Ethical hacking refers to the practice of intentionally probing systems for vulnerabilities in order to fix them before they can be exploited by malicious hackers.\n",
+            "\n",
+            "Types of Hackers:\n",
+            "Hackers are typically categorized into three groups: White Hat (ethical hackers), Black Hat (malicious hackers), and Gray Hat (who may violate laws but without malicious intent).\n",
+            "\n",
+            "Penetration Testing:\n",
+            "A method of evaluating the security of a system by simulating an attack from malicious outsiders and insiders. It helps to identify vulnerabilities.\n",
+            "\n",
+            "Social Engineering:\n",
+            "A tactic used by hackers to manipulate individuals into divulging confidential information, often by exploiting human psychology.\n",
+            "\n",
+            "Common Attacks:\n",
+            "Examples include phishing, malware, denial-of-service (DoS) attacks, and SQL injection.\n",
+            "\n",
+            "Important Dates:\n",
+            "- 1970: The term 'hacker' is first used in the context of computing.\n",
+            "- 1996: The Computer Fraud and Abuse Act (CFAA) becomes law in the U.S., defining illegal hacking.\n",
+            "- 2010: The first known use of ethical hacking certifications begins to gain traction.\n",
+            "\n",
+            "Practice Exercises:\n",
+            "\n",
+            "Exercise 1:\n",
+            "Problem: Using online tools, gather information about a target website (e.g., domain name, IP address, and hosting information).\n",
+            "Solution: Use tools like WHOIS, nslookup, and online services like DNSstuff to collect data on the target website.\n",
+            "\n",
+            "Exercise 2:\n",
+            "Problem: Use a port scanning tool (like Nmap) to identify open ports on a local machine.\n",
+            "Solution: 1. Install Nmap. 2. Run the command 'nmap <target_ip>' to scan for open ports. 3. Analyze the results.\n",
+            "\n",
+            "Exercise 3:\n",
+            "Problem: Create a basic SQL injection to manipulate a sample database query.\n",
+            "Solution: 1. Set up a vulnerable web application (e.g., DVWA). 2. Input a common SQL injection payload (like ' OR '1'='1') into a form field to bypass authentication. 3. Observe the results.\n",
+            "\n",
+            "Real-World Case Studies:\n",
+            "\n",
+            "Case Study 1: Target Data Breach (2013)\n",
+            "Scenario: Target suffered a massive data breach that exposed customer credit card information.\n",
+            "Challenge: The breach occurred due to inadequate security measures and failure to monitor third-party vendors.\n",
+            "Solution: Target implemented stronger network segmentation, improved monitoring of third-party vendors, and conducted comprehensive security assessments.\n",
+            "Outcome: The company faced significant financial losses and damage to reputation, leading to increased focus on cybersecurity.\n",
+            "\n",
+            "Key Lessons Learned:\n",
+            "- Never underestimate the security of third-party vendors.\n",
+            "- Continuous monitoring and assessment of security measures are crucial.\n",
+            "\n",
+            "Related Concepts:\n",
+            "- Penetration Testing\n",
+            "- Social Engineering\n",
+            "--------------------------------------------------\n",
+            "\n",
+            "Study Tips:\n",
+            "- Practice using ethical hacking tools in a controlled environment (e.g., virtual machines).\n",
+            "- Engage in Capture The Flag (CTF) exercises to apply your knowledge practically.\n",
+            "- Stay updated with the latest cybersecurity news and trends.\n",
+            "- Join online forums or communities focused on ethical hacking for shared learning.\n",
+            "\n",
+            "Additional Resources:\n",
+            "- Cybrary: An online platform offering free courses on ethical hacking and cybersecurity.\n",
+            "- OWASP: The Open Web Application Security Project provides comprehensive resources on web application security.\n",
+            "- Kali Linux Documentation: Official documentation for Kali Linux, a popular operating system for penetration testing.\n",
+            "\n",
+            "Summary:\n",
+            "Ethical hacking is a vital field within cybersecurity, focusing on identifying and addressing vulnerabilities before they can be exploited. By understanding the various types of hackers, learning common attack methods, and utilizing key tools and techniques, aspiring ethical hackers can contribute significantly to organizational security.\n"
+          ]
+        }
+      ]
+    },
+    {
+      "cell_type": "code",
+      "source": [],
+      "metadata": {
+        "id": "BhCpfDm2-uHb"
+      },
+      "execution_count": null,
+      "outputs": []
+    }
+  ]
+}
\ No newline at end of file
diff --git a/cookbook/generate_flashcard_usecase_examples.ipynb b/cookbook/generate_flashcard_usecase_examples.ipynb
new file mode 100644
index 0000000..3b3d4d2
--- /dev/null
+++ b/cookbook/generate_flashcard_usecase_examples.ipynb
@@ -0,0 +1,709 @@
+{
+  "nbformat": 4,
+  "nbformat_minor": 0,
+  "metadata": {
+    "colab": {
+      "provenance": []
+    },
+    "kernelspec": {
+      "name": "python3",
+      "display_name": "Python 3"
+    },
+    "language_info": {
+      "name": "python"
+    }
+  },
+  "cells": [
+    {
+      "cell_type": "markdown",
+      "source": [
+        "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1hayElw8s0jGKGWZ-a6L_VjdQMkzeEu2v?usp=sharing)"
+      ],
+      "metadata": {
+        "id": "08OmChpTl3FV"
+      }
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "#🎯 Advanced Flashcard Generator System\n",
+        "\n",
+        "🌟 Overview\n",
+        "\n",
+        "An intelligent educational tool that creates dynamic, interactive flashcards with advanced customization options and learning analytics."
+      ],
+      "metadata": {
+        "id": "OwWEgz7-lYEw"
+      }
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 1,
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "0t5I9GAokUqH",
+        "outputId": "3174ebff-4210-4d93-d333-4598f1667c6f"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "\u001b[?25l     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/67.3 kB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m67.3/67.3 kB\u001b[0m \u001b[31m1.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25h  Installing build dependencies ... \u001b[?25l\u001b[?25hdone\n",
+            "  Getting requirements to build wheel ... \u001b[?25l\u001b[?25hdone\n",
+            "  Preparing metadata (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n",
+            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m50.6/50.6 kB\u001b[0m \u001b[31m1.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m607.0/607.0 kB\u001b[0m \u001b[31m13.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.4/2.4 MB\u001b[0m \u001b[31m46.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.0/1.0 MB\u001b[0m \u001b[31m45.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.4/2.4 MB\u001b[0m \u001b[31m62.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.9/49.9 kB\u001b[0m \u001b[31m3.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m386.9/386.9 kB\u001b[0m \u001b[31m22.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m232.6/232.6 kB\u001b[0m \u001b[31m15.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.9/1.9 MB\u001b[0m \u001b[31m43.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m273.8/273.8 kB\u001b[0m \u001b[31m17.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m94.7/94.7 kB\u001b[0m \u001b[31m7.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m76.4/76.4 kB\u001b[0m \u001b[31m5.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m78.0/78.0 kB\u001b[0m \u001b[31m4.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m325.2/325.2 kB\u001b[0m \u001b[31m21.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.9/1.9 MB\u001b[0m \u001b[31m50.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m408.0/408.0 kB\u001b[0m \u001b[31m25.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m296.9/296.9 kB\u001b[0m \u001b[31m19.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m93.2/93.2 kB\u001b[0m \u001b[31m6.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m13.2/13.2 MB\u001b[0m \u001b[31m83.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m52.5/52.5 kB\u001b[0m \u001b[31m3.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m149.7/149.7 kB\u001b[0m \u001b[31m10.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m64.0/64.0 kB\u001b[0m \u001b[31m4.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m110.5/110.5 kB\u001b[0m \u001b[31m7.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m144.5/144.5 kB\u001b[0m \u001b[31m10.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m54.4/54.4 kB\u001b[0m \u001b[31m3.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.2/1.2 MB\u001b[0m \u001b[31m49.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m63.7/63.7 kB\u001b[0m \u001b[31m4.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.3/58.3 kB\u001b[0m \u001b[31m4.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m442.1/442.1 kB\u001b[0m \u001b[31m27.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.5/49.5 kB\u001b[0m \u001b[31m3.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m54.5/54.5 kB\u001b[0m \u001b[31m4.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m73.3/73.3 kB\u001b[0m \u001b[31m5.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.8/3.8 MB\u001b[0m \u001b[31m75.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m425.7/425.7 kB\u001b[0m \u001b[31m12.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m164.1/164.1 kB\u001b[0m \u001b[31m10.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m46.0/46.0 kB\u001b[0m \u001b[31m3.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m86.8/86.8 kB\u001b[0m \u001b[31m6.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+            "\u001b[?25h  Building wheel for pypika (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n"
+          ]
+        }
+      ],
+      "source": [
+        "!pip install -U educhain --quiet"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "from langchain_openai import ChatOpenAI\n",
+        "import os\n",
+        "from google.colab import userdata\n",
+        "os.environ[\"OPENAI_API_KEY\"] = userdata.get('OPENAI_API_KEY')\n"
+      ],
+      "metadata": {
+        "id": "KYilRkbfkch2"
+      },
+      "execution_count": null,
+      "outputs": []
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "\n",
+        "ContentEngine Cookbook\n",
+        "=======================\n",
+        "Simplified example demonstrating the practical use of ContentEngine\n",
+        "for generating flashcards for medical education and technical certification preparation.\n",
+        "\n"
+      ],
+      "metadata": {
+        "id": "CG62jDMBnXqD"
+      }
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "### Medical Exams Flashcards 🏥"
+      ],
+      "metadata": {
+        "id": "fsAULwccnb6R"
+      }
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "\n",
+        "import json\n",
+        "from educhain import Educhain\n",
+        "\n",
+        "client = Educhain()\n",
+        "\n",
+        "# Generate flashcards for a given topic\n",
+        "def generate_medical_flashcards(topic: str):\n",
+        "    content_engine = client.content_engine\n",
+        "\n",
+        "    flashcards = content_engine.generate_flashcards(\n",
+        "        topic=topic,\n",
+        "        num=5,  # Generate 10 flashcards\n",
+        "        custom_instructions=\"\"\"\n",
+        "        Create flashcards with:\n",
+        "        1. High-yield medical facts\n",
+        "        2. Diagnostic criteria\n",
+        "        3. Treatment protocols\n",
+        "        4. Key clinical pearls\n",
+        "        Include references to the latest research where relevant.\n",
+        "        \"\"\"\n",
+        "    )\n",
+        "\n",
+        "    # Print the flashcards\n",
+        "    print(f\"Flashcards for {topic}:\\n\")\n",
+        "    print(json.dumps(flashcards.dict(), indent=2))\n",
+        "\n",
+        "\n",
+        "\n"
+      ],
+      "metadata": {
+        "id": "vVGXTLsol99b"
+      },
+      "execution_count": null,
+      "outputs": []
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "generate_medical_flashcards(topic=\"Acute Coronary Syndromes\")"
+      ],
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "zTvKC_CFm6JA",
+        "outputId": "ba78731b-ef03-4d67-a676-83f6b50ac25a"
+      },
+      "execution_count": null,
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "Flashcards for Acute Coronary Syndromes:\n",
+            "\n",
+            "{\n",
+            "  \"title\": \"Acute Coronary Syndromes\",\n",
+            "  \"flashcards\": [\n",
+            "    {\n",
+            "      \"front\": \"What are the types of Acute Coronary Syndromes (ACS)?\",\n",
+            "      \"back\": \"The three main types of ACS are Unstable Angina, Non-ST-Elevation Myocardial Infarction (NSTEMI), and ST-Elevation Myocardial Infarction (STEMI).\",\n",
+            "      \"explanation\": \"ACS encompasses a range of conditions associated with sudden reduced blood flow to the heart. Differentiating between these types is crucial for determining the appropriate management and treatment.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"What is the diagnostic criterion for NSTEMI?\",\n",
+            "      \"back\": \"NSTEMI is diagnosed based on elevated cardiac biomarkers (like troponins) and persistent chest pain, without ST-segment elevation on the ECG.\",\n",
+            "      \"explanation\": \"Troponin elevation indicates myocardial injury, which is a key factor in diagnosing NSTEMI. Immediate treatment is necessary to reduce the risk of further heart damage.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"What is the first-line treatment for STEMI?\",\n",
+            "      \"back\": \"The first-line treatment for STEMI is reperfusion therapy, which can be achieved through percutaneous coronary intervention (PCI) or thrombolytic therapy.\",\n",
+            "      \"explanation\": \"Timely reperfusion is critical in STEMI management to restore blood flow and minimize myocardial necrosis. PCI is preferred when available and can often be performed within a few hours of symptom onset.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"What are common risk factors for Acute Coronary Syndromes?\",\n",
+            "      \"back\": \"Common risk factors include hypertension, hyperlipidemia, smoking, diabetes mellitus, obesity, and a sedentary lifestyle.\",\n",
+            "      \"explanation\": \"Understanding these risk factors can aid in prevention strategies and early intervention to reduce the incidence of ACS.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"What is the role of antiplatelet therapy in ACS management?\",\n",
+            "      \"back\": \"Antiplatelet therapy, such as aspirin and P2Y12 inhibitors (e.g., clopidogrel), is crucial in reducing thrombus formation and preventing further cardiovascular events.\",\n",
+            "      \"explanation\": \"These medications are typically initiated as soon as ACS is suspected to improve outcomes and are often part of long-term management post-event.\"\n",
+            "    }\n",
+            "  ]\n",
+            "}\n"
+          ]
+        }
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "## Interactive Flashcards with custom topic and accessiblity 🆒"
+      ],
+      "metadata": {
+        "id": "4b5KRlAWl6Y6"
+      }
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "import json\n",
+        "from educhain import Educhain\n",
+        "from typing import Dict, Any\n",
+        "import os\n",
+        "\n",
+        "class InteractiveFlashcards:\n",
+        "    def __init__(self):\n",
+        "        self.client = Educhain()\n",
+        "        self.current_flashcards = None\n",
+        "        self.shown_cards = set()\n",
+        "\n",
+        "    def generate_medical_flashcards(self, topic: str):\n",
+        "        \"\"\"Generate medical flashcards for a given topic.\"\"\"\n",
+        "        content_engine = self.client.content_engine\n",
+        "\n",
+        "        self.current_flashcards = content_engine.generate_flashcards(\n",
+        "            topic=topic,\n",
+        "            num=5,\n",
+        "            custom_instructions=\"\"\"\n",
+        "            Create flashcards with:\n",
+        "            1. High-yield medical facts\n",
+        "            2. Diagnostic criteria\n",
+        "            3. Treatment protocols\n",
+        "            4. Key clinical pearls\n",
+        "            Include references to the latest research where relevant.\n",
+        "            \"\"\"\n",
+        "        )\n",
+        "        self.shown_cards = set()\n",
+        "        self.display_fronts()\n",
+        "\n",
+        "    def display_fronts(self):\n",
+        "        \"\"\"Display only the front of all flashcards.\"\"\"\n",
+        "        if not self.current_flashcards:\n",
+        "            print(\"No flashcards generated yet!\")\n",
+        "            return\n",
+        "\n",
+        "        print(f\"\\nFlashcards Topic: {self.current_flashcards.title}\")\n",
+        "        print(\"\\nAvailable cards (showing front side only):\")\n",
+        "        print(\"-\" * 50)\n",
+        "\n",
+        "        for idx, card in enumerate(self.current_flashcards.flashcards, 1):\n",
+        "            print(f\"\\nCard {idx}:\")\n",
+        "            print(f\"Front: {card.front}\")\n",
+        "            print(\"-\" * 50)\n",
+        "\n",
+        "        self._show_menu()\n",
+        "\n",
+        "    def reveal_card(self, card_number: int):\n",
+        "        \"\"\"Reveal the back of a specific card.\"\"\"\n",
+        "        if not self.current_flashcards:\n",
+        "            print(\"No flashcards generated yet!\")\n",
+        "            return\n",
+        "\n",
+        "        if not 1 <= card_number <= len(self.current_flashcards.flashcards):\n",
+        "            print(\"Invalid card number!\")\n",
+        "            return\n",
+        "\n",
+        "        card = self.current_flashcards.flashcards[card_number - 1]\n",
+        "        print(f\"\\nCard {card_number}:\")\n",
+        "        print(f\"Front: {card.front}\")\n",
+        "        print(f\"Back: {card.back}\")\n",
+        "        if card.explanation:\n",
+        "            print(f\"Explanation: {card.explanation}\")\n",
+        "        print(\"-\" * 50)\n",
+        "\n",
+        "        self.shown_cards.add(card_number)\n",
+        "        self._show_menu()\n",
+        "\n",
+        "    def _show_menu(self):\n",
+        "        \"\"\"Display the interactive menu.\"\"\"\n",
+        "        print(\"\\nOptions:\")\n",
+        "        print(\"- Enter a card number (1-5) to reveal its back\")\n",
+        "        print(\"- Enter 'r' to refresh/show fronts only\")\n",
+        "        print(\"- Enter 'q' to quit\")\n",
+        "        print(\"\\nYour choice: \", end=\"\")\n",
+        "\n",
+        "    def handle_input(self, user_input: str):\n",
+        "        \"\"\"Handle user input for the interactive menu.\"\"\"\n",
+        "        if user_input.lower() == 'q':\n",
+        "            return False\n",
+        "        elif user_input.lower() == 'r':\n",
+        "            self.display_fronts()\n",
+        "        else:\n",
+        "            try:\n",
+        "                card_num = int(user_input)\n",
+        "                self.reveal_card(card_num)\n",
+        "            except ValueError:\n",
+        "                print(\"Invalid input! Please try again.\")\n",
+        "                self._show_menu()\n",
+        "        return True\n",
+        "\n",
+        "def main():\n",
+        "    flashcard_system = InteractiveFlashcards()\n",
+        "\n",
+        "    # Get the topic from user\n",
+        "    topic = input(\"Enter medical topic for flashcards: \")\n",
+        "\n",
+        "    # Generate initial flashcards\n",
+        "    flashcard_system.generate_medical_flashcards(topic)\n",
+        "\n",
+        "    # Interactive loop\n",
+        "    while True:\n",
+        "        user_input = input()\n",
+        "        if not flashcard_system.handle_input(user_input):\n",
+        "            break\n",
+        "\n",
+        "if __name__ == \"__main__\":\n",
+        "    main()"
+      ],
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "C0Uguc8qk_Go",
+        "outputId": "ef7e5074-e37e-4ec3-c982-8749f2627b87"
+      },
+      "execution_count": null,
+      "outputs": [
+        {
+          "name": "stdout",
+          "output_type": "stream",
+          "text": [
+            "Enter medical topic for flashcards: Machine Learning\n",
+            "\n",
+            "Flashcards Topic: Machine Learning\n",
+            "\n",
+            "Available cards (showing front side only):\n",
+            "--------------------------------------------------\n",
+            "\n",
+            "Card 1:\n",
+            "Front: What is supervised learning?\n",
+            "--------------------------------------------------\n",
+            "\n",
+            "Card 2:\n",
+            "Front: Define overfitting in machine learning.\n",
+            "--------------------------------------------------\n",
+            "\n",
+            "Card 3:\n",
+            "Front: What is a confusion matrix?\n",
+            "--------------------------------------------------\n",
+            "\n",
+            "Card 4:\n",
+            "Front: What is the purpose of cross-validation?\n",
+            "--------------------------------------------------\n",
+            "\n",
+            "Card 5:\n",
+            "Front: Explain the term 'feature engineering'.\n",
+            "--------------------------------------------------\n",
+            "\n",
+            "Options:\n",
+            "- Enter a card number (1-5) to reveal its back\n",
+            "- Enter 'r' to refresh/show fronts only\n",
+            "- Enter 'q' to quit\n",
+            "\n",
+            "Your choice: 5\n",
+            "\n",
+            "Card 5:\n",
+            "Front: Explain the term 'feature engineering'.\n",
+            "Back: The process of selecting, modifying, or creating features in a dataset to improve the performance of a machine learning model.\n",
+            "Explanation: Effective feature engineering can dramatically improve model performance. It involves domain knowledge to create meaningful features that enhance the model's ability to learn from the data.\n",
+            "--------------------------------------------------\n",
+            "\n",
+            "Options:\n",
+            "- Enter a card number (1-5) to reveal its back\n",
+            "- Enter 'r' to refresh/show fronts only\n",
+            "- Enter 'q' to quit\n",
+            "\n",
+            "Your choice: 2\n",
+            "\n",
+            "Card 2:\n",
+            "Front: Define overfitting in machine learning.\n",
+            "Back: Overfitting occurs when a model learns the training data too well, capturing noise along with the underlying patterns.\n",
+            "Explanation: An overfit model performs well on training data but poorly on unseen data. Techniques to prevent overfitting include cross-validation, pruning, and regularization.\n",
+            "--------------------------------------------------\n",
+            "\n",
+            "Options:\n",
+            "- Enter a card number (1-5) to reveal its back\n",
+            "- Enter 'r' to refresh/show fronts only\n",
+            "- Enter 'q' to quit\n",
+            "\n",
+            "Your choice: r\n",
+            "\n",
+            "Flashcards Topic: Machine Learning\n",
+            "\n",
+            "Available cards (showing front side only):\n",
+            "--------------------------------------------------\n",
+            "\n",
+            "Card 1:\n",
+            "Front: What is supervised learning?\n",
+            "--------------------------------------------------\n",
+            "\n",
+            "Card 2:\n",
+            "Front: Define overfitting in machine learning.\n",
+            "--------------------------------------------------\n",
+            "\n",
+            "Card 3:\n",
+            "Front: What is a confusion matrix?\n",
+            "--------------------------------------------------\n",
+            "\n",
+            "Card 4:\n",
+            "Front: What is the purpose of cross-validation?\n",
+            "--------------------------------------------------\n",
+            "\n",
+            "Card 5:\n",
+            "Front: Explain the term 'feature engineering'.\n",
+            "--------------------------------------------------\n",
+            "\n",
+            "Options:\n",
+            "- Enter a card number (1-5) to reveal its back\n",
+            "- Enter 'r' to refresh/show fronts only\n",
+            "- Enter 'q' to quit\n",
+            "\n",
+            "Your choice: q\n"
+          ]
+        }
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "source": [
+        "## Technical flashcards 🧑"
+      ],
+      "metadata": {
+        "id": "3OtfTzq7ngBS"
+      }
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "# Generate technical flashcards for a certification domain\n",
+        "def generate_technical_flashcards(certification: str, domain: str):\n",
+        "    content_engine = client.content_engine\n",
+        "\n",
+        "    flashcards = content_engine.generate_flashcards(\n",
+        "        topic=f\"{certification} - {domain}\",\n",
+        "        num=5,  # Generate 10 flashcards\n",
+        "        custom_instructions=\"\"\"\n",
+        "        Create technical flashcards with:\n",
+        "        1. Key terms and concepts from official exam objectives\n",
+        "        2. Practical examples and scenarios\n",
+        "        3. Best practices and common exam pitfalls\n",
+        "        Include references to relevant technical documentation.\n",
+        "        \"\"\"\n",
+        "    )\n",
+        "\n",
+        "    # Print the flashcards\n",
+        "    print(f\"Flashcards for {certification} - {domain}:\\n\")\n",
+        "    print(json.dumps(flashcards.dict(), indent=2))"
+      ],
+      "metadata": {
+        "id": "QbZsqdN_l-Tg"
+      },
+      "execution_count": null,
+      "outputs": []
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "generate_technical_flashcards(certification=\"AWS Solutions Architect\", domain=\"Design Resilient Architectures\")\n"
+      ],
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "hw46Z6rFm9yT",
+        "outputId": "8fafd407-35dd-4dc8-9d92-bbdd5d30ef5d"
+      },
+      "execution_count": null,
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "Flashcards for AWS Solutions Architect - Design Resilient Architectures:\n",
+            "\n",
+            "{\n",
+            "  \"title\": \"AWS Solutions Architect - Design Resilient Architectures\",\n",
+            "  \"flashcards\": [\n",
+            "    {\n",
+            "      \"front\": \"What is High Availability (HA)?\",\n",
+            "      \"back\": \"High Availability (HA) refers to a system's ability to remain operational and accessible for a high percentage of time, minimizing downtime.\",\n",
+            "      \"explanation\": \"In AWS, HA can be achieved through the use of multiple availability zones (AZs) and load balancers to distribute traffic and resources across different zones, thus reducing the risk of a single point of failure.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"What are Availability Zones (AZs)?\",\n",
+            "      \"back\": \"Availability Zones are isolated locations within a region designed to be independent from failures in other zones, providing fault tolerance.\",\n",
+            "      \"explanation\": \"AZs allow you to build applications that are more resilient. By deploying resources across multiple AZs, you can ensure that if one AZ goes down, the others can continue to serve traffic.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"Define Elastic Load Balancing (ELB).\",\n",
+            "      \"back\": \"Elastic Load Balancing (ELB) automatically distributes incoming application traffic across multiple targets, such as EC2 instances.\",\n",
+            "      \"explanation\": \"ELB enhances the availability and fault tolerance of your applications by routing traffic only to healthy instances, and it can scale automatically in response to incoming traffic.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"What is the purpose of AWS Auto Scaling?\",\n",
+            "      \"back\": \"AWS Auto Scaling automatically adjusts the number of EC2 instances in response to changing traffic patterns, ensuring optimal performance and cost efficiency.\",\n",
+            "      \"explanation\": \"By setting scaling policies based on CloudWatch metrics, you can maintain application performance during traffic spikes while minimizing costs during low-traffic periods.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"What is the significance of Route 53 in designing resilient architectures?\",\n",
+            "      \"back\": \"Amazon Route 53 is a scalable Domain Name System (DNS) web service that provides highly reliable and cost-effective domain registration, DNS routing, and health checking.\",\n",
+            "      \"explanation\": \"Route 53 can route traffic to healthy endpoints and even perform geo-routing, which helps ensure that users are directed to the closest and most responsive resources, enhancing overall application resilience.\"\n",
+            "    }\n",
+            "  ]\n",
+            "}\n"
+          ]
+        }
+      ]
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "# Usage examples\n",
+        "def run_examples():\n",
+        "    # Medical education flashcards\n",
+        "    generate_medical_flashcards(topic=\"Acute Coronary Syndromes\")\n",
+        "\n",
+        "    # Technical certification flashcards\n",
+        "    generate_technical_flashcards(certification=\"AWS Solutions Architect\", domain=\"Design Resilient Architectures\")\n",
+        "\n",
+        "if __name__ == \"__main__\":\n",
+        "    run_examples()\n"
+      ],
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "oDCCKQxGm2me",
+        "outputId": "bb686c94-fb28-493f-877f-5c1ab486c24d"
+      },
+      "execution_count": null,
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "Flashcards for Acute Coronary Syndromes:\n",
+            "\n",
+            "{\n",
+            "  \"title\": \"Acute Coronary Syndromes\",\n",
+            "  \"flashcards\": [\n",
+            "    {\n",
+            "      \"front\": \"What is Acute Coronary Syndrome (ACS)?\",\n",
+            "      \"back\": \"ACS is a term used to describe a range of conditions associated with sudden reduced blood flow to the heart.\",\n",
+            "      \"explanation\": \"This includes unstable angina, non-ST elevation myocardial infarction (NSTEMI), and ST elevation myocardial infarction (STEMI).\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"What are the classic symptoms of ACS?\",\n",
+            "      \"back\": \"Typical symptoms include chest pain or discomfort, shortness of breath, nausea, and sweating.\",\n",
+            "      \"explanation\": \"Symptoms may vary between men and women, with women often experiencing atypical symptoms.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"What is the role of troponin in diagnosing ACS?\",\n",
+            "      \"back\": \"Troponin is a cardiac biomarker that indicates myocardial injury; elevated levels suggest a heart attack.\",\n",
+            "      \"explanation\": \"Troponin tests are key in differentiating between NSTEMI and unstable angina.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"What are the ECG changes associated with STEMI?\",\n",
+            "      \"back\": \"ECG findings typically include ST-segment elevation in the leads corresponding to the affected myocardial area.\",\n",
+            "      \"explanation\": \"These changes are critical for diagnosing STEMI and guiding treatment decisions.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"What is the initial management for suspected ACS?\",\n",
+            "      \"back\": \"Initial management includes oxygen, nitroglycerin, aspirin, and morphine as needed.\",\n",
+            "      \"explanation\": \"These interventions aim to relieve pain and improve blood flow while preparing for further evaluation.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"What is the difference between NSTEMI and unstable angina?\",\n",
+            "      \"back\": \"NSTEMI is characterized by elevated troponin levels indicating myocardial injury, while unstable angina does not show elevated troponin.\",\n",
+            "      \"explanation\": \"Both conditions require urgent medical evaluation and treatment, but NSTEMI indicates more severe heart damage.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"What is the preferred reperfusion therapy for STEMI?\",\n",
+            "      \"back\": \"Primary percutaneous coronary intervention (PCI) is the preferred reperfusion therapy for STEMI.\",\n",
+            "      \"explanation\": \"If PCI cannot be performed within the optimal time frame, thrombolytic therapy may be considered.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"What are the common long-term management strategies for patients with ACS?\",\n",
+            "      \"back\": \"Long-term management includes antiplatelet therapy, beta-blockers, ACE inhibitors, statins, and lifestyle modifications.\",\n",
+            "      \"explanation\": \"These strategies aim to reduce the risk of future cardiovascular events.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"What is the significance of the TIMI score in ACS?\",\n",
+            "      \"back\": \"The TIMI score helps assess the risk of cardiac events in patients with unstable angina or NSTEMI.\",\n",
+            "      \"explanation\": \"It guides treatment decisions and helps in determining the need for invasive procedures.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"What lifestyle changes are recommended for preventing future ACS events?\",\n",
+            "      \"back\": \"Recommended changes include smoking cessation, a heart-healthy diet, regular exercise, and weight management.\",\n",
+            "      \"explanation\": \"These changes help reduce cardiovascular risk factors and improve overall heart health.\"\n",
+            "    }\n",
+            "  ]\n",
+            "}\n",
+            "Flashcards for AWS Solutions Architect - Design Resilient Architectures:\n",
+            "\n",
+            "{\n",
+            "  \"title\": \"AWS Solutions Architect - Design Resilient Architectures\",\n",
+            "  \"flashcards\": [\n",
+            "    {\n",
+            "      \"front\": \"What is High Availability (HA)?\",\n",
+            "      \"back\": \"A design approach that ensures a system is continuously operational for a long period of time.\",\n",
+            "      \"explanation\": \"HA is achieved by eliminating single points of failure and using redundant components. AWS services like ELB and Auto Scaling help implement HA.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"Define Fault Tolerance.\",\n",
+            "      \"back\": \"The ability of a system to continue operating properly in the event of the failure of some of its components.\",\n",
+            "      \"explanation\": \"Fault tolerance can be achieved through redundancy and replication in AWS, such as using multiple Availability Zones.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"What is Disaster Recovery (DR)?\",\n",
+            "      \"back\": \"A set of policies and procedures to enable the recovery of technology infrastructure after a natural or human-induced disaster.\",\n",
+            "      \"explanation\": \"AWS provides various DR strategies such as pilot light, warm standby, and multi-site, which can be implemented using services like AWS Backup and Amazon S3.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"What does the term 'Elasticity' refer to in cloud computing?\",\n",
+            "      \"back\": \"The ability of a system to automatically grow and shrink resources as needed.\",\n",
+            "      \"explanation\": \"AWS services like EC2 Auto Scaling allow applications to adapt to varying loads, ensuring efficient resource utilization.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"What are Availability Zones (AZs)?\",\n",
+            "      \"back\": \"Isolated locations within a region that provide high availability and fault tolerance.\",\n",
+            "      \"explanation\": \"AZs are crucial for building resilient architectures on AWS. Distributing instances across multiple AZs can protect against data center failures.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"What is the AWS Well-Architected Framework?\",\n",
+            "      \"back\": \"A framework that provides best practices and guidelines to help cloud architects build secure, high-performing, resilient, and efficient infrastructure.\",\n",
+            "      \"explanation\": \"It consists of five pillars: Operational Excellence, Security, Reliability, Performance Efficiency, and Cost Optimization.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"Define Load Balancing.\",\n",
+            "      \"back\": \"A method of distributing network traffic across multiple servers to ensure no single server becomes overwhelmed.\",\n",
+            "      \"explanation\": \"AWS Elastic Load Balancing (ELB) automatically distributes incoming application traffic across multiple targets, enhancing the availability of applications.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"What is Amazon Route 53?\",\n",
+            "      \"back\": \"A scalable Domain Name System (DNS) web service designed to provide highly reliable and cost-effective domain registration and DNS routing.\",\n",
+            "      \"explanation\": \"Route 53 can be used to route users to different endpoints based on latency or health checks, contributing to application resilience.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"What is a Multi-Region Architecture?\",\n",
+            "      \"back\": \"An architecture that uses multiple AWS regions to provide redundancy and failover in case one region goes down.\",\n",
+            "      \"explanation\": \"This approach can enhance the availability and durability of applications, especially critical ones requiring stringent SLAs.\"\n",
+            "    },\n",
+            "    {\n",
+            "      \"front\": \"Explain the principle of 'Infrastructure as Code' (IaC).\",\n",
+            "      \"back\": \"The practice of managing and provisioning computing infrastructure through machine-readable definition files, rather than physical hardware configuration.\",\n",
+            "      \"explanation\": \"AWS CloudFormation and Terraform are popular tools for implementing IaC, allowing for reproducible and version-controlled infrastructure deployments.\"\n",
+            "    }\n",
+            "  ]\n",
+            "}\n"
+          ]
+        }
+      ]
+    },
+    {
+      "cell_type": "code",
+      "source": [],
+      "metadata": {
+        "id": "zr1ncUC_nBTT"
+      },
+      "execution_count": null,
+      "outputs": []
+    }
+  ]
+}
\ No newline at end of file
diff --git a/educhain/engines/content_engine.py b/educhain/engines/content_engine.py
index 3a87b9d..de4ca0a 100644
--- a/educhain/engines/content_engine.py
+++ b/educhain/engines/content_engine.py
@@ -5,7 +5,12 @@
 from langchain.chains import LLMChain
 from langchain.output_parsers import PydanticOutputParser
 from educhain.core.config import LLMConfig
+
+from educhain.models.content_models import StudyGuide, CareerConnections
+import json
 from educhain.models.content_models import LessonPlan
+from educhain.models.content_models import FlashcardSet 
+
 
 class ContentEngine:
     def __init__(self, llm_config: Optional[LLMConfig] = None):
@@ -26,6 +31,7 @@ def _initialize_llm(self, llm_config: LLMConfig):
                 default_headers=llm_config.default_headers
             )
 
+    # Lesson Plan
     def generate_lesson_plan(
         self,
         topic: str,
@@ -34,6 +40,7 @@ def generate_lesson_plan(
         custom_instructions: Optional[str] = None,
         response_model: Optional[Type[Any]] = None,
         llm: Optional[Any] = None,
+        output_format: Optional[str] = None,
         **kwargs
     ) -> Any:
         if response_model is None:
@@ -103,9 +110,365 @@ def generate_lesson_plan(
         try:
             # Parse results to match the new LessonPlan structure
             structured_output = parser.parse(results)
+
+            return structured_output
+        except Exception as e:
+            print(f"Error parsing output: {e}")
+            print("Raw output:")
+            print(results)
+            return response_model()
+        
+    # Study Guide
+    def generate_study_guide(
+        self,
+        topic: str,
+        difficulty_level: Optional[str] = None,
+        prompt_template: Optional[str] = None,
+        custom_instructions: Optional[str] = None,
+        response_model: Optional[Type[Any]] = None,
+        llm: Optional[Any] = None,
+        output_format: Optional[str] = None,
+        **kwargs
+    ) -> Any:
+        if response_model is None:
+            response_model = StudyGuide
+
+        parser = PydanticOutputParser(pydantic_object=response_model)
+        format_instructions = parser.get_format_instructions()
+
+        if prompt_template is None:
+            prompt_template = """
+            Create a comprehensive study guide for the following topic:
+            Topic: {topic}
+            Difficulty Level: {difficulty_level}
+
+            The study guide should be engaging, well-structured, and suitable for self-study or classroom use.
+            Include the following elements in your response:
+
+            1. Difficulty level and estimated study time
+            2. Prerequisites (if any)
+            3. Clear learning objectives (3-5 specific, measurable objectives)
+            4. Comprehensive overview of the topic
+            5. Key concepts with detailed explanations
+            6. Important dates and events (if applicable)
+            8. Practice exercises formatted as:
+            "practice_exercises": [
+                {{
+                    "title": "Exercise Title",
+                    "problem": "Detailed problem description",
+                    "solution": "Step-by-step solution",
+                    "difficulty": "beginner|intermediate|advanced"
+                }}
+            ]
+            9. Real-world case studies formatted as:
+            "case_studies": [
+                {{
+                    "title": "Case Study Title",
+                    "scenario": "Description of the real-world situation",
+                    "challenge": "Specific problems or challenges faced",
+                    "solution": "How the challenges were addressed",
+                    "outcome": "Results and impact",
+                    "lessons_learned": ["Key lesson 1", "Key lesson 2"],
+                    "related_concepts": ["Concept 1", "Concept 2"]
+                }}
+            ]
+            10. Study tips and strategies specific to the topic
+            11. Additional resources for deeper learning
+            12. Brief summary of key takeaways
+
+            For the case studies:
+            - Include at least one detailed real-world example
+            - Focus on recent and relevant scenarios
+            - Highlight practical applications of the concepts
+            - Connect the case study to specific learning objectives
+            - Emphasize problem-solving approaches
+            - Include both successes and lessons learned
+            - Make sure the examples are appropriate for the difficulty level
+
+            Make sure all content is hands-on and directly related to real-world applications of {topic}.
+            The study guide should accommodate different learning styles and include various types of learning activities.
+            """
+
+        if custom_instructions:
+            prompt_template += f"\n\nAdditional Instructions:\n{custom_instructions}"
+
+        prompt_template += "\n\nThe response should be in JSON format.\n{format_instructions}"
+
+        study_guide_prompt = PromptTemplate(
+            input_variables=["topic", "difficulty_level"],
+            template=prompt_template,
+            partial_variables={"format_instructions": format_instructions}
+        )
+
+        llm_to_use = llm if llm is not None else self.llm
+
+        study_guide_chain = study_guide_prompt | llm_to_use
+        results = study_guide_chain.invoke(
+            {
+                "topic": topic,
+                "difficulty_level": difficulty_level or "Intermediate",
+                **kwargs
+            },
+        )
+        results = results.content
+
+        try:
+            # Handle empty practice exercises
+            if '"practice_exercises": []' in results or '"practice_exercises":[]' in results:
+                results = results.replace(
+                    '"practice_exercises": []',
+                    '"practice_exercises": [{"title": "Basic Exercise", "problem": "No exercises provided", "solution": "N/A", "difficulty": "beginner"}]'
+                )
+                
+            # Handle empty case studies
+            if '"case_studies": []' in results or '"case_studies":[]' in results:
+                results = results.replace(
+                    '"case_studies": []',
+                    '"case_studies": [{"title": "Sample Case", "scenario": "No case studies provided", "challenge": "N/A", "solution": "N/A", "outcome": "N/A", "lessons_learned": ["N/A"], "related_concepts": ["N/A"]}]'
+                )
+
+            # Parse results to match the new LessonPlan structure
+            structured_output = parser.parse(results)
+
             return structured_output
         except Exception as e:
             print(f"Error parsing output: {e}")
             print("Raw output:")
             print(results)
-            return response_model()
\ No newline at end of file
+            # Return an instance with default values including case studies
+            return response_model(
+                topic=topic,
+                overview="Error generating content",
+                key_concepts={"Basic Concept": "Error generating concepts"},
+                example_questions=[{"question": "Error generating questions", "answer": "N/A", "difficulty": "beginner"}],
+                practice_exercises=[{
+                    "title": "Basic Exercise",
+                    "problem": "Error generating exercises",
+                    "solution": "N/A",
+                    "difficulty": "beginner"
+                }],
+                case_studies=[{
+                    "title": "Sample Case",
+                    "scenario": "Error generating case studies",
+                    "challenge": "N/A",
+                    "solution": "N/A",
+                    "outcome": "N/A",
+                    "lessons_learned": ["N/A"],
+                    "related_concepts": ["N/A"]
+                }]
+            )
+        
+    # Carrer connections
+    def generate_career_connections(
+        self,
+        topic: str,
+        industry_focus: Optional[str] = None,
+        prompt_template: Optional[str] = None,
+        custom_instructions: Optional[str] = None,
+        response_model: Optional[Type[Any]] = None,
+        llm: Optional[Any] = None,
+        output_format: Optional[str] = None,
+        **kwargs
+    ) -> Any:
+        """
+        Generates connections between academic topics and real-world careers,
+        including insights from professionals in the field.
+        """
+        if response_model is None:
+            response_model = CareerConnections
+
+        parser = PydanticOutputParser(pydantic_object=response_model)
+        format_instructions = parser.get_format_instructions()
+
+        if prompt_template is None:
+            prompt_template = """
+            Create comprehensive career connections for the following academic topic:
+            Topic: {topic}
+            Industry Focus: {industry_focus}
+
+            Generate detailed information about how this topic connects to real-world careers and professional opportunities.
+            Include:
+
+            1. Industry Overview
+            - Current state of the industry
+            - Future outlook
+            - Key trends and developments
+
+            2. Career Paths formatted as:
+            "career_paths": [
+                {{
+                    "title": "Job Title",
+                    "description": "Role description",
+                    "typical_responsibilities": ["responsibility1", "responsibility2"],
+                    "required_education": "Education requirements",
+                    "salary_range": "Typical salary range",
+                    "growth_potential": "Career growth opportunities",
+                    "topic_application": "How this topic is used in the role"
+                }}
+            ]
+
+            3. Professional Insights formatted as:
+            "professional_insights": [
+                {{
+                    "role": "Professional's role",
+                    "experience_level": "Years of experience",
+                    "key_insights": ["insight1", "insight2"],
+                    "daily_applications": ["application1", "application2"],
+                    "advice_for_students": ["advice1", "advice2"]
+                }}
+            ]
+
+            4. Required Skills
+            - Technical skills
+            - Soft skills
+            - Industry-specific skills
+            - Future skills needed
+
+            5. Preparation Steps
+            - Educational pathways
+            - Certifications
+            - Experience building
+            - Networking opportunities
+
+            6. Resources
+            - Professional organizations
+            - Learning platforms
+            - Industry publications
+            - Networking opportunities
+
+            Make sure to:
+            - Focus on current and emerging career opportunities
+            - Include both traditional and non-traditional career paths
+            - Highlight the practical applications of the topic
+            - Provide actionable steps for students
+            - Include diverse perspectives and roles
+
+            Response format:
+            {format_instructions}
+            """
+
+        if custom_instructions:
+            prompt_template += f"\n\nAdditional Instructions:\n{custom_instructions}"
+
+        prompt = PromptTemplate(
+            input_variables=["topic", "industry_focus"],
+            template=prompt_template,
+            partial_variables={"format_instructions": format_instructions}
+        )
+
+        llm_to_use = llm if llm is not None else self.llm
+        
+        career_chain = prompt | llm_to_use
+        results = career_chain.invoke(
+            {
+                "topic": topic,
+                "industry_focus": industry_focus or "General",
+                **kwargs
+            },
+        )
+        results = results.content
+
+        try:
+            # Parse results to match the new LessonPlan structure
+            structured_output = parser.parse(results)
+            
+            return structured_output
+        except Exception as e:
+            print(f"Error parsing output: {e}")
+            print("Raw output:")
+            print(results)
+            return response_model(
+                topic=topic,
+                industry_overview="Error generating content",
+                career_paths=[{
+                    "title": "Sample Career",
+                    "description": "Error generating career paths",
+                    "typical_responsibilities": ["N/A"],
+                    "required_education": "N/A",
+                    "salary_range": "N/A",
+                    "growth_potential": "N/A",
+                    "topic_application": "N/A"
+                }],
+                required_skills={
+                    "technical": ["Error generating skills"],
+                    "soft": ["Error generating skills"]
+                },
+                industry_trends=["Error generating trends"],
+                professional_insights=[{
+                    "role": "Sample Professional",
+                    "experience_level": "N/A",
+                    "key_insights": ["Error generating insights"],
+                    "daily_applications": ["N/A"],
+                    "advice_for_students": ["N/A"]
+                }],
+                preparation_steps={
+                    "education": ["Error generating steps"],
+                    "experience": ["Error generating steps"]
+                },
+                resources=[{
+                    "name": "Sample Resource",
+                    "url": "N/A"
+                }]
+            )
+          
+            return response_model()
+    
+    def generate_flashcards(
+        self,
+        topic: str,
+        num: int = 10,
+        prompt_template: Optional[str] = None,
+        custom_instructions: Optional[str] = None,
+        response_model: Optional[Type[Any]] = None,
+        llm: Optional[Any] = None,
+        **kwargs
+    ) -> FlashcardSet:
+        if response_model is None:
+            response_model = FlashcardSet
+        parser = PydanticOutputParser(pydantic_object=response_model)
+        format_instructions = parser.get_format_instructions()
+
+        if prompt_template is None:
+            prompt_template = """
+            Generate a set of {num} flashcards on the topic: {topic}.
+
+            For each flashcard, provide:
+            1. A front side with a question or key term
+            2. A back side with the answer or definition
+            3. An optional explanation or additional context
+
+            The flashcards should cover key concepts, terminology, and important facts related to the topic.
+
+            Ensure that the output follows this structure:
+            - A title for the flashcard set (the main topic)
+            - A list of flashcards, each containing:
+              - front: The question or key term
+              - back: The answer or definition
+              - explanation: Additional context or explanation (optional)
+            """
+
+        if custom_instructions:
+            prompt_template += f"\n\nAdditional Instructions:\n{custom_instructions}"
+
+        prompt_template += "\n\nThe response should be in JSON format.\n{format_instructions}"
+
+        flashcard_prompt = PromptTemplate(
+            input_variables=["num", "topic"],
+            template=prompt_template,
+            partial_variables={"format_instructions": format_instructions}
+        )
+
+        llm_to_use = llm if llm is not None else self.llm
+        flashcard_chain = flashcard_prompt | llm_to_use
+        results = flashcard_chain.invoke(
+            {"num": num, "topic": topic, **kwargs},
+        )
+
+        try:
+            structured_output = parser.parse(results.content)
+            return structured_output
+        except Exception as e:
+            print(f"Error parsing output: {e}")
+            print("Raw output:")
+            print(results.content)
+            return FlashcardSet(title=topic, flashcards=[])
diff --git a/educhain/engines/qna_engine.py b/educhain/engines/qna_engine.py
index 8ddaf21..e578515 100644
--- a/educhain/engines/qna_engine.py
+++ b/educhain/engines/qna_engine.py
@@ -1,6 +1,6 @@
 # educhain/engines/qna_engine.py
 
-from typing import Optional, Type, Any, List, Literal
+from typing import Optional, Type, Any, List, Literal, Union, Tuple
 from pydantic import BaseModel
 from langchain_openai import ChatOpenAI, OpenAIEmbeddings
 from langchain.prompts import PromptTemplate
@@ -16,10 +16,14 @@
     FillInBlankQuestionList, MCQListMath, Option
 )
 from educhain.utils.loaders import PdfFileLoader, UrlLoader
+from educhain.utils.output_formatter import OutputFormatter
+
+# Update the QuestionType definition
 
 import random
 
 QuestionType = Literal["Multiple Choice", "Short Answer", "True/False", "Fill in the Blank"]
+OutputFormatType = Literal["pdf", "csv"]
 
 class QnAEngine:
     def __init__(self, llm_config: Optional[LLMConfig] = None):
@@ -111,6 +115,21 @@ def _load_data(self, source: str, source_type: str) -> str:
             return source
         else:
             raise ValueError("Unsupported source type. Please use 'pdf', 'url', or 'text'.")
+        
+    def _handle_output_format(self, data: Any, output_format: Optional[OutputFormatType]) -> Union[Any, Tuple[Any, str]]:
+        """Handle output format conversion if specified"""
+        if output_format is None:
+            return data
+            
+        formatter = OutputFormatter()
+        if output_format == "pdf":
+            output_file = formatter.to_pdf(data)
+        elif output_format == "csv":
+            output_file = formatter.to_csv(data)
+        else:
+            raise ValueError(f"Unsupported output format: {output_format}")
+            
+        return data, output_file
 
     def generate_questions(
         self,
@@ -120,6 +139,7 @@ def generate_questions(
         prompt_template: Optional[str] = None,
         custom_instructions: Optional[str] = None,
         response_model: Optional[Type[Any]] = None,
+        output_format: Optional[OutputFormatType] = None,
         **kwargs
     ) -> Any:
         parser, model = self._get_parser_and_model(question_type, response_model)
@@ -157,6 +177,10 @@ def generate_questions(
 
         try:
             structured_output = parser.parse(results)
+
+            if output_format:
+                self._handle_output_format(structured_output, output_format)
+                
             return structured_output
         except Exception as e:
             print(f"Error parsing output: {e}")
@@ -173,6 +197,7 @@ def generate_questions_from_data(
         prompt_template: Optional[str] = None,
         custom_instructions: Optional[str] = None,
         response_model: Optional[Type[Any]] = None,
+        output_format: Optional[OutputFormatType] = None,
         **kwargs
     ) -> Any:
         content = self._load_data(source, source_type)
@@ -197,6 +222,7 @@ def generate_questions_with_rag(
         response_model: Optional[Type[Any]] = None,
         learning_objective: str = "",
         difficulty_level: str = "",
+        output_format: Optional[OutputFormatType] = None,
         **kwargs
     ) -> Any:
         # Initialize embeddings only when this method is called
@@ -244,7 +270,12 @@ def generate_questions_with_rag(
         results = qa_chain.invoke({"query": query, "n_results": 3})
 
         try:
-            return parser.parse(results["result"])
+            structured_output = parser.parse(results["result"])
+
+            if output_format:
+                self._handle_output_format(structured_output, output_format)
+            
+            return structured_output
         except Exception as e:
             print(f"Error parsing output: {e}")
             print("Raw output:", results)
@@ -264,6 +295,7 @@ def generate_mcq_math(
         prompt_template: Optional[str] = None,
         custom_instructions: Optional[str] = None,
         response_model: Optional[Type[Any]] = None,
+        output_format: Optional[OutputFormatType] = None,
         **kwargs
     ) -> Any:
 
@@ -333,4 +365,7 @@ def generate_mcq_math(
                 except Exception as e:
                     print(f"LLMMathChain failed to answer: {str(e)}")
 
+        if output_format:
+                self._handle_output_format(structured_output, output_format)
+
         return structured_output
\ No newline at end of file
diff --git a/educhain/models/__init__.py b/educhain/models/__init__.py
index 8f0affe..431642d 100644
--- a/educhain/models/__init__.py
+++ b/educhain/models/__init__.py
@@ -3,4 +3,4 @@
                          TrueFalseQuestion, FillInBlankQuestion, MCQList, 
                          ShortAnswerQuestionList, TrueFalseQuestionList, 
                          FillInBlankQuestionList, Option, MCQMath, MCQListMath)
-from .content_models import ContentElement, SubTopic, MainTopic, LessonPlan
\ No newline at end of file
+from .content_models import ContentElement, SubTopic, MainTopic, LessonPlan,Flashcard, FlashcardSet
diff --git a/educhain/models/content_models.py b/educhain/models/content_models.py
index 01f7fd0..600b13e 100644
--- a/educhain/models/content_models.py
+++ b/educhain/models/content_models.py
@@ -1,5 +1,7 @@
-from typing import List, Optional
+from typing import Optional, Type, Any ,List, Dict
 from pydantic import BaseModel, Field
+from rich.console import Console
+from rich.markdown import Markdown
 
 class ContentElement(BaseModel):
     type: str = Field(..., description="The type of content element (e.g., definition, example, activity).")
@@ -73,6 +75,345 @@ def show(self):
                 for assessment in subtopic.assessment_ideas:
                     print(f"      - {assessment.type.capitalize()}: {assessment.description}")
 
+        print("\n" + "=" * 80)
+
+
+class Flashcard(BaseModel):
+    front: str = Field(..., description="The front side of the flashcard with a question or key term")
+    back: str = Field(..., description="The back side of the flashcard with the answer or definition")
+    explanation: Optional[str] = Field(None, description="An optional explanation or additional context")
+
+class FlashcardSet(BaseModel):
+    title: str = Field(..., description="The title or topic of the flashcard set")
+    flashcards: List[Flashcard] = Field(..., description="A list of flashcards in this set")
+
+    def show(self):
+        print("=" * 80)
+        print(f"Flashcard Set: {self.title}")
+        print("=" * 80)
+        for i, flashcard in enumerate(self.flashcards, 1):
+            print(f"\n{i}. Front: {flashcard.front}")
+            print(f"   Back: {flashcard.back}")
+            if flashcard.explanation:
+                print(f"   Explanation: {flashcard.explanation}")
+        print("\n" + "=" * 80)
         print("\nLearning Adaptations: ", self.learning_adaptations or "None")
         print("Real-World Applications: ", self.real_world_applications or "None")
-        print("Ethical Considerations: ", self.ethical_considerations or "None")
\ No newline at end of file
+        print("Ethical Considerations: ", self.ethical_considerations or "None")
+
+class CaseStudy(BaseModel):
+    title: str
+    scenario: str
+    challenge: str
+    solution: str
+    outcome: str
+    lessons_learned: List[str]
+    related_concepts: List[str]
+
+class StudyGuide(BaseModel):
+    topic: str
+    difficulty_level: Optional[str] = Field(None, description="Difficulty level of the study material (e.g., Beginner, Intermediate, Advanced)")
+    estimated_study_time: Optional[str] = Field(None, description="Estimated time needed to cover the material")
+    prerequisites: Optional[List[str]] = Field(default_factory=list, description="Required prerequisite knowledge")
+    learning_objectives: List[str] = Field(default_factory=list, description="Specific learning objectives for the study guide")
+    overview: str
+    key_concepts: Dict[str, str] = Field(
+        default_factory=dict,
+        description="Dictionary mapping concept names to their detailed explanations"
+    )
+    important_dates: Optional[Dict[str, str]] = Field(
+        None,
+        description="Dictionary mapping dates to their significance"
+    )
+    practice_exercises: Optional[List[Dict[str, Any]]] = Field(
+        None,
+        description="List of practice exercises with solutions"
+    )
+    case_studies: Optional[List[CaseStudy]] = Field(
+        None,
+        description="Real-world case studies demonstrating practical applications"
+    )
+    study_tips: Optional[List[str]] = Field(
+        None,
+        description="Study strategies specific to this topic"
+    )
+    additional_resources: Optional[Dict[str, str]] = Field(
+        None,
+        description="Dictionary mapping resource names to their descriptions/URLs"
+    )
+    summary: Optional[str] = Field(None, description="Brief summary of key takeaways")
+
+    def show(self, format: str = "text"):
+        """
+        Display the study guide in various formats.
+        
+        Args:
+            format (str): Output format - "text", "markdown", or "rich"
+        """
+        if format == "markdown":
+            return self._generate_markdown()
+        elif format == "rich":
+            console = Console()
+            console.print(Markdown(self._generate_markdown()))
+        else:
+            self._print_text_format()
+
+    def _generate_markdown(self) -> str:
+        """Generate a markdown representation of the study guide."""
+        md = [f"# Study Guide: {self.topic}\n"]
+        
+        if self.difficulty_level:
+            md.append(f"**Difficulty Level:** {self.difficulty_level}")
+        if self.estimated_study_time:
+            md.append(f"**Estimated Study Time:** {self.estimated_study_time}\n")
+            
+        if self.prerequisites:
+            md.append("## Prerequisites")
+            for prereq in self.prerequisites:
+                md.append(f"- {prereq}")
+            md.append("")
+            
+        md.append("## Learning Objectives")
+        for obj in self.learning_objectives:
+            md.append(f"- {obj}")
+        md.append("")
+            
+        md.append("## Overview")
+        md.append(f"{self.overview}\n")
+        
+        md.append("## Key Concepts")
+        for concept, explanation in self.key_concepts.items():
+            md.append(f"### {concept}")
+            md.append(f"{explanation}\n")
+            
+        if self.important_dates:
+            md.append("## Important Dates")
+            for date, significance in self.important_dates.items():
+                md.append(f"- **{date}**: {significance}")
+            md.append("")
+            
+        if self.practice_exercises:
+            md.append("## Practice Exercises")
+            for i, exercise in enumerate(self.practice_exercises, 1):
+                md.append(f"### Exercise {i}")
+                md.append(f"**Problem:** {exercise['problem']}")
+                md.append(f"**Solution:** {exercise['solution']}\n")
+
+        if self.case_studies:
+            md.append("## Real-World Case Studies")
+            for i, case in enumerate(self.case_studies, 1):
+                md.append(f"### Case Study {i}: {case.title}")
+                md.append(f"**Scenario:** {case.scenario}")
+                md.append(f"**Challenge:** {case.challenge}")
+                md.append(f"**Solution:** {case.solution}")
+                md.append(f"**Outcome:** {case.outcome}")
+                md.append("\n**Key Lessons Learned:**")
+                for lesson in case.lessons_learned:
+                    md.append(f"- {lesson}")
+                md.append("\n**Related Concepts:**")
+                for concept in case.related_concepts:
+                    md.append(f"- {concept}")
+                md.append("")
+                
+        if self.study_tips:
+            md.append("## Study Tips")
+            for tip in self.study_tips:
+                md.append(f"- {tip}")
+            md.append("")
+            
+        if self.additional_resources:
+            md.append("## Additional Resources")
+            for resource, description in self.additional_resources.items():
+                md.append(f"- **{resource}**: {description}")
+            md.append("")
+            
+        if self.summary:
+            md.append("## Summary")
+            md.append(self.summary)
+            
+        return "\n".join(md)
+
+    def _print_text_format(self):
+        """Print the study guide in plain text format."""
+        print(f"=== Study Guide: {self.topic} ===\n")
+        
+        if self.difficulty_level:
+            print(f"Difficulty Level: {self.difficulty_level}")
+        if self.estimated_study_time:
+            print(f"Estimated Study Time: {self.estimated_study_time}\n")
+            
+        if self.prerequisites:
+            print("Prerequisites:")
+            for prereq in self.prerequisites:
+                print(f"- {prereq}")
+            print()
+            
+        print("Learning Objectives:")
+        for obj in self.learning_objectives:
+            print(f"- {obj}")
+        print()
+            
+        print(f"Overview:\n{self.overview}\n")
+        
+        print("Key Concepts:")
+        for concept, explanation in self.key_concepts.items():
+            print(f"\n{concept}:")
+            print(f"{explanation}")
+            
+        if self.important_dates:
+            print("\nImportant Dates:")
+            for date, significance in self.important_dates.items():
+                print(f"- {date}: {significance}")
+            
+        if self.practice_exercises:
+            print("\nPractice Exercises:")
+            for i, exercise in enumerate(self.practice_exercises, 1):
+                print(f"\nExercise {i}:")
+                print(f"Problem: {exercise['problem']}")
+                print(f"Solution: {exercise['solution']}")
+
+        if self.case_studies:
+            print("\nReal-World Case Studies:")
+            for i, case in enumerate(self.case_studies, 1):
+                print(f"\nCase Study {i}: {case.title}")
+                print(f"Scenario: {case.scenario}")
+                print(f"Challenge: {case.challenge}")
+                print(f"Solution: {case.solution}")
+                print(f"Outcome: {case.outcome}")
+                print("\nKey Lessons Learned:")
+                for lesson in case.lessons_learned:
+                    print(f"- {lesson}")
+                print("\nRelated Concepts:")
+                for concept in case.related_concepts:
+                    print(f"- {concept}")
+                print("-" * 50)
+                
+        if self.study_tips:
+            print("\nStudy Tips:")
+            for tip in self.study_tips:
+                print(f"- {tip}")
+                
+        if self.additional_resources:
+            print("\nAdditional Resources:")
+            for resource, description in self.additional_resources.items():
+                print(f"- {resource}: {description}")
+                
+        if self.summary:
+            print(f"\nSummary:\n{self.summary}")
+
+# Carrer Connection
+class Skill(BaseModel):
+    name: str = Field(..., description="Name of the skill")
+    description: str = Field(..., description="Detailed description of the skill")
+    importance_level: str = Field(..., description="How important this skill is for the career (Essential/Important/Helpful)")
+    acquisition_methods: List[str] = Field(..., description="Ways to acquire or develop this skill")
+
+class CareerPath(BaseModel):
+    title: str = Field(..., description="Job title or role name")
+    description: str = Field(..., description="Detailed description of the career path")
+    typical_responsibilities: List[str] = Field(..., description="List of typical job responsibilities")
+    required_education: str = Field(..., description="Required educational qualifications")
+    salary_range: str = Field(..., description="Typical salary range for this role")
+    growth_potential: str = Field(..., description="Career growth and advancement opportunities")
+    topic_application: str = Field(..., description="How the academic topic is applied in this role")
+    required_skills: List[Skill] = Field(..., description="Skills required for this career path")
+
+class ProfessionalInsight(BaseModel):
+    role: str = Field(..., description="Professional's current role")
+    experience_level: str = Field(..., description="Years of experience in the field")
+    company_type: str = Field(..., description="Type of company or industry sector")
+    key_insights: List[str] = Field(..., description="Key insights about the career path")
+    daily_applications: List[str] = Field(..., description="How they apply the topic in daily work")
+    advice_for_students: List[str] = Field(..., description="Professional advice for students")
+    career_journey: str = Field(..., description="Brief description of their career journey")
+
+class IndustryTrend(BaseModel):
+    name: str = Field(..., description="Name of the trend")
+    description: str = Field(..., description="Detailed description of the trend")
+    impact: str = Field(..., description="Expected impact on the industry")
+    timeframe: str = Field(..., description="Expected timeframe for this trend")
+    related_skills: List[str] = Field(..., description="Skills related to this trend")
+
+class Resource(BaseModel):
+    name: str = Field(..., description="Name of the resource")
+    type: str = Field(..., description="Type of resource (Organization/Platform/Publication)")
+    description: str = Field(..., description="Description of the resource")
+    url: Optional[str] = Field(None, description="URL for the resource if applicable")
+    cost: Optional[str] = Field(None, description="Cost information if applicable")
+
+class PreparationPath(BaseModel):
+    stage: str = Field(..., description="Stage of preparation (e.g., Education, Early Career)")
+    requirements: List[str] = Field(..., description="Requirements for this stage")
+    duration: str = Field(..., description="Expected duration of this stage")
+    milestones: List[str] = Field(..., description="Key milestones to achieve")
+    resources_needed: List[str] = Field(..., description="Resources needed for this stage")
+
+class CareerConnections(BaseModel):
+    topic: str = Field(..., description="The academic topic being connected to careers")
+    industry_overview: str = Field(..., description="Overview of the industry landscape")
+    career_paths: List[CareerPath] = Field(..., description="Detailed career paths related to the topic")
+    industry_trends: List[IndustryTrend] = Field(..., description="Current and emerging industry trends")
+    professional_insights: List[ProfessionalInsight] = Field(..., description="Insights from industry professionals")
+    preparation_paths: List[PreparationPath] = Field(..., description="Steps to prepare for these careers")
+    resources: List[Resource] = Field(..., description="Useful resources for career preparation")
+    skill_categories: Dict[str, List[Skill]] = Field(..., description="Categorized skills required across careers")
+
+    def show(self):
+        print("=" * 80)
+        print(f"Career Connections: {self.topic}")
+        print("=" * 80)
+        print("\nIndustry Overview:")
+        print(self.industry_overview)
+        
+        print("\nCareer Paths:")
+        for i, path in enumerate(self.career_paths, 1):
+            print(f"\n{i}. {path.title}")
+            print(f"   Description: {path.description}")
+            print("   Responsibilities:")
+            for resp in path.typical_responsibilities:
+                print(f"   - {resp}")
+            print(f"   Education: {path.required_education}")
+            print(f"   Salary Range: {path.salary_range}")
+            print(f"   Growth Potential: {path.growth_potential}")
+            print("   Required Skills:")
+            for skill in path.required_skills:
+                print(f"   - {skill.name} ({skill.importance_level})")
+
+        print("\nIndustry Trends:")
+        for trend in self.industry_trends:
+            print(f"\n- {trend.name}")
+            print(f"  Impact: {trend.impact}")
+            print(f"  Timeframe: {trend.timeframe}")
+
+        print("\nProfessional Insights:")
+        for insight in self.professional_insights:
+            print(f"\nFrom {insight.role} ({insight.experience_level})")
+            print("Key Insights:")
+            for key_insight in insight.key_insights:
+                print(f"- {key_insight}")
+            print("Advice for Students:")
+            for advice in insight.advice_for_students:
+                print(f"- {advice}")
+
+        print("\nPreparation Paths:")
+        for path in self.preparation_paths:
+            print(f"\n{path.stage}")
+            print("Requirements:")
+            for req in path.requirements:
+                print(f"- {req}")
+            print(f"Duration: {path.duration}")
+
+        print("\nResources:")
+        for resource in self.resources:
+            print(f"\n- {resource.name} ({resource.type})")
+            print(f"  Description: {resource.description}")
+            if resource.url:
+                print(f"  URL: {resource.url}")
+            if resource.cost:
+                print(f"  Cost: {resource.cost}")
+
+        print("\nSkill Categories:")
+        for category, skills in self.skill_categories.items():
+            print(f"\n{category}:")
+            for skill in skills:
+                print(f"- {skill.name}: {skill.description}")
diff --git a/educhain/utils/output_formatter.py b/educhain/utils/output_formatter.py
new file mode 100644
index 0000000..3b9073f
--- /dev/null
+++ b/educhain/utils/output_formatter.py
@@ -0,0 +1,166 @@
+# educhain/utils/output_formatter.py
+
+from typing import Any, Optional, List, Dict
+import pandas as pd
+from reportlab.lib import colors
+from reportlab.lib.pagesizes import letter
+from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
+from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle
+from reportlab.pdfbase import pdfmetrics
+from reportlab.pdfbase.ttfonts import TTFont
+import json
+from datetime import datetime
+
+class OutputFormatter:
+    @staticmethod
+    def _convert_to_dict_list(data: Any) -> List[Dict]:
+        """Convert Pydantic model data to a list of dictionaries"""
+        if hasattr(data, 'questions'):
+            # If it's a question list model
+            return [q.dict() for q in data.questions]
+        elif isinstance(data, list):
+            # If it's already a list
+            return [item.dict() if hasattr(item, 'dict') else item for item in data]
+        else:
+            # Single item
+            return [data.dict() if hasattr(data, 'dict') else data]
+
+    @staticmethod
+    def to_csv(data: Any, filename: Optional[str] = None) -> str:
+        """Convert data to CSV format"""
+        if filename is None:
+            filename = f"questions_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv"
+        
+        dict_list = OutputFormatter._convert_to_dict_list(data)
+        df = pd.DataFrame(dict_list)
+        
+        # Handle nested structures (like options in MCQs)
+        for col in df.columns:
+            if isinstance(df[col].iloc[0], (list, dict)):
+                df[col] = df[col].apply(json.dumps)
+        
+        df.to_csv(filename, index=False)
+        return filename
+
+    @staticmethod
+    def _format_question(question: Dict, styles: Dict) -> List:
+        """Format a single question for PDF output"""
+        elements = []
+        
+        # Question number and text
+        question_text = Paragraph(f"Q{question.get('id', '')}: {question.get('question', '')}", 
+                                styles['Question'])
+        elements.append(question_text)
+        elements.append(Spacer(1, 12))
+
+        # Options (if present)
+        if 'options' in question:
+            options = question['options']
+            if isinstance(options, str):
+                try:
+                    options = json.loads(options)
+                except:
+                    options = [options]
+                    
+            for i, opt in enumerate(options):
+                if isinstance(opt, dict):
+                    opt_text = opt.get('text', '')
+                    is_correct = opt.get('correct', 'false') == 'true'
+                else:
+                    opt_text = str(opt)
+                    is_correct = False
+                
+                option_style = styles['CorrectOption'] if is_correct else styles['Option']
+                option_text = Paragraph(f"{chr(65+i)}. {opt_text}", option_style)
+                elements.append(option_text)
+                elements.append(Spacer(1, 6))
+
+        # Correct Answer (if not MCQ)
+        if 'answer' in question:
+            answer_text = Paragraph(f"Correct Answer: {question['answer']}", 
+                                  styles['CorrectAnswer'])
+            elements.append(answer_text)
+            elements.append(Spacer(1, 6))
+
+        # Explanation
+        if question.get('explanation'):
+            explanation_text = Paragraph(f"Explanation: {question['explanation']}", 
+                                      styles['Explanation'])
+            elements.append(explanation_text)
+            
+        elements.append(Spacer(1, 20))
+        return elements
+
+    @staticmethod
+    def to_pdf(data: Any, filename: Optional[str] = None) -> str:
+        """Convert data to PDF format using ReportLab"""
+        if filename is None:
+            filename = f"questions_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf"
+
+        # Create the PDF document
+        doc = SimpleDocTemplate(
+            filename,
+            pagesize=letter,
+            rightMargin=72,
+            leftMargin=72,
+            topMargin=72,
+            bottomMargin=72
+        )
+
+        # Define styles
+        styles = getSampleStyleSheet()
+        styles.add(ParagraphStyle(
+            name='Question',
+            parent=styles['Normal'],
+            fontSize=12,
+            spaceAfter=6,
+            fontName='Helvetica-Bold'
+        ))
+        styles.add(ParagraphStyle(
+            name='Option',
+            parent=styles['Normal'],
+            fontSize=11,
+            leftIndent=20,
+            fontName='Helvetica'
+        ))
+        styles.add(ParagraphStyle(
+            name='CorrectOption',
+            parent=styles['Normal'],
+            fontSize=11,
+            leftIndent=20,
+            textColor=colors.green,
+            fontName='Helvetica-Bold'
+        ))
+        styles.add(ParagraphStyle(
+            name='CorrectAnswer',
+            parent=styles['Normal'],
+            fontSize=11,
+            textColor=colors.green,
+            fontName='Helvetica-Bold'
+        ))
+        styles.add(ParagraphStyle(
+            name='Explanation',
+            parent=styles['Normal'],
+            fontSize=10,
+            leftIndent=20,
+            textColor=colors.gray,
+            fontName='Helvetica-Oblique'
+        ))
+
+        # Build the document content
+        elements = []
+        
+        # Add title
+        title = Paragraph("Generated Questions", styles['Title'])
+        elements.append(title)
+        elements.append(Spacer(1, 30))
+
+        # Process questions
+        dict_list = OutputFormatter._convert_to_dict_list(data)
+        for i, question in enumerate(dict_list, 1):
+            question['id'] = i
+            elements.extend(OutputFormatter._format_question(question, styles))
+
+        # Generate the PDF
+        doc.build(elements)
+        return filename
\ No newline at end of file
diff --git a/setup.py b/setup.py
index c43ee13..7cb29cc 100644
--- a/setup.py
+++ b/setup.py
@@ -5,19 +5,19 @@
     version="0.3.2",
     packages=find_packages(),
     install_requires=[
-        "langchain",
-        "langchain-community",
-        "langchain-openai",
-        "openai",
-        "python-dotenv", 
-        "pandas",
-        "reportlab",
-        "PyPDF2",
-        "beautifulsoup4",
-        "youtube_transcript_api",
-        "pydantic",
-        "requests",
-        "chromadb",
+        "langchain==0.3.4",
+        "langchain-community==0.3.3",
+        "langchain-openai==0.2.3",
+        "openai==1.52.2",
+        "python-dotenv==1.0.1", 
+        "pandas==2.2.3",
+        "reportlab==4.2.5",
+        "PyPDF2==5.1.0",
+        "beautifulsoup4==3.2.2",
+        "youtube_transcript_api==0.6.2",
+        "pydantic==2.9.2",
+        "requests==2.32.2",
+        "chromadb==0.5.15",
     ],
     extras_require={
         "dev": [


Test patch:
diff --git a/test_scripts/test_carrer_connections.py b/test_scripts/test_carrer_connections.py
new file mode 100644
index 0000000..bddf5fd
--- /dev/null
+++ b/test_scripts/test_carrer_connections.py
@@ -0,0 +1,39 @@
+from educhain.engines.content_engine import ContentEngine
+from educhain.core.config import LLMConfig
+
+def test_generate_career_connections():
+    try:
+        # Initialize LLM configuration
+        llm_config = LLMConfig(
+            model_name="gpt-4o",
+            api_key="",
+            max_tokens=4000,
+            temperature=0.5,
+        )
+
+        # Initialize content engine
+        content_engine = ContentEngine(llm_config=llm_config)
+
+        # Test parameters
+        topic = "Data Science"
+        industry_focus = "Technology"
+
+        # Generate the career connections
+        print(f"\nGenerating career connections for: {topic}")
+        print(f"Industry Focus: {industry_focus}")
+        
+        career_connections = content_engine.generate_career_connections(
+            topic=topic,
+            industry_focus=industry_focus,
+            output_format="csv"
+        )
+
+        career_connections.show()  # Using the show method we defined in the Pydantic model
+
+    except Exception as e:
+        print(f"\nError generating career connections: {e}")
+        import traceback
+        print(traceback.format_exc())
+
+if __name__ == "__main__":
+    test_generate_career_connections()
\ No newline at end of file
diff --git a/test_scripts/test_generate_lesson_.py b/test_scripts/test_generate_lesson.py
similarity index 90%
rename from test_scripts/test_generate_lesson_.py
rename to test_scripts/test_generate_lesson.py
index 41e82a1..493f8c6 100644
--- a/test_scripts/test_generate_lesson_.py
+++ b/test_scripts/test_generate_lesson.py
@@ -6,9 +6,9 @@ def test_generate_lesson_plan():
     try:
         
         llm_config = LLMConfig(
-            model_name="gpt-4o-mini",
+            model_name="gpt-4o",
             api_key="",
-            max_tokens=3000,
+            max_tokens=4000,
             temperature=0.5,
         )
 
@@ -22,6 +22,7 @@ def test_generate_lesson_plan():
         lesson_plan = content_engine.generate_lesson_plan(
             topic=topic,
             custom_instructions=custom_instructions,
+            output_format="csv"
         )
 
         # Display the lesson plan using the show() function
diff --git a/test_scripts/test_generate_questions.py b/test_scripts/test_generate_questions.py
new file mode 100644
index 0000000..8911e32
--- /dev/null
+++ b/test_scripts/test_generate_questions.py
@@ -0,0 +1,37 @@
+import sys
+from educhain.core.config import LLMConfig
+from educhain.engines.qna_engine import QnAEngine
+
+def test_question_generation():
+    try:
+        
+        llm_config = LLMConfig(
+            model_name="gpt-4o",
+            api_key="",
+            max_tokens=4000,
+            temperature=0.5,
+        )
+
+        qna_engine = QnAEngine(llm_config=llm_config)
+
+        topic = "Gravitation"
+        num = 5
+        question_type = "Multiple Choice"
+
+        # Generate the lesson plan
+        qna = qna_engine.generate_questions(
+            topic=topic,
+            num=num,
+            question_type=question_type,
+            output_format="csv"
+        )
+
+        # Display the lesson plan using the show() function
+        print(qna)
+
+    except Exception as e:
+        print(f"Error generating questions: {e}")
+
+# Run the test
+if __name__ == "__main__":
+    test_question_generation()
diff --git a/test_scripts/test_math.py b/test_scripts/test_math.py
index 39d9918..1d4ee02 100644
--- a/test_scripts/test_math.py
+++ b/test_scripts/test_math.py
@@ -10,12 +10,13 @@
 
 engine = QnAEngine(llm_config=llm_config)
 
-topic = "Geometry"
+topic = "Linear Algebra"
 
-num_questions = 7
+num_questions = 5
 response = engine.generate_mcq_math(
     topic=topic,
-    num=num_questions
+    num=num_questions,
+    output_format="pdf"
 )
 
 print(response)
diff --git a/test_scripts/test_study_guide.py b/test_scripts/test_study_guide.py
new file mode 100644
index 0000000..f4a64ba
--- /dev/null
+++ b/test_scripts/test_study_guide.py
@@ -0,0 +1,43 @@
+from educhain.engines.content_engine import ContentEngine
+from educhain.core.config import LLMConfig
+
+def test_generate_study_guide():
+    try:
+        # Initialize LLM configuration
+        llm_config = LLMConfig(
+            model_name="gpt-4o",
+            api_key="",
+            max_tokens=4000,
+            temperature=0.5,
+        )
+
+        # Initialize content engine
+        content_engine = ContentEngine(llm_config=llm_config)
+
+        # Test parameters
+        topic = "Ethical Hacking"
+        difficulty_level = "Beginner"
+        custom_instructions = """
+        Include hands-on examples and some real-world techniques.
+        Focus on practical applications and security best practices.
+        """
+
+        # Generate the study guide
+        print(f"\nGenerating study guide for: {topic}")
+        study_guide = content_engine.generate_study_guide(
+            topic=topic,
+            difficulty_level=difficulty_level,
+            custom_instructions=custom_instructions,
+            output_format="csv"
+        )
+
+        # Display results
+        print("\nGenerated Study Guide:")
+        print("-" * 50)
+        study_guide.show(format="text")  # Using the new format parameter
+
+    except Exception as e:
+        print(f"\nError generating study guide: {e}")
+
+if __name__ == "__main__":
+    test_generate_study_guide()
\ No newline at end of file