docs: def get_input_spec_patterns():
      ''' Extract the inputSpec patterns, if they exist -- modifed from dx-upload-all-outputs
  
      Returns a dict of all patterns, with keys equal to the respective
      input parameter names.
      '''
      input_spec = None
      if 'DX_JOB_ID' in environ:
          # works in the cloud, not locally
          job_desc = dxpy.describe(dxpy.JOB_ID)
          if job_desc["function"] == "main":
              # The input spec does not apply for subjobs
              desc = dxpy.describe(job_desc.get("app", job_desc.get("applet")))
              if "inputSpec" in desc:
                  input_spec = desc["inputSpec"]
      elif 'DX_TEST_DXAPP_JSON' in environ:
          # works only locally
          path_to_dxapp_json = environ['DX_TEST_DXAPP_JSON']
          with open(path_to_dxapp_json) as fd:
              dxapp_json = json.load(fd)
              input_spec = dxapp_json.get('inputSpec')
  
      # convert to a dictionary. Each entry in the input spec
      # has {name, class} attributes.
      if input_spec is None:
          return {}
  
      # For each field name, return its patterns.
      # Make sure a pattern is legal, ignore illegal patterns.
      def is_legal_pattern(pattern):
          return "*" in pattern
      patterns_dict = {}
      for spec in input_spec:
          name = spec['name']
          if 'patterns' in spec:
              patterns_dict[name] = []
              for p in spec['patterns']:
                  if is_legal_pattern(p):
                      patterns_dict[name].append(p)
      return patterns_dict