{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "33205b12",
   "metadata": {},
   "source": [
    "# Figma\n",
    "\n",
    ">[Figma](https://www.figma.com/) is a collaborative web application for interface design.\n",
    "\n",
    "This notebook covers how to load data from the `Figma` REST API into a format that can be ingested into LangChain, along with example usage for code generation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "90b69c94",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "from langchain.chat_models import ChatOpenAI\n",
    "from langchain.document_loaders.figma import FigmaFileLoader\n",
    "from langchain.indexes import VectorstoreIndexCreator\n",
    "from langchain.prompts.chat import (\n",
    "    ChatPromptTemplate,\n",
    "    HumanMessagePromptTemplate,\n",
    "    SystemMessagePromptTemplate,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d809744a",
   "metadata": {},
   "source": [
    "The Figma API Requires an access token, node_ids, and a file key.\n",
    "\n",
    "The file key can be pulled from the URL.  https://www.figma.com/file/{filekey}/sampleFilename\n",
    "\n",
    "Node IDs are also available in the URL. Click on anything and look for the '?node-id={node_id}' param.\n",
    "\n",
    "Access token instructions are in the Figma help center article: https://help.figma.com/hc/en-us/articles/8085703771159-Manage-personal-access-tokens"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "13deb0f5",
   "metadata": {},
   "outputs": [],
   "source": [
    "figma_loader = FigmaFileLoader(\n",
    "    os.environ.get(\"ACCESS_TOKEN\"),\n",
    "    os.environ.get(\"NODE_IDS\"),\n",
    "    os.environ.get(\"FILE_KEY\"),\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9ccc1e2f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# see https://python.langchain.com/en/latest/modules/data_connection/getting_started.html for more details\n",
    "index = VectorstoreIndexCreator().from_loaders([figma_loader])\n",
    "figma_doc_retriever = index.vectorstore.as_retriever()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3e64cac2",
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_code(human_input):\n",
    "    # I have no idea if the Jon Carmack thing makes for better code. YMMV.\n",
    "    # See https://python.langchain.com/en/latest/modules/models/chat/getting_started.html for chat info\n",
    "    system_prompt_template = \"\"\"You are expert coder Jon Carmack. Use the provided design context to create idiomatic HTML/CSS code as possible based on the user request.\n",
    "    Everything must be inline in one file and your response must be directly renderable by the browser.\n",
    "    Figma file nodes and metadata: {context}\"\"\"\n",
    "\n",
    "    human_prompt_template = \"Code the {text}. Ensure it's mobile responsive\"\n",
    "    system_message_prompt = SystemMessagePromptTemplate.from_template(\n",
    "        system_prompt_template\n",
    "    )\n",
    "    human_message_prompt = HumanMessagePromptTemplate.from_template(\n",
    "        human_prompt_template\n",
    "    )\n",
    "    # delete the gpt-4 model_name to use the default gpt-3.5 turbo for faster results\n",
    "    gpt_4 = ChatOpenAI(temperature=0.02, model_name=\"gpt-4\")\n",
    "    # Use the retriever's 'get_relevant_documents' method if needed to filter down longer docs\n",
    "    relevant_nodes = figma_doc_retriever.get_relevant_documents(human_input)\n",
    "    conversation = [system_message_prompt, human_message_prompt]\n",
    "    chat_prompt = ChatPromptTemplate.from_messages(conversation)\n",
    "    response = gpt_4(\n",
    "        chat_prompt.format_prompt(\n",
    "            context=relevant_nodes, text=human_input\n",
    "        ).to_messages()\n",
    "    )\n",
    "    return response"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "36a96114",
   "metadata": {},
   "outputs": [],
   "source": [
    "response = generate_code(\"page top header\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "baf9b2c9",
   "metadata": {},
   "source": [
    "Returns the following in `response.content`:\n",
    "```\n",
    "<!DOCTYPE html>\\n<html lang=\"en\">\\n<head>\\n    <meta charset=\"UTF-8\">\\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\\n    <style>\\n        @import url(\\'https://fonts.googleapis.com/css2?family=DM+Sans:wght@500;700&family=Inter:wght@600&display=swap\\');\\n\\n        body {\\n            margin: 0;\\n            font-family: \\'DM Sans\\', sans-serif;\\n        }\\n\\n        .header {\\n            display: flex;\\n            justify-content: space-between;\\n            align-items: center;\\n            padding: 20px;\\n            background-color: #fff;\\n            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\\n        }\\n\\n        .header h1 {\\n            font-size: 16px;\\n            font-weight: 700;\\n            margin: 0;\\n        }\\n\\n        .header nav {\\n            display: flex;\\n            align-items: center;\\n        }\\n\\n        .header nav a {\\n            font-size: 14px;\\n            font-weight: 500;\\n            text-decoration: none;\\n            color: #000;\\n            margin-left: 20px;\\n        }\\n\\n        @media (max-width: 768px) {\\n            .header nav {\\n                display: none;\\n            }\\n        }\\n    </style>\\n</head>\\n<body>\\n    <header class=\"header\">\\n        <h1>Company Contact</h1>\\n        <nav>\\n            <a href=\"#\">Lorem Ipsum</a>\\n            <a href=\"#\">Lorem Ipsum</a>\\n            <a href=\"#\">Lorem Ipsum</a>\\n        </nav>\\n    </header>\\n</body>\\n</html>\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "38827110",
   "metadata": {},
   "source": []
  }
 ],
 "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.10.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
