{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "8a0022bb-cb15-4386-9146-6cd47e784bd5",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from dotenv import load_dotenv, find_dotenv\n",
    "_ = load_dotenv(find_dotenv())\n",
    "openai_api_key = os.environ[\"OPENAI_API_KEY\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6862ea12-88ee-4bac-ba59-11e1154b3857",
   "metadata": {},
   "source": [
    "## Quickstart"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "15b41b49-1888-46d1-b8a4-ba9399e35514",
   "metadata": {},
   "outputs": [],
   "source": [
    "from openai import OpenAI"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "bff18300-249d-4102-988e-70f388dfe5ec",
   "metadata": {},
   "outputs": [],
   "source": [
    "client = OpenAI()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "ac4a6f36-c43d-4100-a683-61a48dec758a",
   "metadata": {},
   "outputs": [],
   "source": [
    "completion = client.chat.completions.create(\n",
    "    model=\"gpt-3.5-turbo\",\n",
    "    messages=[\n",
    "        {\n",
    "            \"role\": \"user\",\n",
    "            \"content\": \"tell me a joke about the French people.\"\n",
    "        }\n",
    "    ]\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "8ffd41a2-ca64-48f2-a107-7c5517a37a0b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Why did the French chef only use one egg in his recipe?\n",
      "\n",
      "Because one egg is un œuf!\n"
     ]
    }
   ],
   "source": [
    "print(completion.choices[0].message.content)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "680b318b-4b0f-47a2-b09c-41dffbe4b51f",
   "metadata": {},
   "source": [
    "## Models\n",
    "* GPT-4 Turbo: new context length\n",
    "* Moderation: content compliance\n",
    "* TTS: text to speech"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "77c74a08-fd81-4e23-8f96-3490fd2eba59",
   "metadata": {},
   "source": [
    "## Tutorials\n",
    "* QA from website\n",
    "* Meeting minutes transcription\n",
    "* Coming soon: QA from multiple knowledge bases"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "437badbb-49b6-48e4-a11f-05a0693182c8",
   "metadata": {},
   "source": [
    "## Text Generation\n",
    "* Chat Completions\n",
    "* JSON mode\n",
    "* Seed: reproducible outputs"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "434a991e-d046-401a-a651-41f0795934cc",
   "metadata": {},
   "source": [
    "## Function calling"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8e6d4f22-a58c-4369-8b39-6575825708f0",
   "metadata": {},
   "outputs": [],
   "source": [
    "from openai import OpenAI\n",
    "import json\n",
    "\n",
    "client = OpenAI()\n",
    "\n",
    "# Example dummy function hard coded to return the same weather\n",
    "# In production, this could be your backend API or an external API\n",
    "def get_current_weather(location, unit=\"fahrenheit\"):\n",
    "    \"\"\"Get the current weather in a given location\"\"\"\n",
    "    if \"tokyo\" in location.lower():\n",
    "        return json.dumps({\"location\": \"Tokyo\", \"temperature\": \"10\", \"unit\": \"celsius\"})\n",
    "    elif \"san francisco\" in location.lower():\n",
    "        return json.dumps({\"location\": \"San Francisco\", \"temperature\": \"72\", \"unit\": \"fahrenheit\"})\n",
    "    elif \"paris\" in location.lower():\n",
    "        return json.dumps({\"location\": \"Paris\", \"temperature\": \"22\", \"unit\": \"celsius\"})\n",
    "    else:\n",
    "        return json.dumps({\"location\": location, \"temperature\": \"unknown\"})\n",
    "\n",
    "def run_conversation():\n",
    "    \n",
    "    # Step 1: send the conversation and available functions to the model\n",
    "    messages = [\n",
    "        {\n",
    "            \"role\": \"user\", \n",
    "            \"content\": \"What's the weather like in San Francisco, Tokyo, and Paris?\"\n",
    "        }\n",
    "    ]\n",
    "    \n",
    "    tools = [\n",
    "        {\n",
    "            \"type\": \"function\",\n",
    "            \"function\": {\n",
    "                \"name\": \"get_current_weather\",\n",
    "                \"description\": \"Get the current weather in a given location\",\n",
    "                \"parameters\": {\n",
    "                    \"type\": \"object\",\n",
    "                    \"properties\": {\n",
    "                        \"location\": {\n",
    "                            \"type\": \"string\",\n",
    "                            \"description\": \"The city and state, e.g. San Francisco, CA\",\n",
    "                        },\n",
    "                        \"unit\": {\"type\": \"string\", \"enum\": [\"celsius\", \"fahrenheit\"]},\n",
    "                    },\n",
    "                    \"required\": [\"location\"],\n",
    "                },\n",
    "            },\n",
    "        }\n",
    "    ]\n",
    "    \n",
    "    response = client.chat.completions.create(\n",
    "        model=\"gpt-3.5-turbo-1106\",\n",
    "        messages=messages,\n",
    "        tools=tools,\n",
    "        tool_choice=\"auto\",  # auto is default, but we'll be explicit\n",
    "    )\n",
    "    \n",
    "    response_message = response.choices[0].message\n",
    "    \n",
    "    tool_calls = response_message.tool_calls\n",
    "    \n",
    "    # Step 2: check if the model wanted to call a function\n",
    "    if tool_calls:\n",
    "        \n",
    "        # Step 3: call the function\n",
    "        \n",
    "        # Note: the JSON response may not always be valid; be sure to handle errors\n",
    "        available_functions = {\n",
    "            \"get_current_weather\": get_current_weather,\n",
    "        }  # only one function in this example, but you can have multiple\n",
    "        \n",
    "        messages.append(response_message)  # extend conversation with assistant's reply\n",
    "        \n",
    "        # Step 4: send the info for each function call and function response to the model\n",
    "        for tool_call in tool_calls:\n",
    "            function_name = tool_call.function.name\n",
    "            function_to_call = available_functions[function_name]\n",
    "            function_args = json.loads(tool_call.function.arguments)\n",
    "            function_response = function_to_call(\n",
    "                location=function_args.get(\"location\"),\n",
    "                unit=function_args.get(\"unit\"),\n",
    "            )\n",
    "            messages.append(\n",
    "                {\n",
    "                    \"tool_call_id\": tool_call.id,\n",
    "                    \"role\": \"tool\",\n",
    "                    \"name\": function_name,\n",
    "                    \"content\": function_response,\n",
    "                }\n",
    "            )  # extend conversation with function response\n",
    "            \n",
    "        second_response = client.chat.completions.create(\n",
    "            model=\"gpt-3.5-turbo-1106\",\n",
    "            messages=messages,\n",
    "        )  # get a new response from the model where it can see the function response\n",
    "        \n",
    "        return second_response\n",
    "        \n",
    "print(run_conversation())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8947ee53-ac94-4352-856c-7e05447507fa",
   "metadata": {},
   "source": [
    "## Assistants\n",
    "* Code interpreter\n",
    "* Retrieval\n",
    "* Functions"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "46d8d119-ff68-4cfb-9aaf-fdbbe750a4e2",
   "metadata": {},
   "source": [
    "## Guides\n",
    "* Prompt engineering\n",
    "* Production best practices\n",
    "* Safety best practices\n",
    "* Rate limits"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ae9ccf26-1368-4600-8317-d9ffd5323dab",
   "metadata": {},
   "source": [
    "## Other\n",
    "* Data privacy\n",
    "* Examples gallery\n",
    "* Playground\n",
    "* Cookbook: +120 interesting recipes and tips"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c352c089-ac16-49d6-8b00-475cf381de89",
   "metadata": {},
   "outputs": [],
   "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.11.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
