{"id":55454,"date":"2026-07-12T15:49:20","date_gmt":"2026-07-12T22:49:20","guid":{"rendered":"https:\/\/www.griddb.net\/?p=55454"},"modified":"2026-07-22T15:49:45","modified_gmt":"2026-07-22T22:49:45","slug":"visualize-griddb-data-using-langgraph-and-openai-api","status":"publish","type":"post","link":"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/","title":{"rendered":"Visualize GridDB Data Using LangGraph and OpenAI API"},"content":{"rendered":"<p>\nLarge Language Models (LLMs) allow developers to combine advanced AI reasoning with powerful databases to analyze and visualize complex datasets.\n<\/p>\n<p>\nIn this article, you will see how to build a tabular data visualization assistant using GridDB Cloud, LangGraph, and the OpenAI GPT-4o model. We will import the Titanic dataset into GridDB, query it programmatically, and then use a LangGraph ReAct agent to answer questions and generate plots automatically.\n<\/p>\n<p>\nGridDB&#8217;s flexible schema, high-performance design, and compatibility with structured data make it well-suited for storing both tabular and time series data.\n<\/p>\n<p><strong>Prerequisites:<\/strong><\/p>\n<p>\nYou will need the following to run scripts in this article:\n<\/p>\n<ol>\n<li>A GridDB cloud account. <a href=\"https:\/\/www.global.toshiba\/ww\/products-solutions\/ai-iot\/griddb\/product\/griddb-cloud.html\">Sign up for GridDB cloud<\/a> and complete configuration settings.<\/li>\n<li><a href=\"https:\/\/platform.openai.com\/api-keys\">OpenAI API Key<\/a>. You can use any other LLM provider, but you will need to update the scripts in this article slightly.<\/li>\n<\/ol>\n<h2 id=\"installing-and-importing-required-libraries\">Installing and Importing Required Libraries<\/h2>\n<p>\nThe following script installs and imports the required libraries for this application:\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-plaintext\">!pip install langchain\r\n!pip install langchain-core\r\n!pip install langchain-community\r\n!pip install langgraph\r\n!pip install langchain_huggingface\r\n!pip install tabulate\r\n!pip uninstall -y pydantic\r\n!pip install --no-cache-dir &quot;pydantic&gt;=2.11,&lt;3&quot;<\/code><\/pre>\n<\/div>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">import pandas as pd\r\nimport json\r\nimport datetime as dt\r\nimport base64\r\nimport requests\r\nimport numpy as np\r\nfrom pathlib import Path\r\nimport matplotlib\r\nmatplotlib.use(&quot;Agg&quot;)  # safe, consistent backend\r\nimport matplotlib.pyplot as plt\r\nfrom typing_extensions import Annotated\r\nfrom operator import add  # used as list reducer\r\nfrom typing import TypedDict, List, Dict\r\nfrom pydantic import BaseModel, Field\r\nfrom IPython.display import Image, display\r\n\r\nfrom langchain_core.prompts import ChatPromptTemplate\r\nfrom langchain_core.tools import tool\r\nfrom langchain_openai import ChatOpenAI, OpenAI\r\nfrom langgraph.graph import START, END, StateGraph\r\nfrom langchain_core.messages import HumanMessage\r\nfrom langchain_experimental.agents import create_pandas_dataframe_agent\r\nfrom langgraph.prebuilt import create_react_agent\r\nfrom langchain.agents.agent_types import AgentType<\/code><\/pre>\n<\/div>\n<h2 id=\"importing-the-dataset\">Importing the Dataset<\/h2>\n<p>\nWe will insert the <a href=\"https:\/\/raw.githubusercontent.com\/datasciencedojo\/datasets\/refs\/heads\/master\/titanic.csv\">Titanic dataset<\/a> into GridDB and create visualizations using this data. The following script imports the data into a Pandas dataframe.\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">dataset = pd.read_csv(&quot;https:\/\/raw.githubusercontent.com\/datasciencedojo\/datasets\/refs\/heads\/master\/titanic.csv&quot;,\r\n                      encoding = &#x27;utf-8&#x27;)\r\ndataset.head()<\/code><\/pre>\n<\/div>\n<p><strong>Output:<\/strong><br \/>\n<a href=\"\/wp-content\/uploads\/2026\/07\/img1-titanic-dataset-header.png\"><img fetchpriority=\"high\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/07\/img1-titanic-dataset-header.png\" alt=\"\" width=\"1430\" height=\"271\" class=\"aligncenter size-full wp-image-55457\" srcset=\"\/wp-content\/uploads\/2026\/07\/img1-titanic-dataset-header.png 1430w, \/wp-content\/uploads\/2026\/07\/img1-titanic-dataset-header-300x57.png 300w, \/wp-content\/uploads\/2026\/07\/img1-titanic-dataset-header-1024x194.png 1024w, \/wp-content\/uploads\/2026\/07\/img1-titanic-dataset-header-768x146.png 768w, \/wp-content\/uploads\/2026\/07\/img1-titanic-dataset-header-600x114.png 600w\" sizes=\"(max-width: 1430px) 100vw, 1430px\" \/><\/a><\/p>\n<h2 id=\"establishing-a-connection-with-griddb-cloud\">Establishing a Connection with GridDB Cloud<\/h2>\n<p>\nTo establish a connection with GridDB, replace your credentials in the following script and run it.\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">username = &quot;USER_NAME&quot;\r\npassword = &quot;PASSWORD&quot;\r\nbase_url = &quot;GRIDDB_CLOUD_URL&quot;\r\n\r\nurl = f&quot;{base_url}\/checkConnection&quot;\r\n\r\ncredentials = f&quot;{username}:{password}&quot;\r\nencoded_credentials = base64.b64encode(credentials.encode()).decode()\r\n\r\nheaders = {\r\n    &#x27;Content-Type&#x27;: &#x27;application\/json&#x27;,  # Added this header to specify JSON content\r\n    &#x27;Authorization&#x27;: f&#x27;Basic {encoded_credentials}&#x27;,\r\n    &#x27;User-Agent&#x27;: &#x27;PostmanRuntime\/7.29.0&#x27;\r\n}\r\n\r\nresponse = requests.get(url, headers=headers)\r\n\r\nprint(response.status_code)\r\nprint(response.text)<\/code><\/pre>\n<\/div>\n<p><strong>Output:<\/strong><\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-plaintext\">200<\/code><\/pre>\n<\/div>\n<p>\nIf you see the above message, you have successfully connected with GridDB cloud.\n<\/p>\n<h2 id=\"inserting-data-in-griddb-cloud-dataset\">Inserting Data in GridDB Cloud Dataset<\/h2>\n<p>\nTo insert data in GridDB, you first need to map your dataset types to GridDB dataset types and then create a GridDB container.\n<\/p>\n<h3 id=\"creating-a-container-for-the-titanic-dataset-in-griddb\">Creating a Container for the Titanic Dataset in GridDB<\/h3>\n<p>\nThe following script maps your dataset column types to GridDB column types.\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">dataset.insert(0, &quot;SerialNo&quot;, dataset.index + 1)\r\ndataset.columns.name = None\r\n# Mapping pandas dtypes to GridDB types\r\ntype_mapping = {\r\n    &quot;int64&quot;:          &quot;LONG&quot;,\r\n    &quot;float64&quot;:        &quot;DOUBLE&quot;,\r\n    &quot;bool&quot;:           &quot;BOOL&quot;,\r\n    &#x27;datetime64&#x27;: &quot;TIMESTAMP&quot;,\r\n    &quot;object&quot;:         &quot;STRING&quot;,\r\n    &quot;category&quot;:       &quot;STRING&quot;,\r\n}\r\n\r\n# Generate the columns part of the payload dynamically\r\ncolumns = []\r\nfor col, dtype in dataset.dtypes.items():\r\n    griddb_type = type_mapping.get(str(dtype), &quot;STRING&quot;)  # Default to STRING if unknown\r\n    columns.append({\r\n        &quot;name&quot;: col,\r\n        &quot;type&quot;: griddb_type\r\n    })\r\n\r\nprint(columns)<\/code><\/pre>\n<\/div>\n<div class=\"clipboard\">\n<pre><code class=\"language-plaintext\">[{&#x27;name&#x27;: &#x27;SerialNo&#x27;, &#x27;type&#x27;: &#x27;LONG&#x27;},\r\n{&#x27;name&#x27;: &#x27;PassengerId&#x27;, &#x27;type&#x27;: &#x27;LONG&#x27;},\r\n{&#x27;name&#x27;: &#x27;Survived&#x27;, &#x27;type&#x27;: &#x27;LONG&#x27;},\r\n{&#x27;name&#x27;: &#x27;Pclass&#x27;, &#x27;type&#x27;: &#x27;LONG&#x27;},\r\n{&#x27;name&#x27;: &#x27;Name&#x27;, &#x27;type&#x27;: &#x27;STRING&#x27;},\r\n{&#x27;name&#x27;: &#x27;Sex&#x27;, &#x27;type&#x27;: &#x27;STRING&#x27;},\r\n{&#x27;name&#x27;: &#x27;Age&#x27;, &#x27;type&#x27;: &#x27;DOUBLE&#x27;},\r\n{&#x27;name&#x27;: &#x27;SibSp&#x27;, &#x27;type&#x27;: &#x27;LONG&#x27;},\r\n{&#x27;name&#x27;: &#x27;Parch&#x27;, &#x27;type&#x27;: &#x27;LONG&#x27;},\r\n{&#x27;name&#x27;: &#x27;Ticket&#x27;, &#x27;type&#x27;: &#x27;STRING&#x27;},\r\n{&#x27;name&#x27;: &#x27;Fare&#x27;, &#x27;type&#x27;: &#x27;DOUBLE&#x27;},\r\n{&#x27;name&#x27;: &#x27;Cabin&#x27;, &#x27;type&#x27;: &#x27;STRING&#x27;},\r\n{&#x27;name&#x27;: &#x27;Embarked&#x27;, &#x27;type&#x27;: &#x27;STRING&#x27;}]<\/code><\/pre>\n<\/div>\n<p>\nNext, we will create a collection type container <code>titanic_db<\/code> in our GridDB cloud database.\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">url = f&quot;{base_url}\/containers&quot;\r\ncontainer_name = &quot;titanic_db&quot;\r\n# Create the payload for the POST request\r\npayload = json.dumps({\r\n    &quot;container_name&quot;: container_name,\r\n    &quot;container_type&quot;: &quot;COLLECTION&quot;,\r\n    &quot;rowkey&quot;: True,  # Assuming the first column as rowkey\r\n    &quot;columns&quot;: columns\r\n})\r\n\r\n\r\n# Make the POST request to create the container\r\nresponse = requests.post(url, headers=headers, data=payload)\r\n\r\n# Print the response\r\nprint(f&quot;Status Code: {response.status_code}&quot;)<\/code><\/pre>\n<\/div>\n<p><strong>Output:<\/strong><\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-plaintext\">Status Code: 201<\/code><\/pre>\n<\/div>\n<h3 id=\"inserting-titanic-dataset-in-griddb\">Inserting Titanic Dataset in GridDB<\/h3>\n<p>\nNext, we will iterate through the rows in our dataset, create a JSON payload containing the data, and will insert the data into the container we created in the previous section.\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">url = f&quot;{base_url}\/containers\/{container_name}\/rows&quot;\r\n# Convert dataset to list of lists (row-wise) with proper formatting\r\n\r\ndef format_row(row):\r\n    formatted = []\r\n    for item in row:\r\n        if pd.isna(item):\r\n            formatted.append(None)  # Convert NaN to None\r\n        elif isinstance(item, bool):\r\n            formatted.append(str(item).lower())  # Convert True\/False to true\/false\r\n        elif isinstance(item, (int, float)):\r\n            formatted.append(item)  # Keep integers and floats as they are\r\n        else:\r\n            formatted.append(str(item))  # Convert other types to string\r\n    return formatted\r\n\r\n# Prepare rows with correct formatting\r\nrows = [format_row(row) for row in dataset.values.tolist()]\r\n\r\n# Create payload as a JSON string\r\npayload = json.dumps(rows)\r\n\r\n# Make the PUT request to add the rows to the container\r\nresponse = requests.put(url, headers=headers, data=payload)\r\n\r\n# Print the response\r\nprint(f&quot;Status Code: {response.status_code}&quot;)\r\nprint(f&quot;Response Text: {response.text}&quot;)<\/code><\/pre>\n<\/div>\n<p><strong>Output:<\/strong><\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-plaintext\">Status Code: 200\r\nResponse Text: {&quot;count&quot;:891}<\/code><\/pre>\n<\/div>\n<p>\nThe above output shows that the data has been successfully inserted into GridDB.\n<\/p>\n<p>\nNext, we will see how to retrieve data from GridDB and plot visualizations using it.\n<\/p>\n<h2 id=\"visualizing-griddb-results-using-openai-and-react-agent\">Visualizing GridDB Results Using OpenAI and ReAct Agent<\/h2>\n<p>\nThe following script reads data from GridDB and inserts it in a Pandas dataframe.\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">container_name = &quot;titanic_db&quot;\r\n\r\nurl = f&quot;{base_url}\/containers\/{container_name}\/rows&quot;\r\n\r\n# Define the payload for the query\r\npayload = json.dumps({\r\n    &quot;offset&quot;: 0,           # Start from the first row\r\n    &quot;limit&quot;: 10000,         # Limit the number of rows returned\r\n    &quot;condition&quot;: &quot;&quot;,       # No filtering condition (you can customize it)\r\n    &quot;sort&quot;: &quot;&quot;             # No sorting (you can customize it)\r\n})\r\n\r\n# Make the POST request to read data from the container\r\nresponse = requests.post(url, headers=headers, data=payload)\r\n\r\n# Check response status and print output\r\nprint(f&quot;Status Code: {response.status_code}&quot;)\r\nif response.status_code == 200:\r\n    try:\r\n        data = response.json()\r\n        print(&quot;Data retrieved successfully!&quot;)\r\n\r\n        # Convert the response to a DataFrame\r\n        rows = data.get(&quot;rows&quot;, [])\r\n        titanic_dataset = pd.DataFrame(rows, columns=[col for col in dataset.columns])\r\n\r\n    except json.JSONDecodeError:\r\n        print(&quot;Error: Failed to decode JSON response.&quot;)\r\nelse:\r\n    print(f&quot;Error: Failed to query data from the container. Response: {response.text}&quot;)\r\n\r\nprint(titanic_dataset.shape)\r\ntitanic_dataset.head()<\/code><\/pre>\n<\/div>\n<p><strong>Output:<\/strong><br \/>\n<a href=\"\/wp-content\/uploads\/2026\/07\/img2-data-retrieved-from-griddb.png\"><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/07\/img2-data-retrieved-from-griddb.png\" alt=\"\" width=\"1520\" height=\"329\" class=\"aligncenter size-full wp-image-55458\" srcset=\"\/wp-content\/uploads\/2026\/07\/img2-data-retrieved-from-griddb.png 1520w, \/wp-content\/uploads\/2026\/07\/img2-data-retrieved-from-griddb-300x65.png 300w, \/wp-content\/uploads\/2026\/07\/img2-data-retrieved-from-griddb-1024x222.png 1024w, \/wp-content\/uploads\/2026\/07\/img2-data-retrieved-from-griddb-768x166.png 768w, \/wp-content\/uploads\/2026\/07\/img2-data-retrieved-from-griddb-600x130.png 600w\" sizes=\"(max-width: 1520px) 100vw, 1520px\" \/><\/a><\/p>\n<p>\nLet&#8217;s try to plot the average for the passengers who survived and those who didn&#8217;t. We will use these values to verify the result from our ReAct agent.\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">avg = titanic_dataset.groupby(&#x27;Survived&#x27;)[&#x27;Fare&#x27;].mean().round(2)\r\nprint(avg)<\/code><\/pre>\n<\/div>\n<p><strong>Output:<\/strong><\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-plaintext\">Survived\r\n0    22.12\r\n1    48.40\r\nName: Fare, dtype: float64<\/code><\/pre>\n<\/div>\n<h3 id=\"creating-a-langgraph-react-agent-for-data-visualization\">Creating a LangGraph ReAct Agent for Data Visualization<\/h3>\n<p>\nTo plot visualizations, we will create a <a href=\"https:\/\/langchain-ai.github.io\/langgraph\/agents\/agents\/\">LangGraph ReAct<\/a> agent with two tools: <code>df_answer<\/code> and <code>save_plot<\/code>.\n<\/p>\n<p>\nThe <code>df_answer<\/code> tool will use the <a href=\"http:\/\/python.langchain.com\/api_reference\/experimental\/agents\/langchain_experimental.agents.agent_toolkits.pandas.base.create_pandas_dataframe_agent.html\"><code>create_pandas_dataframe_agent<\/code><\/a> to retrieve information from the database, including the plot, if any. The <code>save_plot<\/code> tool saves the plot to the local drive.\n<\/p>\n<p>\nThe following script defines the agent&#8217;s state and the large language model (OpenAI GPT-4o in this case) we will use to answer the user&#8217;s question.\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">class State(TypedDict):\r\n    question: str\r\n    answer: str\r\n    plots: Annotated[List[Dict[str, str]], add]\r\n\r\n\r\napi_key = &quot;YOUR_OPENAI_API_KEY&quot;\r\n\r\nllm = ChatOpenAI(model=&quot;gpt-4o&quot;,\r\n                 api_key=api_key,\r\n                temperature = 0)<\/code><\/pre>\n<\/div>\n<p>\nNext, we define the <code>create_pandas_dataframe_agent<\/code> function that returns information from the Pandas dataframe retrieved from GridDB.<br \/>\nWe also define the <code>df_answer<\/code> tool that calls the <code>create_pandas_dataframe_agent.<\/code>\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">df_agent = create_pandas_dataframe_agent(llm,\r\n                                     titanic_dataset,\r\n                                     verbose=True,\r\n                                     agent_type=AgentType.ZERO_SHOT_REACT_DESCRIPTION,\r\n                                     allow_dangerous_code=True)\r\n\r\n\r\n_LAST = {&quot;fig&quot;: None}                # keep a handle to the last real figure\r\n\r\n@tool(&quot;df_answer&quot;)\r\ndef df_answer(question: str) -&gt; str:\r\n   &quot;&quot;&quot;\r\n   Use the pandas DataFrame agent to compute\/plot.\r\n   IMPORTANT: do NOT call plt.show() or plt.close() in the generated code.\r\n   &quot;&quot;&quot;\r\n   res = df_agent.invoke(\r\n       question\r\n   )\r\n\r\n   # CAPTURE whichever figure the agent actually created\r\n   fig_nums = plt.get_fignums()          # existing figures in this process\r\n   if fig_nums:\r\n       _LAST[&quot;fig&quot;] = plt.figure(fig_nums[-1])   # latest real figure\r\n   return res[&quot;output&quot;]<\/code><\/pre>\n<\/div>\n<p>\nThe following script defines the <code>save_plot<\/code> tool that saves the plot generated by the <code>df_answer<\/code> tool.\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">\r\n@tool(&quot;save_plot&quot;)\r\ndef save_plot(filename: str = &quot;plot.png&quot;, dpi: int = 200, close: bool = True) -&gt; str:\r\n    &quot;&quot;&quot;\r\n    Save the most recent existing Matplotlib figure (not an empty gcf()).\r\n    Returns {&quot;plot&quot;: {&quot;name&quot;: ..., &quot;path&quot;: ...}} or {&quot;error&quot;: ...}.\r\n    &quot;&quot;&quot;\r\n    Path(&quot;plots&quot;).mkdir(exist_ok=True)\r\n    fig = _LAST.get(&quot;fig&quot;)\r\n\r\n    # Fallback: grab last live figure if we didn&#x27;t capture yet\r\n    if fig is None:\r\n        nums = plt.get_fignums()\r\n        if not nums:\r\n            return json.dumps({&quot;error&quot;: &quot;no_figure&quot;, &quot;message&quot;: &quot;No active figure to save.&quot;})\r\n        fig = plt.figure(nums[-1])\r\n\r\n    # Render + save\r\n    fig.tight_layout()\r\n    try:\r\n        fig.canvas.draw()                # ensure render\r\n    except Exception:\r\n        pass\r\n\r\n    out = Path(&quot;plots&quot;) \/ filename\r\n    fig.savefig(out, dpi=dpi, bbox_inches=&quot;tight&quot;)\r\n\r\n    if close:\r\n        plt.close(fig)                   # avoid accumulating figures\r\n\r\n    return json.dumps({&quot;plot&quot;: {&quot;name&quot;: filename, &quot;path&quot;: str(out.resolve())}})<\/code><\/pre>\n<\/div>\n<p>\nFinally we define the ReAct agent using the LLM and the tool we just defined.\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">\r\nSYSTEM = &quot;&quot;&quot;\r\nYou work over a Titanic pandas DataFrame.\r\n- To compute answers or create charts, call `df_answer(question=...)`.\r\n- If a plot should be saved, call `save_plot(filename=..., dpi=200)`.\r\n- Keep text concise. If you saved a plot, you may echo the absolute path.\r\n&quot;&quot;&quot;\r\n\r\nreact = create_react_agent(\r\n    llm,\r\n    tools=[df_answer, save_plot],\r\n    prompt=SYSTEM,\r\n)<\/code><\/pre>\n<\/div>\n<p>\nThe following script creates our final graph object.\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">def run_react(state: State) -&gt; State:\r\n    out = react.invoke({&quot;messages&quot;: [(&quot;user&quot;, state[&quot;question&quot;])]})\r\n\r\n    msgs = out[&quot;messages&quot;]\r\n    final_text = msgs[-1].content\r\n\r\n    new_plots = []\r\n    for m in msgs:\r\n        # Tool messages include the tool&#x27;s return in `content`\r\n        try:\r\n            data = json.loads(getattr(m, &quot;content&quot;, &quot;&quot;) or &quot;{}&quot;)\r\n        except Exception:\r\n            data = None\r\n        if isinstance(data, dict) and &quot;plot&quot; in data:\r\n            new_plots.append(data[&quot;plot&quot;])  # {&quot;name&quot;: &quot;...&quot;, &quot;path&quot;: &quot;...&quot;}\r\n\r\n    return {&quot;answer&quot;: final_text, &quot;plots&quot;: new_plots}\r\n\r\ngraph_builder = StateGraph(State)\r\ngraph_builder.add_node(&quot;ask_question&quot;, run_react)\r\ngraph_builder.add_edge(START, &quot;ask_question&quot;)\r\ngraph_builder.add_edge(&quot;ask_question&quot;, END)\r\ngraph = graph_builder.compile()\r\ndisplay(Image(graph.get_graph(xray=True).draw_mermaid_png()))<\/code><\/pre>\n<\/div>\n<p><strong>Output:<\/strong><br \/>\n<a href=\"\/wp-content\/uploads\/2026\/07\/img3-react-agent-for-data-visualization.png\"><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/07\/img3-react-agent-for-data-visualization.png\" alt=\"\" width=\"293\" height=\"482\" class=\"aligncenter size-full wp-image-55459\" srcset=\"\/wp-content\/uploads\/2026\/07\/img3-react-agent-for-data-visualization.png 293w, \/wp-content\/uploads\/2026\/07\/img3-react-agent-for-data-visualization-182x300.png 182w\" sizes=\"(max-width: 293px) 100vw, 293px\" \/><\/a><\/p>\n<p>\nThe above output shows the flow of the graph. The user&#8217;s question is passed to the ReAct agent, which decides which tools it requires to answer the user&#8217;s query.\n<\/p>\n<h3 id=\"testing-the-agent-generating-responses\">Testing the Agent &#038; Generating Responses<\/h3>\n<p>\nLet&#8217;s test the agent. We will first ask a simple question that doesn&#8217;t require saving or plotting a graph.\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\"># A) plain Q&amp;A\r\ns = graph.invoke({&quot;question&quot;: &quot;What is the average Fare for passengers that survive and those who did not?&quot;})\r\nprint(f&quot;\\nFinal Answer: {s[&#x27;answer&#x27;]}&quot;)<\/code><\/pre>\n<\/div>\n<p><strong>Output:<\/strong><br \/>\n<a href=\"\/wp-content\/uploads\/2026\/07\/img4-response-from-text-only-agent.png\"><img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/07\/img4-response-from-text-only-agent.png\" alt=\"\" width=\"1815\" height=\"363\" class=\"aligncenter size-full wp-image-55460\" srcset=\"\/wp-content\/uploads\/2026\/07\/img4-response-from-text-only-agent.png 1815w, \/wp-content\/uploads\/2026\/07\/img4-response-from-text-only-agent-300x60.png 300w, \/wp-content\/uploads\/2026\/07\/img4-response-from-text-only-agent-1024x205.png 1024w, \/wp-content\/uploads\/2026\/07\/img4-response-from-text-only-agent-768x154.png 768w, \/wp-content\/uploads\/2026\/07\/img4-response-from-text-only-agent-1536x307.png 1536w, \/wp-content\/uploads\/2026\/07\/img4-response-from-text-only-agent-600x120.png 600w\" sizes=\"(max-width: 1815px) 100vw, 1815px\" \/><\/a><\/p>\n<p>\nThe output displays the average fares for passengers who survived and those who did not. Note that these values are identical to the ones we retrieved earlier by executing a direct operation on the Pandas dataframe.\n<\/p>\n<p>\nNext, we will request our agent to plot a chart using the results.\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\"># B) plot + save (the agent will call save_plot internally)\r\ns = graph.invoke({\r\n    &quot;question&quot;: (&quot;Plot a bar chart of average Fare for passengers that survive and those who did not?&quot;),\r\n})\r\nprint(f&quot;\\nFinal Answer: {s[&#x27;answer&#x27;]}&quot;)\r\nprint(&quot;plots so far:&quot;, s[&quot;plots&quot;])<\/code><\/pre>\n<\/div>\n<p><strong>Output:<\/strong><br \/>\n<a href=\"\/wp-content\/uploads\/2026\/07\/img5-response-from-data-visualization-agent.png\"><img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/07\/img5-response-from-data-visualization-agent.png\" alt=\"\" width=\"1428\" height=\"384\" class=\"aligncenter size-full wp-image-55461\" srcset=\"\/wp-content\/uploads\/2026\/07\/img5-response-from-data-visualization-agent.png 1428w, \/wp-content\/uploads\/2026\/07\/img5-response-from-data-visualization-agent-300x81.png 300w, \/wp-content\/uploads\/2026\/07\/img5-response-from-data-visualization-agent-1024x275.png 1024w, \/wp-content\/uploads\/2026\/07\/img5-response-from-data-visualization-agent-768x207.png 768w, \/wp-content\/uploads\/2026\/07\/img5-response-from-data-visualization-agent-600x161.png 600w\" sizes=\"(max-width: 1428px) 100vw, 1428px\" \/><\/a><\/p>\n<p>\nThe output shows that the agent saved the plot and also returned its location in the output.\n<\/p>\n<p>\nIf you open the plot, you can see the average fare by survival rate plotted in the form of a bar chart.\n<\/p>\n<p><a href=\"\/wp-content\/uploads\/2026\/07\/img6-final_plot.png\"><img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/07\/img6-final_plot.png\" alt=\"\" width=\"1260\" height=\"938\" class=\"aligncenter size-full wp-image-55462\" srcset=\"\/wp-content\/uploads\/2026\/07\/img6-final_plot.png 1260w, \/wp-content\/uploads\/2026\/07\/img6-final_plot-300x223.png 300w, \/wp-content\/uploads\/2026\/07\/img6-final_plot-1024x762.png 1024w, \/wp-content\/uploads\/2026\/07\/img6-final_plot-768x572.png 768w, \/wp-content\/uploads\/2026\/07\/img6-final_plot-600x447.png 600w\" sizes=\"(max-width: 1260px) 100vw, 1260px\" \/><\/a><\/p>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>\nThis article demonstrates how to integrate GridDB Cloud with LangGraph and OpenAI to create a ReAct agent that can query tabular datasets and generate visualizations. By combining structured storage with the reasoning power of LLMs, we developed a system that seamlessly handles both textual answers and graphical plots.\n<\/p>\n<p>\nIf you have questions or need support with GridDB Cloud, feel free to post them on Stack Overflow using the <code>griddb<\/code> tag. The GridDB team will be happy to help.\n<\/p>\n<p>\nFor the complete code and additional examples, visit <a href=\"https:\/\/github.com\/usmanmalik57\/GridDB-Blogs\/tree\/main\/Visualize%20GridDB%20Data%20Using%20LangGraph%20and%20OpenAI%20API\">GridDB Blogs GitHub repository<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Large Language Models (LLMs) allow developers to combine advanced AI reasoning with powerful databases to analyze and visualize complex datasets. In this article, you will see how to build a tabular data visualization assistant using GridDB Cloud, LangGraph, and the OpenAI GPT-4o model. We will import the Titanic dataset into GridDB, query it programmatically, and [&hellip;]<\/p>\n","protected":false},"author":41,"featured_media":55463,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[121],"tags":[],"class_list":["post-55454","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Visualize GridDB Data Using LangGraph and OpenAI API | GridDB: Open Source Time Series Database for IoT<\/title>\n<meta name=\"description\" content=\"Large Language Models (LLMs) allow developers to combine advanced AI reasoning with powerful databases to analyze and visualize complex datasets. In this\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Visualize GridDB Data Using LangGraph and OpenAI API | GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"og:description\" content=\"Large Language Models (LLMs) allow developers to combine advanced AI reasoning with powerful databases to analyze and visualize complex datasets. In this\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/\" \/>\n<meta property=\"og:site_name\" content=\"GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/griddbcommunity\/\" \/>\n<meta property=\"article:published_time\" content=\"2026-07-12T22:49:20+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-07-22T22:49:45+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.griddb.net\/wp-content\/uploads\/2026\/07\/Gemini_Generated_Image_pocb2upocb2upocb-1024x572.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"572\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"griddb-admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@GridDBCommunity\" \/>\n<meta name=\"twitter:site\" content=\"@GridDBCommunity\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"griddb-admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/\"},\"author\":{\"name\":\"griddb-admin\",\"@id\":\"https:\/\/www.griddb.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233\"},\"headline\":\"Visualize GridDB Data Using LangGraph and OpenAI API\",\"datePublished\":\"2026-07-12T22:49:20+00:00\",\"dateModified\":\"2026-07-22T22:49:45+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/\"},\"wordCount\":783,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.griddb.net\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2026\/07\/Gemini_Generated_Image_pocb2upocb2upocb-scaled.png\",\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/\",\"url\":\"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/\",\"name\":\"Visualize GridDB Data Using LangGraph and OpenAI API | GridDB: Open Source Time Series Database for IoT\",\"isPartOf\":{\"@id\":\"https:\/\/www.griddb.net\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2026\/07\/Gemini_Generated_Image_pocb2upocb2upocb-scaled.png\",\"datePublished\":\"2026-07-12T22:49:20+00:00\",\"dateModified\":\"2026-07-22T22:49:45+00:00\",\"description\":\"Large Language Models (LLMs) allow developers to combine advanced AI reasoning with powerful databases to analyze and visualize complex datasets. In this\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/#primaryimage\",\"url\":\"\/wp-content\/uploads\/2026\/07\/Gemini_Generated_Image_pocb2upocb2upocb-scaled.png\",\"contentUrl\":\"\/wp-content\/uploads\/2026\/07\/Gemini_Generated_Image_pocb2upocb2upocb-scaled.png\",\"width\":2560,\"height\":1429},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.griddb.net\/en\/#website\",\"url\":\"https:\/\/www.griddb.net\/en\/\",\"name\":\"GridDB: Open Source Time Series Database for IoT\",\"description\":\"GridDB is an open source time-series database with the performance of NoSQL and convenience of SQL\",\"publisher\":{\"@id\":\"https:\/\/www.griddb.net\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.griddb.net\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.griddb.net\/en\/#organization\",\"name\":\"Fixstars\",\"url\":\"https:\/\/www.griddb.net\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.griddb.net\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png\",\"contentUrl\":\"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png\",\"width\":200,\"height\":83,\"caption\":\"Fixstars\"},\"image\":{\"@id\":\"https:\/\/www.griddb.net\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/griddbcommunity\/\",\"https:\/\/x.com\/GridDBCommunity\",\"https:\/\/www.linkedin.com\/company\/griddb-by-toshiba\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.griddb.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233\",\"name\":\"griddb-admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.griddb.net\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g\",\"caption\":\"griddb-admin\"},\"url\":\"https:\/\/www.griddb.net\/en\/author\/griddb-admin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Visualize GridDB Data Using LangGraph and OpenAI API | GridDB: Open Source Time Series Database for IoT","description":"Large Language Models (LLMs) allow developers to combine advanced AI reasoning with powerful databases to analyze and visualize complex datasets. In this","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/","og_locale":"en_US","og_type":"article","og_title":"Visualize GridDB Data Using LangGraph and OpenAI API | GridDB: Open Source Time Series Database for IoT","og_description":"Large Language Models (LLMs) allow developers to combine advanced AI reasoning with powerful databases to analyze and visualize complex datasets. In this","og_url":"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/","og_site_name":"GridDB: Open Source Time Series Database for IoT","article_publisher":"https:\/\/www.facebook.com\/griddbcommunity\/","article_published_time":"2026-07-12T22:49:20+00:00","article_modified_time":"2026-07-22T22:49:45+00:00","og_image":[{"width":1024,"height":572,"url":"https:\/\/www.griddb.net\/wp-content\/uploads\/2026\/07\/Gemini_Generated_Image_pocb2upocb2upocb-1024x572.png","type":"image\/png"}],"author":"griddb-admin","twitter_card":"summary_large_image","twitter_creator":"@GridDBCommunity","twitter_site":"@GridDBCommunity","twitter_misc":{"Written by":"griddb-admin","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/#article","isPartOf":{"@id":"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/"},"author":{"name":"griddb-admin","@id":"https:\/\/www.griddb.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233"},"headline":"Visualize GridDB Data Using LangGraph and OpenAI API","datePublished":"2026-07-12T22:49:20+00:00","dateModified":"2026-07-22T22:49:45+00:00","mainEntityOfPage":{"@id":"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/"},"wordCount":783,"commentCount":0,"publisher":{"@id":"https:\/\/www.griddb.net\/en\/#organization"},"image":{"@id":"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2026\/07\/Gemini_Generated_Image_pocb2upocb2upocb-scaled.png","articleSection":["Blog"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/","url":"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/","name":"Visualize GridDB Data Using LangGraph and OpenAI API | GridDB: Open Source Time Series Database for IoT","isPartOf":{"@id":"https:\/\/www.griddb.net\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/#primaryimage"},"image":{"@id":"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2026\/07\/Gemini_Generated_Image_pocb2upocb2upocb-scaled.png","datePublished":"2026-07-12T22:49:20+00:00","dateModified":"2026-07-22T22:49:45+00:00","description":"Large Language Models (LLMs) allow developers to combine advanced AI reasoning with powerful databases to analyze and visualize complex datasets. In this","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.griddb.net\/en\/blog\/visualize-griddb-data-using-langgraph-and-openai-api\/#primaryimage","url":"\/wp-content\/uploads\/2026\/07\/Gemini_Generated_Image_pocb2upocb2upocb-scaled.png","contentUrl":"\/wp-content\/uploads\/2026\/07\/Gemini_Generated_Image_pocb2upocb2upocb-scaled.png","width":2560,"height":1429},{"@type":"WebSite","@id":"https:\/\/www.griddb.net\/en\/#website","url":"https:\/\/www.griddb.net\/en\/","name":"GridDB: Open Source Time Series Database for IoT","description":"GridDB is an open source time-series database with the performance of NoSQL and convenience of SQL","publisher":{"@id":"https:\/\/www.griddb.net\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.griddb.net\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.griddb.net\/en\/#organization","name":"Fixstars","url":"https:\/\/www.griddb.net\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.griddb.net\/en\/#\/schema\/logo\/image\/","url":"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png","contentUrl":"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png","width":200,"height":83,"caption":"Fixstars"},"image":{"@id":"https:\/\/www.griddb.net\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/griddbcommunity\/","https:\/\/x.com\/GridDBCommunity","https:\/\/www.linkedin.com\/company\/griddb-by-toshiba"]},{"@type":"Person","@id":"https:\/\/www.griddb.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233","name":"griddb-admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.griddb.net\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g","caption":"griddb-admin"},"url":"https:\/\/www.griddb.net\/en\/author\/griddb-admin\/"}]}},"_links":{"self":[{"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/posts\/55454","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/comments?post=55454"}],"version-history":[{"count":3,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/posts\/55454\/revisions"}],"predecessor-version":[{"id":55464,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/posts\/55454\/revisions\/55464"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/media\/55463"}],"wp:attachment":[{"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/media?parent=55454"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/categories?post=55454"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/tags?post=55454"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}