code: def __repr__(self):
      if self.sender and self.sender_socket:
          sender_repr = f"{self.sender}.{self.sender_socket.name} ({_type_name(self.sender_socket.type)})"
      else:
          sender_repr = "input needed"
  
      if self.receiver and self.receiver_socket:
          receiver_repr = f"({_type_name(self.receiver_socket.type)}) {self.receiver}.{self.receiver_socket.name}"
      else:
          receiver_repr = "output"
  
      return f"{sender_repr} --> {receiver_repr}"
  
file_path: haystack/haystack/core/component/connection.py
imports: import itertools
  from typing import Optional, List, Tuple
  from dataclasses import dataclass
  from haystack.core.component.sockets import InputSocket, OutputSocket
  from haystack.core.type_utils import _type_name, _types_are_compatible
  from haystack.core.errors import PipelineConnectError
label_desc: Use image node_id 2 for calling the Connection obj's underlying member method code with example usage: obj.__repr__() and returns: sender_repr, str, receiver_repr