code: def serialize_module(module, versioned, funcs, dsets):
      in_keys = module.get_inputs()
      name = module.__class__.__name__
  
      if versioned:
          new_ins = {}
          for k, in_key in in_keys.items():
              if in_key not in dsets:
                  dsets[in_key] = 1
              new_ins[k] = f"{in_key} (v{dsets[in_key]})"
          in_keys = new_ins
  
      out_keys = module.get_outputs()
      if versioned:
          new_outs = {}
          for k, out_key in out_keys.items():
              if out_key in dsets:
                  dsets[out_key] += 1
              else:
                  dsets[out_key] = 1
              new_outs[k] = f"{out_key} (v{dsets[out_key]})"
          out_keys = new_outs
  
      # add unique id
      if name not in funcs:
          funcs[name] = {}
      if id(module) not in funcs[name]:
          funcs[name][id(module)] = len(funcs[name]) + 1
  
      return {
          "type": "module",
          "name": f"{name}",
          "i": f"{funcs[name][id(module)]}",
          "desc": module.get_description(),
          "in": in_keys,
          "out": out_keys,
      }
  
file_path: popmon/tools/pipeline_viz.py
imports: import json
  from itertools import cycle
  from pathlib import Path
  import pygraphviz
  from popmon.base import Pipeline
label_desc: Use image node_id 1 for calling a global function with example usage: serialize_module(module, versioned, funcs, dsets) and returns: dict