DOC: (subgraph.ipynb); HTTPSConnectionPool(host='mermaid.ink', port=443): Read timed out. (read timeout=10)? #582

Closed
opened 2026-02-20 17:40:49 -05:00 by yindo · 6 comments
Owner

Originally created by @david101-hunter on GitHub (Apr 15, 2025).

I'm following this guideline, I wrote this script like

import os
# from langchain_openai import ChatOpenAI
# from dotenv import load_dotenv
from langgraph.graph import START, StateGraph
from typing import TypedDict
from langchain_core.runnables.graph import MermaidDrawMethod
# load_dotenv()
# os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_API_KEY')


class SubgraphState(TypedDict):
    foo: str  # note that this key is shared with the parent graph state
    bar: str


def subgraph_node_1(state: SubgraphState):
    return {"bar": "bar"}


def subgraph_node_2(state: SubgraphState):
    # note that this node is using a state key ('bar') that is only available in the subgraph
    # and is sending update on the shared state key ('foo')
    return {"foo": state["foo"] + state["bar"]}


subgraph_builder = StateGraph(SubgraphState)
subgraph_builder.add_node(subgraph_node_1)
subgraph_builder.add_node(subgraph_node_2)
subgraph_builder.add_edge(START, "subgraph_node_1")
subgraph_builder.add_edge("subgraph_node_1", "subgraph_node_2")
subgraph = subgraph_builder.compile()


# Define parent graph
class ParentState(TypedDict):
    foo: str


def node_1(state: ParentState):
    return {"foo": "hi! " + state["foo"]}


builder = StateGraph(ParentState)
builder.add_node("node_1", node_1)
# note that we're adding the compiled subgraph as a node to the parent graph
builder.add_node("node_2", subgraph)
builder.add_edge(START, "node_1")
builder.add_edge("node_1", "node_2")
graph = builder.compile()

# save graph's scheme
try:
    with open('subgraphs-scheme.png', 'wb') as f:
        f.write(graph.get_graph().draw_mermaid_png(
            draw_method=MermaidDrawMethod.API,
        ))
except Exception as e:
    # This requires some extra dependencies and is optional
    print(f"Lỗi khi lưu biểu đồ: {e}")

for chunk in graph.stream({"foo": "foo"}):
    print(chunk)

for chunk in graph.stream({"foo": "foo"}, subgraphs=True):
    print(chunk)

I don't know why it raise the error

Lỗi khi lưu biểu đồ: HTTPSConnectionPool(host='mermaid.ink', port=443): Read timed out. (read timeout=10)

because I have did many example and all of them work fine, save to png file.

import os
from langchain_openai import ChatOpenAI
from typing import Literal
from langgraph.prebuilt import create_react_agent
from langchain_core.tools import tool
from dotenv import load_dotenv

load_dotenv()
os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_API_KEY')

model = ChatOpenAI(model="gpt-4o", temperature=0)
# For this tutorial we will use custom tool that returns pre-defined values for weather in two cities (NYC & SF)


@tool
def get_weather(city: Literal["nyc", "sf"]):
    """Use this to get weather information."""
    if city == "nyc":
        return "It might be cloudy in nyc"
    elif city == "sf":
        return "It's always sunny in sf"
    else:
        raise AssertionError("Unknown city")


tools = [get_weather]

# Define the graph
graph = create_react_agent(model, tools=tools)

# save graph's scheme
try:
    with open('parallel-extras-step-scheme.png', 'wb') as f:
        f.write(graph.get_graph().draw_mermaid_png())
except Exception as e:
    # This requires some extra dependencies and is optional
    print(f"Lỗi khi lưu biểu đồ: {e}")


def print_stream(stream):
    for s in stream:
        message = s["messages"][-1]
        if isinstance(message, tuple):
            print(message)
        else:
            message.pretty_print()


inputs = {"messages": [("user", "what is the weather in sf")]}
print_stream(graph.stream(inputs, stream_mode="values"))

the snippet code is ok

version lib

  • langchain 0.3.19
  • langchain-anthropic 0.3.10
  • langchain-chroma 0.2.2
  • langchain-community 0.3.18
  • langchain-core 0.3.51
  • langchain-experimental 0.3.4
  • langchain-ollama 0.2.3
  • langchain-openai 0.3.7
  • langchain-text-splitters 0.3.6
  • langdetect 1.0.9
  • langgraph 0.3.30
  • langgraph-checkpoint 2.0.16
  • langgraph-prebuilt 0.1.8
  • langgraph-sdk 0.1.53
  • langmem 0.0.22
  • langsmith 0.3.11
  • python 3.12.9
