code: def get_repr(obj: Representable) -> str:
      if not isinstance(obj, Representable):
          raise TypeError(f"Object {obj!r} is not representable")
  
      iterator = obj.__nnx_repr__()
      config = next(iterator)
      if not isinstance(config, Object):
          raise TypeError(
              f"First item must be Config, got {type(config).__name__}"
          )
  
      def _repr_elem(elem: tp.Any) -> str:
          if not isinstance(elem, Attr):
              raise TypeError(
                  f"Item must be Elem, got {type(elem).__name__}"
              )
  
          value = (
              elem.value
              if isinstance(elem.value, str)
              else repr(elem.value)
          )
  
          if "\n" in value and not isinstance(
              elem.value, Representable
          ):
              value = value.replace("\n", "\n" + get_indent())
  
          return f"{get_indent()}{elem.start}{elem.key}{config.value_sep}{value}{elem.end}"
  
      with add_indent(config.elem_indent):
          elems = list(map(_repr_elem, iterator))
      elems = ",\n".join(elems)
  
      if elems:
          elems = "\n" + elems + "\n" + get_indent()
      else:
          elems = config.empty_repr
  
      type_repr = (
          config.type
          if isinstance(config.type, str)
          else config.type.__name__
      )
  
      return f"{type_repr}{config.start}{elems}{config.end}"
  
file_path: flax/flax/experimental/nnx/nnx/reprlib.py
imports: import contextlib
  import dataclasses
  import threading
  import typing
  from abc import ABC, abstractmethod
label_desc: Use image node_id 3 for calling a global function with example usage: get_repr(obj) and returns: type_repr, config, elems, config, get_indent, elem, elem, config, value, elem