├── .DS_Store ├── AIDemos__Technical Demos ├── 2024-10-07_Object Detection │ ├── Amazon Recognition API │ │ └── Amazon_Recognition.ipynb │ ├── Google API │ │ └── Google.ipynb │ └── Imagga API │ │ └── Imagga.ipynb ├── 2024-10-08_Run Llama 3.2 Multimodal │ └── Run_Llama_3_2_Multimodal.ipynb ├── 2024-10-12_Mem0 │ └── Mem0_Tutorial.ipynb └── 2024-10-21_Jina.ai │ └── Jina_Demo.ipynb ├── Comparing PDF Parsing Tools ├── data │ └── testing.pdf └── tools │ ├── AWS Textract.py │ ├── Llama Parse.py │ ├── PDF Plumber.py │ ├── PDFMiner.py │ └── PyPDF.py ├── Comprehensive guide to Qdrant Vector DB ├── data │ └── movies.json ├── qdrant.ipynb └── requirements.txt ├── Finding similar products using chromadb ├── chromadb_script.py └── products.csv ├── Freshdesk Ticketing Automation with AI Agents ├── .env.example ├── docs │ ├── Company Overview.pdf │ ├── Contact Information.pdf │ ├── Payment Methods Supported.pdf │ ├── Privacy Policy.pdf │ ├── Promotion and Discount.pdf │ ├── Return Policy.pdf │ ├── Shipping Policy.pdf │ └── Warranty Policy.pdf └── freshdesk agent.ipynb ├── Google OAuth Integration with FastAPI ├── .env ├── api.py ├── apis │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-311.pyc │ │ ├── __init__.cpython-312.pyc │ │ ├── admin_prompts.cpython-311.pyc │ │ ├── admin_prompts.cpython-312.pyc │ │ ├── authentication.cpython-312.pyc │ │ ├── chatbot.cpython-311.pyc │ │ ├── chatbot.cpython-312.pyc │ │ ├── chatbot_knowledge.cpython-312.pyc │ │ ├── chatbot_support.cpython-312.pyc │ │ ├── document.cpython-311.pyc │ │ ├── session_api.cpython-312.pyc │ │ └── widget_support.cpython-312.pyc │ ├── authentication.py │ └── chatbot.py ├── db_utils │ └── db.py └── requirements.txt ├── LangChain Agents with Gmail API └── langchain_gmail_demo.ipynb ├── Langchain RAG using Async Fastapi and Qdrant ├── .env.example ├── api.py ├── requirements.txt ├── services │ ├── __pycache__ │ │ ├── logger.cpython-311.pyc │ │ ├── logger.cpython-39.pyc │ │ ├── pydantic_models.cpython-311.pyc │ │ └── pydantic_models.cpython-39.pyc │ ├── logger.py │ └── pydantic_models.py ├── uploads │ ├── nalen.txt │ └── watches.txt_6d9782b6-b82f-4584-a9e5-072a07b6581c.txt └── utils │ ├── __init__.py │ ├── __pycache__ │ ├── __init__.cpython-39.pyc │ ├── db_utils.cpython-311.pyc │ ├── db_utils.cpython-39.pyc │ ├── langchain_utils.cpython-311.pyc │ ├── langchain_utils.cpython-39.pyc │ ├── prompts.cpython-311.pyc │ ├── prompts.cpython-39.pyc │ ├── qdrant_utils.cpython-311.pyc │ ├── qdrant_utils.cpython-39.pyc │ ├── utils.cpython-311.pyc │ └── utils.cpython-39.pyc │ ├── db_utils.py │ ├── langchain_utils.py │ ├── prompts.py │ ├── qdrant_utils.py │ └── utils.py ├── Langgraph Agent with websearch, RAG, NL2SQL └── langgraph_with_tools_tutorial_blog.ipynb ├── Langgraph Long-Term Memory Blog └── Langgraph Long-Term Memory.ipynb ├── Langsmith tool └── app.py ├── Linkedin Scraping └── linkedin_scraping.ipynb ├── LlamaIndex NL2SQL Blog └── NL2SQL_With_LlamaIndex.ipynb ├── Llamaindex_DataAgents ├── React__Agent.ipynb ├── Tool__Abstraction.ipynb └── new.py ├── Master RAG with LangChain A Practical Guide └── RAG_using_LangChain_A_complete_Hands_On Tutorial_Blog_Code.ipynb ├── Mem0 with Langchain Blog └── Integrating_Mem0_with_LangChain.ipynb ├── Multi Agent system with LangGraph └── Multi_agent_LangGraph.ipynb ├── OpenAi Swarm └── OpenAI_Swarm_Tutorial.ipynb ├── Small Language Models Blog └── Running_TinyLlama_using_HuggingFace.ipynb ├── Videodb ├── .env ├── .gitignore ├── db_utils.py ├── requirements.txt └── streamlit.py ├── Youtube Q-A Chatbot ├── .env ├── .idea │ ├── .gitignore │ ├── blog_apps.iml │ ├── inspectionProfiles │ │ ├── Project_Default.xml │ │ └── profiles_settings.xml │ ├── misc.xml │ ├── modules.xml │ └── vcs.xml ├── app.py ├── history.csv ├── pinecone_utils.py ├── requirements └── youtube_subtitle_gen.py └── images └── 63eb5ebedd3a9a738e22a03f_open ai whisper.jpg /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/.DS_Store -------------------------------------------------------------------------------- /AIDemos__Technical Demos/2024-10-07_Object Detection/Amazon Recognition API/Amazon_Recognition.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "id": "gftEuRyPfWba" 7 | }, 8 | "source": [ 9 | "# **Amazon Recognition**" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": null, 15 | "metadata": { 16 | "id": "ulfr855iguoO" 17 | }, 18 | "outputs": [], 19 | "source": [ 20 | "!pip install -q boto3" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": null, 26 | "metadata": { 27 | "id": "QzjUHWzDgxvc" 28 | }, 29 | "outputs": [], 30 | "source": [ 31 | "aws_access_key_id = \"your_aws_access_id\"\n", 32 | "aws_secret_access_key = \"your_aws_secret_key\"\n", 33 | "region_name=' '" 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": null, 39 | "metadata": { 40 | "colab": { 41 | "base_uri": "https://localhost:8080/" 42 | }, 43 | "id": "Z8wnRf_NgaAx", 44 | "outputId": "214d19d8-96ad-4f18-9ffb-2a22b55b8393" 45 | }, 46 | "outputs": [ 47 | { 48 | "name": "stdout", 49 | "output_type": "stream", 50 | "text": [ 51 | "Detected labels in /content/image.jpg\n", 52 | "Machine : 99.97028350830078[]\n", 53 | "Spoke : 99.97028350830078[]\n", 54 | "Bicycle : 99.5052261352539[{'BoundingBox': {'Width': 0.571449339389801, 'Height': 0.5124862194061279, 'Left': 0.16833741962909698, 'Top': 0.22136732935905457}, 'Confidence': 99.5052261352539}, {'BoundingBox': {'Width': 0.2420956939458847, 'Height': 0.6571153998374939, 'Left': 0.16403935849666595, 'Top': 0.2835889756679535}, 'Confidence': 62.047969818115234}]\n", 55 | "Transportation : 99.5052261352539[]\n", 56 | "Vehicle : 99.5052261352539[]\n", 57 | "Animal : 99.31156158447266[]\n", 58 | "Canine : 99.31156158447266[]\n", 59 | "Dog : 99.31156158447266[{'BoundingBox': {'Width': 0.2342192381620407, 'Height': 0.5544285178184509, 'Left': 0.17188990116119385, 'Top': 0.38754960894584656}, 'Confidence': 99.31156158447266}]\n", 60 | "Mammal : 99.31156158447266[]\n", 61 | "Pet : 99.31156158447266[]\n", 62 | "Plant : 97.7978286743164[]\n", 63 | "Tree : 97.7978286743164[]\n", 64 | "Wheel : 97.44068145751953[{'BoundingBox': {'Width': 0.24615757167339325, 'Height': 0.314919650554657, 'Left': 0.4911452829837799, 'Top': 0.41441887617111206}, 'Confidence': 97.44068145751953}, {'BoundingBox': {'Width': 0.04160372540354729, 'Height': 0.052048470824956894, 'Left': 0.8289476037025452, 'Top': 0.24493974447250366}, 'Confidence': 80.39229583740234}, {'BoundingBox': {'Width': 0.04330078884959221, 'Height': 0.05542082339525223, 'Left': 0.6620650887489319, 'Top': 0.2236187756061554}, 'Confidence': 73.15531158447266}]\n", 65 | "Car : 97.36234283447266[{'BoundingBox': {'Width': 0.29039180278778076, 'Height': 0.1698329597711563, 'Left': 0.6048358678817749, 'Top': 0.12719792127609253}, 'Confidence': 97.36234283447266}]\n", 66 | "Accessories : 95.96794128417969[]\n", 67 | "Strap : 95.96794128417969[]\n", 68 | "Potted Plant : 95.61145782470703[]\n", 69 | "Architecture : 80.92571258544922[]\n", 70 | "Building : 80.92571258544922[]\n", 71 | "Outdoors : 80.92571258544922[]\n", 72 | "Shelter : 80.92571258544922[]\n", 73 | "Motorcycle : 80.88300323486328[{'BoundingBox': {'Width': 0.07584317028522491, 'Height': 0.1127498671412468, 'Left': 0.07209309190511703, 'Top': 0.12209328263998032}, 'Confidence': 80.88300323486328}]\n", 74 | "Vegetation : 68.34353637695312[]\n", 75 | "Nature : 68.1030044555664[]\n", 76 | "Alloy Wheel : 64.00493621826172[]\n", 77 | "Car Wheel : 64.00493621826172[]\n", 78 | "Tire : 64.00493621826172[]\n", 79 | "Husky : 60.894290924072266[]\n", 80 | "Puppy : 57.95663070678711[]\n", 81 | "Herbal : 57.93125534057617[]\n", 82 | "Herbs : 57.93125534057617[]\n", 83 | "Path : 57.627349853515625[]\n", 84 | "Grass : 57.132530212402344[]\n", 85 | "City : 57.040775299072266[]\n", 86 | "Road : 57.040775299072266[]\n", 87 | "Street : 57.040775299072266[]\n", 88 | "Urban : 57.040775299072266[]\n", 89 | "License Plate : 55.70207214355469[]\n", 90 | "Soil : 55.37385177612305[]\n", 91 | "Slate : 55.242645263671875[]\n", 92 | "Park : 55.22623825073242[]\n", 93 | "Jar : 55.19215393066406[]\n", 94 | "Planter : 55.19215393066406[]\n", 95 | "Pottery : 55.19215393066406[]\n", 96 | "Vase : 55.19215393066406[]\n", 97 | "Walkway : 55.17646789550781[]\n", 98 | "Yard : 55.003910064697266[]\n" 99 | ] 100 | } 101 | ], 102 | "source": [ 103 | "import boto3\n", 104 | "\n", 105 | "def detect_labels_local_file(photo):\n", 106 | "\n", 107 | " client=boto3.client('rekognition', region_name=region_name, aws_access_key_id=aws_access_key_id,aws_secret_access_key=aws_secret_access_key)\n", 108 | " l = []\n", 109 | " with open(photo, 'rb') as image:\n", 110 | " response = client.detect_labels(Image={'Bytes': image.read()})\n", 111 | "\n", 112 | " print('Detected labels in ' + photo)\n", 113 | " for label in response['Labels']:\n", 114 | " print (label['Name'] + ' : ' + str(label['Confidence']) + str(label[\"Instances\"]))\n", 115 | "\n", 116 | "\n", 117 | "photo='/content/image.jpg'\n", 118 | "detect_labels_local_file(photo)" 119 | ] 120 | } 121 | ], 122 | "metadata": { 123 | "colab": { 124 | "provenance": [] 125 | }, 126 | "kernelspec": { 127 | "display_name": "Python 3", 128 | "name": "python3" 129 | }, 130 | "language_info": { 131 | "name": "python" 132 | } 133 | }, 134 | "nbformat": 4, 135 | "nbformat_minor": 0 136 | } 137 | -------------------------------------------------------------------------------- /AIDemos__Technical Demos/2024-10-07_Object Detection/Google API/Google.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "provenance": [] 7 | }, 8 | "kernelspec": { 9 | "name": "python3", 10 | "display_name": "Python 3" 11 | }, 12 | "language_info": { 13 | "name": "python" 14 | } 15 | }, 16 | "cells": [ 17 | { 18 | "cell_type": "markdown", 19 | "source": [ 20 | "# **Google**" 21 | ], 22 | "metadata": { 23 | "id": "mL-fAbu5hCLR" 24 | } 25 | }, 26 | { 27 | "cell_type": "code", 28 | "source": [ 29 | "!pip install -q --upgrade google-cloud-vision" 30 | ], 31 | "metadata": { 32 | "id": "YPkeDbVaiJ_V" 33 | }, 34 | "execution_count": null, 35 | "outputs": [] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "source": [ 40 | "!pip install -q Pillow" 41 | ], 42 | "metadata": { 43 | "id": "xxmvcRPL1-ve" 44 | }, 45 | "execution_count": null, 46 | "outputs": [] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "source": [ 51 | "import io, os\n", 52 | "from numpy import random\n", 53 | "from google.cloud import vision\n", 54 | "from PIL import Image\n", 55 | "import pandas as pd" 56 | ], 57 | "metadata": { 58 | "id": "knsbGnrF18u2" 59 | }, 60 | "execution_count": null, 61 | "outputs": [] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "source": [ 66 | "os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = r\" \"\n", 67 | "client = vision.ImageAnnotatorClient()\n", 68 | "\n", 69 | "file_name = ' '\n", 70 | "image_path = os.path.join('.\\Images', file_name)\n", 71 | "\n", 72 | "with io.open(image_path, 'rb') as image_file:\n", 73 | " content = image_file.read()\n", 74 | "\n", 75 | "image = vision.Image(content=content)\n", 76 | "response = client.object_localization(image=image)\n", 77 | "localized_object_annotations = response.localized_object_annotations" 78 | ], 79 | "metadata": { 80 | "id": "UgQuaOgR17nf" 81 | }, 82 | "execution_count": null, 83 | "outputs": [] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "source": [ 88 | "def localize_objects(path):\n", 89 | " \"\"\"Localize objects in the local image.\n", 90 | "\n", 91 | " Args:\n", 92 | " path: The path to the local file.\n", 93 | " \"\"\"\n", 94 | " from google.cloud import vision\n", 95 | "\n", 96 | " os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = r\" \"\n", 97 | " client = vision.ImageAnnotatorClient()\n", 98 | "\n", 99 | " with open(path, \"rb\") as image_file:\n", 100 | " content = image_file.read()\n", 101 | " image = vision.Image(content=content)\n", 102 | "\n", 103 | " objects = client.object_localization(image=image).localized_object_annotations\n", 104 | " bounding_poly = {}\n", 105 | " print(f\"Number of objects found: {len(objects)}\")\n", 106 | " for object_ in objects:\n", 107 | " print(f\"\\n{object_.name} (confidence: {object_.score})\")\n", 108 | " print(\"Normalized bounding polygon vertices: \")\n", 109 | " d = {}\n", 110 | " i = 1\n", 111 | " for vertex in object_.bounding_poly.normalized_vertices:\n", 112 | " d[f\"normalized_vertices_{i}\"] = {\"x\":vertex.x, \"y\":vertex.y}\n", 113 | " print(f\" - ({vertex.x}, {vertex.y})\")\n", 114 | " i+=1\n", 115 | " print(d)\n", 116 | " key = f\"{object_.name}_{object_.score}\"\n", 117 | " bounding_poly[key] = d\n", 118 | "\n", 119 | " print(bounding_poly)" 120 | ], 121 | "metadata": { 122 | "id": "RtF0u67uKZoo" 123 | }, 124 | "execution_count": null, 125 | "outputs": [] 126 | }, 127 | { 128 | "cell_type": "code", 129 | "source": [ 130 | "path = \"/content/image.jpg\"\n", 131 | "localize_objects(path)" 132 | ], 133 | "metadata": { 134 | "colab": { 135 | "base_uri": "https://localhost:8080/" 136 | }, 137 | "id": "uLpZyQxGKc-j", 138 | "outputId": "21b6dacd-19ae-4f9e-e0a0-2d86a412735f" 139 | }, 140 | "execution_count": null, 141 | "outputs": [ 142 | { 143 | "output_type": "stream", 144 | "name": "stdout", 145 | "text": [ 146 | "Number of objects found: 10\n", 147 | "\n", 148 | "Bicycle (confidence: 0.9054205417633057)\n", 149 | "Normalized bounding polygon vertices: \n", 150 | " - (0.16015625, 0.2255859375)\n", 151 | " - (0.74609375, 0.2255859375)\n", 152 | " - (0.74609375, 0.73046875)\n", 153 | " - (0.16015625, 0.73046875)\n", 154 | "{'normalized_vertices_1': {'x': 0.16015625, 'y': 0.2255859375}, 'normalized_vertices_2': {'x': 0.74609375, 'y': 0.2255859375}, 'normalized_vertices_3': {'x': 0.74609375, 'y': 0.73046875}, 'normalized_vertices_4': {'x': 0.16015625, 'y': 0.73046875}}\n", 155 | "\n", 156 | "Tire (confidence: 0.7708812952041626)\n", 157 | "Normalized bounding polygon vertices: \n", 158 | " - (0.4921875, 0.4140625)\n", 159 | " - (0.734375, 0.4140625)\n", 160 | " - (0.734375, 0.73046875)\n", 161 | " - (0.4921875, 0.73046875)\n", 162 | "{'normalized_vertices_1': {'x': 0.4921875, 'y': 0.4140625}, 'normalized_vertices_2': {'x': 0.734375, 'y': 0.4140625}, 'normalized_vertices_3': {'x': 0.734375, 'y': 0.73046875}, 'normalized_vertices_4': {'x': 0.4921875, 'y': 0.73046875}}\n", 163 | "\n", 164 | "Tire (confidence: 0.7498802542686462)\n", 165 | "Normalized bounding polygon vertices: \n", 166 | " - (0.1611328125, 0.408203125)\n", 167 | " - (0.2890625, 0.408203125)\n", 168 | " - (0.2890625, 0.65234375)\n", 169 | " - (0.1611328125, 0.65234375)\n", 170 | "{'normalized_vertices_1': {'x': 0.1611328125, 'y': 0.408203125}, 'normalized_vertices_2': {'x': 0.2890625, 'y': 0.408203125}, 'normalized_vertices_3': {'x': 0.2890625, 'y': 0.65234375}, 'normalized_vertices_4': {'x': 0.1611328125, 'y': 0.65234375}}\n", 171 | "\n", 172 | "Bicycle wheel (confidence: 0.7476080060005188)\n", 173 | "Normalized bounding polygon vertices: \n", 174 | " - (0.4921875, 0.4140625)\n", 175 | " - (0.734375, 0.4140625)\n", 176 | " - (0.734375, 0.73046875)\n", 177 | " - (0.4921875, 0.73046875)\n", 178 | "{'normalized_vertices_1': {'x': 0.4921875, 'y': 0.4140625}, 'normalized_vertices_2': {'x': 0.734375, 'y': 0.4140625}, 'normalized_vertices_3': {'x': 0.734375, 'y': 0.73046875}, 'normalized_vertices_4': {'x': 0.4921875, 'y': 0.73046875}}\n", 179 | "\n", 180 | "Car (confidence: 0.6787649989128113)\n", 181 | "Normalized bounding polygon vertices: \n", 182 | " - (0.60546875, 0.12890625)\n", 183 | " - (0.921875, 0.12890625)\n", 184 | " - (0.921875, 0.291015625)\n", 185 | " - (0.60546875, 0.291015625)\n", 186 | "{'normalized_vertices_1': {'x': 0.60546875, 'y': 0.12890625}, 'normalized_vertices_2': {'x': 0.921875, 'y': 0.12890625}, 'normalized_vertices_3': {'x': 0.921875, 'y': 0.291015625}, 'normalized_vertices_4': {'x': 0.60546875, 'y': 0.291015625}}\n", 187 | "\n", 188 | "Bicycle wheel (confidence: 0.6777045726776123)\n", 189 | "Normalized bounding polygon vertices: \n", 190 | " - (0.1611328125, 0.408203125)\n", 191 | " - (0.2890625, 0.408203125)\n", 192 | " - (0.2890625, 0.65234375)\n", 193 | " - (0.1611328125, 0.65234375)\n", 194 | "{'normalized_vertices_1': {'x': 0.1611328125, 'y': 0.408203125}, 'normalized_vertices_2': {'x': 0.2890625, 'y': 0.408203125}, 'normalized_vertices_3': {'x': 0.2890625, 'y': 0.65234375}, 'normalized_vertices_4': {'x': 0.1611328125, 'y': 0.65234375}}\n", 195 | "\n", 196 | "Wheel (confidence: 0.6597345471382141)\n", 197 | "Normalized bounding polygon vertices: \n", 198 | " - (0.1611328125, 0.408203125)\n", 199 | " - (0.2890625, 0.408203125)\n", 200 | " - (0.2890625, 0.65234375)\n", 201 | " - (0.1611328125, 0.65234375)\n", 202 | "{'normalized_vertices_1': {'x': 0.1611328125, 'y': 0.408203125}, 'normalized_vertices_2': {'x': 0.2890625, 'y': 0.408203125}, 'normalized_vertices_3': {'x': 0.2890625, 'y': 0.65234375}, 'normalized_vertices_4': {'x': 0.1611328125, 'y': 0.65234375}}\n", 203 | "\n", 204 | "Wheel (confidence: 0.6327399611473083)\n", 205 | "Normalized bounding polygon vertices: \n", 206 | " - (0.4921875, 0.4140625)\n", 207 | " - (0.734375, 0.4140625)\n", 208 | " - (0.734375, 0.73046875)\n", 209 | " - (0.4921875, 0.73046875)\n", 210 | "{'normalized_vertices_1': {'x': 0.4921875, 'y': 0.4140625}, 'normalized_vertices_2': {'x': 0.734375, 'y': 0.4140625}, 'normalized_vertices_3': {'x': 0.734375, 'y': 0.73046875}, 'normalized_vertices_4': {'x': 0.4921875, 'y': 0.73046875}}\n", 211 | "\n", 212 | "Dog (confidence: 0.6011953949928284)\n", 213 | "Normalized bounding polygon vertices: \n", 214 | " - (0.1708984375, 0.388671875)\n", 215 | " - (0.40625, 0.388671875)\n", 216 | " - (0.40625, 0.9375)\n", 217 | " - (0.1708984375, 0.9375)\n", 218 | "{'normalized_vertices_1': {'x': 0.1708984375, 'y': 0.388671875}, 'normalized_vertices_2': {'x': 0.40625, 'y': 0.388671875}, 'normalized_vertices_3': {'x': 0.40625, 'y': 0.9375}, 'normalized_vertices_4': {'x': 0.1708984375, 'y': 0.9375}}\n", 219 | "\n", 220 | "Wheel (confidence: 0.5077753067016602)\n", 221 | "Normalized bounding polygon vertices: \n", 222 | " - (0.1708984375, 0.388671875)\n", 223 | " - (0.40625, 0.388671875)\n", 224 | " - (0.40625, 0.9375)\n", 225 | " - (0.1708984375, 0.9375)\n", 226 | "{'normalized_vertices_1': {'x': 0.1708984375, 'y': 0.388671875}, 'normalized_vertices_2': {'x': 0.40625, 'y': 0.388671875}, 'normalized_vertices_3': {'x': 0.40625, 'y': 0.9375}, 'normalized_vertices_4': {'x': 0.1708984375, 'y': 0.9375}}\n", 227 | "{'Bicycle_0.9054205417633057': {'normalized_vertices_1': {'x': 0.16015625, 'y': 0.2255859375}, 'normalized_vertices_2': {'x': 0.74609375, 'y': 0.2255859375}, 'normalized_vertices_3': {'x': 0.74609375, 'y': 0.73046875}, 'normalized_vertices_4': {'x': 0.16015625, 'y': 0.73046875}}, 'Tire_0.7708812952041626': {'normalized_vertices_1': {'x': 0.4921875, 'y': 0.4140625}, 'normalized_vertices_2': {'x': 0.734375, 'y': 0.4140625}, 'normalized_vertices_3': {'x': 0.734375, 'y': 0.73046875}, 'normalized_vertices_4': {'x': 0.4921875, 'y': 0.73046875}}, 'Tire_0.7498802542686462': {'normalized_vertices_1': {'x': 0.1611328125, 'y': 0.408203125}, 'normalized_vertices_2': {'x': 0.2890625, 'y': 0.408203125}, 'normalized_vertices_3': {'x': 0.2890625, 'y': 0.65234375}, 'normalized_vertices_4': {'x': 0.1611328125, 'y': 0.65234375}}, 'Bicycle wheel_0.7476080060005188': {'normalized_vertices_1': {'x': 0.4921875, 'y': 0.4140625}, 'normalized_vertices_2': {'x': 0.734375, 'y': 0.4140625}, 'normalized_vertices_3': {'x': 0.734375, 'y': 0.73046875}, 'normalized_vertices_4': {'x': 0.4921875, 'y': 0.73046875}}, 'Car_0.6787649989128113': {'normalized_vertices_1': {'x': 0.60546875, 'y': 0.12890625}, 'normalized_vertices_2': {'x': 0.921875, 'y': 0.12890625}, 'normalized_vertices_3': {'x': 0.921875, 'y': 0.291015625}, 'normalized_vertices_4': {'x': 0.60546875, 'y': 0.291015625}}, 'Bicycle wheel_0.6777045726776123': {'normalized_vertices_1': {'x': 0.1611328125, 'y': 0.408203125}, 'normalized_vertices_2': {'x': 0.2890625, 'y': 0.408203125}, 'normalized_vertices_3': {'x': 0.2890625, 'y': 0.65234375}, 'normalized_vertices_4': {'x': 0.1611328125, 'y': 0.65234375}}, 'Wheel_0.6597345471382141': {'normalized_vertices_1': {'x': 0.1611328125, 'y': 0.408203125}, 'normalized_vertices_2': {'x': 0.2890625, 'y': 0.408203125}, 'normalized_vertices_3': {'x': 0.2890625, 'y': 0.65234375}, 'normalized_vertices_4': {'x': 0.1611328125, 'y': 0.65234375}}, 'Wheel_0.6327399611473083': {'normalized_vertices_1': {'x': 0.4921875, 'y': 0.4140625}, 'normalized_vertices_2': {'x': 0.734375, 'y': 0.4140625}, 'normalized_vertices_3': {'x': 0.734375, 'y': 0.73046875}, 'normalized_vertices_4': {'x': 0.4921875, 'y': 0.73046875}}, 'Dog_0.6011953949928284': {'normalized_vertices_1': {'x': 0.1708984375, 'y': 0.388671875}, 'normalized_vertices_2': {'x': 0.40625, 'y': 0.388671875}, 'normalized_vertices_3': {'x': 0.40625, 'y': 0.9375}, 'normalized_vertices_4': {'x': 0.1708984375, 'y': 0.9375}}, 'Wheel_0.5077753067016602': {'normalized_vertices_1': {'x': 0.1708984375, 'y': 0.388671875}, 'normalized_vertices_2': {'x': 0.40625, 'y': 0.388671875}, 'normalized_vertices_3': {'x': 0.40625, 'y': 0.9375}, 'normalized_vertices_4': {'x': 0.1708984375, 'y': 0.9375}}}\n" 228 | ] 229 | } 230 | ] 231 | } 232 | ] 233 | } -------------------------------------------------------------------------------- /AIDemos__Technical Demos/2024-10-07_Object Detection/Imagga API/Imagga.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "id": "pA3VXX52Tec7" 7 | }, 8 | "source": [ 9 | "# **Imagga**" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": null, 15 | "metadata": { 16 | "id": "zuM3s1Xq8BGc" 17 | }, 18 | "outputs": [], 19 | "source": [ 20 | "import requests" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": null, 26 | "metadata": { 27 | "id": "_nrtaR7jfHYJ" 28 | }, 29 | "outputs": [], 30 | "source": [ 31 | "\n", 32 | "api_key = ' '\n", 33 | "api_secret = ' '\n", 34 | "image_path = ' '" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": null, 40 | "metadata": { 41 | "colab": { 42 | "base_uri": "https://localhost:8080/" 43 | }, 44 | "id": "pitiijiLeYiS", 45 | "outputId": "f15c7016-77ec-4e0b-ffc7-1f6762468bcc" 46 | }, 47 | "outputs": [ 48 | { 49 | "name": "stdout", 50 | "output_type": "stream", 51 | "text": [ 52 | "{'result': {'tags': [{'confidence': 100, 'tag': {'en': 'dog'}}, {'confidence': 99.888053894043, 'tag': {'en': 'canine'}}, {'confidence': 71.5936431884766, 'tag': {'en': 'pet'}}, {'confidence': 64.8093719482422, 'tag': {'en': 'boxer'}}, {'confidence': 56.2753715515137, 'tag': {'en': 'puppy'}}, {'confidence': 46.6206665039062, 'tag': {'en': 'cute'}}, {'confidence': 44.8576850891113, 'tag': {'en': 'domestic animal'}}, {'confidence': 41.5463523864746, 'tag': {'en': 'breed'}}, {'confidence': 37.1279678344727, 'tag': {'en': 'friend'}}, {'confidence': 32.5374336242676, 'tag': {'en': 'domestic'}}, {'confidence': 32.0056610107422, 'tag': {'en': 'purebred'}}, {'confidence': 31.3631286621094, 'tag': {'en': 'adorable'}}, {'confidence': 31.2565879821777, 'tag': {'en': 'bull mastiff'}}, {'confidence': 28.2988243103027, 'tag': {'en': 'pedigree'}}, {'confidence': 27.1761455535889, 'tag': {'en': 'bull'}}, {'confidence': 26.4616985321045, 'tag': {'en': 'doggy'}}, {'confidence': 25.3908081054688, 'tag': {'en': 'bulldog'}}, {'confidence': 22.9422950744629, 'tag': {'en': 'funny'}}, {'confidence': 21.575496673584, 'tag': {'en': 'leash'}}, {'confidence': 21.3454093933105, 'tag': {'en': 'portrait'}}, {'confidence': 20.8176689147949, 'tag': {'en': 'device'}}, {'confidence': 19.8645782470703, 'tag': {'en': 'brown'}}, {'confidence': 19.1723861694336, 'tag': {'en': 'pets'}}, {'confidence': 19.0619373321533, 'tag': {'en': 'nose'}}, {'confidence': 18.676097869873, 'tag': {'en': 'pup'}}, {'confidence': 18.4170818328857, 'tag': {'en': 'pug'}}, {'confidence': 17.6779689788818, 'tag': {'en': 'dogs'}}, {'confidence': 17.2566452026367, 'tag': {'en': 'collar'}}, {'confidence': 17.0957469940186, 'tag': {'en': 'restraint'}}, {'confidence': 16.6643924713135, 'tag': {'en': 'pedigreed'}}, {'confidence': 16.3117275238037, 'tag': {'en': 'sitting'}}, {'confidence': 15.8504953384399, 'tag': {'en': 'retriever'}}, {'confidence': 15.7172212600708, 'tag': {'en': 'wrinkle'}}, {'confidence': 15.7009353637695, 'tag': {'en': 'companion'}}, {'confidence': 14.9088268280029, 'tag': {'en': 'face'}}, {'confidence': 14.8528871536255, 'tag': {'en': 'fur'}}, {'confidence': 14.7694358825684, 'tag': {'en': 'obedient'}}, {'confidence': 14.4300346374512, 'tag': {'en': 'studio'}}, {'confidence': 13.6435308456421, 'tag': {'en': 'expression'}}, {'confidence': 12.059757232666, 'tag': {'en': 'play'}}, {'confidence': 11.99001121521, 'tag': {'en': 'looking'}}, {'confidence': 11.9546604156494, 'tag': {'en': 'hunting dog'}}, {'confidence': 11.8501462936401, 'tag': {'en': 'wrinkly'}}, {'confidence': 11.8492994308472, 'tag': {'en': 'sweet'}}, {'confidence': 11.4172315597534, 'tag': {'en': 'black'}}, {'confidence': 11.1099424362183, 'tag': {'en': 'animals'}}, {'confidence': 11.007420539856, 'tag': {'en': 'two'}}, {'confidence': 10.9386777877808, 'tag': {'en': 'harness'}}, {'confidence': 10.8669404983521, 'tag': {'en': 'mastiff'}}, {'confidence': 10.765079498291, 'tag': {'en': 'wrinkled'}}, {'confidence': 10.6067066192627, 'tag': {'en': 'sad'}}, {'confidence': 10.5057935714722, 'tag': {'en': 'look'}}, {'confidence': 10.473840713501, 'tag': {'en': 'fun'}}, {'confidence': 10.0733413696289, 'tag': {'en': 'head'}}, {'confidence': 9.85619926452637, 'tag': {'en': 'ugly'}}, {'confidence': 9.70899772644043, 'tag': {'en': 'little'}}, {'confidence': 9.65012073516846, 'tag': {'en': 'ears'}}, {'confidence': 9.57478046417236, 'tag': {'en': 'watch'}}, {'confidence': 9.40729141235352, 'tag': {'en': 'outside'}}, {'confidence': 8.84793186187744, 'tag': {'en': 'terrier'}}, {'confidence': 8.79454517364502, 'tag': {'en': 'muzzle'}}, {'confidence': 8.74377059936523, 'tag': {'en': 'tired'}}, {'confidence': 8.6741771697998, 'tag': {'en': 'furry'}}, {'confidence': 8.59211444854736, 'tag': {'en': 'rest'}}, {'confidence': 8.56786823272705, 'tag': {'en': 'resting'}}, {'confidence': 8.53564167022705, 'tag': {'en': 'down'}}, {'confidence': 8.50173473358154, 'tag': {'en': 'pooch'}}, {'confidence': 8.4190034866333, 'tag': {'en': 'hound'}}, {'confidence': 8.22844886779785, 'tag': {'en': 'friendly'}}, {'confidence': 8.20689487457275, 'tag': {'en': 'outdoors'}}, {'confidence': 7.98757934570312, 'tag': {'en': 'close'}}, {'confidence': 7.84685897827148, 'tag': {'en': 'overweight'}}, {'confidence': 7.81939649581909, 'tag': {'en': 'paw'}}, {'confidence': 7.77659177780151, 'tag': {'en': 'sleep'}}, {'confidence': 7.77619218826294, 'tag': {'en': 'guard'}}, {'confidence': 7.5606837272644, 'tag': {'en': 'playful'}}, {'confidence': 7.50579595565796, 'tag': {'en': 'mammal'}}, {'confidence': 7.4972562789917, 'tag': {'en': 'support'}}, {'confidence': 7.35531425476074, 'tag': {'en': 'sporting dog'}}, {'confidence': 7.09061050415039, 'tag': {'en': 'male'}}]}, 'status': {'text': '', 'type': 'success'}}\n" 53 | ] 54 | } 55 | ], 56 | "source": [ 57 | "response = requests.post(\n", 58 | " 'https://api.imagga.com/v2/tags',\n", 59 | " auth=(api_key, api_secret),\n", 60 | " files={'image': open(image_path, 'rb')})\n", 61 | "result = response.json()\n", 62 | "print(response.json())" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": null, 68 | "metadata": { 69 | "colab": { 70 | "base_uri": "https://localhost:8080/" 71 | }, 72 | "id": "0xmq3aZDJK4v", 73 | "outputId": "3061c78c-dafc-46b8-e658-ef81cf17ede4" 74 | }, 75 | "outputs": [ 76 | { 77 | "name": "stdout", 78 | "output_type": "stream", 79 | "text": [ 80 | "Object: Dog Confidence: 1.00000\n", 81 | "Object: Canine Confidence: 0.99888\n", 82 | "Object: Pet Confidence: 0.71594\n", 83 | "Object: Boxer Confidence: 0.64809\n", 84 | "Object: Puppy Confidence: 0.56275\n", 85 | "Object: Cute Confidence: 0.46621\n", 86 | "Object: Domestic animal Confidence: 0.44858\n", 87 | "Object: Breed Confidence: 0.41546\n", 88 | "Object: Friend Confidence: 0.37128\n", 89 | "Object: Domestic Confidence: 0.32537\n", 90 | "Object: Purebred Confidence: 0.32006\n", 91 | "Object: Adorable Confidence: 0.31363\n", 92 | "Object: Bull mastiff Confidence: 0.31257\n", 93 | "Object: Pedigree Confidence: 0.28299\n", 94 | "Object: Bull Confidence: 0.27176\n", 95 | "Object: Doggy Confidence: 0.26462\n", 96 | "Object: Bulldog Confidence: 0.25391\n", 97 | "Object: Funny Confidence: 0.22942\n", 98 | "Object: Leash Confidence: 0.21575\n", 99 | "Object: Portrait Confidence: 0.21345\n", 100 | "Object: Device Confidence: 0.20818\n", 101 | "Object: Brown Confidence: 0.19865\n", 102 | "Object: Pets Confidence: 0.19172\n", 103 | "Object: Nose Confidence: 0.19062\n", 104 | "Object: Pup Confidence: 0.18676\n", 105 | "Object: Pug Confidence: 0.18417\n", 106 | "Object: Dogs Confidence: 0.17678\n", 107 | "Object: Collar Confidence: 0.17257\n", 108 | "Object: Restraint Confidence: 0.17096\n", 109 | "Object: Pedigreed Confidence: 0.16664\n", 110 | "Object: Sitting Confidence: 0.16312\n", 111 | "Object: Retriever Confidence: 0.15850\n", 112 | "Object: Wrinkle Confidence: 0.15717\n", 113 | "Object: Companion Confidence: 0.15701\n", 114 | "Object: Face Confidence: 0.14909\n", 115 | "Object: Fur Confidence: 0.14853\n", 116 | "Object: Obedient Confidence: 0.14769\n", 117 | "Object: Studio Confidence: 0.14430\n", 118 | "Object: Expression Confidence: 0.13644\n", 119 | "Object: Play Confidence: 0.12060\n", 120 | "Object: Looking Confidence: 0.11990\n", 121 | "Object: Hunting dog Confidence: 0.11955\n", 122 | "Object: Wrinkly Confidence: 0.11850\n", 123 | "Object: Sweet Confidence: 0.11849\n", 124 | "Object: Black Confidence: 0.11417\n", 125 | "Object: Animals Confidence: 0.11110\n", 126 | "Object: Two Confidence: 0.11007\n", 127 | "Object: Harness Confidence: 0.10939\n", 128 | "Object: Mastiff Confidence: 0.10867\n", 129 | "Object: Wrinkled Confidence: 0.10765\n", 130 | "Object: Sad Confidence: 0.10607\n", 131 | "Object: Look Confidence: 0.10506\n", 132 | "Object: Fun Confidence: 0.10474\n", 133 | "Object: Head Confidence: 0.10073\n", 134 | "Object: Ugly Confidence: 0.09856\n", 135 | "Object: Little Confidence: 0.09709\n", 136 | "Object: Ears Confidence: 0.09650\n", 137 | "Object: Watch Confidence: 0.09575\n", 138 | "Object: Outside Confidence: 0.09407\n", 139 | "Object: Terrier Confidence: 0.08848\n", 140 | "Object: Muzzle Confidence: 0.08795\n", 141 | "Object: Tired Confidence: 0.08744\n", 142 | "Object: Furry Confidence: 0.08674\n", 143 | "Object: Rest Confidence: 0.08592\n", 144 | "Object: Resting Confidence: 0.08568\n", 145 | "Object: Down Confidence: 0.08536\n", 146 | "Object: Pooch Confidence: 0.08502\n", 147 | "Object: Hound Confidence: 0.08419\n", 148 | "Object: Friendly Confidence: 0.08228\n", 149 | "Object: Outdoors Confidence: 0.08207\n", 150 | "Object: Close Confidence: 0.07988\n", 151 | "Object: Overweight Confidence: 0.07847\n", 152 | "Object: Paw Confidence: 0.07819\n", 153 | "Object: Sleep Confidence: 0.07777\n", 154 | "Object: Guard Confidence: 0.07776\n", 155 | "Object: Playful Confidence: 0.07561\n", 156 | "Object: Mammal Confidence: 0.07506\n", 157 | "Object: Support Confidence: 0.07497\n", 158 | "Object: Sporting dog Confidence: 0.07355\n", 159 | "Object: Male Confidence: 0.07091\n" 160 | ] 161 | } 162 | ], 163 | "source": [ 164 | "for item in result['result']['tags']:\n", 165 | " tag = item['tag']['en']\n", 166 | " confidence = item['confidence'] / 100\n", 167 | " print(f\"Object: {tag.capitalize()} Confidence: {confidence:.5f}\")" 168 | ] 169 | } 170 | ], 171 | "metadata": { 172 | "colab": { 173 | "provenance": [] 174 | }, 175 | "kernelspec": { 176 | "display_name": "Python 3", 177 | "name": "python3" 178 | }, 179 | "language_info": { 180 | "name": "python" 181 | } 182 | }, 183 | "nbformat": 4, 184 | "nbformat_minor": 0 185 | } 186 | -------------------------------------------------------------------------------- /Comparing PDF Parsing Tools/data/testing.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Comparing PDF Parsing Tools/data/testing.pdf -------------------------------------------------------------------------------- /Comparing PDF Parsing Tools/tools/AWS Textract.py: -------------------------------------------------------------------------------- 1 | import boto3 2 | from dotenv import load_dotenv 3 | import os 4 | from PIL import Image 5 | import fitz # PyMuPDF 6 | 7 | AWS_ACCESS_KEY_ID= # Give the access key 8 | AWS_SECRET_ACCESS_KEY= # Give Secret Access key 9 | 10 | # Create a boto3 session with access keys 11 | session = boto3.Session(aws_access_key_id=AWS_ACCESS_KEY_ID, aws_secret_access_key=AWS_SECRET_ACCESS_KEY) 12 | textract_client = session.client('textract',region_name='us-east-1') 13 | 14 | 15 | def textract_extract(pdf_path): 16 | """Extracts text using Amazon Textract with access keys.""" 17 | import io 18 | 19 | pdf_document = fitz.open(pdf_path) 20 | pages = "" 21 | 22 | for page_number in range(pdf_document.page_count): 23 | page = pdf_document.load_page(page_number) 24 | image_data = page.get_pixmap().tobytes() 25 | 26 | with io.BytesIO(image_data) as img_buffer: 27 | response = textract_client.detect_document_text(Document={'Bytes': img_buffer.read()}) 28 | 29 | # We can take other data also but for simplicity I have took only word and line 30 | # specifiy "pages" variable as output you wanted as i need only text so i took it 31 | # as a sting if you want in json you can modify accordingly 32 | 33 | 34 | blocks = response['Blocks'] 35 | text = "" 36 | 37 | for block in blocks: 38 | if block['BlockType'] in ['WORD']: 39 | text += block['Text'] + ' ' 40 | pages+="/n"+text # Add newline for readability 41 | 42 | return pages -------------------------------------------------------------------------------- /Comparing PDF Parsing Tools/tools/Llama Parse.py: -------------------------------------------------------------------------------- 1 | import nest_asyncio 2 | from llama_parse import LlamaParse 3 | 4 | def llama_parse_extract(pdf_path): 5 | nest_asyncio.apply() 6 | parser = LlamaParse( 7 | api_key= # LLAMA_CLOUD_API_KEY : you can get it from website (it is free now) 8 | result_type="text", # "markdown" and "text" are available 9 | ) 10 | 11 | data= parser.load_data(pdf_path) 12 | return data[0].text -------------------------------------------------------------------------------- /Comparing PDF Parsing Tools/tools/PDF Plumber.py: -------------------------------------------------------------------------------- 1 | import pdfplumber 2 | 3 | def pdfplumber_extract(pdf_path): 4 | """Extracts text using pdfplumber.""" 5 | with pdfplumber.open(pdf_path) as pdf: 6 | text = '' 7 | for page in pdf.pages: 8 | text += page.extract_text() 9 | return text -------------------------------------------------------------------------------- /Comparing PDF Parsing Tools/tools/PDFMiner.py: -------------------------------------------------------------------------------- 1 | from pdfminer.high_level import extract_text 2 | 3 | def pdfminer_extract(pdf_path): 4 | """Extracts text using pdfminer.six.""" 5 | with open(pdf_path, 'rb') as pdf_file: 6 | text = extract_text(pdf_file) 7 | return text -------------------------------------------------------------------------------- /Comparing PDF Parsing Tools/tools/PyPDF.py: -------------------------------------------------------------------------------- 1 | import pypdf 2 | 3 | def pypdf_extract(pdf_path): 4 | """Extracts text using pypdf""" 5 | with open(pdf_path, 'rb') as pdf_file: 6 | pdf_reader = pypdf.PdfReader(pdf_file) 7 | text = '' 8 | for page_num in range(len(pdf_reader.pages)): 9 | page = pdf_reader.pages[page_num] 10 | text +="\n"+ page.extract_text(extraction_mode="layout", layout_mode_space_vertically=False) 11 | return text -------------------------------------------------------------------------------- /Comprehensive guide to Qdrant Vector DB/data/movies.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "Sholay", 4 | "description": "Two ex-convicts are hired by a retired policeman to capture a ruthless dacoit terrorizing a village.", 5 | "director": "Ramesh Sippy", 6 | "year": 1975 7 | }, 8 | { 9 | "name": "Lagaan", 10 | "description": "Villagers unite to play a cricket match against British officers to abolish oppressive taxes.", 11 | "director": "Ashutosh Gowariker", 12 | "year": 2001 13 | }, 14 | { 15 | "name": "Mughal-e-Azam", 16 | "description": "A prince falls in love with a court dancer, leading to a tragic conflict with his father, the emperor.", 17 | "director": "K. Asif", 18 | "year": 1960 19 | }, 20 | { 21 | "name": "Dangal", 22 | "description": "A former wrestler trains his daughters to become world-class wrestlers against societal odds.", 23 | "director": "Nitesh Tiwari", 24 | "year": 2016 25 | }, 26 | { 27 | "name": "Dilwale Dulhania Le Jayenge", 28 | "description": "A young couple falls in love during a trip to Europe but must overcome familial objections.", 29 | "director": "Aditya Chopra", 30 | "year": 1995 31 | }, 32 | { 33 | "name": "3 Idiots", 34 | "description": "Three engineering students navigate the pressures of academia while challenging societal norms.", 35 | "director": "Rajkumar Hirani", 36 | "year": 2009 37 | }, 38 | { 39 | "name": "Barfi!", 40 | "description": "The heartwarming tale of a mute and deaf man and his relationships with two women.", 41 | "director": "Anurag Basu", 42 | "year": 2012 43 | }, 44 | { 45 | "name": "Gully Boy", 46 | "description": "A young man from the slums of Mumbai rises to fame as a rapper, inspired by his challenging life.", 47 | "director": "Zoya Akhtar", 48 | "year": 2019 49 | }, 50 | { 51 | "name": "Mother India", 52 | "description": "A poor villager struggles to raise her sons and fight against exploitation while maintaining her moral integrity.", 53 | "director": "Mehboob Khan", 54 | "year": 1957 55 | }, 56 | { 57 | "name": "Taare Zameen Par", 58 | "description": "A dyslexic boy discovers his artistic talent with the help of a compassionate teacher.", 59 | "director": "Aamir Khan", 60 | "year": 2007 61 | }, 62 | { 63 | "name": "Andhadhun", 64 | "description": "A blind pianist becomes entangled in a murder mystery with unexpected twists.", 65 | "director": "Sriram Raghavan", 66 | "year": 2018 67 | }, 68 | { 69 | "name": "Pyaasa", 70 | "description": "A struggling poet seeks recognition for his work while exploring themes of love and societal rejection.", 71 | "director": "Guru Dutt", 72 | "year": 1957 73 | }, 74 | { 75 | "name": "Kantara", 76 | "description": "A man becomes a reluctant hero when his village faces an existential crisis involving tradition and greed.", 77 | "director": "Rishab Shetty", 78 | "year": 2022 79 | } 80 | ] -------------------------------------------------------------------------------- /Comprehensive guide to Qdrant Vector DB/requirements.txt: -------------------------------------------------------------------------------- 1 | langchain 2 | sentence_transformers 3 | torch 4 | pypdf 5 | langchain_qdrant 6 | json -------------------------------------------------------------------------------- /Finding similar products using chromadb/chromadb_script.py: -------------------------------------------------------------------------------- 1 | import os 2 | import csv 3 | import chromadb 4 | from sentence_transformers import SentenceTransformer 5 | 6 | model = SentenceTransformer('all-MiniLM-L6-v2') 7 | 8 | client = chromadb.Client() 9 | product_collection = client.create_collection("product_collection") 10 | 11 | csv_file_path = r"C:\Users\Admin\Desktop\FutureAI\FutureSmart-AI-Blog\Finding similar products using chromadb\products.csv" 12 | 13 | documents = [] 14 | metadatas = [] 15 | ids = [] 16 | 17 | with open(csv_file_path, 'r', encoding='utf-8-sig') as file: 18 | csv_reader = csv.reader(file) 19 | next(csv_reader) 20 | for row in csv_reader: 21 | metadata = { 22 | 'id': row[0], 23 | 'name': row[1], 24 | 'category': row[2], 25 | 'price': float(row[3]), 26 | 'quantity': int(row[4]), 27 | 'description': row[5] 28 | } 29 | documents.append(row[5]) 30 | metadatas.append(metadata) 31 | ids.append(row[0]) 32 | 33 | product_collection.add( 34 | documents=documents, 35 | metadatas=metadatas, 36 | ids=ids 37 | ) 38 | 39 | 40 | query = "wireless mouse with RGB lighting and programmable buttons" 41 | 42 | query_results = product_collection.query( 43 | query_texts=[query], 44 | n_results=5, 45 | where={ 46 | '$and': [ 47 | {'category': {'$eq': 'Electronics'}}, 48 | {'price': {'$gte': 100}}, 49 | {'price': {'$lte': 500}} 50 | ] 51 | } 52 | ) 53 | 54 | metadata = query_results.get('metadatas', [])[0] 55 | 56 | print(metadata) -------------------------------------------------------------------------------- /Finding similar products using chromadb/products.csv: -------------------------------------------------------------------------------- 1 | id,name,category,price,quantity,description 2 | 1,Laptop,Electronics,999.99,50,"High-performance laptop with Intel Core i7 processor and 16GB RAM" 3 | 2,Smartphone,Electronics,699.99,100,"Latest smartphone model with 6.5-inch OLED display and dual-camera setup" 4 | 3,Headphones,Electronics,99.99,200,"Over-ear headphones with noise-cancellation feature and Bluetooth connectivity" 5 | 4,Desk Chair,Furniture,149.99,30,"Ergonomic desk chair with adjustable lumbar support and mesh back" 6 | 5,Desk Lamp,Home Decor,29.99,80,"Modern desk lamp with adjustable brightness levels and USB charging port" 7 | 6,Running Shoes,Apparel,79.99,150,"Lightweight running shoes with breathable mesh upper and responsive cushioning" 8 | 7,Backpack,Accessories,49.99,120,"Water-resistant backpack with multiple compartments and padded laptop sleeve" 9 | 8,Coffee Maker,Appliances,129.99,40,"Programmable coffee maker with 12-cup capacity and built-in grinder" 10 | 9,Notebook,Stationery,5.99,300,"Lined notebook with durable cover and perforated pages for easy tearing" 11 | 10,Water Bottle,Accessories,12.99,200,"Stainless steel water bottle with vacuum insulation and leak-proof design" 12 | 11,TV,Electronics,799.99,60,"Smart TV with 4K Ultra HD resolution and built-in streaming apps" 13 | 12,Bluetooth Speaker,Electronics,39.99,180,"Portable Bluetooth speaker with 20W output and IPX7 waterproof rating" 14 | 13,Sofa,Furniture,499.99,20,"Modern sofa with faux leather upholstery and adjustable headrests" 15 | 14,Clock,Home Decor,14.99,150,"Wall clock with silent sweep movement and large easy-to-read numbers" 16 | 15,T-shirt,Apparel,19.99,250,"Cotton crewneck t-shirt with classic fit and tag-free neckline" 17 | 16,Sunglasses,Accessories,29.99,100,"Polarized sunglasses with UV400 protection and lightweight frame" 18 | 17,Toaster,Appliances,39.99,80,"2-slice toaster with extra-wide slots and removable crumb tray" 19 | 18,Pen,Stationery,1.99,500,"Pack of 10 ballpoint pens with medium point and smooth writing ink" 20 | 19,Travel Mug,Accessories,9.99,120,"Insulated travel mug with leak-proof lid and ergonomic grip" 21 | 20,Desktop Computer,Electronics,1299.99,40,"Powerful desktop computer with Intel Core i9 processor and NVIDIA GeForce RTX graphics" 22 | 21,Tablet,Electronics,299.99,90,"10-inch tablet with Full HD display and quad-core processor" 23 | 22,Bookshelf,Furniture,79.99,60,"Wooden bookshelf with adjustable shelves and sturdy construction" 24 | 23,Wall Art,Home Decor,49.99,100,"Canvas wall art with abstract design and ready-to-hang frame" 25 | 24,Running Shorts,Apparel,24.99,200,"Quick-drying running shorts with built-in briefs and zippered pocket" 26 | 25,Hat,Accessories,14.99,180,"Baseball cap with adjustable strap and embroidered logo" 27 | 26,Blender,Appliances,59.99,50,"High-performance blender with 1000W motor and BPA-free pitcher" 28 | 27,Sticky Notes,Stationery,2.99,400,"Pack of 100 sticky notes with assorted colors and adhesive backing" 29 | 28,Travel Backpack,Accessories,34.99,100,"Durable travel backpack with padded laptop compartment and water bottle pockets" 30 | 29,Printer,Electronics,89.99,30,"All-in-one printer with wireless connectivity and automatic document feeder" 31 | 30,Mouse,Electronics,129.99,150,"Wireless optical mouse with ergonomic design and adjustable DPI settings" 32 | 31,Dining Table,Furniture,199.99,40,"Rectangular dining table with solid wood construction and extendable leaf" 33 | 32,Candle Holder,Home Decor,9.99,200,"Metal candle holder with decorative cutout design and glass hurricane" 34 | 33,Sweater,Apparel,34.99,120,"Cozy sweater with ribbed cuffs and hem, made from soft acrylic knit" 35 | 34,Watch,Accessories,49.99,80,"Analog wristwatch with quartz movement and stainless steel band" 36 | 35,Rice Cooker,Appliances,49.99,70,"8-cup rice cooker with non-stick inner pot and automatic keep-warm function" 37 | 36,Notebook Set,Stationery,7.99,250,"Set of 3 notebooks with dotted grid pages and elastic closure" 38 | 37,Gaming Console,Electronics,399.99,25,"Next-gen gaming console with 4K gaming capabilities and SSD storage" 39 | 38,Wireless Mouse,Electronics,29.99,120,"Slim wireless mouse with silent clicking and long battery life" 40 | 39,Shoe Rack,Furniture,29.99,100,"3-tier shoe rack with stackable design and sturdy metal construction" 41 | 40,Wall Mirror,Home Decor,19.99,150,"Round wall mirror with minimalist frame and hook for easy hanging" 42 | 41,Jeans,Apparel,39.99,200,"Classic denim jeans with a slim fit and five-pocket styling" 43 | 42,Scarf,Accessories,12.99,180,"Soft and lightweight scarf made from premium quality fabric" 44 | 43,Microwave,Appliances,79.99,40,"Compact microwave oven with multiple cooking presets and digital display" 45 | 44,Pencil Case,Stationery,3.99,300,"Durable pencil case with zipper closure and multiple compartments" 46 | 45,Digital Camera,Electronics,249.99,50,"High-resolution digital camera with optical zoom and image stabilization" 47 | 46,External Hard Drive,Electronics,79.99,80,"Portable external hard drive with USB 3.0 connectivity and large storage capacity" 48 | 47,Couch,Furniture,399.99,30,"Comfortable couch with plush cushions and sturdy wooden frame" 49 | 48,Plant Pot,Home Decor,8.99,250,"Decorative plant pot made from ceramic material with a glossy finish" 50 | 49,Shorts,Apparel,14.99,180,"Casual shorts made from breathable fabric and featuring an elastic waistband" 51 | 50,Wallet,Accessories,19.99,120,"Stylish wallet with multiple card slots and a zippered coin pocket" 52 | 51,Laptop,Electronics,999.99,50,"High-performance laptop with Intel Core i7 processor and 16GB RAM" 53 | 52,Laptop,Electronics,1099.99,40,"Slim and lightweight laptop with long battery life and fast SSD storage" 54 | 53,Laptop,Electronics,1199.99,30,"Gaming laptop with dedicated NVIDIA graphics card and RGB keyboard" 55 | 54,Phones,Electronics,699.99,100,"Latest smartphone model with 6.5-inch OLED display and dual-camera setup" 56 | 55,Phones,Electronics,799.99,90,"Flagship smartphone with high-resolution display and advanced camera features" 57 | 56,Phones,Electronics,899.99,80,"Budget-friendly smartphone with large battery capacity and fast charging" 58 | 57,TV,Electronics,799.99,60,"Smart TV with 4K Ultra HD resolution and built-in streaming apps" 59 | 58,TV,Electronics,899.99,50,"Curved LED TV with immersive sound quality and HDR support" 60 | 59,TV,Electronics,999.99,40,"OLED TV with Dolby Vision and Dolby Atmos for cinematic viewing experience" 61 | 60,Sunglass,Accessories,29.99,100,"Polarized sunglasses with UV400 protection and lightweight frame" 62 | 61,Sunglass,Accessories,39.99,80,"Designer sunglasses with mirrored lenses and durable acetate frame" 63 | 62,Sunglass,Accessories,49.99,70,"Sporty sunglasses with wraparound design and impact-resistant lenses" 64 | 63,Dining Table,Furniture,199.99,40,"Rectangular dining table with solid wood construction and extendable leaf" 65 | 64,Dining Table,Furniture,249.99,30,"Round dining table with pedestal base and elegant marble top" 66 | 65,Dining Table,Furniture,299.99,25,"Outdoor dining table with weather-resistant finish and umbrella hole" 67 | 66,Mouse,Electronics,199.99,150,"Premium wireless mouse with ergonomic design, customizable buttons, and smooth scrolling" 68 | 67,Mouse,Electronics,299.99,120,"Gaming mouse with customizable RGB lighting and programmable buttons" 69 | 68,Mouse,Electronics,499.99,100,"Bluetooth mouse with silent clicking and rechargeable battery" 70 | 69,Printer,Electronics,89.99,30,"All-in-one printer with wireless connectivity and automatic document feeder" 71 | 70,Printer,Electronics,99.99,25,"Color laser printer with mobile printing capabilities and duplex printing" 72 | 73 | -------------------------------------------------------------------------------- /Freshdesk Ticketing Automation with AI Agents/.env.example: -------------------------------------------------------------------------------- 1 | # .env Template File 2 | 3 | DB_HOST = 4 | DB_NAME = 5 | DB_PASSWORD = 6 | DB_USER = 7 | DB_PORT = 8 | 9 | OPENAI_API_KEY= 10 | FRESHDESK_API_KEY= 11 | FRESHDESK_URL= -------------------------------------------------------------------------------- /Freshdesk Ticketing Automation with AI Agents/docs/Company Overview.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Freshdesk Ticketing Automation with AI Agents/docs/Company Overview.pdf -------------------------------------------------------------------------------- /Freshdesk Ticketing Automation with AI Agents/docs/Contact Information.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Freshdesk Ticketing Automation with AI Agents/docs/Contact Information.pdf -------------------------------------------------------------------------------- /Freshdesk Ticketing Automation with AI Agents/docs/Payment Methods Supported.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Freshdesk Ticketing Automation with AI Agents/docs/Payment Methods Supported.pdf -------------------------------------------------------------------------------- /Freshdesk Ticketing Automation with AI Agents/docs/Privacy Policy.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Freshdesk Ticketing Automation with AI Agents/docs/Privacy Policy.pdf -------------------------------------------------------------------------------- /Freshdesk Ticketing Automation with AI Agents/docs/Promotion and Discount.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Freshdesk Ticketing Automation with AI Agents/docs/Promotion and Discount.pdf -------------------------------------------------------------------------------- /Freshdesk Ticketing Automation with AI Agents/docs/Return Policy.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Freshdesk Ticketing Automation with AI Agents/docs/Return Policy.pdf -------------------------------------------------------------------------------- /Freshdesk Ticketing Automation with AI Agents/docs/Shipping Policy.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Freshdesk Ticketing Automation with AI Agents/docs/Shipping Policy.pdf -------------------------------------------------------------------------------- /Freshdesk Ticketing Automation with AI Agents/docs/Warranty Policy.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Freshdesk Ticketing Automation with AI Agents/docs/Warranty Policy.pdf -------------------------------------------------------------------------------- /Google OAuth Integration with FastAPI/.env: -------------------------------------------------------------------------------- 1 | ####Database#### 2 | DB_HOST= 3 | DB_USER= 4 | DB_PASSWORD= 5 | DB_PORT= 6 | DB_NAME=>database-name> 7 | 8 | #AUTH 9 | GOOGLE_CLIENT_ID = 10 | GOOGLE_CLIENT_SECRET = 11 | SECRET_KEY = 12 | REDIRECT_URL = "http://127.0.0.1:8000/auth" 13 | FRONTEND_URL = "http://localhost:8000/docs" 14 | JWT_SECRET_KEY = 15 | -------------------------------------------------------------------------------- /Google OAuth Integration with FastAPI/api.py: -------------------------------------------------------------------------------- 1 | import os 2 | from fastapi import FastAPI, Header, HTTPException, Depends, Request 3 | from starlette.config import Config 4 | from fastapi.middleware.cors import CORSMiddleware 5 | from starlette.middleware.sessions import SessionMiddleware 6 | from apis import chatbot, authentication 7 | import logging as logger 8 | import time 9 | 10 | 11 | from dotenv import load_dotenv 12 | load_dotenv(override=True) 13 | 14 | config = Config(".env") 15 | 16 | 17 | expected_api_secret = os.getenv("FASTAPI_SECRET_KEY") 18 | 19 | app = FastAPI() 20 | 21 | 22 | app.add_middleware( 23 | CORSMiddleware, 24 | allow_origins=["*"], # or specify allowed origins 25 | allow_credentials=True, 26 | allow_methods=["*"], 27 | allow_headers=["*"], 28 | expose_headers=["*"] 29 | ) 30 | 31 | 32 | # Add Session middleware 33 | app.add_middleware(SessionMiddleware, secret_key=config("SECRET_KEY")) 34 | 35 | # # Logging time taken for each api request 36 | @app.middleware("http") 37 | async def log_response_time(request: Request, call_next): 38 | start_time = time.time() 39 | response = await call_next(request) 40 | process_time = time.time() - start_time 41 | logger.info(f"Request: {request.url.path} completed in {process_time:.4f} seconds") 42 | return response 43 | 44 | app.include_router(chatbot.router, tags=["Chatbot"]) 45 | app.include_router(authentication.router, tags=["Authentication"]) 46 | 47 | if __name__ == "__main__": 48 | import uvicorn 49 | uvicorn.run(app, host="0.0.0.0", port=8000) 50 | 51 | -------------------------------------------------------------------------------- /Google OAuth Integration with FastAPI/apis/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Google OAuth Integration with FastAPI/apis/__init__.py -------------------------------------------------------------------------------- /Google OAuth Integration with FastAPI/apis/__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Google OAuth Integration with FastAPI/apis/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /Google OAuth Integration with FastAPI/apis/__pycache__/__init__.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Google OAuth Integration with FastAPI/apis/__pycache__/__init__.cpython-312.pyc -------------------------------------------------------------------------------- /Google OAuth Integration with FastAPI/apis/__pycache__/admin_prompts.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Google OAuth Integration with FastAPI/apis/__pycache__/admin_prompts.cpython-311.pyc -------------------------------------------------------------------------------- /Google OAuth Integration with FastAPI/apis/__pycache__/admin_prompts.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Google OAuth Integration with FastAPI/apis/__pycache__/admin_prompts.cpython-312.pyc -------------------------------------------------------------------------------- /Google OAuth Integration with FastAPI/apis/__pycache__/authentication.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Google OAuth Integration with FastAPI/apis/__pycache__/authentication.cpython-312.pyc -------------------------------------------------------------------------------- /Google OAuth Integration with FastAPI/apis/__pycache__/chatbot.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Google OAuth Integration with FastAPI/apis/__pycache__/chatbot.cpython-311.pyc -------------------------------------------------------------------------------- /Google OAuth Integration with FastAPI/apis/__pycache__/chatbot.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Google OAuth Integration with FastAPI/apis/__pycache__/chatbot.cpython-312.pyc -------------------------------------------------------------------------------- /Google OAuth Integration with FastAPI/apis/__pycache__/chatbot_knowledge.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Google OAuth Integration with FastAPI/apis/__pycache__/chatbot_knowledge.cpython-312.pyc -------------------------------------------------------------------------------- /Google OAuth Integration with FastAPI/apis/__pycache__/chatbot_support.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Google OAuth Integration with FastAPI/apis/__pycache__/chatbot_support.cpython-312.pyc -------------------------------------------------------------------------------- /Google OAuth Integration with FastAPI/apis/__pycache__/document.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Google OAuth Integration with FastAPI/apis/__pycache__/document.cpython-311.pyc -------------------------------------------------------------------------------- /Google OAuth Integration with FastAPI/apis/__pycache__/session_api.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Google OAuth Integration with FastAPI/apis/__pycache__/session_api.cpython-312.pyc -------------------------------------------------------------------------------- /Google OAuth Integration with FastAPI/apis/__pycache__/widget_support.cpython-312.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Google OAuth Integration with FastAPI/apis/__pycache__/widget_support.cpython-312.pyc -------------------------------------------------------------------------------- /Google OAuth Integration with FastAPI/apis/authentication.py: -------------------------------------------------------------------------------- 1 | from fastapi import APIRouter, Query 2 | from authlib.integrations.starlette_client import OAuth 3 | from starlette.config import Config 4 | from fastapi.responses import JSONResponse 5 | from datetime import datetime, timedelta 6 | from fastapi import HTTPException, status, Request, Cookie 7 | from authlib.integrations.starlette_client import OAuth 8 | from starlette.config import Config 9 | from starlette.responses import RedirectResponse 10 | from fastapi.responses import JSONResponse 11 | from jose import JWTError, jwt, ExpiredSignatureError, JWTError 12 | import traceback 13 | import requests 14 | import uuid 15 | import os 16 | from dotenv import load_dotenv 17 | from pydantic import ValidationError 18 | from typing import Optional 19 | from google.oauth2 import service_account 20 | import google.auth.transport.requests 21 | from google.oauth2.id_token import verify_oauth2_token 22 | from db_utils.db import log_user, log_token 23 | import logging as logger 24 | 25 | load_dotenv(override=True) 26 | 27 | router = APIRouter() 28 | 29 | # Load configurations 30 | config = Config(".env") 31 | 32 | # Setup OAuth2 33 | oauth = OAuth() 34 | 35 | oauth.register( 36 | name="auth_demo", 37 | client_id=config("GOOGLE_CLIENT_ID"), 38 | client_secret=config("GOOGLE_CLIENT_SECRET"), 39 | authorize_url="https://accounts.google.com/o/oauth2/auth", 40 | authorize_params=None, 41 | access_token_url="https://accounts.google.com/o/oauth2/token", 42 | access_token_params=None, 43 | refresh_token_url=None, 44 | authorize_state=config("SECRET_KEY"), 45 | redirect_uri="http://127.0.0.1:8000/auth", 46 | jwks_uri="https://www.googleapis.com/oauth2/v3/certs", 47 | client_kwargs={"scope": "openid profile email"}, 48 | ) 49 | 50 | 51 | # Secret key used to encode JWT tokens (should be kept secret) 52 | SECRET_KEY = config("JWT_SECRET_KEY") 53 | ALGORITHM = "HS256" 54 | REDIRECT_URL = config("REDIRECT_URL") 55 | FRONTEND_URL = config("FRONTEND_URL") 56 | 57 | 58 | def create_access_token(data: dict, expires_delta: timedelta = None): 59 | to_encode = data.copy() 60 | if expires_delta: 61 | expire = datetime.utcnow() + expires_delta 62 | else: 63 | expire = datetime.utcnow() + timedelta(minutes=30) 64 | to_encode.update({"exp": expire}) 65 | encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM) 66 | return encoded_jwt 67 | 68 | 69 | def get_current_user(token: str = Cookie(None)): 70 | if not token: 71 | raise HTTPException(status_code=401, detail="Not authenticated") 72 | 73 | credentials_exception = HTTPException( 74 | status_code=401, 75 | detail="Could not validate credentials", 76 | headers={"WWW-Authenticate": "Bearer"}, 77 | ) 78 | try: 79 | payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) 80 | 81 | user_id: str = payload.get("sub") 82 | user_email: str = payload.get("email") 83 | 84 | if user_id is None or user_email is None: 85 | raise credentials_exception 86 | 87 | return {"user_id": user_id, "user_email": user_email} 88 | 89 | except ExpiredSignatureError: 90 | # Specifically handle expired tokens 91 | traceback.print_exc() 92 | raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Session expired. Please login again.") 93 | except JWTError: 94 | # Handle other JWT-related errors 95 | traceback.print_exc() 96 | raise credentials_exception 97 | except Exception as e: 98 | traceback.print_exc() 99 | raise HTTPException(status_code=401, detail="Not Authenticated") 100 | 101 | 102 | 103 | @router.get("/login") 104 | async def login(request: Request): 105 | request.session.clear() 106 | referer = request.headers.get("referer") 107 | FRONTEND_URL = os.getenv("FRONTEND_URL") 108 | redirect_url = os.getenv("REDIRECT_URL") 109 | request.session["login_redirect"] = redirect_url 110 | 111 | return await oauth.auth_demo.authorize_redirect(request, FRONTEND_URL, prompt="consent") 112 | 113 | 114 | @router.route("/auth") 115 | async def auth(request: Request): 116 | state_in_request = request.query_params.get("state") 117 | 118 | logger.info(f"Request Session: {request.session}") 119 | 120 | logger.info(f"Request state (from query params): {state_in_request}") 121 | 122 | try: 123 | token = await oauth.auth_demo.authorize_access_token(request) 124 | except Exception as e: 125 | logger.info(str(e)) 126 | raise HTTPException(status_code=401, detail="Google authentication failed.") 127 | 128 | try: 129 | user_info_endpoint = "https://www.googleapis.com/oauth2/v2/userinfo" 130 | headers = {"Authorization": f'Bearer {token["access_token"]}'} 131 | google_response = requests.get(user_info_endpoint, headers=headers) 132 | user_info = google_response.json() 133 | except Exception as e: 134 | logger.info(str(e)) 135 | raise HTTPException(status_code=401, detail="Google authentication failed.") 136 | 137 | user = token.get("userinfo") 138 | expires_in = token.get("expires_in") 139 | user_id = user.get("sub") 140 | iss = user.get("iss") 141 | user_email = user.get("email") 142 | first_logged_in = datetime.utcnow() 143 | last_accessed = datetime.utcnow() 144 | 145 | user_name = user_info.get("name") 146 | user_pic = user_info.get("picture") 147 | 148 | logger.info(f"User name:{user_name}") 149 | logger.info(f"User Email:{user_email}") 150 | 151 | if iss not in ["https://accounts.google.com", "accounts.google.com"]: 152 | raise HTTPException(status_code=401, detail="Google authentication failed.") 153 | 154 | if user_id is None: 155 | raise HTTPException(status_code=401, detail="Google authentication failed.") 156 | 157 | # Create JWT token 158 | access_token_expires = timedelta(seconds=expires_in) 159 | access_token = create_access_token(data={"sub": user_id, "email": user_email}, expires_delta=access_token_expires) 160 | 161 | session_id = str(uuid.uuid4()) 162 | log_user(user_id, user_email, user_name, user_pic, first_logged_in, last_accessed) 163 | log_token(access_token, user_email, session_id) 164 | 165 | redirect_url = request.session.pop("login_redirect", "") 166 | logger.info(f"Redirecting to: {redirect_url}") 167 | response = RedirectResponse(redirect_url) 168 | print(f"Access Token: {access_token}") 169 | response.set_cookie( 170 | key="token", 171 | value=access_token, 172 | httponly=True, 173 | secure=True, # Ensure you're using HTTPS 174 | samesite="strict", # Set the SameSite attribute to None 175 | ) 176 | 177 | return response 178 | 179 | @router.get("/logout") 180 | async def logout(request: Request): 181 | request.session.clear() 182 | response = JSONResponse(content={"message": "Logged out successfully."}) 183 | response.delete_cookie("token") 184 | return response 185 | -------------------------------------------------------------------------------- /Google OAuth Integration with FastAPI/apis/chatbot.py: -------------------------------------------------------------------------------- 1 | from fastapi import APIRouter 2 | import logging 3 | from fastapi import Depends 4 | import os 5 | from datetime import * 6 | from apis.authentication import get_current_user 7 | 8 | 9 | router = APIRouter() 10 | 11 | @router.get("/chat") 12 | async def get_response(current_user: dict = Depends(get_current_user)): 13 | return {"message": "Welcome!", "user": current_user} 14 | 15 | 16 | if __name__ == "__main__": 17 | import uvicorn 18 | uvicorn.run(router, host="0.0.0.0", port=8000) 19 | -------------------------------------------------------------------------------- /Google OAuth Integration with FastAPI/db_utils/db.py: -------------------------------------------------------------------------------- 1 | import mysql.connector 2 | from mysql.connector.errors import Error 3 | import os 4 | from datetime import datetime 5 | import logging as logger 6 | 7 | host=os.getenv("DB_HOST") 8 | user=os.getenv("DB_USER") 9 | password=os.getenv("DB_PASSWORD") 10 | database=os.getenv("DB_NAME") 11 | port=os.getenv("DB_PORT") 12 | 13 | def log_user(user_id, user_email, user_name, user_pic, first_logged_in, last_accessed): 14 | try: 15 | connection = mysql.connector.connect(host=host, database=database, user=user, password=password) 16 | 17 | if connection.is_connected(): 18 | cursor = connection.cursor() 19 | sql_query = """SELECT COUNT(*) from users WHERE email_id = %s""" 20 | cursor.execute(sql_query, (user_email,)) 21 | row_count = cursor.fetchone()[0] 22 | 23 | if row_count == 0: 24 | sql_query = """INSERT INTO users (user_id, email_id,user_name,user_pic,first_logged_in, last_accessed) VALUES (%s, %s, %s, %s, %s, %s)""" 25 | cursor.execute(sql_query, (user_id, user_email, user_name, user_pic, first_logged_in, last_accessed)) 26 | 27 | # Commit changes 28 | connection.commit() 29 | logger.info("Record inserted successfully") 30 | 31 | except Error as e: 32 | logger.info("Error while connecting to MySQL", e) 33 | finally: 34 | if connection.is_connected(): 35 | cursor.close() 36 | connection.close() 37 | logger.info("MySQL connection is closed") 38 | 39 | def log_token(access_token, user_email, session_id): 40 | try: 41 | connection = mysql.connector.connect(host=host, database=database, user=user, password=password) 42 | 43 | if connection.is_connected(): 44 | cursor = connection.cursor() 45 | 46 | # SQL query to insert data 47 | sql_query = """INSERT INTO issued_tokens (token, email_id, session_id) VALUES (%s,%s,%s)""" 48 | # Execute the SQL query 49 | cursor.execute(sql_query, (access_token, user_email, session_id)) 50 | 51 | # Commit changes 52 | connection.commit() 53 | logger.info("Record inserted successfully") 54 | 55 | except Error as e: 56 | logger.info("Error while connecting to MySQL", e) 57 | finally: 58 | if connection.is_connected(): 59 | cursor.close() 60 | connection.close() 61 | logger.info("MySQL connection is closed") -------------------------------------------------------------------------------- /Google OAuth Integration with FastAPI/requirements.txt: -------------------------------------------------------------------------------- 1 | python-dotenv 2 | mysql-connector-python 3 | requests 4 | fastapi 5 | uvicorn 6 | python-jose[cryptography] 7 | authlib 8 | pyjwt 9 | itsdangerous 10 | google-auth -------------------------------------------------------------------------------- /LangChain Agents with Gmail API/langchain_gmail_demo.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "provenance": [] 7 | }, 8 | "kernelspec": { 9 | "name": "python3", 10 | "display_name": "Python 3" 11 | }, 12 | "language_info": { 13 | "name": "python" 14 | } 15 | }, 16 | "cells": [ 17 | { 18 | "cell_type": "code", 19 | "execution_count": null, 20 | "metadata": { 21 | "id": "Haz6F_gnRjlS" 22 | }, 23 | "outputs": [], 24 | "source": [ 25 | "!pip install --upgrade --quiet google-auth google-auth-oauthlib google-auth-httplib2 google-api-python-client langchain langchain-community langchain-openai langchainhub" 26 | ] 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "source": [ 31 | "### Create the Gmail Toolkit from LangChain" 32 | ], 33 | "metadata": { 34 | "id": "xKUdDGbbq1_Z" 35 | } 36 | }, 37 | { 38 | "cell_type": "code", 39 | "source": [ 40 | "from langchain_community.agent_toolkits import GmailToolkit\n", 41 | "from langchain_community.tools.gmail.utils import (\n", 42 | " build_resource_service,\n", 43 | " get_gmail_credentials,\n", 44 | ")\n", 45 | "\n", 46 | "\n", 47 | "credentials = get_gmail_credentials(\n", 48 | " scopes=[\"https://www.googleapis.com/auth/gmail.readonly\"],\n", 49 | " client_secrets_file=\"/content/web_credentials.json\",\n", 50 | " token_file = \"/content/token.json\"\n", 51 | ")\n", 52 | "\n", 53 | "print(\"credentials Generated....\")\n", 54 | "api_resource = build_resource_service(credentials=credentials)\n", 55 | "toolkit = GmailToolkit(api_resource=api_resource)" 56 | ], 57 | "metadata": { 58 | "id": "Nf4ovfrvBCai", 59 | "colab": { 60 | "base_uri": "https://localhost:8080/" 61 | }, 62 | "outputId": "1cc5f4fd-6a79-47e2-9f97-eea1daa8e316" 63 | }, 64 | "execution_count": null, 65 | "outputs": [ 66 | { 67 | "output_type": "stream", 68 | "name": "stdout", 69 | "text": [ 70 | "credentials Generated....\n" 71 | ] 72 | } 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "source": [ 78 | "tools = toolkit.get_tools()\n", 79 | "tools" 80 | ], 81 | "metadata": { 82 | "colab": { 83 | "base_uri": "https://localhost:8080/" 84 | }, 85 | "id": "Y8d0GUffCawH", 86 | "outputId": "19fc2a8e-fcac-4f4f-f236-af4ec09644b0" 87 | }, 88 | "execution_count": null, 89 | "outputs": [ 90 | { 91 | "output_type": "execute_result", 92 | "data": { 93 | "text/plain": [ 94 | "[GmailCreateDraft(api_resource=),\n", 95 | " GmailSendMessage(api_resource=),\n", 96 | " GmailSearch(api_resource=),\n", 97 | " GmailGetMessage(api_resource=),\n", 98 | " GmailGetThread(api_resource=)]" 99 | ] 100 | }, 101 | "metadata": {}, 102 | "execution_count": 3 103 | } 104 | ] 105 | }, 106 | { 107 | "cell_type": "markdown", 108 | "source": [ 109 | "### Passing your Openai API Key" 110 | ], 111 | "metadata": { 112 | "id": "l6j47L7Jq_gl" 113 | } 114 | }, 115 | { 116 | "cell_type": "code", 117 | "source": [ 118 | "import getpass\n", 119 | "import os\n", 120 | "\n", 121 | "os.environ[\"OPENAI_API_KEY\"] = getpass.getpass()" 122 | ], 123 | "metadata": { 124 | "id": "bUWQ-oRpDTgs", 125 | "colab": { 126 | "base_uri": "https://localhost:8080/" 127 | }, 128 | "outputId": "0978dbd7-9fab-41c3-e25f-b7239d13d3dc" 129 | }, 130 | "execution_count": null, 131 | "outputs": [ 132 | { 133 | "name": "stdout", 134 | "output_type": "stream", 135 | "text": [ 136 | "··········\n" 137 | ] 138 | } 139 | ] 140 | }, 141 | { 142 | "cell_type": "markdown", 143 | "source": [ 144 | "### Working with Gmails with OpenAI Tools Agent" 145 | ], 146 | "metadata": { 147 | "id": "hs5ZJwWqrKBx" 148 | } 149 | }, 150 | { 151 | "cell_type": "code", 152 | "source": [ 153 | "from langchain import hub\n", 154 | "from langchain.agents import AgentExecutor, create_openai_tools_agent\n", 155 | "from langchain_openai import ChatOpenAI" 156 | ], 157 | "metadata": { 158 | "id": "BRn0Fp2bDxnq" 159 | }, 160 | "execution_count": null, 161 | "outputs": [] 162 | }, 163 | { 164 | "cell_type": "code", 165 | "source": [ 166 | "instructions = \"\"\"You are an assistant.\"\"\"\n", 167 | "base_prompt = hub.pull(\"langchain-ai/openai-functions-template\")\n", 168 | "prompt = base_prompt.partial(instructions=instructions)" 169 | ], 170 | "metadata": { 171 | "id": "B5tX0DVxD07g" 172 | }, 173 | "execution_count": null, 174 | "outputs": [] 175 | }, 176 | { 177 | "cell_type": "code", 178 | "source": [ 179 | "prompt" 180 | ], 181 | "metadata": { 182 | "colab": { 183 | "base_uri": "https://localhost:8080/" 184 | }, 185 | "id": "phl7vbXd7965", 186 | "outputId": "3fd07d2f-fd7f-47d2-bfb3-6bff81574312" 187 | }, 188 | "execution_count": null, 189 | "outputs": [ 190 | { 191 | "output_type": "execute_result", 192 | "data": { 193 | "text/plain": [ 194 | "ChatPromptTemplate(input_variables=['agent_scratchpad', 'input'], input_types={'chat_history': typing.List[typing.Union[langchain_core.messages.ai.AIMessage, langchain_core.messages.human.HumanMessage, langchain_core.messages.chat.ChatMessage, langchain_core.messages.system.SystemMessage, langchain_core.messages.function.FunctionMessage, langchain_core.messages.tool.ToolMessage]], 'agent_scratchpad': typing.List[typing.Union[langchain_core.messages.ai.AIMessage, langchain_core.messages.human.HumanMessage, langchain_core.messages.chat.ChatMessage, langchain_core.messages.system.SystemMessage, langchain_core.messages.function.FunctionMessage, langchain_core.messages.tool.ToolMessage]]}, partial_variables={'instructions': 'You are an assistant.'}, metadata={'lc_hub_owner': 'langchain-ai', 'lc_hub_repo': 'openai-functions-template', 'lc_hub_commit_hash': 'b4198088b0f11cbe911a9e1cb6546893c00283b6cf0f80ae003b3955efdfe281'}, messages=[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=['instructions'], template='{instructions}')), MessagesPlaceholder(variable_name='chat_history', optional=True), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], template='{input}')), MessagesPlaceholder(variable_name='agent_scratchpad')])" 195 | ] 196 | }, 197 | "metadata": {}, 198 | "execution_count": 6 199 | } 200 | ] 201 | }, 202 | { 203 | "cell_type": "code", 204 | "source": [ 205 | "llm = ChatOpenAI(temperature=0)" 206 | ], 207 | "metadata": { 208 | "id": "0EOomk4ED_L9" 209 | }, 210 | "execution_count": null, 211 | "outputs": [] 212 | }, 213 | { 214 | "cell_type": "code", 215 | "source": [ 216 | "agent = create_openai_tools_agent(llm, toolkit.get_tools(), prompt)" 217 | ], 218 | "metadata": { 219 | "id": "EFxek3tLD6-8" 220 | }, 221 | "execution_count": null, 222 | "outputs": [] 223 | }, 224 | { 225 | "cell_type": "code", 226 | "source": [ 227 | "agent_executor = AgentExecutor(\n", 228 | " agent=agent,\n", 229 | " tools=toolkit.get_tools(),\n", 230 | " # This is set to False to prevent information about my email showing up on the screen\n", 231 | " # Normally, it is helpful to have it set to True however.\n", 232 | " verbose=True,\n", 233 | ")" 234 | ], 235 | "metadata": { 236 | "id": "OxVDBrHaEBd0" 237 | }, 238 | "execution_count": null, 239 | "outputs": [] 240 | }, 241 | { 242 | "cell_type": "code", 243 | "source": [ 244 | "agent_executor.invoke(\n", 245 | " {\n", 246 | " \"input\": \"Create a gmail draft for me to reschedule my meeting from sunday to morning to monday morning\"\n", 247 | " \" as I will be not available because of a football match. The recipient is rounak.1210@gmail.com\"\n", 248 | " \" keep the tone of the email polite\"\n", 249 | " }\n", 250 | ")" 251 | ], 252 | "metadata": { 253 | "colab": { 254 | "base_uri": "https://localhost:8080/" 255 | }, 256 | "id": "FNIyQnBdEIqI", 257 | "outputId": "b8bb6498-df3a-4cf3-f111-ecee62d48640" 258 | }, 259 | "execution_count": null, 260 | "outputs": [ 261 | { 262 | "output_type": "stream", 263 | "name": "stdout", 264 | "text": [ 265 | "\n", 266 | "\n", 267 | "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", 268 | "\u001b[32;1m\u001b[1;3m\n", 269 | "Invoking: `create_gmail_draft` with `{'message': 'Dear Rounak, \\n\\nI hope this message finds you well. I wanted to inform you that I have a prior commitment on Sunday morning and will not be available for our meeting. Would it be possible to reschedule our meeting to Monday morning instead? I apologize for any inconvenience this may cause. Thank you for your understanding. \\n\\nBest regards, [Your Name]', 'to': ['rounak.1210@gmail.com'], 'subject': 'Meeting Rescheduling Request'}`\n", 270 | "\n", 271 | "\n", 272 | "\u001b[0m\u001b[36;1m\u001b[1;3mDraft created. Draft Id: r-922369640620305716\u001b[0m\u001b[32;1m\u001b[1;3mI have created a draft email for you to reschedule your meeting from Sunday morning to Monday morning. The draft has been saved, and you can review and send it from your Gmail account.\u001b[0m\n", 273 | "\n", 274 | "\u001b[1m> Finished chain.\u001b[0m\n" 275 | ] 276 | }, 277 | { 278 | "output_type": "execute_result", 279 | "data": { 280 | "text/plain": [ 281 | "{'input': 'Create a gmail draft for me to reschedule my meeting from sunday to morning to monday morning as I will be not available because of a football match. The recipient is rounak.1210@gmail.com keep the tone of the email polite',\n", 282 | " 'output': 'I have created a draft email for you to reschedule your meeting from Sunday morning to Monday morning. The draft has been saved, and you can review and send it from your Gmail account.'}" 283 | ] 284 | }, 285 | "metadata": {}, 286 | "execution_count": 12 287 | } 288 | ] 289 | }, 290 | { 291 | "cell_type": "code", 292 | "source": [ 293 | "agent_executor.invoke(\n", 294 | " {\"input\": \"Could you search in primary inbox for the latest email? what is the title?\"}\n", 295 | ")" 296 | ], 297 | "metadata": { 298 | "colab": { 299 | "base_uri": "https://localhost:8080/" 300 | }, 301 | "id": "0fZ0KmYmEgaT", 302 | "outputId": "cb694274-0354-4ab7-e7c3-eae42e7a8a1e" 303 | }, 304 | "execution_count": null, 305 | "outputs": [ 306 | { 307 | "output_type": "stream", 308 | "name": "stdout", 309 | "text": [ 310 | "\n", 311 | "\n", 312 | "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", 313 | "\u001b[32;1m\u001b[1;3m\n", 314 | "Invoking: `search_gmail` with `{'query': 'label:inbox category:primary', 'max_results': 1}`\n", 315 | "\n", 316 | "\n", 317 | "\u001b[0m\u001b[38;5;200m\u001b[1;3m[{'id': '18e609ee4cb6fb88', 'threadId': '18e609ee4cb6fb88', 'snippet': '[11/25/2023, 12:06] Rik: Developed a Python-based NLP tool using Google API and BERT for sentiment analysis of YouTube video comments. I scraped comments from YouTube video URLs, conducted contextual', 'body': '[11/25/2023, 12:06] Rik: Developed a Python-based NLP tool using Google API\\r\\nand BERT for sentiment analysis of YouTube video comments. I scraped\\r\\ncomments from YouTube video URLs, conducted contextual sentiment analysis,\\r\\nand predicted sentiment as star ratings (1-5).\\r\\n[11/25/2023, 12:08] Rik: Moreover, my News QnA Analyzer Tool project\\r\\ninvolved implementing advanced NLP techniques. I developed and implemented\\r\\nan automated content analysis tool that processed URLs of news articles,\\r\\ndelivering comprehensive answers to user-generated\\r\\nquestions; reduced research time by 50% and improved content accuracy by\\r\\n20%. I utilize Langchain and LLM to automatically analyze news articles and\\r\\nprovide detailed answers to user-generated questions related to the content.\\r\\n', 'subject': 'Sample msg', 'sender': 'Rounak show '}]\u001b[0m\u001b[32;1m\u001b[1;3mThe latest email in your primary inbox has the title \"Sample msg\".\u001b[0m\n", 318 | "\n", 319 | "\u001b[1m> Finished chain.\u001b[0m\n" 320 | ] 321 | }, 322 | { 323 | "output_type": "execute_result", 324 | "data": { 325 | "text/plain": [ 326 | "{'input': 'Could you search in primary inbox for the latest email? what is the title?',\n", 327 | " 'output': 'The latest email in your primary inbox has the title \"Sample msg\".'}" 328 | ] 329 | }, 330 | "metadata": {}, 331 | "execution_count": 27 332 | } 333 | ] 334 | }, 335 | { 336 | "cell_type": "markdown", 337 | "source": [ 338 | "### Pass Custom Prompt" 339 | ], 340 | "metadata": { 341 | "id": "QpZzG7j7rlHG" 342 | } 343 | }, 344 | { 345 | "cell_type": "code", 346 | "source": [ 347 | "from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n", 348 | "\n", 349 | "prompt = ChatPromptTemplate.from_messages(\n", 350 | " [\n", 351 | " (\"system\", \"\"\"\n", 352 | "You are a helpful assistant.\n", 353 | "\"\"\"),\n", 354 | " MessagesPlaceholder(\"chat_history\", optional=True),\n", 355 | " (\"human\", \"{input}\"),\n", 356 | " MessagesPlaceholder(\"agent_scratchpad\"),\n", 357 | " ]\n", 358 | ")\n", 359 | "\n", 360 | "agent = create_openai_tools_agent(llm, tools, prompt)\n", 361 | "agent_executor = AgentExecutor(\n", 362 | " agent=agent,\n", 363 | " tools=tools,\n", 364 | " verbose=True,\n", 365 | " return_intermediate_steps=True\n", 366 | " )\n", 367 | "\n", 368 | "response = agent_executor.invoke(\n", 369 | " {\n", 370 | " \"input\": user_query,\n", 371 | " \"chat_history\": chat_history,\n", 372 | " }\n", 373 | " )\n" 374 | ], 375 | "metadata": { 376 | "id": "jM-37mFdyjpj" 377 | }, 378 | "execution_count": null, 379 | "outputs": [] 380 | } 381 | ] 382 | } -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/.env.example: -------------------------------------------------------------------------------- 1 | qdrant_db_path ='http://localhost:6333' 2 | OPENAI_API_KEY= 3 | llm_provider="openai" 4 | model="gpt-4o-mini" 5 | temperature="0.1" -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/api.py: -------------------------------------------------------------------------------- 1 | from fastapi import FastAPI, HTTPException, UploadFile, File, Form 2 | from pydantic import BaseModel 3 | from typing import Optional,List 4 | import uuid 5 | import logging 6 | from fastapi import HTTPException, APIRouter 7 | import logging 8 | import uuid,time 9 | from fastapi.responses import JSONResponse 10 | from typing import List 11 | from fastapi import Depends 12 | import langsmith as ls 13 | import nest_asyncio 14 | import os 15 | from datetime import * 16 | from services.pydantic_models import ChatRequest,ChatResponse 17 | from services.logger import logger 18 | import langsmith as ls 19 | from langsmith.wrappers import wrap_openai 20 | from fastapi.openapi.models import Response 21 | from typing import AsyncGenerator 22 | from uuid import uuid4 23 | import asyncio 24 | from utils.db_utils import get_past_conversation_async,add_conversation_async 25 | from utils.langchain_utils import generate_chatbot_response, index_documents 26 | from utils.utils import extract_text_from_file 27 | import uvicorn 28 | import aiomonitor 29 | nest_asyncio.apply() 30 | 31 | 32 | 33 | app = FastAPI() 34 | 35 | @app.post("/upload-knowledge") 36 | async def upload_knwoledge( 37 | username: str = Form(...), 38 | file: Optional[UploadFile] = File(None) 39 | ): 40 | try: 41 | extracted_text = "" 42 | if file: 43 | logger.info(f"File uploaded: {file.filename}") 44 | file_content = await file.read() 45 | file_extension = file.filename.split('.')[-1].lower() 46 | extracted_text = await extract_text_from_file(file_content, file_extension) 47 | logger.info(f"File content size: {len(file_content)} bytes") 48 | logger.info(f"Extracted text from file: {extracted_text}") 49 | 50 | logger.info(f"Indexing documents in QdrantDB") 51 | await index_documents(username,extracted_text,file.filename,file_extension) 52 | return {'response':'Indexed Documents Successfully','extracted_text':extracted_text} 53 | except ValueError as e: 54 | raise HTTPException(status_code=400, detail=str(e)) 55 | except Exception as e: 56 | logger.error(f"Error processing indexing request: {str(e)}") 57 | raise HTTPException(status_code=500, detail=f"An unexpected error occurred while indexing documents {e}") 58 | 59 | @app.post("/chat", response_model=ChatResponse) 60 | async def chat( 61 | request: ChatRequest 62 | ): 63 | try: 64 | start_time = datetime.now() 65 | logger.info(f"Request started at {start_time}") 66 | logger.info(f"Received request from {request.username} for question: {request.query}") 67 | if request.session_id is not None: 68 | logger.info(f"Fetching past messages") 69 | past_messages = await get_past_conversation_async(request.session_id) 70 | 71 | logger.info(f"Fetched past messages: {past_messages}") 72 | elif request.session_id is None: 73 | request.session_id = str(uuid4()) 74 | past_messages = [] 75 | 76 | 77 | logger.info(f"Generating chatbot response") 78 | response, response_time, input_tokens, output_tokens, total_tokens, final_context, refined_query, extracted_documents = await generate_chatbot_response(request.query, past_messages,request.no_of_chunks,request.username) 79 | logger.info(f"Response generated for User question: {request.query}") 80 | 81 | logger.info(f"Adding conversation to chat history") 82 | await add_conversation_async(request.session_id, request.query, response) 83 | logger.info(f"Added conversation to chat history") 84 | 85 | 86 | debug_info = { 87 | "sources": [{"file_name": doc.metadata["file_name"], "context": doc.page_content} for doc in extracted_documents] 88 | } 89 | 90 | end_time = datetime.now() 91 | logger.info(f"Request ended at {end_time}") 92 | return {"username": request.username,"query": request.query,"refine_query": refined_query,"response": response,"session_id": request.session_id,"debug_info": debug_info} 93 | 94 | 95 | except ValueError as e: 96 | raise HTTPException(status_code=400, detail=str(e)) 97 | except Exception as e: 98 | logger.error(f"Error processing chat request: {str(e)}") 99 | raise HTTPException(status_code=500, detail=f"An unexpected error occurred while generating chatbot response {e}") 100 | 101 | 102 | 103 | 104 | # if __name__ == "__main__": 105 | # asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) 106 | # with aiomonitor.start_monitor(loop=asyncio.get_event_loop()): 107 | # uvicorn.run(app, host="0.0.0.0", port=8000) -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/requirements.txt: -------------------------------------------------------------------------------- 1 | langsmith 2 | langchain-qdrant 3 | langchain_core 4 | aiomonitor 5 | python-dotenv 6 | mysql-connector-python 7 | openai 8 | fastapi 9 | uvicorn 10 | langchain 11 | openai 12 | langchain-openai 13 | sentence-transformers 14 | pypdf 15 | nest_asyncio 16 | IPython 17 | PyPDF2 18 | python-docx 19 | beautifulsoup4 20 | python-multipart 21 | aiosqlite -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/services/__pycache__/logger.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Langchain RAG using Async Fastapi and Qdrant/services/__pycache__/logger.cpython-311.pyc -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/services/__pycache__/logger.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Langchain RAG using Async Fastapi and Qdrant/services/__pycache__/logger.cpython-39.pyc -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/services/__pycache__/pydantic_models.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Langchain RAG using Async Fastapi and Qdrant/services/__pycache__/pydantic_models.cpython-311.pyc -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/services/__pycache__/pydantic_models.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Langchain RAG using Async Fastapi and Qdrant/services/__pycache__/pydantic_models.cpython-39.pyc -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/services/logger.py: -------------------------------------------------------------------------------- 1 | import os 2 | from datetime import * 3 | import logging 4 | 5 | today_date = datetime.now().strftime('%Y-%m-%d') 6 | log_base_directory = 'logs' 7 | log_subdirectory = os.path.join(log_base_directory, today_date) 8 | os.makedirs(log_subdirectory, exist_ok=True) 9 | 10 | # Define the path to the log file inside the day-wise subdirectory 11 | log_file_path = os.path.join(log_subdirectory, 'app.log') 12 | 13 | logging.basicConfig( 14 | level=logging.INFO, # Set the default logging level (e.g., DEBUG, INFO, WARNING, ERROR, CRITICAL) 15 | format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', # Log message format 16 | handlers=[ 17 | logging.FileHandler(log_file_path), # Output logs to the log file 18 | logging.StreamHandler() # Output logs to the console (optional) 19 | ] 20 | ) 21 | 22 | logger= logging.getLogger('api_logger') -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/services/pydantic_models.py: -------------------------------------------------------------------------------- 1 | from fastapi import Form, UploadFile, File 2 | from pydantic import BaseModel, field_validator, model_validator 3 | from typing import Optional, List, ClassVar 4 | from datetime import datetime 5 | from enum import Enum 6 | from dotenv import load_dotenv 7 | import os 8 | import re 9 | load_dotenv(override=True) 10 | 11 | 12 | 13 | class ChatRequest(BaseModel): 14 | username: str 15 | query: str 16 | session_id: Optional[str] = None 17 | no_of_chunks: Optional[int] = 3 18 | 19 | 20 | 21 | class ChatResponse(BaseModel): 22 | username: str 23 | query: str 24 | refine_query: str 25 | response: str 26 | session_id: str 27 | debug_info: Optional[dict] = None -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/uploads/nalen.txt: -------------------------------------------------------------------------------- 1 | Here's a look at Nalen Ayurveda, a distinctive e-commerce website that offers skincare products based on Ayurvedic principles. This site stands out with its fresh and airy design, showcasing natural cosmetics that emphasize healing and well-being. 2 | 3 | Features of Nalen Ayurveda 4 | Product Offerings The website features a variety of natural skincare products, including creams and oils, all aimed at promoting a holistic approach to beauty. 5 | Visual Aesthetic The homepage is marked by strong visual elements, such as a beautifully composed image of ginger root, reflecting the essence of their products. The design maintains a balance of simplicity and elegance, creating an inviting atmosphere. 6 | Emotional Copywriting Product descriptions are crafted to resonate emotionally with customers. For example, one cream is described as “Aabha is glowing and radiant,” emphasizing its holistic benefits rather than just its functional aspects. 7 | User Experience 8 | Clean Layout The layout utilizes ample white space, allowing the products to stand out and ensuring an uncluttered browsing experience. 9 | Connection with Nature The overall design and content of the site promote a connection with nature, aligning with the brand's philosophy of using natural ingredients for skincare. 10 | Nalen Ayurveda effectively combines thoughtful design with a strong brand narrative, making it a compelling example of an e-commerce site focused on natural beauty product -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/uploads/watches.txt_6d9782b6-b82f-4584-a9e5-072a07b6581c.txt: -------------------------------------------------------------------------------- 1 | Company Name: Timely Precision 2 | Founder: John Harrison 3 | Founded Date: March 15, 1985 4 | Headquarters: Geneva, Switzerland 5 | Industry: Luxury Watches 6 | Website: www.timelyprecision.com 7 | 8 | About the Company: 9 | Timely Precision is a renowned luxury watchmaker, dedicated to the art of timekeeping since its inception in 1985. Founded by John Harrison, the company has carved a niche for itself in the world of horology, combining traditional craftsmanship with modern innovation. Timely Precision watches are celebrated for their exquisite design, superior quality, and precision engineering, making them a preferred choice for watch enthusiasts and collectors around the globe. 10 | Features: 11 | Swiss Movement: All Timely Precision watches are equipped with Swiss-made movements, ensuring exceptional accuracy and reliability. 12 | Handcrafted Excellence: Each watch is meticulously handcrafted by skilled artisans, maintaining the highest standards of quality. 13 | Innovative Designs: The brand offers a diverse range of designs, from classic elegance to contemporary style, catering to varied tastes. 14 | Premium Materials: Only the finest materials, such as sapphire crystal, premium leather, and stainless steel, are used in the creation of Timely Precision watches. 15 | Water Resistance: Timely Precision watches are designed to withstand various water depths, ensuring durability and functionality in all conditions. 16 | Employees: 17 | Timely Precision employs over 500 dedicated professionals, including master watchmakers, designers, engineers, and support staff. The company fosters a culture of innovation and excellence, encouraging its employees to push the boundaries of horology while preserving the timeless traditions of watchmaking. 18 | -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Langchain RAG using Async Fastapi and Qdrant/utils/__init__.py -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/utils/__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Langchain RAG using Async Fastapi and Qdrant/utils/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/utils/__pycache__/db_utils.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Langchain RAG using Async Fastapi and Qdrant/utils/__pycache__/db_utils.cpython-311.pyc -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/utils/__pycache__/db_utils.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Langchain RAG using Async Fastapi and Qdrant/utils/__pycache__/db_utils.cpython-39.pyc -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/utils/__pycache__/langchain_utils.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Langchain RAG using Async Fastapi and Qdrant/utils/__pycache__/langchain_utils.cpython-311.pyc -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/utils/__pycache__/langchain_utils.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Langchain RAG using Async Fastapi and Qdrant/utils/__pycache__/langchain_utils.cpython-39.pyc -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/utils/__pycache__/prompts.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Langchain RAG using Async Fastapi and Qdrant/utils/__pycache__/prompts.cpython-311.pyc -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/utils/__pycache__/prompts.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Langchain RAG using Async Fastapi and Qdrant/utils/__pycache__/prompts.cpython-39.pyc -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/utils/__pycache__/qdrant_utils.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Langchain RAG using Async Fastapi and Qdrant/utils/__pycache__/qdrant_utils.cpython-311.pyc -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/utils/__pycache__/qdrant_utils.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Langchain RAG using Async Fastapi and Qdrant/utils/__pycache__/qdrant_utils.cpython-39.pyc -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/utils/__pycache__/utils.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Langchain RAG using Async Fastapi and Qdrant/utils/__pycache__/utils.cpython-311.pyc -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/utils/__pycache__/utils.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Langchain RAG using Async Fastapi and Qdrant/utils/__pycache__/utils.cpython-39.pyc -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/utils/db_utils.py: -------------------------------------------------------------------------------- 1 | import sqlite3 2 | import time 3 | import aiosqlite 4 | import asyncio 5 | from typing import List 6 | from services.logger import logger 7 | 8 | 9 | def get_db_connection(): 10 | """Simulate getting a connection to an in-memory SQLite DB.""" 11 | connection = sqlite3.connect(":memory:") # This creates a new in-memory database 12 | return connection, connection.cursor() 13 | 14 | async def get_past_conversation_async(session_id: str) -> List[dict]: 15 | start_time = asyncio.get_event_loop().time() 16 | messages = [] 17 | 18 | try: 19 | # Open an async SQLite connection 20 | async with aiosqlite.connect("chat_log.db") as connection: 21 | await connection.execute('''CREATE TABLE IF NOT EXISTS chat_logs ( 22 | session_id TEXT, 23 | user_query TEXT, 24 | gpt_response TEXT 25 | )''') 26 | logger.info("Database schema ensured.") 27 | 28 | # Fetch chat logs for the given session_id 29 | async with connection.execute( 30 | "SELECT user_query, gpt_response FROM chat_logs WHERE session_id=?", (session_id,) 31 | ) as cursor: 32 | async for row in cursor: 33 | message_user = {"role": "user", "content": row[0]} 34 | message_assistant = {"role": "assistant", "content": row[1]} 35 | messages.extend([message_user, message_assistant]) 36 | 37 | elapsed_time = asyncio.get_event_loop().time() - start_time 38 | logger.info(f"History For Context (get_conversation): {messages} in {elapsed_time:.2f}s") 39 | return messages 40 | 41 | except Exception as e: 42 | logger.exception(f"Error occurred: {str(e)}") 43 | raise e 44 | 45 | 46 | async def add_conversation_async(session_id, user_query, gpt_response): 47 | try: 48 | # Open an async SQLite connection 49 | async with aiosqlite.connect(":memory:") as connection: 50 | cursor = await connection.cursor() 51 | 52 | # Create table if it doesn't exist 53 | await cursor.execute('''CREATE TABLE IF NOT EXISTS chat_logs ( 54 | session_id TEXT, 55 | user_query TEXT, 56 | gpt_response TEXT)''') 57 | 58 | # Insert new conversation 59 | await cursor.execute("INSERT INTO chat_logs (session_id, user_query, gpt_response) VALUES (?, ?, ?)", 60 | (session_id, user_query, gpt_response)) 61 | 62 | await connection.commit() 63 | logger.info(f"Conversation added for session {session_id}") 64 | 65 | except Exception as e: 66 | logger.exception(f"Error occurred while adding conversation: {str(e)}") 67 | raise e 68 | -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/utils/langchain_utils.py: -------------------------------------------------------------------------------- 1 | import langsmith as ls 2 | from langsmith.wrappers import wrap_openai 3 | from langchain_core.output_parsers import StrOutputParser 4 | from langchain_core.chat_history import InMemoryChatMessageHistory 5 | from langchain_openai.chat_models import ChatOpenAI 6 | from langchain.callbacks import get_openai_callback 7 | import time 8 | import os 9 | from utils.prompts import get_query_refiner_prompt, get_main_prompt 10 | from qdrant_client import QdrantClient,AsyncQdrantClient 11 | from utils.qdrant_utils import DocumentIndexer 12 | import asyncio 13 | from services.logger import logger 14 | from dotenv import load_dotenv 15 | 16 | load_dotenv(override=True) 17 | OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") 18 | qdrant_db_path=os.getenv("qdrant_db_path") 19 | 20 | 21 | async def format_docs(docs): 22 | return "\n\n".join(doc.page_content for doc in docs) 23 | 24 | async def index_documents(username,extracted_text,filename,file_extension): 25 | try: 26 | indexer = DocumentIndexer(qdrant_db_path) 27 | start_time = time.time() 28 | logger.info("Searching for similar documents in ChromaDB...") 29 | 30 | await indexer.index_in_qdrantdb( 31 | extracted_text=extracted_text, 32 | file_name=filename, 33 | doc_type=file_extension, 34 | chunk_size=1500 35 | ) 36 | logger.info(f"Document indexing completed in {time.time() - start_time:.2f} seconds") 37 | 38 | except Exception as e: 39 | logger.error(f"Error processing documents: {str(e)}") 40 | raise RuntimeError(f"Failed to process documents: {str(e)}") 41 | 42 | 43 | 44 | async def retrieve_similar_documents(refined_query: str, num_of_chunks: int,username: str) -> str: 45 | try: 46 | indexer = DocumentIndexer(qdrant_db_path) 47 | start_time = time.time() 48 | logger.info("Searching for similar documents in ChromaDB...") 49 | 50 | if num_of_chunks is None: 51 | num_of_chunks = os.getenv('no_of_chunks') 52 | if not isinstance(num_of_chunks, int) or num_of_chunks <= 0: 53 | raise ValueError(f"Invalid number of chunks: {num_of_chunks}") 54 | retriever = await indexer.get_retriever(top_k=num_of_chunks) 55 | if not retriever: 56 | raise ValueError("Failed to initialize document retriever") 57 | extracted_documents = await retriever.ainvoke(refined_query) 58 | if not extracted_documents: 59 | extracted_text_data="" 60 | else: 61 | extracted_text_data = await format_docs(extracted_documents) 62 | logger.info(f"Document retrieval and formatting completed in {time.time() - start_time:.2f} seconds") 63 | return extracted_text_data, extracted_documents 64 | 65 | except Exception as e: 66 | logger.error(f"Error processing documents: {str(e)}") 67 | raise RuntimeError(f"Failed to process documents: {str(e)}") 68 | 69 | 70 | async def invoke_chain(query, context, history, llm): 71 | """Handles the streamed response asynchronously.""" 72 | logger.info(f"Initializing Chain using ...") 73 | final_chain = get_main_prompt() | llm | StrOutputParser() 74 | logger.info("Chain initialized.") 75 | input_data = {"user_query": query, "context": context, "messages": history.messages} 76 | 77 | with get_openai_callback() as cb: 78 | final_response = await final_chain.ainvoke(input_data) # Asynchronous method 79 | 80 | return final_response, cb 81 | 82 | 83 | def create_history(messages): 84 | history = InMemoryChatMessageHistory() 85 | for message in messages: 86 | if message["role"] == "user": 87 | history.add_user_message(message["content"]) 88 | else: 89 | history.add_ai_message(message["content"]) 90 | 91 | return history 92 | 93 | def initialize_llm(model=None, temperature=None, llm_provider=None): 94 | """Initialize the language model.""" 95 | if temperature is None: 96 | temperature = os.getenv('temperature') 97 | if llm_provider is None: 98 | llm_provider = os.getenv('llm_provider') 99 | model= os.getenv('model') 100 | 101 | if llm_provider == "openai": 102 | logger.info(f"Initializing OpenAI model with values {model} and {temperature}") 103 | llm=ChatOpenAI(api_key=OPENAI_API_KEY,temperature=temperature, model_name=model,streaming=True,stream_usage=True) 104 | return llm 105 | 106 | async def refine_user_query(query, messages): 107 | """Refines the user query asynchronously.""" 108 | llm = ChatOpenAI(temperature=0, model_name="gpt-4o") 109 | history = create_history(messages) 110 | prompt = get_query_refiner_prompt() 111 | refined_query_chain = prompt | llm | StrOutputParser() 112 | refined_query = await refined_query_chain.ainvoke({"query": query, "messages": history.messages}) # Async method 113 | return refined_query 114 | 115 | 116 | @ls.traceable(run_type="chain", name="Chat Pipeline") 117 | async def generate_chatbot_response(query, past_messages, no_of_chunks,username): 118 | """Main function to generate chatbot responses asynchronously.""" 119 | logger.info("Refining user query") 120 | refined_query = await refine_user_query(query, past_messages) # Async call 121 | logger.info(f"Generated refined query: {refined_query}") 122 | 123 | extracted_text_data, extracted_documents = await retrieve_similar_documents(refined_query, int(no_of_chunks),username) # Async call 124 | # logger.info(f"Extracted text data: {extracted_text_data}") 125 | logger.info(f"Extracted text data") 126 | 127 | 128 | llm = initialize_llm() # Synchronous initialization 129 | history = create_history(past_messages) 130 | logger.info(f"Created history for session: {history}") 131 | 132 | logger.info("Fetching response") 133 | start_time = time.time() 134 | final_response, cb = await invoke_chain(query, extracted_text_data, history, llm) # Async call 135 | response_time = time.time() - start_time 136 | 137 | # logger.info(f"Got response from chain: {final_response}") 138 | logger.info(f"Got response from chain:") 139 | 140 | return final_response, response_time, cb.prompt_tokens, cb.completion_tokens, cb.total_tokens, extracted_text_data, refined_query, extracted_documents 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | # def create_rag_chain(retriever, llm, prompt): 150 | # return ( 151 | # {"context": retriever, "question": RunnablePassthrough()} 152 | # | prompt 153 | # | llm 154 | # ) 155 | 156 | # def create_chain_qdrant(chroma_persist_directory): 157 | # llm = create_llm() 158 | # prompt = create_prompt() 159 | 160 | # rag_chain = create_rag_chain(retriever, llm, prompt) 161 | # # response = rag_chain.invoke(query) 162 | 163 | # return rag_chain 164 | 165 | 166 | 167 | # def create_chat_history_prompt(): 168 | # contextualize_q_prompt = ChatPromptTemplate.from_messages( 169 | # [ 170 | # ("system", refine_query_prompt), 171 | # MessagesPlaceholder("chat_history"), 172 | # ("human", "{input}"), 173 | # ] 174 | # ) 175 | # qa_prompt = ChatPromptTemplate.from_messages( 176 | # [ 177 | # ("system", question_answering_prompt), 178 | # MessagesPlaceholder("chat_history"), 179 | # ("human", "{input}"), 180 | # ] 181 | # ) 182 | 183 | # return contextualize_q_prompt, qa_prompt -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/utils/prompts.py: -------------------------------------------------------------------------------- 1 | from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder,FewShotChatMessagePromptTemplate,PromptTemplate 2 | from services.logger import logger 3 | 4 | def get_main_prompt(): 5 | prompt = """ 6 | "You are an assistant for question-answering tasks." 7 | "Use the following pieces of retrieved context and user information to answer the question." 8 | "If you don't find the answer of the query,then just say I don't have that information at hand. Please provide more details or check your sources." 9 | """ 10 | 11 | prompt=prompt + "\n\n" + "{context}" 12 | 13 | final_prompt = ChatPromptTemplate.from_messages( 14 | [ 15 | ("system", prompt), 16 | MessagesPlaceholder (variable_name="messages"), 17 | ("human", "{user_query}") 18 | ]) 19 | return final_prompt 20 | 21 | 22 | def get_query_refiner_prompt(): 23 | contextualize_q_system_prompt = (""" 24 | "Given a chat history and the latest user question " 25 | "which might reference context in the chat history, " 26 | "formulate a standalone question which can be understood " 27 | "without the chat history. Do NOT answer the question, " 28 | "just reformulate it if needed and otherwise return it as it is." 29 | """) 30 | 31 | final_prompt = ChatPromptTemplate.from_messages( 32 | [ 33 | ("system", contextualize_q_system_prompt), 34 | MessagesPlaceholder(variable_name="messages"), 35 | ("human","{query}"), 36 | ] 37 | ) 38 | # print(final_prompt) 39 | return final_prompt -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/utils/qdrant_utils.py: -------------------------------------------------------------------------------- 1 | # General Imports 2 | import os 3 | import time 4 | from dotenv import load_dotenv 5 | from uuid import uuid4 6 | import asyncio 7 | 8 | # Langchain imports 9 | from langchain.text_splitter import RecursiveCharacterTextSplitter 10 | from langchain_core.documents import Document 11 | from langchain_qdrant import QdrantVectorStore 12 | from langchain_openai import OpenAIEmbeddings 13 | 14 | # Qdrant imports 15 | from qdrant_client import QdrantClient, AsyncQdrantClient 16 | from qdrant_client.http.models import Distance, VectorParams 17 | 18 | 19 | from services.logger import logger 20 | from uuid import uuid4 21 | 22 | load_dotenv(override=True) 23 | 24 | OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") 25 | qdrant_db_path=os.getenv("qdrant_db_path") 26 | 27 | 28 | 29 | 30 | 31 | class DocumentIndexer: 32 | def __init__(self, qdrant_db_path): 33 | self.db_path = qdrant_db_path 34 | self.embedding_function = OpenAIEmbeddings(model="text-embedding-3-large",api_key=OPENAI_API_KEY) 35 | 36 | self.vectors = None 37 | self.client = AsyncQdrantClient(self.db_path) 38 | 39 | 40 | async def index_in_qdrantdb(self, extracted_text, file_name, doc_type, chunk_size): 41 | """ 42 | Index extracted text in ChromaDB with batch processing to handle large documents. 43 | """ 44 | try: 45 | # Create a Document object 46 | doc = Document( 47 | page_content=extracted_text, 48 | metadata={ 49 | "file_name": file_name, 50 | "doc_type": doc_type 51 | } 52 | ) 53 | 54 | # Use default chunk size if none provided 55 | if chunk_size is None: 56 | # Calculate dynamic chunk size based on text length 57 | text_length = len(extracted_text) 58 | if text_length < 10000: 59 | chunk_size = int(os.getenv("chunk_size")) 60 | elif text_length < 50000: 61 | chunk_size = 1500 62 | else: 63 | chunk_size = 2000 64 | logger.info(f"Using dynamic chunk size: {chunk_size}") 65 | 66 | # Split the document 67 | text_splitter = RecursiveCharacterTextSplitter( 68 | separators=['\n\n', '\n', ','], 69 | chunk_size=chunk_size, 70 | chunk_overlap=200 71 | ) 72 | docus = text_splitter.split_documents([doc]) 73 | 74 | 75 | # Generate UUIDs for all chunks 76 | uuids = [f"{str(uuid4())}" for _ in range(len(docus))] 77 | collection = "rag_demo_collection" 78 | 79 | 80 | collections = await self.client.get_collections() 81 | 82 | if collection in [collection_name.name for collection_name in collections.collections]: 83 | logger.info(f"Collection {collection} already exists in QdrantDB") 84 | else: 85 | await self.client.create_collection( 86 | collection_name=collection, 87 | vectors_config=VectorParams(size=3072, distance=Distance.COSINE)) 88 | 89 | # self.vectors = QdrantVectorStore( 90 | # client=self.client, 91 | # collection_name=collection, 92 | # embedding=self.embedding_function, 93 | # ) 94 | 95 | print(collection) 96 | self.vectors = QdrantVectorStore.from_existing_collection(collection_name=collection, embedding=self.embedding_function, url=self.db_path) 97 | 98 | await self.vectors.aadd_documents(documents=docus, ids=uuids) 99 | 100 | logger.info(f"Successfully indexed document in QdrantDB") 101 | return True 102 | 103 | except Exception as e: 104 | logger.error(f"Error indexing document in QdrantDB: {e}") 105 | raise 106 | 107 | async def get_retriever(self, top_k): 108 | """Get a retriever for querying the indexed documents.""" 109 | try: 110 | collection = "rag_demo_collection" 111 | if self.vectors is None: 112 | # self.vectors = QdrantVectorStore(client=self.client,collection_name=collection,embedding=self.embedding_function) 113 | self.vectors = QdrantVectorStore.from_existing_collection(collection_name=collection, embedding=self.embedding_function, url=self.db_path) 114 | 115 | return self.vectors.as_retriever(search_type="similarity",search_kwargs={"k": top_k}) 116 | except Exception as e: 117 | logger.error(f"Error creating retriever: {e}") 118 | raise 119 | -------------------------------------------------------------------------------- /Langchain RAG using Async Fastapi and Qdrant/utils/utils.py: -------------------------------------------------------------------------------- 1 | import io 2 | import PyPDF2 3 | from docx import Document 4 | from fastapi import HTTPException 5 | import asyncio 6 | 7 | # Async version of the extract_text_from_docx 8 | async def extract_text_from_docx(file_content: bytes) -> str: 9 | """ 10 | Extract text from a DOCX file. 11 | """ 12 | return await asyncio.to_thread(extract_text_from_docx_sync, file_content) 13 | 14 | def extract_text_from_docx_sync(file_content: bytes) -> str: 15 | """ 16 | Extract text from a DOCX file (blocking version). 17 | """ 18 | doc = Document(io.BytesIO(file_content)) 19 | extracted_text = "" 20 | for para in doc.paragraphs: 21 | extracted_text += para.text + "\n" 22 | return extracted_text 23 | 24 | # Async version of the extract_text_from_pdf 25 | async def extract_text_from_pdf(file_content: bytes) -> str: 26 | """ 27 | Extract text from a PDF file. 28 | """ 29 | return await asyncio.to_thread(extract_text_from_pdf_sync, file_content) 30 | 31 | def extract_text_from_pdf_sync(file_content: bytes) -> str: 32 | """ 33 | Extract text from a PDF file (blocking version). 34 | """ 35 | content = "" 36 | pdf_reader = PyPDF2.PdfReader(file_content) 37 | num_pages = len(pdf_reader.pages) 38 | for i in range(num_pages): 39 | page = pdf_reader.pages[i] 40 | content += page.extract_text() 41 | return content 42 | 43 | 44 | # Async version of extract_text_from_txt 45 | async def extract_text_from_txt(file_content: bytes) -> str: 46 | """ 47 | Extract text from a text file. 48 | """ 49 | return await asyncio.to_thread(extract_text_from_txt_sync, file_content) 50 | 51 | def extract_text_from_txt_sync(file_content: bytes) -> str: 52 | """ 53 | Extract text from a text file (blocking version). 54 | """ 55 | return file_content.decode("utf-8") # Assuming the file is in UTF-8 encoding 56 | 57 | # Asynchronous file text extraction 58 | async def extract_text_from_file(file_content: bytes, file_type: str) -> str: 59 | """ 60 | Extract text from different file types based on the file type. 61 | """ 62 | if file_type == "txt": 63 | return await extract_text_from_txt(file_content) 64 | elif file_type == "pdf": 65 | return await extract_text_from_pdf(file_content) 66 | elif file_type == "docx": 67 | return await extract_text_from_docx(file_content) 68 | else: 69 | raise HTTPException(status_code=400, detail="Unsupported file type") 70 | 71 | -------------------------------------------------------------------------------- /Langgraph Long-Term Memory Blog/Langgraph Long-Term Memory.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "!pip install langchain_openai langchain_core langgraph " 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "import uuid\n", 19 | "from typing import Annotated\n", 20 | "# from langchain_core.messages import AIMessage\n", 21 | "from langchain_openai import ChatOpenAI\n", 22 | "from langchain_core.runnables import RunnableConfig\n", 23 | "from langgraph.graph import StateGraph, MessagesState, START, END\n", 24 | "from langgraph.store.base import BaseStore\n", 25 | "from typing import Annotated, Optional\n", 26 | "from langchain_core.tools import InjectedToolArg, tool\n", 27 | "\n", 28 | "from langgraph.store.memory import InMemoryStore\n", 29 | "from langgraph.checkpoint.memory import MemorySaver\n", 30 | "in_memory_store = InMemoryStore()" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": 2, 36 | "metadata": {}, 37 | "outputs": [], 38 | "source": [ 39 | "\n", 40 | "@tool\n", 41 | "def upsert_memory(\n", 42 | " content: str,\n", 43 | " context: str,\n", 44 | " memory_id: Optional[str] = None,\n", 45 | " *,\n", 46 | " config: Annotated[RunnableConfig, InjectedToolArg],\n", 47 | " store: Annotated[BaseStore, InjectedToolArg],\n", 48 | "):\n", 49 | " \"\"\"Upsert a memory in the database.\n", 50 | "\n", 51 | " If a memory conflicts with an existing one, then just UPDATE the\n", 52 | " existing one by passing in memory_id - don't create two memories\n", 53 | " that are the same. If the user corrects a memory, UPDATE it.\n", 54 | "\n", 55 | " Args:\n", 56 | " content: The main content of the memory. For example:\n", 57 | " \"User expressed interest in learning about French.\"\n", 58 | " context: Additional context for the memory. For example:\n", 59 | " \"This was mentioned while discussing career options in Europe.\"\n", 60 | " memory_id: ONLY PROVIDE IF UPDATING AN EXISTING MEMORY.\n", 61 | " The memory to overwrite.\n", 62 | " \"\"\"\n", 63 | " mem_id = memory_id or uuid.uuid4()\n", 64 | " user_id = config[\"configurable\"][\"user_id\"]\n", 65 | " store.put(\n", 66 | " (\"memories\", user_id),\n", 67 | " key=str(mem_id),\n", 68 | " value={\"content\": content, \"context\": context},\n", 69 | " )\n", 70 | " return f\"Stored memory {mem_id}\"" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 4, 76 | "metadata": {}, 77 | "outputs": [], 78 | "source": [ 79 | "model = ChatOpenAI(model=\"gpt-4o\")\n", 80 | "\n", 81 | "def store_memory(state: MessagesState, config: RunnableConfig, store: BaseStore):\n", 82 | " # Extract tool calls from the last message\n", 83 | " tool_calls = state[\"messages\"][-1].tool_calls\n", 84 | " saved_memories=[]\n", 85 | " for tc in tool_calls:\n", 86 | " content = tc['args']['content']\n", 87 | " context = tc['args']['context']\n", 88 | " saved_memories.append([\n", 89 | " upsert_memory.invoke({'content': content, 'context': context, 'config':config, 'store':store}) \n", 90 | " ])\n", 91 | " # print(\"saved_memories: \", saved_memories)\n", 92 | " # Format the results of memory storage operations\n", 93 | " # This provides confirmation to the model that the actions it took were completed\n", 94 | " results = [\n", 95 | " {\n", 96 | " \"role\": \"tool\",\n", 97 | " \"content\": mem[0],\n", 98 | " \"tool_call_id\": tc[\"id\"],\n", 99 | " }\n", 100 | " for tc, mem in zip(tool_calls, saved_memories)\n", 101 | " ]\n", 102 | " # print(results)\n", 103 | " return {\"messages\": results[0]}\n", 104 | "\n", 105 | "def route_message(state: MessagesState):\n", 106 | " \"\"\"Determine the next step based on the presence of tool calls.\"\"\"\n", 107 | " msg = state[\"messages\"][-1]\n", 108 | " if msg.tool_calls:\n", 109 | " # If there are tool calls, we need to store memories\n", 110 | " return \"store_memory\"\n", 111 | " # Otherwise, finish; user can send the next message\n", 112 | " return END\n", 113 | "\n", 114 | "def call_model(state: MessagesState, config: RunnableConfig, *, store: BaseStore):\n", 115 | " user_id = config[\"configurable\"][\"user_id\"]\n", 116 | " namespace = (\"memories\", user_id)\n", 117 | " memories = store.search(namespace)\n", 118 | " info = \"\\n\".join(f\"[{mem.key}]: {mem.value}\" for mem in memories)\n", 119 | " if info:\n", 120 | " info = f\"\"\"\n", 121 | " \n", 122 | " {info}\n", 123 | " \"\"\"\n", 124 | " \n", 125 | " system_msg = f'''You are a helpful assistant talking to the user. You must decide whether to store information as memory from list of messages and then answer the user query or directly answer the user query\n", 126 | " User context info: {info}'''\n", 127 | " print(\"system_msg:\", system_msg)\n", 128 | " # Store new memories if the user asks the model to remember\n", 129 | " last_message = state[\"messages\"][-1]\n", 130 | " # if \"remember\" in last_message.content.lower():\n", 131 | " # memory = \"User name is Bob\"\n", 132 | " # store.put(namespace, str(uuid.uuid4()), {\"data\": memory})\n", 133 | " # print( [{\"type\": \"system\", \"content\": system_msg}] + state[\"messages\"])\n", 134 | " response = model.bind_tools([upsert_memory]).invoke(\n", 135 | " [{\"type\": \"system\", \"content\": system_msg}] + state[\"messages\"]\n", 136 | " )\n", 137 | " return {\"messages\": response}\n", 138 | "\n", 139 | "\n", 140 | "builder = StateGraph(MessagesState)\n", 141 | "builder.add_node(\"call_model\", call_model)\n", 142 | "builder.add_edge(START, \"call_model\")\n", 143 | "\n", 144 | "builder.add_node(store_memory)\n", 145 | "\n", 146 | "builder.add_conditional_edges(\"call_model\", route_message, [\"store_memory\", END])\n", 147 | "\n", 148 | "builder.add_edge(\"store_memory\", \"call_model\")\n", 149 | "\n", 150 | "graph = builder.compile(store=in_memory_store)" 151 | ] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "execution_count": 5, 156 | "metadata": {}, 157 | "outputs": [ 158 | { 159 | "name": "stdout", 160 | "output_type": "stream", 161 | "text": [ 162 | "================================\u001b[1m Human Message \u001b[0m=================================\n", 163 | "\n", 164 | "Hi! Remember: my name is Bob\n", 165 | "system_msg: You are a helpful assistant talking to the user. You must decide whether to store information as memory from list of messages and then answer the user query or directly answer the user query\n", 166 | " User context info: \n", 167 | "[{'type': 'system', 'content': 'You are a helpful assistant talking to the user. You must decide whether to store information as memory from list of messages and then answer the user query or directly answer the user query\\n User context info: '}, HumanMessage(content='Hi! Remember: my name is Bob', additional_kwargs={}, response_metadata={}, id='7ce923c3-1b4c-4487-891f-40273067f60b')]\n", 168 | "==================================\u001b[1m Ai Message \u001b[0m==================================\n", 169 | "Tool Calls:\n", 170 | " upsert_memory (call_PrjfPMYG7sYUlJJE6gdMQSWQ)\n", 171 | " Call ID: call_PrjfPMYG7sYUlJJE6gdMQSWQ\n", 172 | " Args:\n", 173 | " content: User's name is Bob.\n", 174 | " context: User mentioned their name.\n", 175 | "saved_memories: [['Stored memory e424aeb4-7cb0-4c1f-90ed-efb7da4333c7']]\n", 176 | "[{'role': 'tool', 'content': 'Stored memory e424aeb4-7cb0-4c1f-90ed-efb7da4333c7', 'tool_call_id': 'call_PrjfPMYG7sYUlJJE6gdMQSWQ'}]\n", 177 | "=================================\u001b[1m Tool Message \u001b[0m=================================\n", 178 | "\n", 179 | "Stored memory e424aeb4-7cb0-4c1f-90ed-efb7da4333c7\n", 180 | "system_msg: You are a helpful assistant talking to the user. You must decide whether to store information as memory from list of messages and then answer the user query or directly answer the user query\n", 181 | " User context info: \n", 182 | " \n", 183 | " [e424aeb4-7cb0-4c1f-90ed-efb7da4333c7]: {'content': \"User's name is Bob.\", 'context': 'User mentioned their name.'}\n", 184 | " \n", 185 | "[{'type': 'system', 'content': 'You are a helpful assistant talking to the user. You must decide whether to store information as memory from list of messages and then answer the user query or directly answer the user query\\n User context info: \\n \\n [e424aeb4-7cb0-4c1f-90ed-efb7da4333c7]: {\\'content\\': \"User\\'s name is Bob.\", \\'context\\': \\'User mentioned their name.\\'}\\n '}, HumanMessage(content='Hi! Remember: my name is Bob', additional_kwargs={}, response_metadata={}, id='7ce923c3-1b4c-4487-891f-40273067f60b'), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_PrjfPMYG7sYUlJJE6gdMQSWQ', 'function': {'arguments': '{\"content\":\"User\\'s name is Bob.\",\"context\":\"User mentioned their name.\"}', 'name': 'upsert_memory'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 27, 'prompt_tokens': 225, 'total_tokens': 252, 'completion_tokens_details': {'audio_tokens': None, 'reasoning_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 0}}, 'model_name': 'gpt-4o-2024-08-06', 'system_fingerprint': 'fp_45c6de4934', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-a6f0ba23-16b2-4611-ba8f-01aada6a556c-0', tool_calls=[{'name': 'upsert_memory', 'args': {'content': \"User's name is Bob.\", 'context': 'User mentioned their name.'}, 'id': 'call_PrjfPMYG7sYUlJJE6gdMQSWQ', 'type': 'tool_call'}], usage_metadata={'input_tokens': 225, 'output_tokens': 27, 'total_tokens': 252}), ToolMessage(content='Stored memory e424aeb4-7cb0-4c1f-90ed-efb7da4333c7', id='6dab31c8-1993-4640-8bab-ebe025acc1a7', tool_call_id='call_PrjfPMYG7sYUlJJE6gdMQSWQ')]\n", 186 | "==================================\u001b[1m Ai Message \u001b[0m==================================\n", 187 | "\n", 188 | "Hi Bob! I've got your name remembered. How can I assist you today?\n" 189 | ] 190 | } 191 | ], 192 | "source": [ 193 | "config = {\"configurable\": {\"thread_id\": \"1\", \"user_id\": \"1\"}}\n", 194 | "input_message = {\"type\": \"user\", \"content\": \"Hi! My name is Bob. I love keep updated on Latest Tech\"}\n", 195 | "for chunk in graph.stream({\"messages\": [input_message]}, config, stream_mode=\"values\"):\n", 196 | " chunk[\"messages\"][-1].pretty_print()" 197 | ] 198 | }, 199 | { 200 | "cell_type": "code", 201 | "execution_count": 6, 202 | "metadata": {}, 203 | "outputs": [ 204 | { 205 | "name": "stdout", 206 | "output_type": "stream", 207 | "text": [ 208 | "================================\u001b[1m Human Message \u001b[0m=================================\n", 209 | "\n", 210 | "What do you know about me\n", 211 | "system_msg: You are a helpful assistant talking to the user. You must decide whether to store information as memory from list of messages and then answer the user query or directly answer the user query\n", 212 | " User context info: \n", 213 | " \n", 214 | " [e424aeb4-7cb0-4c1f-90ed-efb7da4333c7]: {'content': \"User's name is Bob.\", 'context': 'User mentioned their name.'}\n", 215 | " \n", 216 | "[{'type': 'system', 'content': 'You are a helpful assistant talking to the user. You must decide whether to store information as memory from list of messages and then answer the user query or directly answer the user query\\n User context info: \\n \\n [e424aeb4-7cb0-4c1f-90ed-efb7da4333c7]: {\\'content\\': \"User\\'s name is Bob.\", \\'context\\': \\'User mentioned their name.\\'}\\n '}, HumanMessage(content='What do you know about me', additional_kwargs={}, response_metadata={}, id='21fe0c1b-2ea9-427f-ae18-3c8ef8b40c31')]\n", 217 | "==================================\u001b[1m Ai Message \u001b[0m==================================\n", 218 | "\n", 219 | "You mentioned that your name is Bob. Is there anything else you'd like to share or update?\n" 220 | ] 221 | } 222 | ], 223 | "source": [ 224 | "config = {\"configurable\": {\"thread_id\": \"1\", \"user_id\": \"1\"}}\n", 225 | "input_message = {\"type\": \"user\", \"content\": \"What do you know about me\"}\n", 226 | "for chunk in graph.stream({\"messages\": [input_message]}, config, stream_mode=\"values\"):\n", 227 | " chunk[\"messages\"][-1].pretty_print()" 228 | ] 229 | }, 230 | { 231 | "cell_type": "code", 232 | "execution_count": 7, 233 | "metadata": {}, 234 | "outputs": [ 235 | { 236 | "name": "stdout", 237 | "output_type": "stream", 238 | "text": [ 239 | "[e424aeb4-7cb0-4c1f-90ed-efb7da4333c7]: {'content': \"User's name is Bob.\", 'context': 'User mentioned their name.'}\n" 240 | ] 241 | } 242 | ], 243 | "source": [ 244 | "namespace = (\"memories\", \"1\")\n", 245 | "memories = in_memory_store.search(namespace)\n", 246 | "info = \"\\n\".join(f\"[{mem.key}]: {mem.value}\" for mem in memories)\n", 247 | "print(info)" 248 | ] 249 | }, 250 | { 251 | "cell_type": "code", 252 | "execution_count": 8, 253 | "metadata": {}, 254 | "outputs": [ 255 | { 256 | "data": { 257 | "image/jpeg": "/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAD5ARoDASIAAhEBAxEB/8QAHQABAAMAAwEBAQAAAAAAAAAAAAUGBwIDBAgBCf/EAFAQAAEDAwICAg0IBwUECwAAAAEAAgMEBQYREgchEzEIFBUWFyJBUVaU0dLTIzI2VWF0gZUzVHGTobK0QkdSdbEJYpGWJCU0Q1NkcnOCosH/xAAbAQEBAAMBAQEAAAAAAAAAAAAAAQIDBAUGB//EADMRAQABAgEJBQgCAwAAAAAAAAABAhEDBBIUITFBUVKRYXGhwdEFExUjYoGSsSIzMuHw/9oADAMBAAIRAxEAPwD+qaIiAiIgIiICIiAiIgIiIC/CQ0Ek6AcySoy/Xo2iGJkEBrbhUu6OlpGu29I7ylztDtY0c3O0Og6g5xa0xrcJgubhPkMpvlQSHdBKNKSIjyMh6iNfK/c77eoDdTRFs6ubR4rbilJMltELy2S60THDra6oYCP4rj31WX64oPWWe1cI8RsULAyOy25jB1NbSRgD+C596tl+p6D1ZnsWXye3wXUd9Vl+uKD1lntTvqsv1xQess9qd6tl+p6D1ZnsTvVsv1PQerM9ifJ7fA1HfVZfrig9ZZ7U76rL9cUHrLPanerZfqeg9WZ7E71bL9T0HqzPYnye3wNR31WX64oPWWe1dlPkFrqpAyC5Uczz1NjnY4n8AV196tl+p6D1ZnsXXPhtgqo9k1jtszP8MlJG4f8AAhPk9vgakwiq5xWbHm9Pjkr4WMHO0zSE0so8zddTE7yAtIb52nyTVnu8N7oWVMLXx6kskhmG2SJ45OY8eRwPLzeUEggrCqiIjOpm8f8AbUs9yIi1IIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiCsWDS7ZZfrjJo7tJ7bZTdfiNDGSSkf+p7wD/wC23zKzqsYg3tS75RRO1D23Dtluo645YmOBHn8YPH/xKs66Mf8Azt2R+oWRee4XCmtNBU11bPHS0dNE6aaeVwayNjQS5zieoAAkn7F6FEZfTUlbid7p6+3S3ihloZ46i3QN3SVUZjcHRNGo1Lhq0DUcz1hc6Mqy7sr8QtvCbKs1xySoyJtjpo5u1nUNVTCUya9Cdz4dejdtd8oAWaA81Z67j/hdpxS3ZDcK24UVBXzOp6dktlrm1EkjRq4Cn6HpdAATrs00566L5/p8czbL+DfFjB7JbcoqMPbj8cONxZhQ9qXFlRtfvo2Fwa6WNrWxhr3jrdt3OA1Vzz/P7/mlPg1VTWXiDYcKfLVQ36ntVqqaa79O2KI0zNrB0zYC50odJHyLmAbgOZDUrhx8wC14hYspqMkpxYL5UdqW6ujikkbPNtkd0ejWktd8lINHAHc3b84gGrVHZSY7FxQx/FWUN3dR3e1S17K51lrxIyQVEcLIzD2vua07nl0jtGt2t3abgTj+A4Jfosb4dUFTi1/pRa+KlZcZYLpTySywUr4quWKeSTxg5vy0QMu4jpCRu3arWeJtRcMK7IHEszdj16vlidj9fZZn2OhfWS08756aWMyRsBcGOETxu00BHPRBuCIiAqxHpaOIL4WbWw3mjdUuaNf08BjYXebV0ckY/ZEFZ1WK1vbvEW1NbrpQW6omlOnIGV8bY+f29HL/AMF0YO2qJ2Wn/XjZYWdERc6CIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIggb7bamnuEF7tsXT1sEZhnpQQ01UGuuxpJAEjT4zC7lzc0loeXN4VtFjfE3Hqi33Cjo77aZXNbU0FfAHtD2kODZYnjVrmkA7XAEEDkrCoa74ja7zUiqmhfBXAACso5n08+g6gXsILgOfinUczy5lb4qpqiKa929e9UG9jbwoYdW8N8WadCNRaYOo8j/ZXrs/APhrj10pbla8Cxy33ClkEsFVTWyGOSJ46nNcG6gjzhSvePM3kzJ78xvkHbEbv4ujJ/ineTUelV+/fQ/CV93h8/hJaOK0Iqv3k1HpVfv30PwlU+LNuu2GcLsuv9tym8G42u01VbTiolhMfSRxOc3d8mOWoGvMftT3eHz+Elo4tURVfvJqPSq/fvofhJ3k1HpVfv30Pwk93h8/hJaOKAk7G7hTK9z38OMWc9xJLjaYCSfP81JOxu4Uyvc9/DjF3vcSXOdaYCSfOfFU/3k1HpVfv30Pwk7x3v0E2SX6ZmvNvbTY9fxYxp/inu8Pn8JLRxe2rudtxKio7dTQNEjYmw0NqomtEj2tAa1rGcg1oGg1OjWjrIC5Y5Zpre2qq650cl1r3iWqdESWMIaGtjYTz2NA0B0GpLnaAuIXbZcatuPiQ0NMI5ZP0k8j3SzSebfI8lzvxJUosaqqYiaaN+/idwiItKCIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAs+7IQtHAfiIXkhgx+v1IGpA7Xf9o/1H7VoKz/shNfAPxE0LQe9+v0LwCP0D+vdy0/byQaAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICz3shwDwE4jAuawHHq/xnjUD/AKO/meR5fgtCWe9kRp4A+I24kN73q/Uhu7l2u/yeVBoSIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiICIiAiIgIiqVfllyq6uohsVBTVMNPIYZKutndEx0jSQ5rA1ji7aRoSdBrqBrodNuHh1Yk2pWy2oqR3dzD9Qsfrc3w07u5h+oWP1ub4a36LXxjrBZd0VI7u5h+oWP1ub4ad3cw/ULH63N8NNFr4x1gsu6+Wuzt7IOu4M4NNZZcQdeLPlVuqrc27MrhGKWdzC0tdEYnA+K4OGp8bRw05c9u7u5h+oWP1ub4az7jxwzvHH3htcMQvNJZqWKdzJoKyKoldJTTMOrZGgx6E6FzT5w4hNFr4x1gssHY0cc5+yH4bnL5calxiB9bLTU9PLVdsdPGxrPlQ7YzkXF7dND8w8+fLWFlWB2e/cOcNs2M2e1WOG22umZSwt7al1IaObjpF85x1cT5yVPd3cw/ULH63N8NNFr4x1gsu6Kkd3cw/ULH63N8NO7uYfqFj9bm+Gmi18Y6wWXdFSO7uYfqFj9bm+Gnd3MP1Cx+tzfDTRa+MdYLLuirVmyiqluMduu9HDRVU4c6nlppjLDNt1Lm6lrS14HPaRzGuhOh0sq568OrDm1RsERFrQREQEREBERAREQEREBERAREQEREBERAWeYIdce1PWaysJ+09syrQ1neB/Rwfe6v+plXfk/8AXV3x5ruWFERbEERVC48W8TtNpyi51d16KhxmoFLdpe1pT2tLtjft0DNX+LLGdWBw8b7DpBb0RFQREQEUTlmV2vBsbuN/vdV2labfCZ6mo6N8nRsHWdrAXH9gBKlGPEjGvadWuGoP2KDkihxl1pOXuxcVf/XraEXI0vRv/wCzmQxh+/Tb88Eaa6+XTRTCCEvh25Hh2nX3VcNdP/J1KvyoF9+keG/5s7+jqVf1ryrZR3ecsp2QIiLhYiIiAiIgIiICIiAiIgIiICIiAiIgIiICzvA/o4PvdX/UyrRFneB/Rwfe6v8AqZV35P8A11d8ea7lhWBcMrPcOL18ynJ7xmGRUU9qyestlJZ7TcXUtJSwUsuxscsLeUjpANzi/Xk8bdvJb6s/vPAPA79lcmSVlhBu8skc00sFVPBHUSRkFj5YmPbHI4aDQvaTyCymLowPiHmeQxZTX5vilZkjLNasrpbNVT3DICKKZ3bcdNUQQ24Rlro9XOb0jnNeHAuGoC48RiBwm7KEE8xkDSfsHatDzW6XzscOHWR3G5V1wxwTz3GY1VQ1tZUMjM501nZG2QMjm5fpWBr+vxuZU3W8I8QuN0yK4VNjgmqcipG0V23OfsrImt2gPZrtLgABv03aAc+SwzZFv61iWf0Fbl3ZD2LF35BfLTZJsWra6ems9xkozLKyqp2McXMIcCBIebSDy0JIJBtIxDNccihteI3rG7XjdHFHBRUdztFXW1ETGtA0fN263fz10O0ctBz01Mxj+FytvNJkmRuoLhl1PSTW5lwtsE1LCKaSRkhjEL5pBrujYS4knly0BIWc69Q+bsAuWRWzCeE2ZTZjkV0ut1yw2Guir7g6WlqKTp6mnDTByZvAhY7pNN5dqSTry/JckyQcGp+Mr8uvbcnZfnMbYhWnuaIW3LtTtE0vzSTGPn6dJuOu5fR9LwkxOisNkssNq2W2y3HutQQdsynoarpHydJuL9XePK87XEt8bTTQDSOfwDwKTL++d2OxG7dud0NTPL2v21+sdr7+i6Xy9Js3a89deawzZHzjxYpbjxR4O8b8tuuUXunks1fcbRR2KhrTDRQQUzwwNmhHKV8g1e5z9To9u3TQFWW/VGfcUuK2b2azT1UFFjDaKlpIKPKpbK6Iy0zZe2HsjpZen3OcQN52gR6bddSddy7sbeHGc3a6XK844KiqurAyvMNbUU7KrQaB0kccjWucABo8jcNBzXvzPgTg3EC7RXO+WMVFwjgFKamnqp6Z8sI6o5DE9vSM/wB1+o5lM2RnvDuHIKXshLZBlk9LVZLHw7p2V89GfkpZhXPDnt5N5E8+odfUt/Vbn4c43UZLYsgda423iyQPpaCrje9jooXt2ujIaQHs0PJrgQDzGh5qyLOIsIO+/SPDf82d/R1Kv6oF9+keG/5s7+jqVf1hlWyju85ZTsgREXCxEREBERAREQEREBERAREQEREBERAREQFneB/Rwfe6v+plWiKiy2q7YvPUQ0FrfebbNNJURCCeNk0Je4vexwkc1pbucdpDuo7S0bdXd2TzE01UXtM226tl/VY2WS6KrV+YXK2yCKbErq6pMZlbSwz0ksz2BzWlzY2zlxaC9gJA0G4a6L3d1r96GXX1qi+OunM+qPyj1WybRQnda/ehl19aovjp3Wv3oZdfWqL46Zn1R+UepZNooTutfvQy6+tUXx1BZzxPdw2xWvyTJMcuVsstAwPqKp89I/aCQ0aNbMXEkkDQAnmmZ9UflHqWXhFWrVlV0vdro7jQYpcqqhrIWVEE8dVRlskb2hzXD5fqIIK9Xda/ehl19aovjpmfVH5R6lk2ihO61+9DLr61RfHTutfvQy6+tUXx0zPqj8o9SybRQnda/ehl19aovjrw3TMbjZInTV+J3SkpY4pJ5auaoo2wQxsbue6STp9sYA1OriByPmTM+qPyj1LPbffpHhv+bO/o6lX9UyyW2vv90t91rqdtBQ0ZdNSwCdsr5pHMcwSOLCWBgY92gBdqXa8to3XNcmU1RM00xOyPOZSRERcaCIiAiIgIiICIiAiIgIiICIiAiIgIijbxfqe0BsRBqrhLFLLS26F7BUVXRt3ObGHuaNebRq4hoLm6kaoJCSRsUbnvcGMaC5znHQADrJKg47zXXisiba6YRUUFZLT1tRXxSRPIjGh6BhA3gv8AF3khujXEbgRrwGPS34ySZB0VXSSdqzRWd0bXQ0ksXjlxf1yu6TQgnRo6OMhocC51hQRdkx2lskURDpK2vbAynluVXo+qna0ucN8gA1G57yGjRoLjtAHJSiIgIiIC+Uf9oTwuzrifwuLbDcLRb8VscM95u7K2olbUVJhYXNaxrInAgNDjzcNXEdWmq+rln/ZAFruCWcQuDXOqrRUUjGOJAe+VhjY3Uc+bngcufNBX+xT4bZpwh4P0OJZvcrZdK62zyR0U9rlkkYKQ7XMa50kbDuDjIOrQN28/INgREBERAX4RqNDzC/UQV6sxypoGzz47VR2+qcynibTVTXy0TY4j81sTXtEZcwlu5mmmjCWvDdp7o8qpoa40lyYbNPJWmio+3ZI2ivf0ZkHQEOO8lrXnbycOjf4ug1M2uEsMc7Q2WNsjQ5rwHjUaggg/tBAI+0IOaKtxW644pFBHb3SXS0QR1Ek1NUyulrS4nfG2GR7tHAHczbIRyLfHAbo6Ztlzgu9FFUwdI1r2MeY5o3RSx7mhwbJG4BzHaOBLXAEa8wg9aIiAiIgIiICIiAiIgIiICIiAiIgjL5dprdCyOipmXC5TECGjdUMh3N3NDpCXc9jNwLi0OOnU0kgHlarOLeHSTVElwrHPlcaqoDd7Wvfu6Nu0ANY3xWgeZjS4udq4xthdHcslyCskdaameiqG2+CWjZrVU8XQwyuineeYcXvLw0ctpjPMkqxoCIiAiIgIiICz7JHHiBmFHjtKd9nslVFX3qdp8V07NstNR6g/O3GOZ48jGxgjSUEeu65NcMpudTYcUmbAaaXobnfnRh8dD/iigBBbLU+TQ6siJ3SBxAhks1hsNFjVpgt1vidFTQg6dJI6SR7iSXPe9xLnvc4lznuJc5xJJJJKCQREQEREBERAREQFDXTHGT1M9wtrobXe5WwxPuLKdr3yxRyF7YpNeb2eNIANdW9K8tLSdVMogj7RdH3GOZs9HLb6qGV8b6eZzXEtDiGyNLSQWPADmnr0Ojg1wc0SCrmZRNttIcigFvp662Rl0tbXROdsot7H1LA5njDVkeo6xuYwlp00U/T1EdXBHPDI2WGRoeyRh1Dmkagg+bRB2IiICIiAiIgIihbxm2PY/VCmud8t1vqSN3Q1NUxj9PPtJ10WdNFVc2pi8ra6aRVbwpYd6U2j12P2p4UsO9KbR67H7Vt0fG5J6SubPBaUVW8KWHelNo9dj9qeFLDvSm0eux+1NHxuSekmbPBaUVW8KWHelNo9dj9qeFLDvSm0eux+1NHxuSekmbPBD3LiHjXDvMLvS5PlGL47FXtgrKSGsqo6OpmJaYnvkLyBJ+iYAQSQBodAG66Cv5eZp2KmMY72VuJVWO3W21nDe5XNtdUBtWx7Lc2N3SSQPOvJh00YXde4N1JHP+jXhSw70ptHrsftTR8bknpJmzwWlFVvClh3pTaPXY/anhSw70ptHrsftTR8bknpJmzwWlFVvClh3pTaPXY/aonJ+OWIY7bRUQ3amvFVI8RQUVvqI3PleQdAXFwZG3kdXvc1o8+pALR8bknpJmzwXa5XKjs9BPXV9VBQ0UDDJNU1MgjjjaOtznEgAfaVRDLeuKgAhNXjWGvHjTh0lNc7m3zMGgfSwkf29RM7U6CLQOfB2u945frhS3rNMusVbXU8jZ6OzUtex9vt8gOrXt3Brp5hy+VeBoQCxkert138KWHelNo9dj9qaPjck9JM2eCetNoobBbKa3W2kgoKCljEUFNTRiOOJg6mtaOQC9aq44o4e4gDKLQSeQArY+f8VPW650d4o46ugq4K6lk5snppGyMd+xwJBWFeFiUReumY74S0w9SIi1IIiICIiAiIgIiIOudglhkY7TRzSDuGo6vKPKoPh7Wm54DjVYa+lupqLZTSmvoouigqd0TT0sbP7LHa7g3yAgJl/EHFsBgp5cnyWz43FUlzIJLvXRUrZXAakNMjhuI1GoHnUNwizvHMwxOgpbJlePZTW22ipoq9+O1EToYpDHoD0THHoWuLH7WHTQNI8hQXlERAREQEREHivVY632euqmAF8EEkrQfO1pI/0VRxKkjprBRSAbp6mJk88zub5pHNBc9xPMkk/h1dQVnyr6MXj7nN/IVXsa+jlq+6RfyBehgasKe9dySREWaCIiAiIgIiICIiAiIgIiICireRbOIFHHTgRR3KjqH1MbRo2SSN0WyQ+TcA9zddNSNNT4oUqoj+8XH/ALlW/wCsCzp1xVHZP6lYXpEReSgiIgIiICrl34iYzYal9NXXujhqWHR8DZQ+Rh/3mt1I/EeRZpxF4jVGQVlRa7TUyU1pge6KapgftfVuHJzWuHNsYOo1BBcR/h+dQ6emipYhHDEyKMdTWNAAX0+SexpxKIrx5tfdG37+i6o2t18M2G/XTfV5fcTwzYb9dN9Xl9xYci9D4Hk3NV1j0S8JLsq4cJ498F71jkd3iN4jb25a5HQSjbVRglo12jQOBcw68vG18ip3YKWLGOAvCFwvlwbSZVfJu27jC6GQuha3VsURIBBLWlxOnleR5FPonwPJuarrHoXhuPhmw366b6vL7ieGbDfrpvq8vuLDkT4Hk3NV1j0Lw323cUcTukzIYL/RCV50YyaToi4+YB+mp+wK0r5XkjZKwse0PaetrhqCrNg2fVGCyxwTySVGPcmvp3HcaQa/pI/LtA62dWg1aAQQ7iyn2Jm0zVk9UzMbp8jVL6CRcY5GTRtkjc18bwHNc06gg9RBXJfKiLyr6MXj7nN/IVXsa+jlq+6RfyBWHKvoxePuc38hVexr6OWr7pF/IF6OD/TPf5Lueytqm0VHPUOY+RsMbpCyJu5zgBroB5T9iwNnHvLc14CZfnFkxijtMUVknr7TWi9RVLtWscXdKwRHo5Y2jf0ZDgSAwuGpI3+fpOhk6Hb0u07N+u3dpy108i+f8f4A5PcrznNwyJ+OY83JsdmslTSYoJjBVTybta6VkjWgSBri0Abjo46vPJSb7kS1s40ZLZcAwht1xiG5Zrkro6a12yjuocyraKYTSVM0zoWCEBoe5zQx+nIDdry6bv2TFTj+MXqe4YdPHlNlvVDZq+wQ1zJCTVOj6GWGbYBI1zZNQCGElpadvWuiPhVxGmsODVtRPjEOX4TLstxilqH0dfTOpjTzNmJjD4nOBDgWh4aWjrXmquAWVX6mu94u9wtByq95NZ7xVxUrpRR01LQyR7IY3Fm979jHnc5rQXP6mgarH+Qlc67Iyp4dOs9qv1msdsyu5tmqWUNdk0VLRQ0sbmt6SSrlib47i7QRsY48nc9Gkq5cGuLdv4yYpUXehiZTyUdbLbquGGqjqomTx7SejmjJbKwtexwcOsO6gdQoTiXwzyKu4hWXO8OmtEl6o6CW01duv3SClq6V72yDSSNrnRvY9uoO12oJHLyykPEEYFbKGizKCTu9Mx08wxaw3Cso2gvcGgPjhfzDQAdxBJGu0AgLLXE6x3cU+JlZw9qMVpLfYTf67IbmbZBD222mEb+gllD3OLT4vyWh8oBJAcQGnOp+ydyG2WnJrpdOHgpLdidwbQZBNFe2SmEnY4yU7eiBmaGSsed3RnnoNSDpaL1HHxlyDB7rYH1NPTYvfO6Fa28Wyst75I3Us8QETZoW7zukaT5AAeeugMFlfAi/33AuNFkp6y2sq80uLqy3vklkEcTDT08ekxDCWnWF3zQ7kRz69JN9w6+I3ZYWzC8vvVioaWzVz7GGi4OumSUtsldIWCTo6aKXUzODXN1J2N3HbuJB09U3ZH3C+VssWG4cMip243R5O2oq7o2iBp5+lIjIMbyJAIhoPmnV2rm6Dd2VvC7OsQzvK7thEmL11ryadldUU2RtmD6GrEbY3vjMTT0rHBjSWOLNCOTgFYDwyuh4k5bkPTULaO741S2eCJjnh7Jo31DnOc3boGfLN00JPI8urV/IQWG9kXU3+4YdJd8UdYLBl9FNWWi4vuLJ5NIoOnc2eIMAj1iDnAh7+rQ6HkOvHeyOrrs/F7tX4XPacJymuZQWi9vr2STvfLu7XdNTBgMTJdujSHu03N1A1XG08CLtDZeClur6i3yw4bRTUd2Ecr9JxJbZKX5HVg3Dc/Xxtvi8+vkouwcC857n4LiF9utjlwnDrhTVtNV0fTd0K9tKSaWKWNzRHGAdhcWudu2cgNSp/Ieuk7I3Jrlg+SZfR8PGyWGwzVsVQ995DZpxSzlkj4YxAdzdjXP8YtO5pbzHjnQqTifBd+JFvxe1Ura+mmsndyoujZ9GQxPkDKdobtO4yaSu6xoIz16qI4eYvFwe4UXaly6roe0Yqy53CrnYXPgbTz1U0wDtzQToyQBw069QNetVDsPcBqMXwq63islqp+6tYYLXJWxOjmbaKbWGgaWuAc0Fgc8ajXSUKxfVA31RH94uP/cq3/WBS6iP7xcf+5Vv+sC30b+6f1KwvSIi8lBERAVZ4l3qbH8DvVbTPdFUtpzHDI3rZI8hjXD9hcD+CsyrPEqyzZBgl6oadhlqX05khjb1vkYQ9jR+1zQPxXRk+b76jP2Xi/ddY2vnungjpaeKGJoZHG0Ma0dQAGgC7F109Qyrp4ponB0cjQ9rh5QRqFBX7PbTjdcKStZc3TbA/WktFXVM0Ov9uKJzdeXVrqv0+qqKddU2YLCqNxO4q0XDg2umkbSS3K5ukFPHXV8dFAGsAL3yTP1DQNzQAASS4aDr07/C3j//AIV8/wCXbh8BV/I7dPxCu9lynEZGx3axump3UuQW+ppYKqGZrd7DvjDwQWtcHNaRqNCuXFxc6i2FVF/tPf4DxUfZCRXO0Uktvs0dxuct7ZY5KWjuUUsIkfC+VkjJ2gtewhoB6iNXctW6GTdxp7l2rITebJJSX20VdPQ9y6OoFR21LOGmnEUha3Xfu05tGmh8y9FzwzI8jpMTkuPcemr7Xfo7nUx0BkEXQtjlYGsLm6uf8o3mQ0Hn1KKynhBdb7eMtuVNX0lJV1ldbLnaZHhzxFPSMA0mboPFcQR4pPI6/YueZymIvE3+0cJ8b2HLD8lyW68aq2jvtvfY42Y7FMy2x3HtqAuNS8dKNA0B2ninxdfF6yNFq6yy3W/IsfzaszXLxbo4DaIrWKewRVVZIHidz92wRbiDu6wOXl6tVYPC7jw/7q+/8u3D4C3YNcUUzGJVrvO20SLmnWqxaeJFmvVxhoqaO7CeYkNNRZK2CPkCeb5IWtb1eUhWcnQanqXXTVTXF6ZujaeCVyfXYHDTPcXOt08tE0nyMa7WMfgxzG/gr6qFwTtj6DA4Kl7Sx1xnlrQD5WOdpGfxY1h/FX1fm+XZulYmbsvLZO1F5V9GLx9zm/kKr2NfRy1fdIv5ArTeaN1xtFdSMID54JIgT5C5pH/6qhiVZHUWGjhB2VNNCyCogdyfDI1oDmOB5gg/8RoRyIWWBrwpjtNyYREWaCIiAiIgIiICIiAiIgIiICiP7xcf+5Vv+sCl1E27bdc+pJaZwmittHUR1MjDq1kkjoiyMnq3bWOcRrqBt1HjArOnVFU9k/qYWF5REXkoIiICIiDEuIvDepsVZUXW0U0lVa53mWelgZufSOPNzmtHNzCdSQAS0k8i35lCp6mGrjEkMrJWH+0xwIX1Uq9eOH2NX6odUV9koqipfzdP0IbI79rhoT+JX0+Se2Zw6Iox4vbfG37mqdr56Rbl4G8N+o4v3snvJ4G8N+o4v3snvL0PjmTctXSPUtDDUW5eBvDfqOL97J7yeBvDfqOL97J7yfHMm5aukepaGGoty8DeG/UcX72T3k8DeG/UcX72T3k+OZNy1dI9S0MLllZCwvke2Ng63OOgCs+DcP6nOZo6ipikpseBDnzPG01g1/Rxjr2Edb/MdG6klzNatvDLFLTOyamsFCJmHVskkQkc0+cF2pB+1WdcWU+286macCm0zvnyXVGxxjjbFG1jGhjGgNa1o0AHkAC5Ii+VQULeMKx/IagVF0sdtuM4G0S1VJHI8DzauBOimkWVNdVE3pm0mxVvBXhnonZPy+L3U8FeGeidk/L4vdVpRbtIxueesreeKreCvDPROyfl8Xup4K8M9E7J+Xxe6rSiaRjc89ZLzxVbwV4Z6J2T8vi91PBXhnonZPy+L3VaUTSMbnnrJeeKreCvDPROyfl8Xup4K8M9E7J+Xxe6rSiaRjc89ZLzxVbwV4Z6J2T8vi91PBXhnonZPy+L3VaUTSMbnnrJeeKreCvDPROyfl8Xup4K8M9E7J+Xxe6rSiaRjc89ZLzxVbwV4Z6J2T8vi91PBXhnonZPy+L3VaUTSMbnnrJeeKrt4W4axwc3FLKHA6gigi1H/wBVP2+3UlppI6WhpYaOljGjIKeMRsb+xo5BelFhXi4mJFq6pnvkvMiIi1IIiICIiAiIgIiICIiAiIgIiICIiD//2Q==", 258 | "text/plain": [ 259 | "" 260 | ] 261 | }, 262 | "metadata": {}, 263 | "output_type": "display_data" 264 | } 265 | ], 266 | "source": [ 267 | "from IPython.display import Image, display\n", 268 | "try:\n", 269 | " display(Image(graph.get_graph().draw_mermaid_png()))\n", 270 | "except Exception as e:\n", 271 | " print(e)" 272 | ] 273 | }, 274 | { 275 | "cell_type": "code", 276 | "execution_count": null, 277 | "metadata": {}, 278 | "outputs": [], 279 | "source": [] 280 | } 281 | ], 282 | "metadata": { 283 | "kernelspec": { 284 | "display_name": "futuresmart", 285 | "language": "python", 286 | "name": "python3" 287 | }, 288 | "language_info": { 289 | "codemirror_mode": { 290 | "name": "ipython", 291 | "version": 3 292 | }, 293 | "file_extension": ".py", 294 | "mimetype": "text/x-python", 295 | "name": "python", 296 | "nbconvert_exporter": "python", 297 | "pygments_lexer": "ipython3", 298 | "version": "3.11.4" 299 | } 300 | }, 301 | "nbformat": 4, 302 | "nbformat_minor": 2 303 | } 304 | -------------------------------------------------------------------------------- /Langsmith tool/app.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | from langchain_openai import ChatOpenAI 3 | from langchain_core.prompts import ChatPromptTemplate 4 | from langchain_core.output_parsers import StrOutputParser 5 | import os 6 | from dotenv import load_dotenv 7 | 8 | # Load environment variables from .env file 9 | load_dotenv() 10 | 11 | os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY") 12 | os.environ["LANGCHAIN_TRACING_V2"] = "true" 13 | os.environ["LANGCHAIN_API_KEY"] = os.getenv("LANGCHAIN_API_KEY") 14 | 15 | # Define the prompt template 16 | prompt = ChatPromptTemplate.from_messages( 17 | [ 18 | ("system", "You are my blog genertor. You are required to create a blog on that topic{question}"), 19 | ("user", "Question:{question}") 20 | ] 21 | ) 22 | 23 | # Initialize the model and output parser 24 | model = ChatOpenAI(model="gpt-3.5-turbo") 25 | output_parser = StrOutputParser() 26 | 27 | # Chain the prompt, model, and output parser 28 | chain = prompt | model | output_parser 29 | 30 | # Streamlit interface 31 | st.title("LangChain OpenAI Streamlit App") 32 | 33 | question = st.text_input("Enter your topic:") 34 | 35 | if st.button("Generate blog..."): 36 | if not question: 37 | st.write("Please provide your topic.") 38 | else: 39 | result = chain.invoke({"question": question}) 40 | st.write("Blog:") 41 | st.write(result) 42 | 43 | -------------------------------------------------------------------------------- /LlamaIndex NL2SQL Blog/NL2SQL_With_LlamaIndex.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "colab_type": "text", 7 | "id": "view-in-github" 8 | }, 9 | "source": [ 10 | "\"Open" 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "metadata": { 16 | "id": "TfTfxFyiwvd_" 17 | }, 18 | "source": [ 19 | "## Setting up logging credentials" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": null, 25 | "metadata": { 26 | "id": "asnqVxCzdQfI" 27 | }, 28 | "outputs": [], 29 | "source": [ 30 | "import logging\n", 31 | "import sys\n", 32 | "\n", 33 | "logging.basicConfig(stream=sys.stdout, level=logging.INFO, force=True)\n", 34 | "logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))\n", 35 | "from IPython.display import Markdown, display" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": null, 41 | "metadata": { 42 | "colab": { 43 | "base_uri": "https://localhost:8080/" 44 | }, 45 | "id": "XqskaZZfmKyZ", 46 | "outputId": "252f1d6e-3243-469a-cca5-451420016864" 47 | }, 48 | "outputs": [ 49 | { 50 | "name": "stdout", 51 | "output_type": "stream", 52 | "text": [ 53 | "Requirement already satisfied: pymysql in /usr/local/lib/python3.10/dist-packages (1.1.0)\n" 54 | ] 55 | } 56 | ], 57 | "source": [ 58 | "!pip install pymysql" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": null, 64 | "metadata": { 65 | "id": "o34KEKFSqu4M" 66 | }, 67 | "outputs": [], 68 | "source": [ 69 | "!pip install llama_index" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": null, 75 | "metadata": { 76 | "id": "Djyt4ntlA2kO" 77 | }, 78 | "outputs": [], 79 | "source": [ 80 | "pip install --force-reinstall 'sqlalchemy<2.0.0'" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": null, 86 | "metadata": { 87 | "id": "gVol6tE8mVRi" 88 | }, 89 | "outputs": [], 90 | "source": [ 91 | "import pymysql" 92 | ] 93 | }, 94 | { 95 | "cell_type": "markdown", 96 | "metadata": { 97 | "id": "4XE0pxRww7No" 98 | }, 99 | "source": [ 100 | "## Connect to Database" 101 | ] 102 | }, 103 | { 104 | "cell_type": "code", 105 | "execution_count": null, 106 | "metadata": { 107 | "id": "bb_dKSVXhxt3" 108 | }, 109 | "outputs": [], 110 | "source": [ 111 | "db_user = \"user_name\"\n", 112 | "db_password = \"your_passsword\"\n", 113 | "db_host = \"your_host_name\"\n", 114 | "db_name = \"your_database_name\"" 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "execution_count": null, 120 | "metadata": { 121 | "colab": { 122 | "base_uri": "https://localhost:8080/" 123 | }, 124 | "id": "Gsv3AI5AlwUc", 125 | "outputId": "bee2205b-aa33-4bc2-d612-d6d2ee3c6160" 126 | }, 127 | "outputs": [ 128 | { 129 | "name": "stdout", 130 | "output_type": "stream", 131 | "text": [ 132 | "('Customers',)\n", 133 | "('OrderDetails',)\n", 134 | "('Orders',)\n", 135 | "('info',)\n", 136 | "('table_36370395d9314572970b325bee42817d',)\n", 137 | "('table_59af3c5a5388482193f88093fc2eaa36',)\n" 138 | ] 139 | } 140 | ], 141 | "source": [ 142 | "from sqlalchemy import create_engine, text\n", 143 | "\n", 144 | "# Construct the connection string\n", 145 | "connection_string = f\"mysql+pymysql://{db_user}:{db_password}@{db_host}/{db_name}\"\n", 146 | "\n", 147 | "# Create an engine instance\n", 148 | "engine = create_engine(connection_string)\n", 149 | "\n", 150 | "# Test the connection using raw SQL\n", 151 | "with engine.connect() as connection:\n", 152 | " result = connection.execute(text(\"show tables\"))\n", 153 | " for row in result:\n", 154 | " print(row)" 155 | ] 156 | }, 157 | { 158 | "cell_type": "markdown", 159 | "metadata": { 160 | "id": "UeIX0zRWxBVd" 161 | }, 162 | "source": [ 163 | "## Load database to llamaIndex SQLDatabase" 164 | ] 165 | }, 166 | { 167 | "cell_type": "code", 168 | "execution_count": null, 169 | "metadata": { 170 | "colab": { 171 | "base_uri": "https://localhost:8080/" 172 | }, 173 | "id": "WpzC82mtrxT5", 174 | "outputId": "2fd4a8a7-19b1-4ad7-a2c3-5b10f91b733d" 175 | }, 176 | "outputs": [ 177 | { 178 | "name": "stdout", 179 | "output_type": "stream", 180 | "text": [ 181 | "INFO:numexpr.utils:NumExpr defaulting to 2 threads.\n", 182 | "NumExpr defaulting to 2 threads.\n" 183 | ] 184 | } 185 | ], 186 | "source": [ 187 | "from llama_index.core import SQLDatabase" 188 | ] 189 | }, 190 | { 191 | "cell_type": "code", 192 | "execution_count": null, 193 | "metadata": { 194 | "colab": { 195 | "base_uri": "https://localhost:8080/" 196 | }, 197 | "id": "O79JFO7Tr3-E", 198 | "outputId": "864f4f9f-3bfa-4a54-b198-d343b426573a" 199 | }, 200 | "outputs": [ 201 | { 202 | "data": { 203 | "text/plain": [ 204 | "" 205 | ] 206 | }, 207 | "execution_count": 9, 208 | "metadata": {}, 209 | "output_type": "execute_result" 210 | } 211 | ], 212 | "source": [ 213 | "tables = ['table_36370395d9314572970b325bee42817d', 'table_59af3c5a5388482193f88093fc2eaa36']\n", 214 | "sql_database = SQLDatabase(engine, include_tables=tables, sample_rows_in_table_info=2)\n", 215 | "sql_database" 216 | ] 217 | }, 218 | { 219 | "cell_type": "code", 220 | "execution_count": null, 221 | "metadata": { 222 | "colab": { 223 | "base_uri": "https://localhost:8080/" 224 | }, 225 | "id": "AXf7FLDUr_qB", 226 | "outputId": "1f12f61f-4d1e-400c-955c-bdd33a712083" 227 | }, 228 | "outputs": [ 229 | { 230 | "data": { 231 | "text/plain": [ 232 | "{'Customers',\n", 233 | " 'OrderDetails',\n", 234 | " 'Orders',\n", 235 | " 'info',\n", 236 | " 'table_36370395d9314572970b325bee42817d',\n", 237 | " 'table_59af3c5a5388482193f88093fc2eaa36'}" 238 | ] 239 | }, 240 | "execution_count": 10, 241 | "metadata": {}, 242 | "output_type": "execute_result" 243 | } 244 | ], 245 | "source": [ 246 | "sql_database._all_tables" 247 | ] 248 | }, 249 | { 250 | "cell_type": "code", 251 | "execution_count": null, 252 | "metadata": { 253 | "colab": { 254 | "base_uri": "https://localhost:8080/", 255 | "height": 121 256 | }, 257 | "id": "YDdsRtylsCvB", 258 | "outputId": "2b01a53b-5c03-42bb-b6d0-d4477d2f2d41" 259 | }, 260 | "outputs": [ 261 | { 262 | "data": { 263 | "text/html": [ 264 | "
\n", 276 | "
llama_index.core.utilities.sql_wrapper.SQLDatabase.get_single_table_info
def get_single_table_info(table_name: str) -> str
/usr/local/lib/python3.10/dist-packages/llama_index/core/utilities/sql_wrapper.pyGet table info for a single table.
\n", 279 | " \n", 298 | "
" 299 | ], 300 | "text/plain": [ 301 | ">" 302 | ] 303 | }, 304 | "execution_count": 12, 305 | "metadata": {}, 306 | "output_type": "execute_result" 307 | } 308 | ], 309 | "source": [ 310 | "sql_database.get_single_table_info" 311 | ] 312 | }, 313 | { 314 | "cell_type": "markdown", 315 | "metadata": { 316 | "id": "uMncMEfVxIBT" 317 | }, 318 | "source": [ 319 | "## Connect to OpenAI account" 320 | ] 321 | }, 322 | { 323 | "cell_type": "code", 324 | "execution_count": null, 325 | "metadata": { 326 | "id": "sZZ9L0uQsQpA" 327 | }, 328 | "outputs": [], 329 | "source": [ 330 | "import os\n", 331 | "import openai" 332 | ] 333 | }, 334 | { 335 | "cell_type": "code", 336 | "execution_count": null, 337 | "metadata": { 338 | "id": "zYtPpql9wrw5" 339 | }, 340 | "outputs": [], 341 | "source": [ 342 | "# enter your openai key\n", 343 | "# openai.api_key = \"your_openai_key\"" 344 | ] 345 | }, 346 | { 347 | "cell_type": "code", 348 | "execution_count": null, 349 | "metadata": { 350 | "id": "7ywQn3vHw44-" 351 | }, 352 | "outputs": [], 353 | "source": [ 354 | "!pip install llama-index-callbacks-aim\n" 355 | ] 356 | }, 357 | { 358 | "cell_type": "markdown", 359 | "metadata": { 360 | "id": "7Cy6D7p6xTtg" 361 | }, 362 | "source": [ 363 | "## Connect to LLM and initialize the service context" 364 | ] 365 | }, 366 | { 367 | "cell_type": "code", 368 | "execution_count": null, 369 | "metadata": { 370 | "id": "SIzfNJajwunr" 371 | }, 372 | "outputs": [], 373 | "source": [ 374 | "import tiktoken\n", 375 | "from llama_index.core.callbacks import CallbackManager, TokenCountingHandler\n", 376 | "token_counter = TokenCountingHandler(\n", 377 | " tokenizer=tiktoken.encoding_for_model(\"gpt-3.5-turbo\").encode\n", 378 | ")\n", 379 | "\n", 380 | "callback_manager = CallbackManager([token_counter])" 381 | ] 382 | }, 383 | { 384 | "cell_type": "code", 385 | "execution_count": null, 386 | "metadata": { 387 | "colab": { 388 | "base_uri": "https://localhost:8080/" 389 | }, 390 | "id": "fSyv99l6wzd6", 391 | "outputId": "ec73509f-4ff6-4d1c-a7a0-1aa7377fc087" 392 | }, 393 | "outputs": [ 394 | { 395 | "name": "stderr", 396 | "output_type": "stream", 397 | "text": [ 398 | ":7: DeprecationWarning: Call to deprecated class method from_defaults. (ServiceContext is deprecated, please use `llama_index.settings.Settings` instead.) -- Deprecated since version 0.10.0.\n", 399 | " service_context = ServiceContext.from_defaults(\n" 400 | ] 401 | } 402 | ], 403 | "source": [ 404 | "from llama_index.core.indices.service_context import ServiceContext\n", 405 | "from llama_index.embeddings.openai import OpenAIEmbedding\n", 406 | "#import llama_index.indices.prompt_helper.PromptHelper\n", 407 | "from llama_index.llms.openai import OpenAI\n", 408 | "llm = OpenAI(temperature=0.1, model=\"gpt-3.5-turbo\")\n", 409 | "\n", 410 | "service_context = ServiceContext.from_defaults(\n", 411 | " llm=llm,callback_manager=callback_manager\n", 412 | ")" 413 | ] 414 | }, 415 | { 416 | "cell_type": "markdown", 417 | "metadata": { 418 | "id": "LNC8smcaxZCl" 419 | }, 420 | "source": [ 421 | "## Create SQL table node mapping" 422 | ] 423 | }, 424 | { 425 | "cell_type": "code", 426 | "execution_count": null, 427 | "metadata": { 428 | "id": "Vbkj9BEk0Nqt" 429 | }, 430 | "outputs": [], 431 | "source": [ 432 | "#creating SQL table node mapping\n", 433 | "from llama_index.core import VectorStoreIndex\n", 434 | "from llama_index.core.objects import ObjectIndex, SQLTableNodeMapping, SQLTableSchema\n", 435 | "import pandas as pd\n", 436 | "\n", 437 | "# list all the tables from database and crate table schema for prompt to LLM\n", 438 | "tables = list(sql_database._all_tables)\n", 439 | "table_node_mapping = SQLTableNodeMapping(sql_database)\n", 440 | "table_schema_objs = []\n", 441 | "for table in tables:\n", 442 | " table_schema_objs.append((SQLTableSchema(table_name = table)))" 443 | ] 444 | }, 445 | { 446 | "cell_type": "code", 447 | "execution_count": null, 448 | "metadata": { 449 | "colab": { 450 | "base_uri": "https://localhost:8080/" 451 | }, 452 | "id": "RXuln6id55cT", 453 | "outputId": "eaddc7c9-21e5-41ab-9a7f-b631bd7f10a3" 454 | }, 455 | "outputs": [ 456 | { 457 | "name": "stdout", 458 | "output_type": "stream", 459 | "text": [ 460 | "[SQLTableSchema(table_name='table_59af3c5a5388482193f88093fc2eaa36', context_str=None), SQLTableSchema(table_name='Orders', context_str=None), SQLTableSchema(table_name='table_36370395d9314572970b325bee42817d', context_str=None), SQLTableSchema(table_name='OrderDetails', context_str=None), SQLTableSchema(table_name='info', context_str=None), SQLTableSchema(table_name='Customers', context_str=None)]\n" 461 | ] 462 | } 463 | ], 464 | "source": [ 465 | "print(table_schema_objs)" 466 | ] 467 | }, 468 | { 469 | "cell_type": "markdown", 470 | "metadata": { 471 | "id": "gyVYfOfoxh9q" 472 | }, 473 | "source": [ 474 | "## Initialize SQL Table Retrieval Engine" 475 | ] 476 | }, 477 | { 478 | "cell_type": "code", 479 | "execution_count": null, 480 | "metadata": { 481 | "id": "mYTMGRF-4kpY" 482 | }, 483 | "outputs": [], 484 | "source": [ 485 | "from llama_index.core.indices.struct_store.sql_query import SQLTableRetrieverQueryEngine\n", 486 | "\n", 487 | "obj_index = ObjectIndex.from_objects(\n", 488 | " table_schema_objs,\n", 489 | " table_node_mapping,\n", 490 | " VectorStoreIndex\n", 491 | ")" 492 | ] 493 | }, 494 | { 495 | "cell_type": "code", 496 | "execution_count": null, 497 | "metadata": { 498 | "id": "-1-6vmM95mcd" 499 | }, 500 | "outputs": [], 501 | "source": [ 502 | "query_engine = SQLTableRetrieverQueryEngine(\n", 503 | " sql_database, obj_index.as_retriever(similarity_top_k=3), service_context=service_context\n", 504 | ")" 505 | ] 506 | }, 507 | { 508 | "cell_type": "code", 509 | "execution_count": null, 510 | "metadata": { 511 | "id": "q2jaDosADoMK" 512 | }, 513 | "outputs": [], 514 | "source": [ 515 | "response = query_engine.query(\"How many people have previous work experience?\")" 516 | ] 517 | }, 518 | { 519 | "cell_type": "code", 520 | "execution_count": null, 521 | "metadata": { 522 | "id": "4cKVpcUkDqqy" 523 | }, 524 | "outputs": [], 525 | "source": [ 526 | "print(response)" 527 | ] 528 | }, 529 | { 530 | "cell_type": "markdown", 531 | "metadata": { 532 | "id": "vHLOaQMoxtv0" 533 | }, 534 | "source": [ 535 | "## Few-shot examples prompting" 536 | ] 537 | }, 538 | { 539 | "cell_type": "code", 540 | "execution_count": null, 541 | "metadata": { 542 | "id": "n7NT73COxxTp" 543 | }, 544 | "outputs": [], 545 | "source": [ 546 | "# select few examples\n", 547 | " examples = [\n", 548 | " {\n", 549 | " \"input\": \"List all customers in France with a credit limit over 20,000.\",\n", 550 | " \"query\": \"SELECT * FROM customers WHERE country = 'France' AND creditLimit > 20000;\"\n", 551 | " },\n", 552 | " {\n", 553 | " \"input\": \"Get the highest payment amount made by any customer.\",\n", 554 | " \"query\": \"SELECT MAX(amount) FROM payments;\"\n", 555 | " },\n", 556 | " .....\n", 557 | " ]\n" 558 | ] 559 | }, 560 | { 561 | "cell_type": "code", 562 | "execution_count": null, 563 | "metadata": { 564 | "id": "uzNlsQ7rx64O" 565 | }, 566 | "outputs": [], 567 | "source": [ 568 | "# few shot examples prompt using llamaIndex prompt tempelates\n", 569 | " from llama_index.core import PromptTemplate\n", 570 | " from llama_index.llms.openai import OpenAI\n", 571 | "\n", 572 | " # Example prompt for SQL query generation\n", 573 | " qa_prompt_tmpl_str = \"\"\"\\\n", 574 | " Context information is below.\n", 575 | " ---------------------\n", 576 | " (\"human\", \"{input}\\nSQLQuery:\"),\n", 577 | " (\"ai\", \"{query}\") \\,\n", 578 | " \"\"\"\n", 579 | " # Variable mapping to generate templates\n", 580 | " template_var_mappings = {\"user_queries\": \"input\", \"ai_sql\": \"query\"}\n", 581 | "\n", 582 | " # Prompt template\n", 583 | " prompt_tmpl = PromptTemplate(\n", 584 | " qa_prompt_tmpl_str, template_var_mappings=template_var_mappings\n", 585 | " )\n", 586 | "\n", 587 | " # format prompt with user queries and sql queries\n", 588 | " fmt_prompt = partial_prompt_tmpl.format(\n", 589 | " user_queries=\"List all customers in France with a credit limit over 20,000.\",\n", 590 | " ai_sql=\"SELECT * FROM customers WHERE country = 'France' AND creditLimit > 20000;\",\n", 591 | " )\n", 592 | " print(fmt_prompt)" 593 | ] 594 | }, 595 | { 596 | "cell_type": "code", 597 | "execution_count": null, 598 | "metadata": { 599 | "id": "dsjj-ZYXyJxj" 600 | }, 601 | "outputs": [], 602 | "source": [ 603 | "# Dynamic few shot examples selection\n", 604 | "from llama_index.core import VectorStoreIndex\n", 605 | "from llama_index.llms.openai import OpenAI\n", 606 | "\n", 607 | "gpt35_llm = OpenAI(model=\"gpt-3.5-turbo\")\n", 608 | "\n", 609 | "# set up an index of few shot examples\n", 610 | "index = VectorStoreIndex.from_documents(examples)\n", 611 | "\n", 612 | "# query string\n", 613 | "query_str = \"How many employees we have?\"\n", 614 | "\n", 615 | "# retrieve vectors from index to get most relevant examples\n", 616 | "query_engine = index.as_query_engine(similarity_top_k=2, llm=gpt35_llm)\n", 617 | "\n", 618 | "# print the few shot examples further used for few shot prompting\n", 619 | "response_prompt = query_engine.query(query_str)" 620 | ] 621 | } 622 | ], 623 | "metadata": { 624 | "colab": { 625 | "include_colab_link": true, 626 | "provenance": [], 627 | "toc_visible": true 628 | }, 629 | "kernelspec": { 630 | "display_name": "Python 3", 631 | "name": "python3" 632 | }, 633 | "language_info": { 634 | "name": "python" 635 | } 636 | }, 637 | "nbformat": 4, 638 | "nbformat_minor": 0 639 | } 640 | -------------------------------------------------------------------------------- /Llamaindex_DataAgents/React__Agent.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "provenance": [], 7 | "authorship_tag": "ABX9TyO+Ei/lQiImh9VcDPU28mRL", 8 | "include_colab_link": true 9 | }, 10 | "kernelspec": { 11 | "name": "python3", 12 | "display_name": "Python 3" 13 | }, 14 | "language_info": { 15 | "name": "python" 16 | } 17 | }, 18 | "cells": [ 19 | { 20 | "cell_type": "markdown", 21 | "metadata": { 22 | "id": "view-in-github", 23 | "colab_type": "text" 24 | }, 25 | "source": [ 26 | "\"Open" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "source": [ 32 | "!pip install llama_index\n", 33 | "!pip install pyPDF\n", 34 | "!pip install openai" 35 | ], 36 | "metadata": { 37 | "colab": { 38 | "base_uri": "https://localhost:8080/" 39 | }, 40 | "id": "LWXJardck7aS", 41 | "outputId": "5f4235d9-9e1c-4982-860e-121f4eec2762" 42 | }, 43 | "execution_count": null, 44 | "outputs": [ 45 | { 46 | "output_type": "stream", 47 | "name": "stdout", 48 | "text": [ 49 | "Requirement already satisfied: llama_index in /usr/local/lib/python3.10/dist-packages (0.8.8)\n", 50 | "Requirement already satisfied: tiktoken in /usr/local/lib/python3.10/dist-packages (from llama_index) (0.4.0)\n", 51 | "Requirement already satisfied: dataclasses-json in /usr/local/lib/python3.10/dist-packages (from llama_index) (0.5.14)\n", 52 | "Requirement already satisfied: langchain<=0.0.266,>=0.0.262 in /usr/local/lib/python3.10/dist-packages (from llama_index) (0.0.266)\n", 53 | "Requirement already satisfied: sqlalchemy>=2.0.15 in /usr/local/lib/python3.10/dist-packages (from llama_index) (2.0.20)\n", 54 | "Requirement already satisfied: numpy in /usr/local/lib/python3.10/dist-packages (from llama_index) (1.23.5)\n", 55 | "Requirement already satisfied: tenacity<9.0.0,>=8.2.0 in /usr/local/lib/python3.10/dist-packages (from llama_index) (8.2.3)\n", 56 | "Requirement already satisfied: openai>=0.26.4 in /usr/local/lib/python3.10/dist-packages (from llama_index) (0.27.9)\n", 57 | "Requirement already satisfied: pandas in /usr/local/lib/python3.10/dist-packages (from llama_index) (1.5.3)\n", 58 | "Requirement already satisfied: urllib3<2 in /usr/local/lib/python3.10/dist-packages (from llama_index) (1.26.16)\n", 59 | "Requirement already satisfied: fsspec>=2023.5.0 in /usr/local/lib/python3.10/dist-packages (from llama_index) (2023.6.0)\n", 60 | "Requirement already satisfied: typing-inspect>=0.8.0 in /usr/local/lib/python3.10/dist-packages (from llama_index) (0.9.0)\n", 61 | "Requirement already satisfied: typing-extensions>=4.5.0 in /usr/local/lib/python3.10/dist-packages (from llama_index) (4.7.1)\n", 62 | "Requirement already satisfied: beautifulsoup4 in /usr/local/lib/python3.10/dist-packages (from llama_index) (4.11.2)\n", 63 | "Requirement already satisfied: nest-asyncio in /usr/local/lib/python3.10/dist-packages (from llama_index) (1.5.7)\n", 64 | "Requirement already satisfied: PyYAML>=5.3 in /usr/local/lib/python3.10/dist-packages (from langchain<=0.0.266,>=0.0.262->llama_index) (6.0.1)\n", 65 | "Requirement already satisfied: aiohttp<4.0.0,>=3.8.3 in /usr/local/lib/python3.10/dist-packages (from langchain<=0.0.266,>=0.0.262->llama_index) (3.8.5)\n", 66 | "Requirement already satisfied: async-timeout<5.0.0,>=4.0.0 in /usr/local/lib/python3.10/dist-packages (from langchain<=0.0.266,>=0.0.262->llama_index) (4.0.3)\n", 67 | "Requirement already satisfied: langsmith<0.1.0,>=0.0.21 in /usr/local/lib/python3.10/dist-packages (from langchain<=0.0.266,>=0.0.262->llama_index) (0.0.26)\n", 68 | "Requirement already satisfied: numexpr<3.0.0,>=2.8.4 in /usr/local/lib/python3.10/dist-packages (from langchain<=0.0.266,>=0.0.262->llama_index) (2.8.5)\n", 69 | "Requirement already satisfied: openapi-schema-pydantic<2.0,>=1.2 in /usr/local/lib/python3.10/dist-packages (from langchain<=0.0.266,>=0.0.262->llama_index) (1.2.4)\n", 70 | "Requirement already satisfied: pydantic<2,>=1 in /usr/local/lib/python3.10/dist-packages (from langchain<=0.0.266,>=0.0.262->llama_index) (1.10.12)\n", 71 | "Requirement already satisfied: requests<3,>=2 in /usr/local/lib/python3.10/dist-packages (from langchain<=0.0.266,>=0.0.262->llama_index) (2.31.0)\n", 72 | "Requirement already satisfied: marshmallow<4.0.0,>=3.18.0 in /usr/local/lib/python3.10/dist-packages (from dataclasses-json->llama_index) (3.20.1)\n", 73 | "Requirement already satisfied: tqdm in /usr/local/lib/python3.10/dist-packages (from openai>=0.26.4->llama_index) (4.66.1)\n", 74 | "Requirement already satisfied: greenlet!=0.4.17 in /usr/local/lib/python3.10/dist-packages (from sqlalchemy>=2.0.15->llama_index) (2.0.2)\n", 75 | "Requirement already satisfied: mypy-extensions>=0.3.0 in /usr/local/lib/python3.10/dist-packages (from typing-inspect>=0.8.0->llama_index) (1.0.0)\n", 76 | "Requirement already satisfied: soupsieve>1.2 in /usr/local/lib/python3.10/dist-packages (from beautifulsoup4->llama_index) (2.4.1)\n", 77 | "Requirement already satisfied: python-dateutil>=2.8.1 in /usr/local/lib/python3.10/dist-packages (from pandas->llama_index) (2.8.2)\n", 78 | "Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas->llama_index) (2023.3)\n", 79 | "Requirement already satisfied: regex>=2022.1.18 in /usr/local/lib/python3.10/dist-packages (from tiktoken->llama_index) (2023.6.3)\n", 80 | "Requirement already satisfied: attrs>=17.3.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain<=0.0.266,>=0.0.262->llama_index) (23.1.0)\n", 81 | "Requirement already satisfied: charset-normalizer<4.0,>=2.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain<=0.0.266,>=0.0.262->llama_index) (3.2.0)\n", 82 | "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<=0.0.266,>=0.0.262->llama_index) (6.0.4)\n", 83 | "Requirement already satisfied: yarl<2.0,>=1.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain<=0.0.266,>=0.0.262->llama_index) (1.9.2)\n", 84 | "Requirement already satisfied: frozenlist>=1.1.1 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain<=0.0.266,>=0.0.262->llama_index) (1.4.0)\n", 85 | "Requirement already satisfied: aiosignal>=1.1.2 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain<=0.0.266,>=0.0.262->llama_index) (1.3.1)\n", 86 | "Requirement already satisfied: packaging>=17.0 in /usr/local/lib/python3.10/dist-packages (from marshmallow<4.0.0,>=3.18.0->dataclasses-json->llama_index) (23.1)\n", 87 | "Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.10/dist-packages (from python-dateutil>=2.8.1->pandas->llama_index) (1.16.0)\n", 88 | "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2->langchain<=0.0.266,>=0.0.262->llama_index) (3.4)\n", 89 | "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2->langchain<=0.0.266,>=0.0.262->llama_index) (2023.7.22)\n", 90 | "Requirement already satisfied: pyPDF in /usr/local/lib/python3.10/dist-packages (3.15.2)\n", 91 | "Requirement already satisfied: openai in /usr/local/lib/python3.10/dist-packages (0.27.9)\n", 92 | "Requirement already satisfied: requests>=2.20 in /usr/local/lib/python3.10/dist-packages (from openai) (2.31.0)\n", 93 | "Requirement already satisfied: tqdm in /usr/local/lib/python3.10/dist-packages (from openai) (4.66.1)\n", 94 | "Requirement already satisfied: aiohttp in /usr/local/lib/python3.10/dist-packages (from openai) (3.8.5)\n", 95 | "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests>=2.20->openai) (3.2.0)\n", 96 | "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests>=2.20->openai) (3.4)\n", 97 | "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests>=2.20->openai) (1.26.16)\n", 98 | "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests>=2.20->openai) (2023.7.22)\n", 99 | "Requirement already satisfied: attrs>=17.3.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp->openai) (23.1.0)\n", 100 | "Requirement already satisfied: multidict<7.0,>=4.5 in /usr/local/lib/python3.10/dist-packages (from aiohttp->openai) (6.0.4)\n", 101 | "Requirement already satisfied: async-timeout<5.0,>=4.0.0a3 in /usr/local/lib/python3.10/dist-packages (from aiohttp->openai) (4.0.3)\n", 102 | "Requirement already satisfied: yarl<2.0,>=1.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp->openai) (1.9.2)\n", 103 | "Requirement already satisfied: frozenlist>=1.1.1 in /usr/local/lib/python3.10/dist-packages (from aiohttp->openai) (1.4.0)\n", 104 | "Requirement already satisfied: aiosignal>=1.1.2 in /usr/local/lib/python3.10/dist-packages (from aiohttp->openai) (1.3.1)\n" 105 | ] 106 | } 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "source": [ 112 | "import openai\n", 113 | "openai.api_key = \"your_key_here\"" 114 | ], 115 | "metadata": { 116 | "id": "DElxZiPClVnQ" 117 | }, 118 | "execution_count": null, 119 | "outputs": [] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "execution_count": null, 124 | "metadata": { 125 | "id": "fcfFx0QAklLV" 126 | }, 127 | "outputs": [], 128 | "source": [ 129 | "from llama_index import (\n", 130 | " SimpleDirectoryReader,\n", 131 | " VectorStoreIndex,\n", 132 | " StorageContext,\n", 133 | " load_index_from_storage,\n", 134 | ")\n", 135 | "\n", 136 | "from llama_index.tools import QueryEngineTool, ToolMetadata\n" 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "source": [ 142 | "try:\n", 143 | " storage_context = StorageContext.from_defaults(persist_dir=\"./storage\")\n", 144 | " index = load_index_from_storage(storage_context)\n", 145 | "\n", 146 | " index_loaded = True\n", 147 | "except:\n", 148 | " index_loaded = False" 149 | ], 150 | "metadata": { 151 | "id": "RWFPifvwknGZ" 152 | }, 153 | "execution_count": null, 154 | "outputs": [] 155 | }, 156 | { 157 | "cell_type": "code", 158 | "source": [ 159 | "if not index_loaded:\n", 160 | " # load data\n", 161 | " docs = SimpleDirectoryReader(\n", 162 | " input_files=[\"/content/storage/Job Description Data Scientist Microsoft.pdf\"]\n", 163 | " ).load_data()\n", 164 | "\n", 165 | "\n", 166 | " # build index\n", 167 | " index = VectorStoreIndex.from_documents(docs)\n", 168 | "\n", 169 | " # persist index\n", 170 | " index.storage_context.persist(persist_dir=\"./storage/index\")" 171 | ], 172 | "metadata": { 173 | "id": "q-plQmQBkpop" 174 | }, 175 | "execution_count": null, 176 | "outputs": [] 177 | }, 178 | { 179 | "cell_type": "code", 180 | "source": [ 181 | "from llama_index.agent import ReActAgent\n", 182 | "from llama_index.llms import OpenAI" 183 | ], 184 | "metadata": { 185 | "id": "RuPENy-KktLR" 186 | }, 187 | "execution_count": null, 188 | "outputs": [] 189 | }, 190 | { 191 | "cell_type": "code", 192 | "source": [ 193 | "engine = index.as_query_engine(similarity_top_k=3)\n", 194 | "\n", 195 | "query_engine_tools = [\n", 196 | " QueryEngineTool(\n", 197 | " query_engine=engine,\n", 198 | " metadata=ToolMetadata(\n", 199 | " name=\"Data Scientist JD\",\n", 200 | " description=\"Provides information about Job description for data scientist \"\n", 201 | " \"Use a detailed plain text question as input to the tool.\",\n", 202 | " ),\n", 203 | " ),\n", 204 | "]" 205 | ], 206 | "metadata": { 207 | "id": "j3Pn5KRIkrnd" 208 | }, 209 | "execution_count": null, 210 | "outputs": [] 211 | }, 212 | { 213 | "cell_type": "code", 214 | "source": [ 215 | "llm = OpenAI(model=\"gpt-3.5-turbo-0613\")\n", 216 | "agent = ReActAgent.from_tools(query_engine_tools, llm=llm, verbose=True)" 217 | ], 218 | "metadata": { 219 | "id": "UcFFu7TzkvHE" 220 | }, 221 | "execution_count": null, 222 | "outputs": [] 223 | }, 224 | { 225 | "cell_type": "code", 226 | "source": [ 227 | "response = agent.chat(\"What is the work experience required in years?\")\n", 228 | "print(str(response))" 229 | ], 230 | "metadata": { 231 | "colab": { 232 | "base_uri": "https://localhost:8080/" 233 | }, 234 | "id": "ruEamnjnkwmQ", 235 | "outputId": "b25d3ec8-1de0-4ee1-b0df-1d2b8d26f3d5" 236 | }, 237 | "execution_count": null, 238 | "outputs": [ 239 | { 240 | "output_type": "stream", 241 | "name": "stdout", 242 | "text": [ 243 | "\u001b[38;5;200m\u001b[1;3mThought: I need to use a tool to help me answer the question.\n", 244 | "Action: Data Scientist JD\n", 245 | "Action Input: {'input': 'work experience'}\n", 246 | "\u001b[0m\u001b[36;1m\u001b[1;3mObservation: The job description mentions that the ideal candidate should have at least 5 years of experience working with large data sets or doing large scale quantitative analysis. Additionally, the candidate should have experience manipulating large data sets through statistical software or other methods.\n", 247 | "\u001b[0m\u001b[38;5;200m\u001b[1;3mResponse: The job description mentions that the ideal candidate should have at least 5 years of experience working with large data sets or doing large scale quantitative analysis.\n", 248 | "\u001b[0mThe job description mentions that the ideal candidate should have at least 5 years of experience working with large data sets or doing large scale quantitative analysis.\n" 249 | ] 250 | } 251 | ] 252 | } 253 | ] 254 | } -------------------------------------------------------------------------------- /Llamaindex_DataAgents/new.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/Llamaindex_DataAgents/new.py -------------------------------------------------------------------------------- /Small Language Models Blog/Running_TinyLlama_using_HuggingFace.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "provenance": [] 7 | }, 8 | "kernelspec": { 9 | "name": "python3", 10 | "display_name": "Python 3" 11 | }, 12 | "language_info": { 13 | "name": "python" 14 | } 15 | }, 16 | "cells": [ 17 | { 18 | "cell_type": "markdown", 19 | "source": [ 20 | "## Using HuggingFace Text Generation Pipeline" 21 | ], 22 | "metadata": { 23 | "id": "8WYE_29w3bPj" 24 | } 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": null, 29 | "metadata": { 30 | "colab": { 31 | "base_uri": "https://localhost:8080/" 32 | }, 33 | "id": "luOwrS6kBGX0", 34 | "outputId": "cb880954-527a-4edc-ee5c-d64ec843a4c5" 35 | }, 36 | "outputs": [ 37 | { 38 | "output_type": "execute_result", 39 | "data": { 40 | "text/plain": [ 41 | "[{'generated_text': [{'role': 'user',\n", 42 | " 'content': 'What is the capital of France?'},\n", 43 | " {'role': 'assistant', 'content': 'The capital of France is Paris.'}]}]" 44 | ] 45 | }, 46 | "metadata": {}, 47 | "execution_count": 6 48 | } 49 | ], 50 | "source": [ 51 | "# Use a pipeline as a high-level helper\n", 52 | "from transformers import pipeline\n", 53 | "\n", 54 | "messages = [\n", 55 | " {\"role\": \"user\", \"content\": \"What is the capital of France?\"},\n", 56 | "]\n", 57 | "pipe = pipeline(\"text-generation\", model=\"TinyLlama/TinyLlama-1.1B-Chat-v1.0\")\n", 58 | "pipe(messages)" 59 | ] 60 | }, 61 | { 62 | "cell_type": "markdown", 63 | "source": [ 64 | "## Using HuggingFace Inference API" 65 | ], 66 | "metadata": { 67 | "id": "mfB5jwDu3g_J" 68 | } 69 | }, 70 | { 71 | "cell_type": "code", 72 | "source": [ 73 | "from huggingface_hub import InferenceClient\n", 74 | "\n", 75 | "client = InferenceClient(api_key=\"api_key\")\n", 76 | "\n", 77 | "for message in client.chat_completion(\n", 78 | "\tmodel=\"TinyLlama/TinyLlama-1.1B-Chat-v1.0\",\n", 79 | "\tmessages=[{\"role\": \"user\", \"content\": \"What is the capital of France?\"}],\n", 80 | "\tmax_tokens=500,\n", 81 | "\tstream=True,\n", 82 | "):\n", 83 | " print(message.choices[0].delta.content, end=\"\")" 84 | ], 85 | "metadata": { 86 | "colab": { 87 | "base_uri": "https://localhost:8080/" 88 | }, 89 | "id": "g_ztA7FRCWpJ", 90 | "outputId": "7f3eac7e-6b64-428f-b868-08e76fb6bcd9" 91 | }, 92 | "execution_count": null, 93 | "outputs": [ 94 | { 95 | "output_type": "stream", 96 | "name": "stdout", 97 | "text": [ 98 | "The capital of France (le chef-lieu de France) is Paris. Paris is the seat of the Parliament of France, the National Assembly, the Conseil d'Etat, the French Council of State, the Constitutional Council, and some public offices." 99 | ] 100 | } 101 | ] 102 | } 103 | ] 104 | } -------------------------------------------------------------------------------- /Videodb/.env: -------------------------------------------------------------------------------- 1 | videodb_api_key = "" 2 | openai_api_key = "" 3 | -------------------------------------------------------------------------------- /Videodb/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ -------------------------------------------------------------------------------- /Videodb/db_utils.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | from videodb import connect 3 | from dotenv import load_dotenv 4 | load_dotenv() 5 | import os 6 | from openai import OpenAI 7 | 8 | openai_api_key = os.getenv("openai_api_key") 9 | videodb_api_key = os.getenv("videodb_api_key") 10 | 11 | client = OpenAI(api_key = openai_api_key) 12 | 13 | conn = connect(api_key=videodb_api_key) 14 | coll = conn.get_collection() 15 | 16 | # Function to upload videos 17 | def upload_videos_to_database(): 18 | for link in st.session_state.youtube_links: 19 | try: 20 | coll.upload(url=link) 21 | print(f"Video: {link} uploaded successfully") 22 | for video in coll.get_videos(): 23 | video.index_spoken_words() 24 | print(f"Indexed {video.name}") 25 | except Exception as e: 26 | print(f"Exception occured for video {link} as {e}") 27 | 28 | def getanswer(query): 29 | result = coll.search(query = query) 30 | print("Type: ") 31 | first_shot = result.get_shots()[0] 32 | video_title = first_shot.video_title 33 | text = first_shot.text 34 | print("Video Title:", video_title) 35 | print("Text:", text) 36 | answer = "" 37 | answer = get_openai_ans(query=query, text=text) 38 | matching_video = { 39 | "video_title": video_title, 40 | "text": text 41 | } 42 | return answer, matching_video 43 | 44 | def get_openai_ans(query, text): 45 | messages = [ 46 | { 47 | "role": "assistant", 48 | "content": f"""You are an helpful AI chatbot, who answers questions based on the generated transcript of a video. Remember to be precise and to the point while answering questions. 49 | You need to output the query only based on the below context provided, if you don't find answer in the context, output 'Information to the query is not in the provided video context' 50 | The context to answer query is: {text} 51 | 52 | Now answer the queries given by user""" 53 | }, 54 | { 55 | "role": "user", 56 | "content": query 57 | } 58 | ] 59 | 60 | response = client.chat.completions.create( 61 | model="gpt-3.5-turbo", 62 | messages = messages 63 | ) 64 | 65 | answer = response.choices[0].message.content 66 | return answer -------------------------------------------------------------------------------- /Videodb/requirements.txt: -------------------------------------------------------------------------------- 1 | videodb 2 | streamlit 3 | openai -------------------------------------------------------------------------------- /Videodb/streamlit.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | from db_utils import upload_videos_to_database, getanswer 3 | 4 | st.set_page_config( 5 | page_title="Youtube Video Query Bot🤖", layout="centered", initial_sidebar_state="auto" 6 | ) 7 | 8 | def initialize_session_state(): 9 | if "messages" not in st.session_state.keys(): 10 | st.session_state.messages = [ 11 | {"role": "assistant", "content": "Hi! How may I assist you today?"} 12 | ] 13 | 14 | if "youtube_links" not in st.session_state.keys(): 15 | st.session_state.youtube_links = [] 16 | 17 | if "links_submitted" not in st.session_state.keys(): 18 | st.session_state.links_submitted = False 19 | 20 | initialize_session_state() 21 | 22 | st.header("Enter YouTube Video Links") 23 | if not st.session_state.links_submitted: 24 | youtube_link = st.text_input("Enter a YouTube link:") 25 | if st.button("Add YouTube Link"): 26 | st.session_state.youtube_links.append(youtube_link) 27 | st.success(f"YouTube link {youtube_link} added successfully!") 28 | youtube_link = "" 29 | 30 | if st.button("Submit All YouTube Links"): 31 | st.session_state.links_submitted = True 32 | with st.spinner("Uploading and Indexing Video"): 33 | upload_videos_to_database() 34 | st.success("All YouTube links uploaded and indexed successfully!") 35 | else: 36 | st.success("YouTube links have been submitted and locked.") 37 | 38 | st.title("Youtube Video Query Bot🤖") 39 | 40 | for message in st.session_state.messages: 41 | with st.chat_message(message["role"]): 42 | st.write(message["content"]) 43 | 44 | if user_query := st.chat_input("Enter query"): 45 | st.session_state.messages.append({"role": "user", "content": user_query}) 46 | with st.chat_message("user"): 47 | st.write(user_query) 48 | 49 | if st.session_state.messages[-1]["role"] != "assistant": 50 | with st.chat_message("assistant"): 51 | with st.spinner("Thinking🤔"): 52 | bot_id = st.session_state.bot_id 53 | session_id = st.session_state.session_id 54 | res_box = st.empty() 55 | final_response, matching_videos = getanswer(user_query) 56 | 57 | res_box.write(f"{final_response}") 58 | 59 | st.session_state.messages.append({"role": "assistant", "content": final_response}) 60 | 61 | with st.expander(f"Context Details"): 62 | st.write(matching_videos) 63 | -------------------------------------------------------------------------------- /Youtube Q-A Chatbot/.env: -------------------------------------------------------------------------------- 1 | openai_key = "Enter your openai key" 2 | pinecone_key = "Provide your pinecone key" -------------------------------------------------------------------------------- /Youtube Q-A Chatbot/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /Youtube Q-A Chatbot/.idea/blog_apps.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Youtube Q-A Chatbot/.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 30 | -------------------------------------------------------------------------------- /Youtube Q-A Chatbot/.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /Youtube Q-A Chatbot/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Youtube Q-A Chatbot/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Youtube Q-A Chatbot/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Youtube Q-A Chatbot/app.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | import openai 3 | from streamlit_chat import message 4 | import pinecone 5 | import os 6 | import pinecone_utils 7 | 8 | # We will pasting our openai credentials over here 9 | openai.api_key = os.getenv("openai_key") 10 | 11 | pinecone.init(api_key=os.getenv("pinecone_key"), environment="us-east-1-aws") 12 | 13 | index = pinecone.Index("demo-youtube-app") 14 | 15 | 16 | # openai embeddings method 17 | def get_embedding(text): 18 | response = openai.Embedding.create( 19 | input=text, 20 | model="text-embedding-ada-002" 21 | ) 22 | 23 | return response['data'][0]['embedding'] 24 | 25 | 26 | def find_top_match(query, k): 27 | query_em = pinecone_utils.get_embedding(query) 28 | result = index.query(query_em, top_k=k, includeMetadata=True) 29 | 30 | return [result['matches'][i]['metadata']['video_url'] for i in range(k)], [result['matches'][i]['metadata']['title'] 31 | for i in range(k)], [ 32 | result['matches'][i]['metadata']['context'] 33 | for i in range(k)] 34 | 35 | 36 | def get_message_history(contexts): 37 | message_hist = [ 38 | {"role": "system", 39 | "content": """As a Bot, it's important to show empathy and understanding when answering questions.You are a smart AI who have to answer the question only from the provided context If you 40 | are unable to understand the question and need more clarity then your response should be 'Could you please be 41 | more specific?'. If you are unable to find the answer from the given context then your response should be 'Answer is not present in the provided video' \n"""}, 42 | {"role": "system", "content": contexts}, 43 | ] 44 | 45 | return message_hist 46 | 47 | 48 | def chat(var, message, role="user"): 49 | message_history.append({"role": role, "content": f"{var}"}) 50 | completion = openai.ChatCompletion.create( 51 | model="gpt-3.5-turbo", 52 | messages=message 53 | ) 54 | reply = completion.choices[0].message.content 55 | message_history.append({"role": "assistant", "content": f"{reply}"}) 56 | return reply 57 | 58 | 59 | st.title("Youtube Chatbot") 60 | 61 | if 'generated' not in st.session_state: 62 | st.session_state['generated'] = ["How can I assist you?"] 63 | 64 | if 'past' not in st.session_state: 65 | st.session_state['past'] = [] 66 | 67 | 68 | def get_text(): 69 | input_text = st.text_input(key="input", label="Type your query here") 70 | return input_text 71 | 72 | 73 | # container for chat history 74 | response_container = st.container() 75 | # container for text box 76 | textcontainer = st.container() 77 | 78 | with textcontainer: 79 | user_input = get_text() 80 | 81 | if st.session_state.past or user_input: 82 | urls, title, context = find_top_match(user_input, 1) 83 | message_history = get_message_history(context[0]) 84 | 85 | with st.spinner("Generating the answer..."): 86 | response = chat(user_input, message_history) 87 | 88 | st.session_state.past.append(user_input) 89 | st.session_state.generated.append(response) 90 | 91 | st.subheader("References") 92 | 93 | link_expander = st.expander("Context obtained from url") 94 | link_expander.write(urls) 95 | 96 | # st.session_state.pastModified.append(user_input) 97 | 98 | with response_container: 99 | if st.session_state['generated'] or len(message_history) > 0: 100 | for i in range(len(st.session_state['generated'])): 101 | message(st.session_state["generated"][i], key=str(i)) 102 | if i < len(st.session_state['past']): 103 | message(st.session_state['past'][i], is_user=True, key=str(i) + '_user') 104 | -------------------------------------------------------------------------------- /Youtube Q-A Chatbot/pinecone_utils.py: -------------------------------------------------------------------------------- 1 | import pinecone 2 | import pandas as pd 3 | import openai 4 | import os 5 | 6 | pinecone.init(api_key=os.getenv("pinecone_key"), environment="us-east-1-aws") 7 | 8 | index = pinecone.Index("demo-youtube-app") 9 | print(index.describe_index_stats()) 10 | 11 | df = pd.read_csv("history.csv") 12 | print(df.head()) 13 | openai.api_key = "" 14 | 15 | 16 | def get_embedding(text): 17 | response = openai.Embedding.create( 18 | input=text, 19 | model="text-embedding-ada-002" 20 | ) 21 | 22 | return response['data'][0]['embedding'] 23 | 24 | 25 | def addData(index,url, title,context): 26 | my_id = index.describe_index_stats()['total_vector_count'] 27 | 28 | chunkInfo = (str(my_id), 29 | get_embedding(context), 30 | {'video_url': url, 'title':title,'context':context}) 31 | 32 | index.upsert(vectors=[chunkInfo]) 33 | 34 | 35 | for indexx, row in df.iterrows(): 36 | addData(index,row["url"],row["title"],row["content"]) 37 | 38 | 39 | print("Completed") -------------------------------------------------------------------------------- /Youtube Q-A Chatbot/requirements: -------------------------------------------------------------------------------- 1 | openai 2 | pinecone-client 3 | streamlit 4 | streamlit-chat 5 | pandas 6 | numpy 7 | pytube 8 | python-dotenv 9 | 10 | -------------------------------------------------------------------------------- /Youtube Q-A Chatbot/youtube_subtitle_gen.py: -------------------------------------------------------------------------------- 1 | # file name youtube_subtitle_gen.py 2 | import openai 3 | import tempfile 4 | import numpy as np 5 | import pandas as pd 6 | from pytube import YouTube, Search 7 | import os 8 | from dotenv import load_dotenv 9 | load_dotenv() 10 | 11 | openai.api_key = os.getenv("openai_key") 12 | 13 | video_dict = { 14 | "url": [], 15 | "title": [], 16 | "content": [] 17 | } 18 | 19 | 20 | def video_to_audio(video_URL): 21 | # Get the video 22 | video = YouTube(video_URL) 23 | video_dict["url"].append(video_URL) 24 | try: 25 | video_dict["title"].append(video.title) 26 | except: 27 | video_dict["title"].append("Title not found") 28 | 29 | 30 | # Convert video to Audio 31 | audio = video.streams.filter(only_audio=True).first() 32 | 33 | temp_dir = tempfile.mkdtemp() 34 | variable = np.random.randint(1111, 1111111) 35 | file_name = f'recording{variable}.mp3' 36 | temp_path = os.path.join(temp_dir, file_name) 37 | # audio_in = AudioSegment.from_file(uploaded_file.name, format="m4a") 38 | # with open(temp_path, "wb") as f: 39 | # f.write(uploaded_file.getvalue()) 40 | 41 | # Save to destination 42 | output = audio.download(output_path=temp_path) 43 | 44 | audio_file = open(output, "rb") 45 | textt = openai.Audio.translate("whisper-1", audio_file)["text"] 46 | 47 | return textt 48 | 49 | 50 | def create_dataframe(data): 51 | df = pd.DataFrame(data) 52 | df.to_csv("history.csv") 53 | 54 | 55 | s = Search("history lessons under 4 minutes") 56 | print(len(s.results)) 57 | 58 | for ele in s.results[0:5:1]: 59 | transcription = video_to_audio(ele.watch_url) 60 | print(transcription) 61 | print("\n\n\n") 62 | video_dict["content"].append(transcription) 63 | 64 | create_dataframe(video_dict) 65 | 66 | print("Created Dataframe") 67 | -------------------------------------------------------------------------------- /images/63eb5ebedd3a9a738e22a03f_open ai whisper.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PradipNichite/FutureSmart-AI-Blog/8f1ed20f09ac6720b4201dc23c54f8b6fdfd0d2d/images/63eb5ebedd3a9a738e22a03f_open ai whisper.jpg --------------------------------------------------------------------------------