Instruction:
Create a Python 3 function for
printing a orphaned string representation of an object without the clutter of its parent object.

Response:
def fmt_repr(obj):
  """Print a orphaned string representation of an object without the
  clutter of its parent object.

  """
  items = ["%s = %r" % (k, v) for k, v in list(exclude_fields(obj).items())]
  return "<%s: {%s}>" % (obj.__class__.__name__, ', '.join(items))


Instruction:
Can you create a Python 3 function that
reads an SBP specification file.

Response:
def read_spec(filename, verbose=False):
  """
  Read an SBP specification.

  Parameters
  ----------
  filename : str
    Local filename for specification.
  verbose : bool
    Print out some debugging info

  Returns
  ----------

  Raises
  ----------
  Exception
    On empty file.
  yaml.YAMLError
    On Yaml parsing error
  voluptuous.Invalid
    On invalid SBP schema
  """
  contents = None
  with open(filename, 'r') as f:
    contents = yaml.load(f)
    if contents is None:
      raise Exception("Empty yaml file: %s." % filename)
    try:
      s.package_schema(contents)
    except Exception as e:
      sys.stderr.write("Invalid SBP YAML specification: %s.\n" % filename)
      raise e
  return contents


Instruction:
Can you implement a function in Python 3 that
returns the base directory and index of files to generate.

Response:
def get_files(input_file):
  """
  Initializes an index of files to generate, returns the base
  directory and index.

  """
  file_index = {}
  base_dir = None
  if os.path.isfile(input_file):
    file_index[input_file] = None
    base_dir = os.path.dirname(input_file)
  elif os.path.isdir(input_file):
    base_dir = input_file
    for inf in glob.glob(input_file + s.SBP_EXTENSION):
      file_index[os.path.abspath(inf)] = None
    for inf in glob.glob(input_file + '/*'):
      base, index = get_files(os.path.abspath(inf))
      z = file_index.copy()
      z.update(index)
      file_index = z
  return (base_dir, file_index)


Instruction:
Can you implement a function in Python 3 that
gives a base directory and an initial set of files retrieves dependencies and adds them to the file_index.

Response:
def resolve_deps(base_dir, file_index):
  """
  Given a base directory and an initial set of files, retrieves
  dependencies and adds them to the file_index.

  """
  def flatten(tree, index = {}):
    for include in tree.get('include', []):
      fname = base_dir + "/" + include
      assert os.path.exists(fname), "File %s does not exist." % fname
      if fname not in index:
        index[fname] = read_spec(fname)
        index.update(flatten(index[fname], file_index))
    return index
  for fname, contents in file_index.items():
    file_index[fname] = read_spec(fname)
    file_index.update(flatten(file_index[fname], file_index))
  return file_index


Instruction:
Can you generate the documentation for the following Python 3 function
def mk_package(contents):
  package = contents.get('package', None)
  description = contents.get('description', None)
  include = contents.get('include', [])
  definitions = contents.get('definitions', [])
  resolved = [mk_definition(defn) for defn in definitions]
  return sbp.PackageSpecification(identifier=package,
                                  description=description,
                                  includes=include,
                                  definitions=resolved,
                                  render_source=contents.get('render_source', True),
                                  stable=contents.get('stable', False),
                                  public=contents.get('public', True))

Response:
Instantiates a package specification from a parsed AST of a
  package.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def mk_field(field):
  assert len(field) == 1
  identifier, contents = next(iter(field.items()))
  contents = dict(list({'units': '', 'n_with_values': 0}.items()) + list(contents.items()))
  return sbp.resolve_type(sbp.Field(identifier=identifier,
                                    type_id=contents.pop('type'),
                                    options=contents))

Response:
Instantiates a field specification from a parsed AST of a
 field.


Instruction:
Can you write a function in Python 3 where it
formats a global variable name.

Response:
def to_global(s):
  """
  Format a global variable name.
  """
  if s.startswith('GPSTime'):
    s = 'Gps' + s[3:]

  if '_' in s:
    s = "".join([i.capitalize() for i in s.split("_")])
  return s[0].lower() + s[1:]


Instruction:
Can you tell what is the following Python 3 function doing
def to_data(s):
  if s.startswith('GPSTime'):
    s = 'Gps' + s[3:]

  if '_' in s:
    return "".join([i.capitalize() for i in s.split("_")])
  return s

Response: Format a data variable name.


Instruction:
Explain what the following Python 3 code does
def to_type(f, type_map=CONSTRUCT_CODE):
  name = f.type_id
  if name.startswith('GPSTime'):
    name = 'Gps' + name[3:]
  if type_map.get(name, None):
    return type_map.get(name, None)
  elif name == 'array':
    fill = f.options['fill'].value
    f_ = copy.copy(f)
    f_.type_id = fill
    return "[%s]" % to_type(f_)
  return name

Response: Format a proper type.


Instruction:
Can you tell what is the following Python 3 function doing
def render_source(output_dir, package_spec):
  path, name = package_spec.filepath
  module_prefix = "SwiftNav.SBP"
  module_name = camel_case(name)
  full_module_name = ".".join([module_prefix, module_name])
  destination_filename = "%s/src/SwiftNav/SBP/%s.hs" % (output_dir, module_name)
  py_template = JENV.get_template(MESSAGES_TEMPLATE_NAME)
  module_includes = [".".join([module_prefix] + [camel_case(j) for j in i.split(".")[:-1]])
                     for i in package_spec.includes]

  with open(destination_filename, 'w') as f:
    f.write(py_template.render(msgs=package_spec.definitions,
                               description=package_spec.description,
                               module_name=full_module_name,
                               module_includes=module_includes))

Response: Render and output a file given a package specification.


Instruction:
Can you write a function in Python 3 where it
converts a string to a comment.

Response:
def to_comment(value):
  """
  Builds a comment.
  """
  if value is None:
    return
  if len(value.split('\n')) == 1:
    return "* " + value
  else:
    return '\n'.join([' * ' + l for l in value.split('\n')[:-1]])


Instruction:
How would you explain what the following Python 3 function does
def to_identifier(s):
  if s.startswith('GPS'):
      s = 'Gps' + s[3:]
  return ''.join([i.capitalize() for i in s.split('_')]) if '_' in s else s

Response: Convert snake_case to camel_case.


Instruction:
Write a Python 3 script to
render and output a single source file given a package specification.

Response:
def render_source(output_dir, package_spec):
    """
    Render and output to a directory given a package specification.
    """
    path, name = package_spec.filepath
    destination_filename = '%s/%s.proto' % (output_dir, name)
    pb_template = JENV.get_template(MESSAGES_TEMPLATE_NAME)
    includes = [include[:-5] if include.endswith('.yaml') else include for include in package_spec.includes]
    if 'types' in includes:
        includes.remove('types')
    with open(destination_filename, 'w') as f:
        f.write(pb_template.render(
            name=name,
            package=package_spec.identifier,
            messages=package_spec.definitions,
            includes=includes,
            description=package_spec.description,
        ))


Instruction:
Can you write a function in Python 3 where it
loads an app resource into a new container.

Response:
def load_app_resource(**kwargs):
    '''
    :param kwargs: keyword args for :func:`~dxpy.bindings.search.find_one_data_object`, with the exception of "project"
    :raises: :exc:`~dxpy.exceptions.DXError` if "project" is given, if this is called with dxpy.JOB_ID not set, or if "DX_RESOURCES_ID" or "DX_PROJECT_CONTEXT_ID" is not found in the environment variables
    :returns: None if no matching object is found; otherwise returns a dxpy object handler for that class of object

    Searches for a data object in the app resources container matching the given keyword arguments.  If found, the
    object will be cloned into the running job's workspace container, and the handler for it will be returned. If the
    app resources container ID is not found in DX_RESOURCES_ID, falls back to looking in the current project.

    Example::

        @dxpy.entry_point('main')
        def main(*args, **kwargs):
            x = load_app_resource(name="Indexed genome", classname='file')
            dxpy.download_dxfile(x)
    '''

    if 'project' in kwargs:
        raise DXError('Unexpected kwarg: "project"')
    if dxpy.JOB_ID is None:
        raise DXError('Not called by a job')
    if 'DX_RESOURCES_ID' not in os.environ and 'DX_PROJECT_CONTEXT_ID' not in os.environ:
        raise DXError('App resources container ID could not be found')

    kwargs['project'] = os.environ.get('DX_RESOURCES_ID', os.environ.get('DX_PROJECT_CONTEXT_ID'))
    kwargs['return_handler'] = True

    return find_one_data_object(**kwargs)


