{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "65af1ebf-354a-47b9-a882-f88ee8a28d64",
   "metadata": {},
   "source": [
    "## LangChain + ToDo Full Stack App"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1f65de69-4c22-48cb-8eb2-caf234d31f39",
   "metadata": {},
   "source": [
    "### Add OpenAI key in backend/.env"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "af660ffe-b777-4053-a2a4-73f8b6da9842",
   "metadata": {},
   "source": [
    "### Add imports in backend/routers/todos.py"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5508ce92-1e7e-4302-9c15-e1e4bd598e93",
   "metadata": {},
   "outputs": [],
   "source": [
    "# from langchain import OpenAI, PromptTemplate\n",
    "# from langchain.chains import LLMChain"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3f1ab301-9e2f-484a-b990-896da9b69265",
   "metadata": {},
   "source": [
    "### Add basic LangChain code in backend/routers/todos.py"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b0aeae91-3a1f-46c4-b63d-a4d7c8f441f1",
   "metadata": {},
   "outputs": [],
   "source": [
    "# # LANGCHAIN\n",
    "# langchain_llm = OpenAI(temperature=0)\n",
    "\n",
    "# summarize_template_string = \"\"\"\n",
    "#         Provide a summary for the following text:\n",
    "#         {text}\n",
    "# \"\"\"\n",
    "\n",
    "# summarize_prompt = PromptTemplate(\n",
    "#     template=summarize_template_string,\n",
    "#     input_variables=['text'],\n",
    "# )\n",
    "\n",
    "# summarize_chain = LLMChain(\n",
    "#     llm=langchain_llm,\n",
    "#     prompt=summarize_prompt,\n",
    "# )\n",
    "\n",
    "# @router.post('/summarize-text')\n",
    "# async def summarize_text(text: str):\n",
    "#     summary = summarize_chain.run(text=text)\n",
    "#     return {'summary': summary}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ab976fcc-1eed-4f63-ad31-8f822ae43472",
   "metadata": {},
   "source": [
    "### Check backend"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "1ab84822-47ad-49b0-bb23-040db5a5b368",
   "metadata": {},
   "outputs": [],
   "source": [
    "#uvicorn main:app --reload"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "259699f1-8b01-44fe-bd3b-3567db2798f8",
   "metadata": {},
   "source": [
    "http://127.0.0.1:8000/docs\n",
    "* Check how POST /todos/summarize-test works"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bc8096fc-5f46-4de3-a233-9aaf12f17abc",
   "metadata": {},
   "source": [
    "### Add advanced LangChain code in backend/routers/todos.py"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "526fbc70-e697-47fd-b01f-add7ea8e0cb3",
   "metadata": {},
   "outputs": [],
   "source": [
    "# write_poem_template_string = \"\"\"\n",
    "#         Write a short poem with the following text:\n",
    "#         {text}\n",
    "# \"\"\"\n",
    "\n",
    "# write_poem_prompt = PromptTemplate(\n",
    "#     template=write_poem_template_string,\n",
    "#     input_variables=['text'],\n",
    "# )\n",
    "\n",
    "# write_poem_chain = LLMChain(\n",
    "#     llm=langchain_llm,\n",
    "#     prompt=write_poem_prompt,\n",
    "# )\n",
    "\n",
    "# @router.post(\"/write-poem/{id}\")\n",
    "# async def get_todo_by_id(id: int, db: Session = Depends(get_db)):\n",
    "#     todo = crud.read_todo(db, id)\n",
    "#     if todo is None:\n",
    "#         raise HTTPException(status_code=404, detail=\"to do not found\")\n",
    "#     poem = write_poem_chain.run(text=todo.name)\n",
    "#     return {'poem': poem}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bd3e0b90-beac-4ac6-9689-fe7d045b4d00",
   "metadata": {},
   "source": [
    "## Update frontend"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a73858ea-8f2f-43f0-bd74-a0e7517c6ba6",
   "metadata": {},
   "source": [
    "### components/todo.js\n",
    "* The generatePoem(id) function is the key\n",
    "* We are displaying the generated poem in a pop-up box\n",
    "* The associated styles are in styles/todo.module.css"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d2e81d81-8a30-452b-85b2-c1690fe8db05",
   "metadata": {},
   "outputs": [],
   "source": [
    "# import Image from 'next/image'\n",
    "# import styles from '../styles/todo.module.css'\n",
    "# import { useState } from 'react'\n",
    "\n",
    "# export default function ToDo(props) {\n",
    "#   const { todo, onChange, onDelete } = props;\n",
    "#   const [poem, setPoem] = useState(null); // Add this line to define the poem state\n",
    "#   const [isPoemVisible, setIsPoemVisible] = useState(false); // Track the visibility of the poem box\n",
    "\n",
    "#   // The following function is added for our LangChain test:\n",
    "#   async function generatePoem(id) {\n",
    "#     const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/todos/write-poem/${id}`, {\n",
    "#         method: 'POST',\n",
    "#         headers: {\n",
    "#           'Content-Type': 'application/json',\n",
    "#         },\n",
    "#       });\n",
    "  \n",
    "#     if (res.ok) {\n",
    "#         const data = await res.json();\n",
    "#         setPoem(data.poem);\n",
    "#         setIsPoemVisible(true); // Show the poem box when a poem is generated\n",
    "#     }\n",
    "#   }\n",
    "\n",
    "#   // Function to close the poem box\n",
    "#   function closePoemBox() {\n",
    "#     setIsPoemVisible(false);\n",
    "#   }\n",
    "\n",
    "#   return (\n",
    "#     <div className={styles.toDoRow} key={todo.id}>\n",
    "#       <input\n",
    "#         className={styles.toDoCheckbox}\n",
    "#         name=\"completed\"\n",
    "#         type=\"checkbox\"\n",
    "#         checked={todo.completed}\n",
    "#         value={todo.completed}\n",
    "#         onChange={(e) => onChange(e, todo.id)}\n",
    "#       ></input>\n",
    "#       <input\n",
    "#         className={styles.todoInput}\n",
    "#         autoComplete='off'\n",
    "#         name=\"name\"\n",
    "#         type=\"text\"\n",
    "#         value={todo.name}\n",
    "#         onChange={(e) => onChange(e, todo.id)}\n",
    "#       ></input>\n",
    "#       <button\n",
    "#         className={styles.generatePoemBtn} // Style the poem button as needed\n",
    "#         onClick={() => generatePoem(todo.id)} // Call the generatePoem function\n",
    "#       >\n",
    "#         Generate Poem\n",
    "#       </button>\n",
    "#       <button className={styles.deleteBtn} onClick={() => onDelete(todo.id)}>\n",
    "#         <Image src=\"/delete-outline.svg\" width=\"24\" height=\"24\" />\n",
    "#       </button>\n",
    "#       {isPoemVisible && (\n",
    "#         <div className={styles.poemBox}>\n",
    "#           <button className={styles.closeButton} onClick={closePoemBox}>\n",
    "#             &times; {/* Add a close icon (×) */}\n",
    "#           </button>\n",
    "#           <div className={styles.poem}>\n",
    "#             <p>{poem}</p>\n",
    "#           </div>\n",
    "#         </div>\n",
    "#       )}\n",
    "#     </div>\n",
    "#   );  \n",
    "\n",
    "# }"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
