code: def extract_schema(cls):
      """
      Extract schema from a given class
  
      Args:
          cls (type): Class from which to extract.
  
      Returns:
          schema (SchemaDict): Extracted schema.
      """
      ctor = cls.__init__
      # python 2 compatibility
      if hasattr(inspect, "getfullargspec"):
          argspec = inspect.getfullargspec(ctor)
          annotations = argspec.annotations
          has_kwargs = argspec.varkw is not None
      else:
          argspec = inspect.getfullargspec(ctor)
          # python 2 type hinting workaround, see pep-3107
          # however, since `typeguard` does not support python 2, type checking
          # is still python 3 only for now
          annotations = getattr(ctor, "__annotations__", {})
          has_kwargs = argspec.varkw is not None
  
      names = [arg for arg in argspec.args if arg != "self"]
      defaults = argspec.defaults
      num_defaults = (
          argspec.defaults is not None and len(argspec.defaults) or 0
      )
      num_required = len(names) - num_defaults
  
      docs = cls.__doc__
      if docs is None and getattr(cls, "__category__", None) == "op":
          docs = cls.__call__.__doc__
      try:
          docstring = doc_parse(docs)
      except Exception:
          docstring = None
  
      if docstring is None:
          comments = {}
      else:
          comments = {}
          for p in docstring.params:
              match_obj = re.match(
                  "^([a-zA-Z_]+[a-zA-Z_0-9]*).*", p.arg_name
              )
              if match_obj is not None:
                  comments[match_obj.group(1)] = p.description
  
      schema = SchemaDict()
      schema.name = cls.__name__
      schema.doc = ""
      if docs is not None:
          start_pos = docs[0] == "\n" and 1 or 0
          schema.doc = docs[start_pos:].split("\n")[0].strip()
      # XXX handle paddle's weird doc convention
      if "**" == schema.doc[:2] and "**" == schema.doc[-2:]:
          schema.doc = schema.doc[2:-2].strip()
      schema.category = (
          hasattr(cls, "__category__")
          and getattr(cls, "__category__")
          or "module"
      )
      schema.strict = not has_kwargs
      schema.pymodule = importlib.import_module(cls.__module__)
      schema.inject = getattr(cls, "__inject__", [])
      schema.shared = getattr(cls, "__shared__", [])
      for idx, name in enumerate(names):
          comment = name in comments and comments[name] or name
          if name in schema.inject:
              type_ = None
          else:
              type_ = name in annotations and annotations[name] or None
          value_schema = SchemaValue(name, comment, type_)
          if name in schema.shared:
              assert (
                  idx >= num_required
              ), "shared config must have default value"
              default = defaults[idx - num_required]
              value_schema.set_default(SharedConfig(name, default))
          elif idx >= num_required:
              default = defaults[idx - num_required]
              value_schema.set_default(default)
          schema.set_schema(name, value_schema)
  
      return schema
  
imports: from __future__ import absolute_import
  from __future__ import print_function
  from __future__ import division
  import inspect
  import importlib
  import re
label_desc: Use image node_id 1 for calling a global function with example usage: extract_schema(cls) and returns: schema