Instruction:
Here you have a function in Python 3, explain what it does
def load_from_cache(**kwargs):
    '''
    :param kwargs: keyword args for :func:`~dxpy.bindings.search.find_one_data_object`, with the exception of "project"
    :raises: :exc:`~dxpy.exceptions.DXError` if "project" is given, if this is called with dxpy.JOB_ID not set, or if "DX_PROJECT_CACHE_ID" is not found in the environment variables
    :returns: None if no matching object is found; otherwise returns a dxpy object handler for that class of object

    Searches for a data object in the project cache container matching
    the given keyword arguments.  If found, the object will be cloned
    into the running job's workspace container, and the handler for it
    will be returned.

    Example::

        @dxpy.entry_point('main')
        def main(*args, **kwargs):
            x = load_from_cache(name="Indexed genome", classname='file')
            if x is None:
                x = compute_result(*args)
                save_to_cache(x)
    '''

    if 'project' in kwargs:
        raise DXError('Unexpected kwarg: "project"')
    if dxpy.JOB_ID is None:
        raise DXError('Not called by a job')
    if 'DX_PROJECT_CACHE_ID' not in os.environ:
        raise DXError('Project cache ID could not be found in the environment variable DX_PROJECT_CACHE_ID')

    kwargs['project'] = os.environ.get('DX_PROJECT_CACHE_ID')
    kwargs['return_handler'] = True

    cached_object = find_one_data_object(**kwargs)

    if cached_object is None:
        return None

    return cached_object.clone(dxpy.WORKSPACE_ID)

Response: Loads a data object from the project cache container.


Instruction:
Implement a Python 3 function for
saving the given object to the project cache.

Response:
def save_to_cache(dxobject):
    '''
    :param dxobject: a dxpy object handler for an object to save to the cache
    :raises: :exc:`~dxpy.exceptions.DXError` if this is called with dxpy.JOB_ID not set, or if "DX_PROJECT_CACHE_ID" is not found in the environment variables

    Clones the given object to the project cache.

    Example::

        @dxpy.entry_point('main')
        def main(*args, **kwargs):
            x = load_from_cache(name="Indexed genome", classname='file')
            if x is None:
                x = compute_result(*args)
                save_to_cache(x)
    '''

    if dxpy.JOB_ID is None:
        raise DXError('Not called by a job')
    if 'DX_PROJECT_CACHE_ID' not in os.environ:
        raise DXError('Project cache ID could not be found in the environment variable DX_PROJECT_CACHE_ID')

    dxobject.clone(os.environ.get('DX_PROJECT_CACHE_ID'))


Instruction:
Explain what the following Python 3 code does
def _get_run_input_common_fields(executable_input, **kwargs):
        '''
        Takes the same arguments as the run method. Creates an input hash for the /executable-xxxx/run method,
        translating ONLY the fields that can be handled uniformly across all executables: project, folder, name, tags,
        properties, details, depends_on, allow_ssh, debug, delay_workspace_destruction, ignore_reuse, and extra_args.
        '''
        project = kwargs.get('project') or dxpy.WORKSPACE_ID

        run_input = {"input": executable_input}
        for arg in ['folder', 'name', 'tags', 'properties', 'details']:
            if kwargs.get(arg) is not None:
                run_input[arg] = kwargs[arg]

        if kwargs.get('instance_type') is not None or kwargs.get('cluster_spec') is not None:
            instance_type_srd = SystemRequirementsDict.from_instance_type(kwargs.get('instance_type'))
            cluster_spec_srd = SystemRequirementsDict(kwargs.get('cluster_spec'))
            run_input["systemRequirements"] = (instance_type_srd + cluster_spec_srd).as_dict()

        if kwargs.get('depends_on') is not None:
            run_input["dependsOn"] = []
            if isinstance(kwargs['depends_on'], list):
                for item in kwargs['depends_on']:
                    if isinstance(item, DXJob) or isinstance(item, DXDataObject):
                        if item.get_id() is None:
                            raise DXError('A dxpy handler given in depends_on does not have an ID set')
                        run_input["dependsOn"].append(item.get_id())
                    elif isinstance(item, basestring):
                        run_input['dependsOn'].append(item)
                    else:
                        raise DXError('Expected elements of depends_on to only be either instances of DXJob or DXDataObject, or strings')
            else:
                raise DXError('Expected depends_on field to be a list')

        if kwargs.get('delay_workspace_destruction') is not None:
            run_input["delayWorkspaceDestruction"] = kwargs['delay_workspace_destruction']

        if kwargs.get('allow_ssh') is not None:
            run_input["allowSSH"] = kwargs['allow_ssh']

        if kwargs.get('debug') is not None:
            run_input["debug"] = kwargs['debug']

        if kwargs.get('priority') is not None:
            run_input["priority"] = kwargs['priority']

        if kwargs.get('ignore_reuse') is not None:
            run_input["ignoreReuse"] = kwargs['ignore_reuse']

        if dxpy.JOB_ID is None:
            run_input["project"] = project

        if kwargs.get('extra_args') is not None:
            merge(run_input, kwargs['extra_args'])

        return run_input

Response: Returns the input hash for the run method.


Instruction:
Can you generate the documentation for the following Python 3 function
def _get_run_input_fields_for_applet(executable_input, **kwargs):
        '''
        Takes the same arguments as the run method. Creates an input
        hash for the /applet-xxxx/run method.
        '''
        # Although it says "for_applet", this is factored out of
        # DXApplet because apps currently use the same mechanism
        for unsupported_arg in ['stage_instance_types', 'stage_folders', 'rerun_stages', 'ignore_reuse_stages']:
            if kwargs.get(unsupported_arg):
                raise DXError(unsupported_arg + ' is not supported for applets (only workflows)')

        return DXExecutable._get_run_input_common_fields(executable_input, **kwargs)

Response: Returns the input fields needed to run an apple workflow.


Instruction:
Can you create a Python 3 function that
runs a new job in the execution tree.

Response:
def run(self, executable_input, project=None, folder=None, name=None, tags=None, properties=None, details=None,
            instance_type=None, stage_instance_types=None, stage_folders=None, rerun_stages=None, cluster_spec=None,
            depends_on=None, allow_ssh=None, debug=None, delay_workspace_destruction=None, priority=None,
            ignore_reuse=None, ignore_reuse_stages=None, extra_args=None, **kwargs):
        '''
        :param executable_input: Hash of the executable's input arguments
        :type executable_input: dict
        :param project: Project ID of the project context
        :type project: string
        :param folder: Folder in which executable's outputs will be placed in *project*
        :type folder: string
        :param name: Name for the new job (default is "<name of the executable>")
        :type name: string
        :param tags: Tags to associate with the job
        :type tags: list of strings
        :param properties: Properties to associate with the job
        :type properties: dict with string values
        :param details: Details to set for the job
        :type details: dict or list
        :param instance_type: Instance type on which the jobs will be run, or a dict mapping function names to instance type requests
        :type instance_type: string or dict
        :param depends_on: List of data objects or jobs to wait that need to enter the "closed" or "done" states, respectively, before the new job will be run; each element in the list can either be a dxpy handler or a string ID
        :type depends_on: list
        :param allow_ssh: List of hostname or IP masks to allow SSH connections from
        :type allow_ssh: list
        :param debug: Configuration options for job debugging
        :type debug: dict
        :param delay_workspace_destruction: Whether to keep the job's temporary workspace around for debugging purposes for 3 days after it succeeds or fails
        :type delay_workspace_destruction: boolean
        :param priority: Priority level to request for all jobs created in the execution tree, either "normal" or "high"
        :type priority: string
        :param ignore_reuse: Disable job reuse for this execution
        :type ignore_reuse: boolean
        :param ignore_reuse_stages: Stages of a workflow (IDs, names, or indices) or "*" for which job reuse should be disabled
        :type ignore_reuse_stages: list
        :param extra_args: If provided, a hash of options that will be merged into the underlying JSON given for the API call
        :type extra_args: dict
        :returns: Object handler of the newly created job
        :rtype: :class:`~dxpy.bindings.dxjob.DXJob`

        Creates a new job that executes the function "main" of this executable with
        the given input *executable_input*.

        '''
        # stage_instance_types, stage_folders, and rerun_stages are
        # only supported for workflows, but we include them
        # here. Applet-based executables should detect when they
        # receive a truthy workflow-specific value and raise an error.
        run_input = self._get_run_input(executable_input,
                                        project=project,
                                        folder=folder,
                                        name=name,
                                        tags=tags,
                                        properties=properties,
                                        details=details,
                                        instance_type=instance_type,
                                        stage_instance_types=stage_instance_types,
                                        stage_folders=stage_folders,
                                        rerun_stages=rerun_stages,
                                        cluster_spec=cluster_spec,
                                        depends_on=depends_on,
                                        allow_ssh=allow_ssh,
                                        ignore_reuse=ignore_reuse,
                                        ignore_reuse_stages=ignore_reuse_stages,
                                        debug=debug,
                                        delay_workspace_destruction=delay_workspace_destruction,
                                        priority=priority,
                                        extra_args=extra_args)

        return self._run_impl(run_input, **kwargs)


Instruction:
Implement a Python 3 function for
creating a new applet with the given hash and input specification.