Originally created by @david101-hunter on GitHub (Apr 15, 2025). I'm following this [guideline](https://github.com/langchain-ai/langgraph/blob/main/docs/docs/how-tos/subgraph.ipynb), I wrote this script like ```python import os # from langchain_openai import ChatOpenAI # from dotenv import load_dotenv from langgraph.graph import START, StateGraph from typing import TypedDict from langchain_core.runnables.graph import MermaidDrawMethod # load_dotenv() # os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_API_KEY') class SubgraphState(TypedDict): foo: str # note that this key is shared with the parent graph state bar: str def subgraph_node_1(state: SubgraphState): return {"bar": "bar"} def subgraph_node_2(state: SubgraphState): # note that this node is using a state key ('bar') that is only available in the subgraph # and is sending update on the shared state key ('foo') return {"foo": state["foo"] + state["bar"]} subgraph_builder = StateGraph(SubgraphState) subgraph_builder.add_node(subgraph_node_1) subgraph_builder.add_node(subgraph_node_2) subgraph_builder.add_edge(START, "subgraph_node_1") subgraph_builder.add_edge("subgraph_node_1", "subgraph_node_2") subgraph = subgraph_builder.compile() # Define parent graph class ParentState(TypedDict): foo: str def node_1(state: ParentState): return {"foo": "hi! " + state["foo"]} builder = StateGraph(ParentState) builder.add_node("node_1", node_1) # note that we're adding the compiled subgraph as a node to the parent graph builder.add_node("node_2", subgraph) builder.add_edge(START, "node_1") builder.add_edge("node_1", "node_2") graph = builder.compile() # save graph's scheme try: with open('subgraphs-scheme.png', 'wb') as f: f.write(graph.get_graph().draw_mermaid_png( draw_method=MermaidDrawMethod.API, )) except Exception as e: # This requires some extra dependencies and is optional print(f"Lỗi khi lưu biểu đồ: {e}") for chunk in graph.stream({"foo": "foo"}): print(chunk) for chunk in graph.stream({"foo": "foo"}, subgraphs=True): print(chunk) ``` I don't know why it raise the error ``` Lỗi khi lưu biểu đồ: HTTPSConnectionPool(host='mermaid.ink', port=443): Read timed out. (read timeout=10) ``` because I have did many example and all of them work fine, save to png file. ``` import os from langchain_openai import ChatOpenAI from typing import Literal from langgraph.prebuilt import create_react_agent from langchain_core.tools import tool from dotenv import load_dotenv load_dotenv() os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_API_KEY') model = ChatOpenAI(model="gpt-4o", temperature=0) # For this tutorial we will use custom tool that returns pre-defined values for weather in two cities (NYC & SF) @tool def get_weather(city: Literal["nyc", "sf"]): """Use this to get weather information.""" if city == "nyc": return "It might be cloudy in nyc" elif city == "sf": return "It's always sunny in sf" else: raise AssertionError("Unknown city") tools = [get_weather] # Define the graph graph = create_react_agent(model, tools=tools) # save graph's scheme try: with open('parallel-extras-step-scheme.png', 'wb') as f: f.write(graph.get_graph().draw_mermaid_png()) except Exception as e: # This requires some extra dependencies and is optional print(f"Lỗi khi lưu biểu đồ: {e}") def print_stream(stream): for s in stream: message = s["messages"][-1] if isinstance(message, tuple): print(message) else: message.pretty_print() inputs = {"messages": [("user", "what is the weather in sf")]} print_stream(graph.stream(inputs, stream_mode="values")) ``` the snippet code is ok version lib - langchain 0.3.19 - langchain-anthropic 0.3.10 - langchain-chroma 0.2.2 - langchain-community 0.3.18 - langchain-core 0.3.51 - langchain-experimental 0.3.4 - langchain-ollama 0.2.3 - langchain-openai 0.3.7 - langchain-text-splitters 0.3.6 - langdetect 1.0.9 - langgraph 0.3.30 - langgraph-checkpoint 2.0.16 - langgraph-prebuilt 0.1.8 - langgraph-sdk 0.1.53 - langmem 0.0.22 - langsmith 0.3.11 - python 3.12.9
yindo closed this issue 2026-02-20 17:40:49 -05:00
Author
Owner

