{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "sqi5B7V_Rjim"
      },
      "outputs": [],
      "source": [
        "# Copyright 2025 Google LLC\n",
        "#\n",
        "# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "#     https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "VyPmicX9RlZX"
      },
      "source": [
        "# Intro to Url Context\n",
        "\n",
        "<table align=\"left\">\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/generative-ai/blob/main/gemini/url-context/intro_url_context.ipynb\">\n",
        "      <img width=\"32px\" src=\"https://www.gstatic.com/pantheon/images/bigquery/welcome_page/colab-logo.svg\" alt=\"Google Colaboratory logo\"><br> Open in Colab\n",
        "    </a>\n",
        "  </td>\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://console.cloud.google.com/vertex-ai/colab/import/https:%2F%2Fraw.githubusercontent.com%2FGoogleCloudPlatform%2Fgenerative-ai%2Fmain%2Fgemini%2Furl-context%2Fintro_url_context.ipynb\">\n",
        "      <img width=\"32px\" src=\"https://lh3.googleusercontent.com/JmcxdQi-qOpctIvWKgPtrzZdJJK-J3sWE1RsfjZNwshCFgE_9fULcNpuXYTilIR2hjwN\" alt=\"Google Cloud Colab Enterprise logo\"><br> Open in Colab Enterprise\n",
        "    </a>\n",
        "  </td>\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/generative-ai/main/gemini/url-context/intro_url_context.ipynb\">\n",
        "      <img src=\"https://www.gstatic.com/images/branding/gcpiconscolors/vertexai/v1/32px.svg\" alt=\"Vertex AI logo\"><br> Open in Vertex AI Workbench\n",
        "    </a>\n",
        "  </td>\n",
        "  <td style=\"text-align: center\">\n",
        "    <a href=\"https://github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/url-context/intro_url_context.ipynb\">\n",
        "      <img width=\"32px\" src=\"https://raw.githubusercontent.com/primer/octicons/refs/heads/main/icons/mark-github-24.svg\" alt=\"GitHub logo\"><br> View on GitHub\n",
        "    </a>\n",
        "  </td>\n",
        "</table>\n",
        "\n",
        "<div style=\"clear: both;\"></div>\n",
        "\n",
        "<b>Share to:</b>\n",
        "\n",
        "<a href=\"https://www.linkedin.com/sharing/share-offsite/?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/url-context/intro_url_context.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/8/81/LinkedIn_icon.svg\" alt=\"LinkedIn logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://bsky.app/intent/compose?text=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/url-context/intro_url_context.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/7/7a/Bluesky_Logo.svg\" alt=\"Bluesky logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://twitter.com/intent/tweet?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/url-context/intro_url_context.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/5a/X_icon_2.svg\" alt=\"X logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://reddit.com/submit?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/url-context/intro_url_context.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://redditinc.com/hubfs/Reddit%20Inc/Brand/Reddit_Logo.png\" alt=\"Reddit logo\">\n",
        "</a>\n",
        "\n",
        "<a href=\"https://www.facebook.com/sharer/sharer.php?u=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/url-context/intro_url_context.ipynb\" target=\"_blank\">\n",
        "  <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg\" alt=\"Facebook logo\">\n",
        "</a>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "8MqT58L6Rm_q"
      },
      "source": [
        "| Author |\n",
        "| --- |\n",
        "| [Eric Dong](https://github.com/gericdong) |"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "nVxnv1D5RoZw"
      },
      "source": [
        "## Overview\n",
        "\n",
        "The URL context tool in the Gemini API allows you to include URLs as context for your prompts. The model can then use the content from these URLs to generate more informed and relevant responses.\n",
        "\n",
        "### Objectives\n",
        "\n",
        "This tutorial provides a guide to using the URL context in the Gemini API.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "gPiTOAHURvTM"
      },
      "source": [
        "## Getting Started"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "CHRZUpfWSEpp"
      },
      "source": [
        "### Install the Google Gen AI SDK for Python\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "sG3_LKsWSD3A"
      },
      "outputs": [],
      "source": [
        "%pip install --upgrade --quiet google-genai"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HlMVjiAWSMNX"
      },
      "source": [
        "### Authenticate your notebook environment\n",
        "\n",
        "If you are running this notebook on Google Colab, run the cell below to authenticate your environment."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "12fnq4V0SNV3"
      },
      "outputs": [],
      "source": [
        "import sys\n",
        "\n",
        "if \"google.colab\" in sys.modules:\n",
        "    from google.colab import auth\n",
        "\n",
        "    auth.authenticate_user()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "be18ac9c5ec8"
      },
      "source": [
        "### Authenticate to Vertex AI on Google Cloud\n",
        "\n",
        "You'll need to set up authentication by choosing **one** of the following methods:\n",
        "\n",
        "1.  **Use a Google Cloud Project:** (Recommended for most users)\n",
        "    - See instructions [Set up a project and development environment](https://cloud.google.com/vertex-ai/docs/start/cloud-environment)\n",
        "2.  **Use a Vertex AI API Key (Express Mode):** For quick experimentation.\n",
        "    - [Get an API Key](https://cloud.google.com/vertex-ai/generative-ai/docs/start/express-mode/overview)\n",
        "    - See tutorial [Getting started with Gemini using Vertex AI in Express Mode](https://github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/getting-started/intro_gemini_express.ipynb).\n",
        "\n",
        "This tutorial uses a Google Cloud Project for authentication."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "6wXh1aH7BlPl"
      },
      "outputs": [],
      "source": [
        "import os\n",
        "\n",
        "# fmt: off\n",
        "PROJECT_ID = \"[your-project-id]\"  # @param {type: \"string\", placeholder: \"[your-project-id]\", isTemplate: true}\n",
        "# fmt: on\n",
        "if not PROJECT_ID or PROJECT_ID == \"[your-project-id]\":\n",
        "    PROJECT_ID = str(os.environ.get(\"GOOGLE_CLOUD_PROJECT\"))\n",
        "\n",
        "LOCATION = \"global\""
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "EdvJRUWRNGHE"
      },
      "source": [
        "### Import libraries\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "qgdSpVmDbdQ9"
      },
      "outputs": [],
      "source": [
        "from IPython.display import Markdown, display\n",
        "from google import genai\n",
        "from google.genai.types import (\n",
        "    GenerateContentConfig,\n",
        "    GoogleSearch,\n",
        "    HttpOptions,\n",
        "    Tool,\n",
        "    UrlContext,\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "uhAZMeVrCcKS"
      },
      "source": [
        "### Connect to the generative AI service on Vertex AI"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "pv_22mKMCjQY"
      },
      "outputs": [],
      "source": [
        "client = genai.Client(vertexai=True, project=PROJECT_ID, location=LOCATION)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "n4yRkFg6BBu4"
      },
      "source": [
        "### Supported Models\n",
        "\n",
        "Learn more about [supported Gemini models](https://cloud.google.com/vertex-ai/generative-ai/docs/models). This tutorial uses the Gemini 2.5 Flash model."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "-coEslfWPrxo"
      },
      "outputs": [],
      "source": [
        "# fmt: off\n",
        "MODEL_ID = \"gemini-2.5-flash\"  # @param {type: \"string\"}\n",
        "# fmt: on"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "37CH91ddY9kG"
      },
      "source": [
        "## Use URL Context\n",
        "\n",
        "The URL context tool is particularly useful for a variety of tasks, such as:\n",
        "\n",
        "- Extracting data: You can pull key data points or talking points directly from articles.\n",
        "- Comparing information: It allows for the comparison of information across multiple different links.\n",
        "- Synthesizing data: The tool can be used to synthesize data from several different online sources.\n",
        "- Answering questions: It's useful for answering questions based on the content found on one or more specific web pages.\n",
        "- Content analysis: You can analyze content for a specific purpose, such as writing a job description or creating test questions from a webpage's text\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "mdlFHjmDEoDo"
      },
      "source": [
        "#### **Example 1**: One URL only\n",
        "\n",
        "The most direct way to use the feature is to provide a specific URL in your prompt that you want the model to analyze."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "xRJuHj0KZ8xz"
      },
      "outputs": [],
      "source": [
        "# Define the Url context tool\n",
        "url_context_tool = Tool(url_context=UrlContext)\n",
        "\n",
        "response = client.models.generate_content(\n",
        "    model=MODEL_ID,\n",
        "    contents=\"Summarize this document: https://blog.google/technology/developers/introducing-gemini-cli-open-source-ai-agent/\",\n",
        "    config=GenerateContentConfig(\n",
        "        tools=[url_context_tool],\n",
        "    ),\n",
        ")\n",
        "\n",
        "display(Markdown(response.text))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "VUnF-lUjIa_w"
      },
      "source": [
        "**Inspect url context metadata**\n",
        "\n",
        "When the model uses URLs to inform its answer, the response object will contain\n",
        "`url_context_metadata`. This metadata lists the URLs the model retrieved and the status of that retrieval.\n",
        "\n",
        "You can inspect this metadata to confirm which sources were used, as shown in the code example below. Inspecting this metadata is useful for debugging which sources were successfully retrieved or for verifying the model's information sources.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "cMZWGgrBIWGI"
      },
      "outputs": [],
      "source": [
        "print(response.candidates[0].url_context_metadata)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "EfMCR7pkKMo5"
      },
      "source": [
        "### **Example 2**: Multiple URLs\n",
        "\n",
        "The feature currently supports a maximum of 20 URLs per request."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "VRy0vsPtMt_a"
      },
      "outputs": [],
      "source": [
        "url_context_tool = Tool(url_context=UrlContext)\n",
        "\n",
        "URL1 = \"https://www.allrecipes.com/recipe/10813/best-chocolate-chip-cookies/\"\n",
        "URL2 = \"https://www.allrecipes.com/recipe/17165/big-soft-ginger-cookies/\"\n",
        "\n",
        "prompt = f\"Compare the ingredients and instructions from the recipe at {URL1} with the one at {URL2}. What are the key differences?\"\n",
        "\n",
        "response = client.models.generate_content(\n",
        "    model=MODEL_ID,\n",
        "    contents=prompt,\n",
        "    config=GenerateContentConfig(\n",
        "        tools=[url_context_tool],\n",
        "    ),\n",
        ")\n",
        "\n",
        "display(Markdown(response.text))\n",
        "\n",
        "print(response.candidates[0].url_context_metadata)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "9_FXg9BZSOdw"
      },
      "source": [
        "### **Example 3**: Grounding with Google Search\n",
        "\n",
        "You can combine the URL context tool with Grounding with Google Search. This allows the model to first search for relevant information online and then use the URL context tool to get a deeper understanding of the content from the search results.\n",
        "\n",
        "> ⚠️ This feature is experimental and only available in API version `v1beta1`. By default, the SDK uses the beta API endpoints. You also can set the API version to `v1beta1` explicitly, as below:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "d33a5e5d1427"
      },
      "outputs": [],
      "source": [
        "client_v1beta1 = genai.Client(\n",
        "    vertexai=True,\n",
        "    project=PROJECT_ID,\n",
        "    location=LOCATION,\n",
        "    http_options=HttpOptions(api_version=\"v1beta1\"),\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "urM7aDRKhuav"
      },
      "outputs": [],
      "source": [
        "# Define Url Context and Google Search tools\n",
        "tools = [Tool(url_context=UrlContext), Tool(google_search=GoogleSearch())]"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Zya1jFS0Vh_4"
      },
      "source": [
        "#### **Use Case**: Answering a question using search and a specific page\n",
        "\n",
        "In this example, we ask the model to create a schedule based on a specific URL but also ask a follow-up question. The model can use the provided URL and perform a Google search to answer the entire prompt comprehensively."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "A339OQ05Sq8q"
      },
      "outputs": [],
      "source": [
        "URL = \"https://www.metmuseum.org/visit/plan-your-visit\"\n",
        "\n",
        "prompt = f\"\"\"Using the 'Exhibitions' and 'Must-See Artwork' sections of the URL {URL},\n",
        "design a 2-hour art tour of the Met for someone primarily interested in European paintings.\n",
        "Also, what are the museum's hours for next Saturday?\n",
        "\"\"\"\n",
        "\n",
        "response = client_v1beta1.models.generate_content(\n",
        "    model=MODEL_ID,\n",
        "    contents=prompt,\n",
        "    config=GenerateContentConfig(\n",
        "        tools=tools,\n",
        "    ),\n",
        ")\n",
        "\n",
        "display(Markdown(response.text))\n",
        "\n",
        "print(response.candidates[0].url_context_metadata)\n",
        "print(response.candidates[0].grounding_metadata)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "O6lHgdmcZurD"
      },
      "source": [
        "#### **Use Case**: Analyze an API docs guide\n",
        "\n",
        "Developers constantly need to learn new APIs. This example demonstrates using the URL context to analyze API documentation and extract key information, making integration faster. This is a great way to synthesize data from several sources."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "VggoVVB5XOur"
      },
      "outputs": [],
      "source": [
        "URL = \"https://jsonplaceholder.typicode.com/guide/\"\n",
        "\n",
        "prompt = f\"\"\"\"Analyze the API documentation guide at the provided URL {URL}.\n",
        "Provide a summary of the available resource endpoints and list all the HTTP methods\n",
        "that are supported for the '/posts' endpoint.\n",
        "\"\"\"\n",
        "\n",
        "response = client_v1beta1.models.generate_content(\n",
        "    model=MODEL_ID,\n",
        "    contents=prompt,\n",
        "    config=GenerateContentConfig(\n",
        "        tools=tools,\n",
        "    ),\n",
        ")\n",
        "\n",
        "display(Markdown(response.text))\n",
        "\n",
        "print(response.candidates[0].url_context_metadata)\n",
        "print(response.candidates[0].grounding_metadata)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "6u5VrSCebF4O"
      },
      "source": [
        "#### **Use Case**: Generate code based on a tutorial\n",
        "\n",
        "This example shows how to use the URL context to read a programming tutorial and write functional code based on its concepts, a task that can dramatically speed up learning and development."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "gx9Us4sQagC9"
      },
      "outputs": [],
      "source": [
        "URL = \"https://realpython.com/python-requests/\"\n",
        "\n",
        "prompt = f\"\"\"\"\"Read the tutorial from the provided URL {URL}. Write a Python script\n",
        "that performs a GET request to 'https://api.github.com/users/google' and prints the\n",
        "user's name and number of public repositories. Include comments explaining each step\n",
        "and basic error handling for the request.\n",
        "\"\"\"\n",
        "\n",
        "response = client_v1beta1.models.generate_content(\n",
        "    model=MODEL_ID,\n",
        "    contents=prompt,\n",
        "    config=GenerateContentConfig(\n",
        "        tools=tools,\n",
        "    ),\n",
        ")\n",
        "\n",
        "display(Markdown(response.text))\n",
        "\n",
        "print(response.candidates[0].url_context_metadata)\n",
        "print(response.candidates[0].grounding_metadata)"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "name": "intro_url_context.ipynb",
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