Response:
def _new(self, dx_hash, **kwargs):
        '''
        :param dx_hash: Standard hash populated in :func:`dxpy.bindings.DXDataObject.new()` containing attributes common to all data object classes.
        :type dx_hash: dict
        :param runSpec: Run specification
        :type runSpec: dict
        :param dxapi: API version string
        :type dxapi: string
        :param inputSpec: Input specification (optional)
        :type inputSpec: dict
        :param outputSpec: Output specification (optional)
        :type outputSpec: dict
        :param access: Access specification (optional)
        :type access: dict
        :param title: Title string (optional)
        :type title: string
        :param summary: Summary string (optional)
        :type summary: string
        :param description: Description string (optional)
        :type description: string

        .. note:: It is highly recommended that the higher-level module
           :mod:`dxpy.app_builder` or (preferably) its frontend `dx build
           <https://wiki.dnanexus.com/Command-Line-Client/Index-of-dx-Commands#build>`_
           be used instead for applet creation.

        Creates an applet with the given parameters. See the API
        documentation for the `/applet/new
        <https://wiki.dnanexus.com/API-Specification-v1.0.0/Applets-and-Entry-Points#API-method:-/applet/new>`_
        method for more info. The applet is not run until :meth:`run()`
        is called.

        '''
        for field in 'runSpec', 'dxapi':
            if field not in kwargs:
                raise DXError("%s: Keyword argument %s is required" % (self.__class__.__name__, field))
            dx_hash[field] = kwargs[field]
            del kwargs[field]
        for field in 'inputSpec', 'outputSpec', 'access', 'title', 'summary', 'description':
            if field in kwargs:
                dx_hash[field] = kwargs[field]
                del kwargs[field]

        resp = dxpy.api.applet_new(dx_hash, **kwargs)
        self.set_ids(resp["id"], dx_hash["project"])


Instruction:
Can you tell what is the following Python 3 function doing
def run(self, applet_input, *args, **kwargs):
        # Rename applet_input arg to preserve API compatibility when calling
        # DXApplet.run(applet_input=...)
        return super(DXApplet, self).run(applet_input, *args, **kwargs)

Response: Creates a new applet with the given input applet_input.


Instruction:
Make a summary of the following Python 3 code
def set_env_from_args(args):
    ''' Sets the environment variables for this process from arguments (argparse.Namespace)
    and calls dxpy._initialize() to reset any values that it has already set.
    '''
    args = vars(args)

    if args.get('apiserver_host') is not None:
        config['DX_APISERVER_HOST'] = args['apiserver_host']
    if args.get('apiserver_port') is not None:
        config['DX_APISERVER_PORT'] = args['apiserver_port']
    if args.get('apiserver_protocol') is not None:
        config['DX_APISERVER_PROTOCOL'] = args['apiserver_protocol']
    if args.get('project_context_id') is not None:
        config['DX_PROJECT_CONTEXT_ID'] = args['project_context_id']
    if args.get('workspace_id') is not None:
        config['DX_WORKSPACE_ID'] = args['workspace_id']
    if args.get('cli_wd') is not None:
        config['DX_CLI_WD'] = args['cli_wd']
    if args.get('security_context') is not None:
        config['DX_SECURITY_CONTEXT'] = args['security_context']
    if args.get('auth_token') is not None:
        config['DX_SECURITY_CONTEXT'] = json.dumps({"auth_token": args['auth_token'],
                                                    "auth_token_type": "Bearer"})

Response: Sets the environment variables for this process from the given arguments.


Instruction:
Make a summary of the following Python 3 code
def validate_conf(asset_conf):
    if 'name' not in asset_conf:
        raise AssetBuilderException('The asset configuration does not contain the required field "name".')
    # TODO: this default is not a good idea, and we will have to remove it once we ask customers to always provide release
    if 'release' not in asset_conf:
        asset_conf['release'] = "12.04"
    elif asset_conf['release'] not in ['16.04', '14.04', '12.04']:
        raise AssetBuilderException('The "release" field value should be either "12.04" (DEPRECATED), "14.04", "16.04".')
    if 'version' not in asset_conf:
        raise AssetBuilderException('The asset configuration does not contain the required field "version". ')
    if 'title' not in asset_conf:
        raise AssetBuilderException('The asset configuration does not contain the required field "title". ')
    if 'description' not in asset_conf:
        raise AssetBuilderException('The asset configuration does not contain the required field "description".')
    if 'distribution' in asset_conf:
        if asset_conf['distribution'] != 'Ubuntu':
            raise AssetBuilderException('The distribution may only take the value "Ubuntu".')
    else:
        asset_conf['distribution'] = "Ubuntu"

Response: Validates the contents of the conf file and makes sure that the required information is provided.


Instruction:
Write a Python 3 function for
uploading an asset to the platform

Response:
def get_asset_tarball(asset_name, src_dir, dest_project, dest_folder, json_out):
    """
    If the src_dir contains a "resources" directory its contents are archived and
    the archived file is uploaded to the platform
    """
    if os.path.isdir(os.path.join(src_dir, "resources")):
        temp_dir = tempfile.mkdtemp()
        try:
            resource_file = os.path.join(temp_dir, asset_name + "_resources.tar.gz")
            cmd = ["tar", "-czf", resource_file, "-C", os.path.join(src_dir, "resources"), "."]
            subprocess.check_call(cmd)
            file_id = dx_upload(resource_file, dest_project, dest_folder, json_out)
            return file_id
        finally:
            shutil.rmtree(temp_dir)


Instruction:
Make a summary of the following Python 3 code
def pick(choices, default=None, str_choices=None, prompt=None, allow_mult=False, more_choices=False):
    '''
    :param choices: Strings between which the user will make a choice
    :type choices: list of strings
    :param default: Number the index to be used as the default
    :type default: int or None
    :param str_choices: Strings to be used as aliases for the choices; must be of the same length as choices and each string must be unique
    :type str_choices: list of strings
    :param prompt: A custom prompt to be used
    :type prompt: string
    :param allow_mult: Whether "*" is a valid option to select all choices
    :type allow_mult: boolean
    :param more_choices: Whether "m" is a valid option to ask for more options
    :type more_choices: boolean
    :returns: The user's choice, i.e. one of a numbered index of choices (e.g. 0 for the first item), "*" (only if allow_mult is True), or "m" (only if more_results is True)
    :rtype: int or string
    :raises: :exc:`EOFError` to signify quitting the process

    At most one of allow_mult and more_choices should be set to True.
    '''
    for i in range(len(choices)):
        prefix = str(i) + ') '
        lines = choices[i].split("\n")
        joiner = "\n" + " " * len(prefix)
        print(prefix + joiner.join(lines))
    if more_choices:
        print('m) More options not shown...')
    print('')
    if prompt is None:
        prompt = 'Pick a numbered choice'
        if allow_mult:
            prompt += ' or "*" for all'
        elif more_choices:
            prompt += ' or "m" for more options'
        if default is not None:
            prompt += ' [' + str(default) + ']'
        prompt += ': '
    while True:
        try:
            value = input(prompt)
        except KeyboardInterrupt:
            print('')
            raise
        except EOFError:
            print('')
            raise
        if default is not None and value == '':
            return default
        if allow_mult and value == '*':
            return value
        if more_choices and value == 'm':
            return value
        try:
            choice = str_choices.index(value)
            return choice
        except:
            pass
        try:
            choice = int(value)
            if choice not in range(len(choices)):
                raise IndexError()
            return choice
        except Exception:
            print('Not a valid selection')

Response: This function asks the user for a numbered choice from a list of strings.


Instruction:
Can you generate the documentation for the following Python 3 function
def object_exists_in_project(obj_id, proj_id):
    '''
    :param obj_id: object ID
    :type obj_id: str
    :param proj_id: project ID
    :type proj_id: str

    Returns True if the specified data object can be found in the specified
    project.
    '''
    if obj_id is None:
        raise ValueError("Expected obj_id to be a string")
    if proj_id is None:
        raise ValueError("Expected proj_id to be a string")
    if not is_container_id(proj_id):
        raise ValueError('Expected %r to be a container ID' % (proj_id,))
    return try_call(dxpy.DXHTTPRequest, '/' + obj_id + '/describe', {'project': proj_id})['project'] == proj_id

Response: Checks if the specified object exists in the specified project.


Instruction:
Implement a Python 3 function for
returning the index of the last occurrence of a character in a string where the character is not an escaped character.

Response:
def get_last_pos_of_char(char, string):
    '''
    :param char: The character to find
    :type char: string
    :param string: The string in which to search for *char*
    :type string: string
    :returns: Index in *string* where *char* last appears (unescaped by a preceding "\\"), -1 if not found
    :rtype: int

    Finds the last occurrence of *char* in *string* in which *char* is
    not present as an escaped character.

    '''
    pos = len(string)
    while pos > 0:
        pos = string[:pos].rfind(char)
        if pos == -1:
            return -1
        num_backslashes = 0
        test_index = pos - 1
        while test_index >= 0 and string[test_index] == '\\':
            num_backslashes += 1
            test_index -= 1
        if num_backslashes % 2 == 0:
            return pos
    return -1


