code: def task_id_str(task_family, params):
      
      # task_id is a concatenation of task family, the first values of the first 3 parameters
      # sorted by parameter name and a md5hash of the family/parameters as a cananocalised json.
      param_str = json.dumps(params, separators=(',', ':'), sort_keys=True)
      param_hash = hashlib.md5(param_str.encode('utf-8')).hexdigest()
  
      param_summary = '_'.join(p[:TASK_ID_TRUNCATE_PARAMS]
                               for p in (params[p] for p in sorted(params)[:TASK_ID_INCLUDE_PARAMS]))
      param_summary = TASK_ID_INVALID_CHAR_REGEX.sub('_', param_summary)
  
      return '{}_{}_{}'.format(task_family, param_summary, param_hash[:TASK_ID_TRUNCATE_HASH])
docs: Returns a canonical string used to identify a particular task
  
      :param task_family: The task family (class name) of the task
      :param params: a dict mapping parameter names to their serialized values
      :return: A unique, shortened identifier corresponding to the family and params