@hinthornw commented on GitHub (Apr 15, 2025):

This is just a transient reliability error in the mermaid service that is used to draw the diagrams. You can probably run again or in use draw_method=MermaidDrawMethod.PYPPETEER, in draw_mermaid_png or use a different drawing method (such as ascii)

It isn't an error in any of the actual runtime functionality thankfully

@hinthornw commented on GitHub (Apr 15, 2025): This is just a transient reliability error in the mermaid service that is used to draw the diagrams. You can probably run again or in use draw_method=MermaidDrawMethod.PYPPETEER, in draw_mermaid_png or use a different drawing method (such as ascii) It isn't an error in any of the actual runtime functionality thankfully
Author
Owner

@david101-hunter commented on GitHub (Apr 15, 2025):

I have run again with your suggestion, but it's not working

Lỗi khi lưu biểu đồ: Loading script from https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js failed
{'node_1': {'foo': 'hi! foo'}}
{'node_2': {'foo': 'hi! foobar'}}
((), {'node_1': {'foo': 'hi! foo'}})
(('node_2:9fdc130d-41a5-8176-fa9a-c1953a56e241',), {'subgraph_node_1': {'bar': 'bar'}})
(('node_2:9fdc130d-41a5-8176-fa9a-c1953a56e241',), {'subgraph_node_2': {'foo': 'hi! foobar'}})
((), {'node_2': {'foo': 'hi! foobar'}})
Hi from parent-graph-and-subgraph-share-scheme-keys.py!
Exception ignored in atexit callback: <function Launcher.launch.<locals>._close_process at 0x7f3f28debba0>
Traceback (most recent call last):
  File "/media/manhdt4/sda1/miniconda3/envs/langgraph/lib/python3.12/site-packages/pyppeteer/launcher.py", line 153, in _close_process
    self._loop.run_until_complete(self.killChrome())
  File "/media/manhdt4/sda1/miniconda3/envs/langgraph/lib/python3.12/asyncio/base_events.py", line 666, in run_until_complete
    self._check_closed()
  File "/media/manhdt4/sda1/miniconda3/envs/langgraph/lib/python3.12/asyncio/base_events.py", line 545, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
sys:1: RuntimeWarning: coroutine 'Launcher.killChrome' was never awaited
RuntimeWarning: Enable tracemalloc to get the object allocation traceback

this is change

# save graph's scheme
try:
    # with open('graphs-scheme.png', 'wb') as f:
    #     f.write(graph.get_graph().draw_mermaid_png(
    #         draw_method=MermaidDrawMethod.API,
    #     ))
    with open('graphs-scheme.png', 'wb') as f:
        f.write(graph.get_graph().draw_mermaid_png(draw_method=MermaidDrawMethod.PYPPETEER))
except Exception as e:
    # This requires some extra dependencies and is optional
    print(f"Lỗi khi lưu biểu đồ: {e}")
@david101-hunter commented on GitHub (Apr 15, 2025): I have run again with your suggestion, but it's not working ``` Lỗi khi lưu biểu đồ: Loading script from https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js failed {'node_1': {'foo': 'hi! foo'}} {'node_2': {'foo': 'hi! foobar'}} ((), {'node_1': {'foo': 'hi! foo'}}) (('node_2:9fdc130d-41a5-8176-fa9a-c1953a56e241',), {'subgraph_node_1': {'bar': 'bar'}}) (('node_2:9fdc130d-41a5-8176-fa9a-c1953a56e241',), {'subgraph_node_2': {'foo': 'hi! foobar'}}) ((), {'node_2': {'foo': 'hi! foobar'}}) Hi from parent-graph-and-subgraph-share-scheme-keys.py! Exception ignored in atexit callback: <function Launcher.launch.<locals>._close_process at 0x7f3f28debba0> Traceback (most recent call last): File "/media/manhdt4/sda1/miniconda3/envs/langgraph/lib/python3.12/site-packages/pyppeteer/launcher.py", line 153, in _close_process self._loop.run_until_complete(self.killChrome()) File "/media/manhdt4/sda1/miniconda3/envs/langgraph/lib/python3.12/asyncio/base_events.py", line 666, in run_until_complete self._check_closed() File "/media/manhdt4/sda1/miniconda3/envs/langgraph/lib/python3.12/asyncio/base_events.py", line 545, in _check_closed raise RuntimeError('Event loop is closed') RuntimeError: Event loop is closed sys:1: RuntimeWarning: coroutine 'Launcher.killChrome' was never awaited RuntimeWarning: Enable tracemalloc to get the object allocation traceback ``` this is change ``` # save graph's scheme try: # with open('graphs-scheme.png', 'wb') as f: # f.write(graph.get_graph().draw_mermaid_png( # draw_method=MermaidDrawMethod.API, # )) with open('graphs-scheme.png', 'wb') as f: f.write(graph.get_graph().draw_mermaid_png(draw_method=MermaidDrawMethod.PYPPETEER)) except Exception as e: # This requires some extra dependencies and is optional print(f"Lỗi khi lưu biểu đồ: {e}") ```
Author
Owner