Instruction:
Can you generate the documentation for the following Python 3 function
def get_first_pos_of_char(char, string):
    '''
    :param char: The character to find
    :type char: string
    :param string: The string in which to search for *char*
    :type string: string
    :returns: Index in *string* where *char* last appears (unescaped by a preceding "\\"), -1 if not found
    :rtype: int

    Finds the first occurrence of *char* in *string* in which *char* is
    not present as an escaped character.

    '''
    first_pos = -1
    pos = len(string)
    while pos > 0:
        pos = string[:pos].rfind(char)
        if pos == -1:
            return first_pos
        num_backslashes = 0
        test_index = pos - 1
        while test_index >= 0 and string[test_index] == '\\':
            num_backslashes += 1
            test_index -= 1
        if num_backslashes % 2 == 0:
            first_pos = pos
    return first_pos

Response: Returns the index of the first occurrence of a character in a string where the character is not an escaped character.


Instruction:
Create a Python 3 function to
split the string at the given character and returns a list of substrings of the string that are not empty.

Response:
def split_unescaped(char, string, include_empty_strings=False):
    '''
    :param char: The character on which to split the string
    :type char: string
    :param string: The string to split
    :type string: string
    :returns: List of substrings of *string*
    :rtype: list of strings

    Splits *string* whenever *char* appears without an odd number of
    backslashes ('\\') preceding it, discarding any empty string
    elements.

    '''
    words = []
    pos = len(string)
    lastpos = pos
    while pos >= 0:
        pos = get_last_pos_of_char(char, string[:lastpos])
        if pos >= 0:
            if pos + 1 != lastpos or include_empty_strings:
                words.append(string[pos + 1: lastpos])
            lastpos = pos
    if lastpos != 0 or include_empty_strings:
        words.append(string[:lastpos])
    words.reverse()
    return words


Instruction:
Can you implement a function in Python 3 that
cleans a folder path into a folder path and name and entity name.

Response:
def clean_folder_path(path, expected=None):
    '''
    :param path: A folder path to sanitize and parse
    :type path: string
    :param expected: Whether a folder ("folder"), a data object ("entity"), or either (None) is expected
    :type expected: string or None
    :returns: *folderpath*, *name*

    Unescape and parse *path* as a folder path to possibly an entity
    name.  Consecutive unescaped forward slashes "/" are collapsed to
    a single forward slash.  If *expected* is "folder", *name* is
    always returned as None.  Otherwise, the string to the right of
    the last unescaped "/" is considered a possible data object name
    and returned as such.

    '''
    folders = split_unescaped('/', path)

    if len(folders) == 0:
        return '/', None

    if expected == 'folder' or folders[-1] == '.' or folders[-1] == '..' or get_last_pos_of_char('/', path) == len(path) - 1:
        entity_name = None
    else:
        entity_name = unescape_name_str(folders.pop())

    sanitized_folders = []

    for folder in folders:
        if folder == '.':
            pass
        elif folder == '..':
            if len(sanitized_folders) > 0:
                sanitized_folders.pop()
        else:
            sanitized_folders.append(unescape_folder_str(folder))

    return ('/' + '/'.join(sanitized_folders)), entity_name


Instruction:
Create a Python 3 function to
resolve a container ID or name from a potential project or container ID.

Response:
def resolve_container_id_or_name(raw_string, is_error=False, multi=False):
    '''
    :param raw_string: A potential project or container ID or name
    :type raw_string: string
    :param is_error: Whether to raise an exception if the project or
            container ID cannot be resolved
    :type is_error: boolean
    :returns: Project or container ID if found or else None
    :rtype: string or None
    :raises: :exc:`ResolutionError` if *is_error* is True and the
            project or container could not be resolved

    Unescapes and attempts to resolve *raw_string* to a project or
    container ID.

    '''
    string = unescape_name_str(raw_string)
    if is_container_id(string):
        return ([string] if multi else string)

    if string in cached_project_names:
        return ([cached_project_names[string]] if multi else cached_project_names[string])

    try:
        results = list(dxpy.find_projects(name=string, describe=True, level='VIEW'))
    except Exception as details:
        raise ResolutionError(str(details))

    if len(results) == 1:
        cached_project_names[string] = results[0]['id']
        return ([results[0]['id']] if multi else results[0]['id'])
    elif len(results) == 0:
        if is_error:
            raise ResolutionError('Could not find a project named "' + string + '"')
        return ([] if multi else None)
    elif not multi:
        if INTERACTIVE_CLI:
            print('Found multiple projects with name "' + string + '"')
            choice = pick(['{id} ({level})'.format(id=result['id'], level=result['level'])
                           for result in results])
            return results[choice]['id']
        else:
            raise ResolutionError('Found multiple projects with name "' + string + '"; please use a project ID to specify the desired project')
    else:
        # len(results) > 1 and multi
        return [result['id'] for result in results]


Instruction:
Here you have a function in Python 3, explain what it does
def resolve_path(path, expected=None, multi_projects=False, allow_empty_string=True):
    '''
    :param path: A path to a data object to attempt to resolve
    :type path: string
    :param expected: one of the following: "folder", "entity", or None
            to indicate whether the expected path is a folder, a data
            object, or either
    :type expected: string or None
    :returns: A tuple of 3 values: container_ID, folderpath, entity_name
    :rtype: string, string, string
    :raises: exc:`ResolutionError` if the project cannot be resolved by
            name or the path is malformed
    :param allow_empty_string: If false, a ResolutionError will be
            raised if *path* is an empty string. Use this when resolving
            the empty string could result in unexpected behavior.
    :type allow_empty_string: boolean

    Attempts to resolve *path* to a project or container ID, a folder
    path, and a data object or folder name.  This method will NOT
    raise an exception if the specified folder or object does not
    exist.  This method is primarily for parsing purposes.

    Returns one of the following:

      (project, folder, maybe_name)
      where
        project is a container ID (non-null)
        folder is a folder path
        maybe_name is a string if the path could represent a folder or an object, or
        maybe_name is None if the path could only represent a folder

    OR

      (maybe_project, None, object_id)
      where
        maybe_project is a container ID or None
        object_id is a dataobject, app, or execution (specified by ID, not name)

    OR

      (job_id, None, output_name)
      where
        job_id and output_name are both non-null

    '''
    # TODO: callers that intend to obtain a data object probably won't be happy
    # with an app or execution ID. Callers should probably have to specify
    # whether they are okay with getting an execution ID or not.

    # TODO: callers that are looking for a place to write data, rather than
    # read it, probably won't be happy with receiving an object ID, or a
    # JBOR. Callers should probably specify whether they are looking for an
    # "LHS" expression or not.

    if '_DX_FUSE' in os.environ:
        from xattr import xattr
        path = xattr(path)['project'] + ":" + xattr(path)['id']

    if path == '' and not allow_empty_string:
        raise ResolutionError('Cannot parse ""; expected the path to be a non-empty string')
    path = _maybe_convert_stringified_dxlink(path)

    # Easy case: ":"
    if path == ':':
        if dxpy.WORKSPACE_ID is None:
            raise ResolutionError("Cannot resolve \":\": expected a project name or ID "
                                  "to the left of the colon, or for a current project to be set")
        return ([dxpy.WORKSPACE_ID] if multi_projects else dxpy.WORKSPACE_ID), '/', None
    # Second easy case: empty string
    if path == '':
        if dxpy.WORKSPACE_ID is None:
            raise ResolutionError('Expected a project name or ID to the left of a colon, '
                                  'or for a current project to be set')
        return ([dxpy.WORKSPACE_ID] if multi_projects else dxpy.WORKSPACE_ID), dxpy.config.get('DX_CLI_WD', '/'), None
    # Third easy case: hash ID
    if is_container_id(path):
        return ([path] if multi_projects else path), '/', None
    elif is_hashid(path):
        return ([dxpy.WORKSPACE_ID] if multi_projects else dxpy.WORKSPACE_ID), None, path

    # using a numerical sentinel value to indicate that it hasn't been
    # set in case dxpy.WORKSPACE_ID is actually None
    project = 0
    folderpath = None
    entity_name = None
    wd = dxpy.config.get('DX_CLI_WD', u'/')

    # Test for multiple colons
    last_colon = get_last_pos_of_char(':', path)
    if last_colon >= 0:
        last_last_colon = get_last_pos_of_char(':', path[:last_colon])
        if last_last_colon >= 0:
            raise ResolutionError('Cannot parse "' + path + '" as a path; at most one unescaped colon can be present')

    substrings = split_unescaped(':', path)

    if len(substrings) == 2:
        # One of the following:
        # 1) job-id:fieldname
        # 2) project-name-or-id:folderpath/to/possible/entity
        if is_job_id(substrings[0]):
            return ([substrings[0]] if multi_projects else substrings[0]), None, substrings[1]

        if multi_projects:
            project_ids = resolve_container_id_or_name(substrings[0], is_error=True, multi=True)
        else:
            project = resolve_container_id_or_name(substrings[0], is_error=True)
        wd = '/'
    elif get_last_pos_of_char(':', path) >= 0:
        # :folderpath/to/possible/entity OR project-name-or-id:
        # Colon is either at the beginning or at the end
        wd = '/'
        if path.startswith(':'):
            if dxpy.WORKSPACE_ID is None:
                raise ResolutionError('Cannot resolve "%s": expected a project name or ID to the left of the '
                                      'colon, or for a current project to be set' % (path,))
            project = dxpy.WORKSPACE_ID
        else:
            # One nonempty string to the left of a colon
            project = resolve_container_id_or_name(substrings[0], is_error=True)
            folderpath = '/'
    else:
        # One nonempty string, no colon present, do NOT interpret as
        # project
        project = dxpy.WORKSPACE_ID
        if project is None:
            raise ResolutionError('Cannot resolve "%s": expected the path to be qualified with a project name or ID, '
                                  'and a colon; or for a current project to be set' % (path,))

    # Determine folderpath and entity_name if necessary
    if folderpath is None:
        folderpath = substrings[-1]
        folderpath, entity_name = clean_folder_path(('' if folderpath.startswith('/') else wd + '/') + folderpath, expected)

    if multi_projects:
        return (project_ids if project == 0 else [project]), folderpath, entity_name
    else:
        return project, folderpath, entity_name

Response: Resolves a path to a container or a data object.


Instruction:
Here you have a function in Python 3, explain what it does
def _check_resolution_needed(path, project, folderpath, entity_name, expected_classes=None, describe=True,
                             enclose_in_list=False):
    """
    :param path: Path to the object that required resolution; propagated from
                 command-line
    :type path: string
    :param project: The potential project the entity belongs to
    :type project: string
    :param folderpath: Path to the entity
    :type folderpath: string
    :param entity_name: The name of the entity
    :type entity_name: string
    :param expected_classes: A list of expected classes the entity is allowed
                             to belong to if it is an ID (e.g. "record",
                             "file", "job"); if None, then entity_name may be
                             any data object class
    :type expected_classes: list or None
    :param describe: Dictionary of inputs to the describe API call; if
                     no describe input is provided (default value True), then
                     an empty mapping is passed to the describe API method
    :type describe: dict or True
    :param enclose_in_list: Whether the describe output is to be in the form
                            of a list (if False, the last return value is a
                            dictionary; if True, the last return value is a
                            list of one dictionary); it will only have an
                            effect if entity_name is a DX ID and is described
    :type enclose_in_list: boolean
    :returns: Whether or not the entity needs to be resolved with a more
              general resolution method, the project, the folderpath, and the
              entity name
    :rtype: tuple of 4 elements
    :raises: ResolutionError if the entity fails to be described

    Attempts to resolve the entity to a folder or an object, and describes
    the entity iff it is a DX ID of an expected class in the list
    expected_classes.
    Otherwise, determines whether or not more general resolution may be able
    to resolve the entity.

    If a more general resolution method is needed, then the return values will
    look like:
    (True, <project>, <folderpath>, <entity_name>)

    If the entity is a DX ID, but is not one of the supplied expected
    classes, then the return values will look like:
    (False, None, None, None)

    If the entity can be successfully described, then the return values will
    look like:
    <desc_output> ::= {"id": entity_name, "describe": {...}}
    <desc_or_desc_list> ::= <desc_output> || [<desc_output>]
    (False, <project>, <folderpath>, <desc_or_desc_list>)

    If the entity may be a folder, then the return values will look like:
    (False, <project>, <folderpath>, None)

    TODO: Allow arbitrary flags for the describe mapping.
    """
    if entity_name is None:
        # Definitely a folder (or project)
        # TODO: find a good way to check if folder exists and expected=folder
        return False, project, folderpath, None
    elif is_hashid(entity_name):

        found_valid_class = True
        if expected_classes is not None:
            found_valid_class = False
            for klass in expected_classes:
                if entity_name.startswith(klass):
                    found_valid_class = True
        if not found_valid_class:
            return False, None, None, None

        if describe is True:
            describe = {}

        # entity is an ID of a valid class, try to describe it
        if 'project' not in describe:
            if project != dxpy.WORKSPACE_ID:
                describe['project'] = project
            elif dxpy.WORKSPACE_ID is not None:
                describe['project'] = dxpy.WORKSPACE_ID
        try:
            desc = dxpy.DXHTTPRequest('/' + entity_name + '/describe', describe)
            desc = dxpy.append_underlying_workflow_describe(desc)
        except Exception as details:
            if 'project' in describe:
                # Now try it without the hint
                del describe['project']
                try:
                    desc = dxpy.DXHTTPRequest('/' + entity_name + '/describe', describe)
                except Exception as details2:
                    raise ResolutionError(str(details2))
            else:
                raise ResolutionError(str(details))
        result = {"id": entity_name, "describe": desc}
        if enclose_in_list:
            return False, project, folderpath, [result]
        else:
            return False, project, folderpath, result

    else:
        # Need to resolve later
        return True, project, folderpath, entity_name

Response: Checks if a more general resolution method is needed for the given entity.


Instruction:
Write a Python 3 script to
resolve a folder_name to a folder_name in the specified project.

Response:
def _resolve_folder(project, parent_folder, folder_name):
    """
    :param project: The project that the folder belongs to
    :type project: string
    :param parent_folder: Full path to the parent folder that contains
                         folder_name
    :type parent_folder: string
    :param folder_name: Name of the folder
    :type folder_name: string
    :returns: The path to folder_name, if it exists, in the form of
              "<parent_folder>/<folder_name>"
    :rtype: string
    :raises: ResolutionError if folder_name is not a folder, or if
             folder_name points to a folder that does not exist

    Attempts to resolve folder_name at location parent_folder in project.
    """
    if '/' in folder_name:
        # Then there's no way it's supposed to be a folder
        raise ResolutionError('Object of name ' + str(folder_name) + ' could not be resolved in folder ' +
                              str(parent_folder) + ' of project ID ' + str(project))
    possible_folder, _skip = clean_folder_path(parent_folder + '/' + folder_name, 'folder')

    if not check_folder_exists(project, parent_folder, folder_name):
        raise ResolutionError('Unable to resolve "' + folder_name +
                              '" to a data object or folder name in \'' + parent_folder + "'")
    return possible_folder


Instruction:
Can you tell what is the following Python 3 function doing
def _validate_resolution_output_length(path, entity_name, results, allow_mult=False, all_mult=False,
                                       ask_to_resolve=True):
    """
    :param path: Path to the object that required resolution; propagated from
                 command-line
    :type path: string
    :param entity_name: Name of the object
    :type entity_name: string
    :param results: Result of resolution; non-empty list of object
                    specifications (each specification is a dictionary with
                    keys "project" and "id")
    :type results: list of dictionaries
    :param allow_mult: If True, it is okay to choose from multiple results
                       of a single resolved object, or return all results
                       found; if False, raise an error if multiple results
                       are found
    :type allow_mult: boolean
    :param all_mult: If True, return all results if multiple results are
                     found for a single resolved object; if False, user needs
                     to choose a single result if multiple are found; the value
                     of all_mult only has an effect if allow_mult is True)
    :type all_mult: boolean
    :param ask_to_resolve: Whether picking may be necessary (if True, a
                           list is returned; if False, only one result
                           is returned); if specified as True, then all
                           results will be returned, regardless of the
                           values of allow_mult and all_mult
    :type ask_to_resolve: boolean
    :returns: The results of resolving entity_name, expected to be of the
              following form:
              <resolved_object>  # If only one result is present or the user
                                 # is able to select from multiple
              OR
              [<resolved_object>, ...]  # If multiple results are present and
                                        # it is allowed
              where <resolved_object> is of the following form:
              {"project": <project_id>, "id": <object_id>}
    :rtype: dict or list of dicts
    :raises: ValueError if results is empty
    :raises: ResolutionError if too many results are found and the user is
             not in interactive mode and cannot select one

    Precondition: results must be a nonempty list

    Validates length of results.

    If there are multiple results found and the user is in interactive mode,
    then the user will be prompted to select a single result to be returned.
    """
    if len(results) == 0:
        raise ValueError("'results' must be nonempty.")

    # Caller wants ALL results, so return the entire results list
    # At this point, do not care about the values of allow_mult or all_mult
    if not ask_to_resolve:
        return results

    if len(results) > 1:
        # The other way the caller can specify it wants all results is by setting
        # allow_mult to be True and allowing all_mult to be True (or if the object name is a glob pattern)
        if allow_mult and (all_mult or is_glob_pattern(entity_name)):
            return results
        if INTERACTIVE_CLI:
            print('The given path "' + path + '" resolves to the following data objects:')
            if any(['describe' not in result for result in results]):
                # findDataObject API call must be made to get 'describe' mappings
                project, folderpath, entity_name = resolve_path(path, expected='entity')
                results = _resolve_global_entity(project, folderpath, entity_name)
            choice = pick([get_ls_l_desc(result['describe']) for result in results],
                          allow_mult=allow_mult)
            if allow_mult and choice == '*':
                return results
            else:
                return [results[choice]] if allow_mult else results[choice]
        else:
            raise ResolutionError('The given path "' + path + '" resolves to ' +
                                  str(len(results)) + ' data objects')
    else:
        return [results[0]] if allow_mult else results[0]