@zyararbas commented on GitHub (Apr 22, 2025):

+1

@zyararbas commented on GitHub (Apr 22, 2025): +1
Author
Owner

@jpangburn commented on GitHub (Apr 23, 2025):

I think @hinthornw is probably right, this seems transitory. Ran into this with a new graph, thought it was that, but then tried displaying older simpler graphs that used to work fine and still getting this HTTPS timeout error. So seems like the service has a problem.

Trying to workaround, I tried the draw_ascii method, but it fails in Jupyter notebook

from IPython.display import Image, display
display(Image(langgraph.get_graph().draw_ascii()))

TypeError Traceback (most recent call last)
File ~/python_envs/langchain/lib/python3.9/site-packages/IPython/core/display.py:1045, in Image._data_and_metadata(self, always_both)
1044 try:
-> 1045 b64_data = b2a_base64(self.data, newline=False).decode("ascii")
1046 except TypeError as e:

TypeError: a bytes-like object is required, not 'str'

It does end up drawing something in the stderr output, but not really what you want. So seems like this is buggy too.

The thing that did end up working is the draw_png method:

from IPython.display import Image, display
display(Image(langgraph.get_graph().draw_png()))

But it does require that you install graphviz, which can involve some hoops. The upside of getting this working is that drawing is done locally, so no worries about an online service being offline.