Response: Validate the resolution output length of the object that is required by the user.


Instruction:
Make a summary of the following Python 3 code
def _resolve_global_entity(project_or_job_id, folderpath, entity_name, describe=True, visibility="either"):
    if is_job_id(project_or_job_id):
        if describe is True:
            describe = {}
        # The following function call will raise a ResolutionError if no results
        # could be found.
        # If the call is successful, then the project will be incorporated into the
        # "describe" mapping of the returned dictionaries.
        return resolve_job_ref(project_or_job_id, entity_name, describe=describe)
    else:
        try:
            return list(dxpy.find_data_objects(project=project_or_job_id,
                                               folder=folderpath,
                                               name=entity_name,
                                               name_mode='glob',
                                               recurse=False,
                                               describe=describe,
                                               visibility=visibility))
        except Exception as details:
            raise ResolutionError(str(details))

Response: Resolves a global entity.


Instruction:
Can you tell what is the following Python 3 function doing
def _format_resolution_output(path, project, folderpath, entity_name, result):
    try:
        if len(result) == 0:
            folder = _resolve_folder(project, folderpath, entity_name)
            return {"project": project, "folder": folder, "name": None}
        else:
            validated_results = _validate_resolution_output_length(path, entity_name, result)
            return {"project": None if is_job_id(project) else project,
                    "folder": None, "name": validated_results}
    except ResolutionError:
        return {"project": None, "folder": None, "name": None}

Response: Formats the resolution output of a single entity in the order they were resolved.


Instruction:
How would you explain what the following Python 3 function does
def resolve_multiple_existing_paths(paths):
    done_objects = {}  # Return value
    to_resolve_in_batch_paths = []  # Paths to resolve
    to_resolve_in_batch_inputs = []  # Project, folderpath, and entity name
    for path in paths:
        project, folderpath, entity_name = resolve_path(path, expected='entity')
        try:
            must_resolve, project, folderpath, entity_name = _check_resolution_needed(
                path, project, folderpath, entity_name)
        except:
            must_resolve = False

        if must_resolve:
            if is_glob_pattern(entity_name):
                # TODO: Must call findDataObjects because resolveDataObjects does not support glob patterns
                try:
                    find_results = _resolve_global_entity(project, folderpath, entity_name)
                    done_objects[path] = _format_resolution_output(path, project, folderpath, entity_name,
                                                                   find_results)
                except ResolutionError:
                    # Catches any ResolutionError thrown by _resolve_global_entity
                    done_objects[path] = {"project": None, "folder": None, "name": None}
            else:
                # Prepare batch call for resolveDataObjects
                to_resolve_in_batch_paths.append(path)
                to_resolve_in_batch_inputs.append({"project": project, "folder": folderpath, "name": entity_name})
        else:
            # No need to resolve
            done_objects[path] = {"project": project, "folder": folderpath, "name": entity_name}

    # Call resolveDataObjects
    resolution_results = dxpy.resolve_data_objects(to_resolve_in_batch_inputs)
    for path, inputs, result in zip(to_resolve_in_batch_paths, to_resolve_in_batch_inputs,
                                    resolution_results):
        done_objects[path] = _format_resolution_output(path, inputs["project"], inputs["folder"], inputs["name"],
                                                       result)
    return done_objects

Response: Resolves multiple paths in a single object or Nones.


Instruction:
How would you implement a function in Python 3 that
resolves an existing path to a list of results.

Response:
def resolve_existing_path(path, expected=None, ask_to_resolve=True, expected_classes=None, allow_mult=False,
                          describe=True, all_mult=False, allow_empty_string=True, visibility="either"):
    '''
    :param expected: one of the following: "folder", "entity", or None to indicate
                     whether the expected path is a folder, a data object, or either
    :type expected: string or None
    :param ask_to_resolve: Whether picking may be necessary (if true, a list is returned; if false, only one result is returned)
    :type ask_to_resolve: boolean
    :param expected_classes: A list of expected classes the entity is allowed
                             to belong to if it is an ID (e.g. "record",
                             "file", "job"); if None, then entity_name may be
                             any data object class
    :type expected_classes: list or None
    :param allow_mult: Whether to allow the user to select multiple results from the same path
    :type allow_mult: boolean
    :param describe: Input hash to describe call for the results, or True if no describe input
                     is to be provided
    :type describe: dict or True
    :param all_mult: Whether to return all matching results without prompting (only applicable if allow_mult == True)
    :type all_mult: boolean
    :returns: A LIST of results when ask_to_resolve is False or allow_mult is True
    :raises: :exc:`ResolutionError` if the request path was invalid, or a single result was requested and input is not a TTY
    :param allow_empty_string: If false, a ResolutionError will be raised if *path* is an empty string. Use this when resolving the empty string could result in unexpected behavior.
    :type allow_empty_string: boolean
    :param visibility: The visibility expected ("either", "hidden", or "visible")
    :type visibility: string

    Returns either a list of results or a single result (depending on
    how many is expected; if only one, then an interactive picking of
    a choice will be initiated if input is a tty, or else throw an error).

    TODO: Always treats the path as a glob pattern.

    Output is of the form {"id": id, "describe": describe hash} a list
    of those

    TODO: Callers should specify exactly what fields they want, and then
    hopefully we can avoid having a default set of fields that may be very
    expensive

    NOTE: if expected_classes is provided and conflicts with the class
    of the hash ID, it will return None for all fields.
    '''
    project, folderpath, entity_name = resolve_path(path, expected=expected, allow_empty_string=allow_empty_string)
    must_resolve, project, folderpath, entity_name = _check_resolution_needed(path,
                                                                              project,
                                                                              folderpath,
                                                                              entity_name,
                                                                              expected_classes=expected_classes,
                                                                              describe=describe,
                                                                              enclose_in_list=(not ask_to_resolve or
                                                                                allow_mult))

    if must_resolve:
        results = _resolve_global_entity(project, folderpath, entity_name, describe=describe, visibility=visibility)
        if len(results) == 0:
            # Could not resolve entity, so it is probably a folder
            folder = _resolve_folder(project, folderpath, entity_name)
            return project, folder, None
        else:
            validated_results = _validate_resolution_output_length(path,
                                                                   entity_name,
                                                                   results,
                                                                   allow_mult=allow_mult,
                                                                   all_mult=all_mult,
                                                                   ask_to_resolve=ask_to_resolve)
            if is_job_id(project):
                return None, None, validated_results
            return project, None, validated_results
    return project, folderpath, entity_name


Instruction:
Write a Python 3 function for
checking if a folder exists at the specified path.

Response:
def check_folder_exists(project, path, folder_name):
    '''
    :param project: project id
    :type project: string
    :param path: path to where we should look for the folder in question
    :type path: string
    :param folder_name: name of the folder in question
    :type folder_name: string
    :returns: A boolean True or False whether the folder exists at the specified path
    :type: boolean
    :raises: :exc:'ResolutionError' if dxpy.api.container_list_folder raises an exception

    This function returns a boolean value that indicates whether a folder of the
    specified name exists at the specified path

    Note: this function will NOT work on the root folder case, i.e. '/'
    '''
    if folder_name is None or path is None:
        return False
    try:
        folder_list = dxpy.api.container_list_folder(project, {"folder": path, "only": "folders"})
    except dxpy.exceptions.DXAPIError as e:
        if e.name == 'ResourceNotFound':
            raise ResolutionError(str(e.msg))
        else:
            raise e
    target_folder = path + '/' + folder_name
    # sanitize input if necessary
    target_folder, _skip = clean_folder_path(target_folder, 'folder')

    # Check that folder name exists in return from list folder API call
    return target_folder in folder_list['folders']


Instruction:
Create a Python 3 function for
trying to resolve to an app object and returns the describe hash of the app object if found otherwise None.

Response:
def get_app_from_path(path):
    '''
    :param path: A string to attempt to resolve to an app object
    :type path: string
    :returns: The describe hash of the app object if found, or None otherwise
    :rtype: dict or None

    This method parses a string that is expected to perhaps refer to
    an app object.  If found, its describe hash will be returned.  For
    more information on the contents of this hash, see the API
    documentation. [TODO: external link here]

    '''
    alias = None
    if not path.startswith('app-'):
        path = 'app-' + path
    if '/' in path:
        alias = path[path.find('/') + 1:]
        path = path[:path.find('/')]
    try:
        return dxpy.api.app_describe(path, alias=alias)
    except dxpy.DXAPIError:
        return None


Instruction:
Implement a Python 3 function for
trying to resolve a global workflow object from a path.

Response:
def get_global_workflow_from_path(path):
    '''
    :param path: A string to attempt to resolve to a global workflow object
    :type path: string
    :returns: The describe hash of the global workflow object if found, or None otherwise
    :rtype: dict or None

    This method parses a string that is expected to perhaps refer to
    a global workflow object.  If found, its describe hash will be returned.
    For more information on the contents of this hash, see the API
    documentation. [TODO: external link here]

    '''
    alias = None
    if not path.startswith('globalworkflow-'):
        path = 'globalworkflow-' + path
    if '/' in path:
        alias = path[path.find('/') + 1:]
        path = path[:path.find('/')]

    try:
        return dxpy.api.global_workflow_describe(path, alias=alias)
    except dxpy.DXAPIError:
        return None


Instruction:
Can you implement a function in Python 3 that
resolves a global executable.

Response:
def resolve_global_executable(path, is_version_required=False):
    """
    :param path: A string which is supposed to identify a global executable (app or workflow)
    :type path: string
    :param is_version_required: If set to True, the path has to specify a specific version/alias, e.g. "myapp/1.0.0"
    :type is_version_required: boolean
    :returns: The describe hash of the global executable object (app or workflow)
    :raises: :exc:`ResolutionError` if it cannot be found

    *path* is expected to have one of the following forms:

    - hash ID, e.g. "globalworkflow-F85Z6bQ0xku1PKY6FjGQ011J", "app-FBZ3f200yfzkKYyp9JkFVQ97"
    - named ID, e.g. "app-myapp", "globalworkflow-myworkflow"
    - named ID with alias (version or tag), e.g. "myapp/1.2.0", "myworkflow/1.2.0"
    - named ID with prefix and with alias (version or tag), e.g. "app-myapp/1.2.0", "globalworkflow-myworkflow/1.2.0"
    """
    if not is_hashid(path) and is_version_required and "/" not in path:
        raise ResolutionError('Version is required, e.g. "myexec/1.0.0"'.format())

    # First, check if the prefix is provided, then we don't have to resolve the name
    if path.startswith('app-'):
        return resolve_app(path)
    elif path.startswith('globalworkflow-'):
        return resolve_global_workflow(path)

    # If the path doesn't include a prefix, we must try describing
    # as an app and, if that fails, as a global workflow
    desc = get_app_from_path(path)
    if not desc:
        desc = get_global_workflow_from_path(path)
    if desc is None:
        raise ResolutionError(
            'The given path "' + path + '" could not be resolved to an accessible global executable (app or workflow)')
    return desc


Instruction:
How would you explain what the following Python 3 function does
def resolve_to_objects_or_project(path, all_matching_results=False):
    '''
    :param path: Path to resolve
    :type path: string
    :param all_matching_results: Whether to return a list of all matching results
    :type all_matching_results: boolean

    A thin wrapper over :meth:`resolve_existing_path` which throws an
    error if the path does not look like a project and doesn't match a
    data object path.

    Returns either a list of results or a single result (depending on
    how many is expected; if only one, then an interactive picking of
    a choice will be initiated if input is a tty, or else throw an error).
    '''
    # Attempt to resolve name
    project, folderpath, entity_results = resolve_existing_path(path,
                                                                expected='entity',
                                                                allow_mult=True,
                                                                all_mult=all_matching_results)
    if entity_results is None and not is_container_id(path):
        if folderpath != None and folderpath != '/':
            raise ResolutionError('Could not resolve "' + path + \
                                  '''" to an existing data object or to only a project;
                                  if you were attempting to refer to a project by name,
                                  please append a colon ":" to indicate that it is a project.''')
    return project, folderpath, entity_results

Response: Resolves a path to a data object or a project.


Instruction:
Write a Python 3 script for
creating a new job that will execute a particular function on the current applet.

Response:
def new_dxjob(fn_input, fn_name, name=None, tags=None, properties=None, details=None,
              instance_type=None, depends_on=None,
              **kwargs):
    '''
    :param fn_input: Function input
    :type fn_input: dict
    :param fn_name: Name of the function to be called
    :type fn_name: string
    :param name: Name for the new job (default is "<parent job name>:<fn_name>")
    :type name: string
    :param tags: Tags to associate with the job
    :type tags: list of strings
    :param properties: Properties to associate with the job
    :type properties: dict with string values
    :param details: Details to set for the job
    :type details: dict or list
    :param instance_type: Instance type on which the job will be run, or a dict mapping function names to instance type requests
    :type instance_type: string or dict
    :param depends_on: List of data objects or jobs to wait that need to enter the "closed" or "done" states, respectively, before the new job will be run; each element in the list can either be a dxpy handler or a string ID
    :type depends_on: list
    :rtype: :class:`~dxpy.bindings.dxjob.DXJob`

    Creates and enqueues a new job that will execute a particular
    function (from the same app or applet as the one the current job is
    running). Returns the :class:`~dxpy.bindings.dxjob.DXJob` handle for
    the job.

    Note that this function is shorthand for::

        dxjob = DXJob()
        dxjob.new(fn_input, fn_name, **kwargs)

    .. note:: This method is intended for calls made from within
       already-executing jobs or apps. If it is called from outside of
       an Execution Environment, an exception will be thrown. To create
       new jobs from outside the Execution Environment, use
       :func:`dxpy.bindings.dxapplet.DXApplet.run` or
       :func:`dxpy.bindings.dxapp.DXApp.run`.

    .. note:: If the environment variable ``DX_JOB_ID`` is not set, this method assmes that it is running within the debug harness, executes the job in place, and provides a debug job handler object that does not have a corresponding remote API job object.

    '''
    dxjob = DXJob()
    dxjob.new(fn_input, fn_name, name=name, tags=tags, properties=properties,
              details=details, instance_type=instance_type, depends_on=depends_on, **kwargs)
    return dxjob


Instruction:
How would you explain what the following Python 3 function does
def new(self, fn_input, fn_name, name=None, tags=None, properties=None, details=None,
            instance_type=None, depends_on=None,
            **kwargs):
        '''
        :param fn_input: Function input
        :type fn_input: dict
        :param fn_name: Name of the function to be called
        :type fn_name: string
        :param name: Name for the new job (default is "<parent job name>:<fn_name>")
        :type name: string
        :param tags: Tags to associate with the job
        :type tags: list of strings
        :param properties: Properties to associate with the job
        :type properties: dict with string values
        :param details: Details to set for the job
        :type details: dict or list
        :param instance_type: Instance type on which the job will be run, or a dict mapping function names to instance type requests
        :type instance_type: string or dict
        :param depends_on: List of data objects or jobs to wait that need to enter the "closed" or "done" states, respectively, before the new job will be run; each element in the list can either be a dxpy handler or a string ID
        :type depends_on: list

        Creates and enqueues a new job that will execute a particular
        function (from the same app or applet as the one the current job
        is running).

        .. note:: This method is intended for calls made from within
           already-executing jobs or apps. If it is called from outside
           of an Execution Environment, an exception will be thrown. To
           create new jobs from outside the Execution Environment, use
           :func:`dxpy.bindings.dxapplet.DXApplet.run` or
           :func:`dxpy.bindings.dxapp.DXApp.run`.

        '''
        final_depends_on = []
        if depends_on is not None:
            if isinstance(depends_on, list):
                for item in depends_on:
                    if isinstance(item, DXJob) or isinstance(item, DXDataObject):
                        if item.get_id() is None:
                            raise DXError('A dxpy handler given in depends_on does not have an ID set')
                        final_depends_on.append(item.get_id())
                    elif isinstance(item, basestring):
                        final_depends_on.append(item)
                    else:
                        raise DXError('Expected elements of depends_on to only be either instances of DXJob or DXDataObject, or strings')
            else:
                raise DXError('Expected depends_on field to be a list')

        if 'DX_JOB_ID' in os.environ:
            req_input = {}
            req_input["input"] = fn_input
            req_input["function"] = fn_name
            if name is not None:
                req_input["name"] = name
            if tags is not None:
                req_input["tags"] = tags
            if properties is not None:
                req_input["properties"] = properties
            if instance_type is not None:
                req_input["systemRequirements"] = SystemRequirementsDict.from_instance_type(instance_type, fn_name).as_dict()
            if depends_on is not None:
                req_input["dependsOn"] = final_depends_on
            if details is not None:
                req_input["details"] = details
            resp = dxpy.api.job_new(req_input, **kwargs)
            self.set_id(resp["id"])
        else:
            self.set_id(queue_entry_point(function=fn_name, input_hash=fn_input,
                                          depends_on=final_depends_on,
                                          name=name))

Response: Creates a new job with the given parameters.


Instruction:
Given the following Python 3 function, write the documentation
def set_id(self, dxid):
        '''
        :param dxid: New job ID to be associated with the handler (localjob IDs also accepted for local runs)
        :type dxid: string

        Discards the currently stored ID and associates the handler with *dxid*
        '''
        if dxid is not None:
            if not (isinstance(dxid, basestring) and dxid.startswith('localjob-')):
                # localjob IDs (which do not follow the usual ID
                # syntax) should be allowed; otherwise, follow the
                # usual syntax checking
                verify_string_dxid(dxid, self._class)
        self._dxid = dxid