@jpangburn commented on GitHub (Apr 23, 2025): I think @hinthornw is probably right, this seems transitory. Ran into this with a new graph, thought it was that, but then tried displaying older simpler graphs that used to work fine and still getting this HTTPS timeout error. So seems like the service has a problem. Trying to workaround, I tried the `draw_ascii` method, but it fails in Jupyter notebook ``` from IPython.display import Image, display display(Image(langgraph.get_graph().draw_ascii())) ``` > --------------------------------------------------------------------------- > TypeError Traceback (most recent call last) > File [~/python_envs/langchain/lib/python3.9/site-packages/IPython/core/display.py:1045](http://localhost:8888/lab/tree/~/python_envs/langchain/lib/python3.9/site-packages/IPython/core/display.py#line=1044), in Image._data_and_metadata(self, always_both) > 1044 try: > -> 1045 b64_data = b2a_base64(self.data, newline=False).decode("ascii") > 1046 except TypeError as e: > > TypeError: a bytes-like object is required, not 'str' It does end up drawing something in the stderr output, but not really what you want. So seems like this is buggy too. The thing that did end up working is the `draw_png` method: ``` from IPython.display import Image, display display(Image(langgraph.get_graph().draw_png())) ``` But it does require that you install graphviz, which can involve some hoops. The upside of getting this working is that drawing is done locally, so no worries about an online service being offline.
Author
Owner

@labdmitriy commented on GitHub (Apr 24, 2025):

This is just a transient reliability error in the mermaid service that is used to draw the diagrams. You can probably run again or in use draw_method=MermaidDrawMethod.PYPPETEER, in draw_mermaid_png or use a different drawing method (such as ascii)

It isn't an error in any of the actual runtime functionality thankfully

Hi @hinthornw,

I tried to use this method based on the example from the documentation:

import nest_asyncio

nest_asyncio.apply()  # Required for Jupyter Notebook to run async functions

display(
    Image(
        graph.get_graph().draw_mermaid_png(
            curve_style=CurveStyle.LINEAR,
            node_colors=NodeStyles(first="#ffdfba", last="#baffc9", default="#fad7de"),
            wrap_label_n_words=9,
            output_file_path=None,
            draw_method=MermaidDrawMethod.PYPPETEER,
            background_color="white",
            padding=10,
        )
    )
)

And I've got the following error:

AttributeError: module 'websockets' has no attribute 'client'

There are recommendations about downgrading websockets to version 8.1, but langgraph-cli[inmem] which we are also using has indirect dependency to websockets>=10.4, so we can't use this method. Are there any workarounds for it?

@labdmitriy commented on GitHub (Apr 24, 2025): > This is just a transient reliability error in the mermaid service that is used to draw the diagrams. You can probably run again or in use draw_method=MermaidDrawMethod.PYPPETEER, in draw_mermaid_png or use a different drawing method (such as ascii) > > It isn't an error in any of the actual runtime functionality thankfully Hi @hinthornw, I tried to use this method based on the example from the documentation: ```python import nest_asyncio nest_asyncio.apply() # Required for Jupyter Notebook to run async functions display( Image( graph.get_graph().draw_mermaid_png( curve_style=CurveStyle.LINEAR, node_colors=NodeStyles(first="#ffdfba", last="#baffc9", default="#fad7de"), wrap_label_n_words=9, output_file_path=None, draw_method=MermaidDrawMethod.PYPPETEER, background_color="white", padding=10, ) ) ) ``` And I've got the following error: ```bash AttributeError: module 'websockets' has no attribute 'client' ``` There are [recommendations](https://stackoverflow.com/questions/69257248/module-websockets-has-no-attribute-client) about downgrading `websockets` to version 8.1, but `langgraph-cli[inmem]` which we are also using has indirect dependency to `websockets>=10.4`, so we can't use this method. Are there any workarounds for it?
Author
Owner

@jeremy-feng commented on GitHub (May 13, 2025):

I'm encountering the same issue. The strange thing is that sometimes calling .draw_mermaid_png() works without errors, but other times it throws a HTTPSConnectionPool(host='mermaid.ink', port=443): Read timed out. error.

My current workaround is to first print the mermaid code:

from IPython.display import Image, display

print(graph.get_graph().draw_mermaid())

This prints out mermaid code that looks like this:

config:
  flowchart:
    curve: linear
---
graph TD;
	__start__([<p>__start__</p>]):::first
	test(test)
	__end__([<p>__end__</p>]):::last
	__start__ --> test;
	test --> __end__;
	classDef default fill:#f2f0ff,line-height:1.2
	classDef first fill-opacity:0
	classDef last fill:#bfb6fc

Then I manually render it as a mermaid diagram.

---
config:
  flowchart:
    curve: linear
---
graph TD;
	__start__([<p>__start__</p>]):::first
	test(test)
	__end__([<p>__end__</p>]):::last
	__start__ --> test;
	test --> __end__;
	classDef default fill:#f2f0ff,line-height:1.2
	classDef first fill-opacity:0
	classDef last fill:#bfb6fc

Alternatively, I can call the draw_png method to draw a diagram, even though it isn't a mermaid diagram.

display(Image(graph.get_graph().draw_png()))

Image

@jeremy-feng commented on GitHub (May 13, 2025): I'm encountering the same issue. The strange thing is that sometimes calling `.draw_mermaid_png()` works without errors, but other times it throws a `HTTPSConnectionPool(host='mermaid.ink', port=443): Read timed out.` error. My current workaround is to first print the mermaid code: ```python from IPython.display import Image, display print(graph.get_graph().draw_mermaid()) ``` This prints out mermaid code that looks like this: ``` config: flowchart: curve: linear --- graph TD; __start__([<p>__start__</p>]):::first test(test) __end__([<p>__end__</p>]):::last __start__ --> test; test --> __end__; classDef default fill:#f2f0ff,line-height:1.2 classDef first fill-opacity:0 classDef last fill:#bfb6fc ``` Then I manually render it as a mermaid diagram. ```mermaid --- config: flowchart: curve: linear --- graph TD; __start__([<p>__start__</p>]):::first test(test) __end__([<p>__end__</p>]):::last __start__ --> test; test --> __end__; classDef default fill:#f2f0ff,line-height:1.2 classDef first fill-opacity:0 classDef last fill:#bfb6fc ``` Alternatively, I can call the `draw_png` method to draw a diagram, even though it isn't a mermaid diagram. ``` display(Image(graph.get_graph().draw_png())) ``` ![Image](https://github.com/user-attachments/assets/bf348a0c-9879-4e99-a2fb-251395e5b9f0 )
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/langgraph#582