Response: Sets the ID of the currently stored handler.


Instruction:
Here you have a function in Python 3, explain what it does
def describe(self, fields=None, io=None, **kwargs):
        if fields is not None and io is not None:
            raise DXError('DXJob.describe: cannot provide non-None values for both fields and io')
        describe_input = {}
        if fields is not None:
            describe_input['fields'] = fields
        if io is not None:
            describe_input['io'] = io
        self._desc = dxpy.api.job_describe(self._dxid, describe_input, **kwargs)
        return self._desc

Response: Returns a dictionary containing information about the job and its related entries.


Instruction:
Create a Python 3 function for
adding each of the specified tags to the job.

Response:
def add_tags(self, tags, **kwargs):
        """
        :param tags: Tags to add to the job
        :type tags: list of strings

        Adds each of the specified tags to the job. Takes no
        action for tags that are already listed for the job.

        """

        dxpy.api.job_add_tags(self._dxid, {"tags": tags}, **kwargs)


Instruction:
Can you tell what is the following Python 3 function doing
def remove_tags(self, tags, **kwargs):

        dxpy.api.job_remove_tags(self._dxid, {"tags": tags}, **kwargs)

Response: Removes the specified tags from the job.


Instruction:
Make a summary of the following Python 3 code
def set_properties(self, properties, **kwargs):

        dxpy.api.job_set_properties(self._dxid, {"properties": properties}, **kwargs)

Response: Sets the properties of the job for the given key - value pairs.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def wait_on_done(self, interval=2, timeout=3600*24*7, **kwargs):
        '''
        :param interval: Number of seconds between queries to the job's state
        :type interval: integer
        :param timeout: Maximum amount of time to wait, in seconds, until the job is done running
        :type timeout: integer
        :raises: :exc:`~dxpy.exceptions.DXError` if the timeout is reached before the job has finished running, or :exc:`dxpy.exceptions.DXJobFailureError` if the job fails

        Waits until the job has finished running.
        '''

        elapsed = 0
        while True:
            state = self._get_state(**kwargs)
            if state == "done":
                break
            if state == "failed":
                desc = self.describe(**kwargs)
                err_msg = "Job has failed because of {failureReason}: {failureMessage}".format(**desc)
                if desc.get("failureFrom") != None and desc["failureFrom"]["id"] != desc["id"]:
                    err_msg += " (failure from {id})".format(id=desc['failureFrom']['id'])
                raise DXJobFailureError(err_msg)
            if state == "terminated":
                raise DXJobFailureError("Job was terminated.")

            if elapsed >= timeout or elapsed < 0:
                raise DXJobFailureError("Reached timeout while waiting for the job to finish")

            time.sleep(interval)
            elapsed += interval

Response: Waits until the job is done.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _get_state(self, **kwargs):
        '''
        :returns: State of the remote object
        :rtype: string

        Queries the API server for the job's state.

        Note that this function is shorthand for:

            dxjob.describe(io=False, **kwargs)["state"]

        '''

        return self.describe(fields=dict(state=True), **kwargs)["state"]

Response: Returns the state of the remote object in the format that is expected by the API server.


Instruction:
How would you explain what the following Python 3 function does
def get_user_id(user_id_or_username):
    user_id_or_username = user_id_or_username.lower()
    if not user_id_or_username.startswith("user-"):
        user_id = "user-" + user_id_or_username.lower()
    else:
        user_id = user_id_or_username
    return user_id

Response: Gets the user ID based on the value specified on the command - line.


Instruction:
Can you tell what is the following Python 3 function doing
def get_org_invite_args(user_id, args):
    org_invite_args = {"invitee": user_id}
    org_invite_args["level"] = args.level
    if "set_bill_to" in args and args.set_bill_to is True:
        # /org-x/invite is called in conjunction with /user/new.
        org_invite_args["allowBillableActivities"] = True
    else:
        org_invite_args["allowBillableActivities"] = args.allow_billable_activities
    org_invite_args["appAccess"] = args.app_access
    org_invite_args["projectAccess"] = args.project_access
    org_invite_args["suppressEmailNotification"] = args.no_email
    return org_invite_args

Response: Returns the arguments to pass to the org - x invite command.


Instruction:
Create a Python 3 function to
get the user new arguments.

Response:
def _get_user_new_args(args):
    """
    PRECONDITION: `_validate_new_user_input()` has been called on `args`.
    """
    user_new_args = {"username": args.username,
                     "email": args.email}
    if args.first is not None:
        user_new_args["first"] = args.first
    if args.last is not None:
        user_new_args["last"] = args.last
    if args.middle is not None:
        user_new_args["middle"] = args.middle
    if args.token_duration is not None:
        token_duration_ms = normalize_timedelta(args.token_duration)
        if token_duration_ms > 30 * 24 * 60 * 60 * 1000:
            raise ValueError("--token-duration must be 30 days or less")
        else:
            user_new_args["tokenDuration"] = token_duration_ms
    if args.occupation is not None:
        user_new_args["occupation"] = args.occupation
    if args.set_bill_to is True:
        user_new_args["billTo"] = args.org
    return user_new_args


Instruction:
Can you tell what is the following Python 3 function doing
def _get_input_for_run(args, executable, preset_inputs=None, input_name_prefix=None):
    # The following may throw if the executable is a workflow with no
    # input spec available (because a stage is inaccessible)
    exec_inputs = try_call(ExecutableInputs,
                           executable,
                           input_name_prefix=input_name_prefix,
                           active_region=args.region)

    # Use input and system requirements from a cloned execution
    if args.input_json is None and args.filename is None:
        # --input-json and --input-json-file completely override input
        # from the cloned job
        exec_inputs.update(args.input_from_clone, strip_prefix=False)

    # Update with inputs passed to the this function
    if preset_inputs is not None:
        exec_inputs.update(preset_inputs, strip_prefix=False)

    # Update with inputs passed with -i, --input_json, --input_json_file, etc.
    # If batch_tsv is set, do not prompt for missing arguments
    require_all_inputs = (args.batch_tsv is None)
    try_call(exec_inputs.update_from_args, args, require_all_inputs)

    return exec_inputs.inputs

Response: Returns an input dictionary that can be passed to the executable. run method.


Instruction:
Here you have a function in Python 3, explain what it does
def register_parser(parser, subparsers_action=None, categories=('other', ), add_help=True):
    name = re.sub('^dx ', '', parser.prog)
    if subparsers_action is None:
        subparsers_action = subparsers
    if isinstance(categories, basestring):
        categories = (categories, )

    parser_map[name] = parser
    if add_help:
        _help = subparsers_action._choices_actions[-1].help
        parser_categories['all']['cmds'].append((name, _help))
        for category in categories:
            parser_categories[category]['cmds'].append((name, _help))

Response: Register a parser with the global parser_map.


Instruction:
Create a Python 3 function for
returning True if the exception is always safe to retry.

Response:
def _is_retryable_exception(e):
    """Returns True if the exception is always safe to retry.

    This is True if the client was never able to establish a connection
    to the server (for example, name resolution failed or the connection
    could otherwise not be initialized).

    Conservatively, if we can't tell whether a network connection could
    have been established, we return False.

    """
    if isinstance(e, urllib3.exceptions.ProtocolError):
        e = e.args[1]
    if isinstance(e, (socket.gaierror, socket.herror)):
        return True
    if isinstance(e, socket.error) and e.errno in _RETRYABLE_SOCKET_ERRORS:
        return True
    if isinstance(e, urllib3.exceptions.NewConnectionError):
        return True
    return False


Instruction:
Can you tell what is the following Python 3 function doing
def _extract_msg_from_last_exception():
    ''' Extract a useful error message from the last thrown exception '''
    last_exc_type, last_error, last_traceback = sys.exc_info()
    if isinstance(last_error, exceptions.DXAPIError):
        # Using the same code path as below would not
        # produce a useful message when the error contains a
        # 'details' hash (which would have a last line of
        # '}')
        return last_error.error_message()
    else:
        return traceback.format_exc().splitlines()[-1].strip()

Response: Extract a useful error message from the last thrown exception.


Instruction:
Write a Python 3 script for
calculating the delay that we should wait for a resource to be retried.

Response:
def _calculate_retry_delay(response, num_attempts):
    '''
    Returns the time in seconds that we should wait.

    :param num_attempts: number of attempts that have been made to the
        resource, including the most recent failed one
    :type num_attempts: int
    '''
    if response is not None and response.status == 503 and 'retry-after' in response.headers:
        try:
            return int(response.headers['retry-after'])
        except ValueError:
            # In RFC 2616, retry-after can be formatted as absolute time
            # instead of seconds to wait. We don't bother to parse that,
            # but the apiserver doesn't generate such responses anyway.
            pass
    if num_attempts <= 1:
        return 1
    num_attempts = min(num_attempts, 7)
    return randint(2 ** (num_attempts - 2), 2 ** (num_attempts - 1))