Instruction:
Can you generate a brief explanation for the following Python 3 code
def DXHTTPRequest(resource, data, method='POST', headers=None, auth=True,
                  timeout=DEFAULT_TIMEOUT,
                  use_compression=None, jsonify_data=True, want_full_response=False,
                  decode_response_body=True, prepend_srv=True, session_handler=None,
                  max_retries=DEFAULT_RETRIES, always_retry=False,
                  **kwargs):
    '''
    :param resource: API server route, e.g. "/record/new". If *prepend_srv* is False, a fully qualified URL is expected. If this argument is a callable, it will be called just before each request attempt, and expected to return a tuple (URL, headers). Headers returned by the callback are updated with *headers* (including headers set by this method).
    :type resource: string
    :param data: Content of the request body
    :type data: list or dict, if *jsonify_data* is True; or string or file-like object, otherwise
    :param headers: Names and values of HTTP headers to submit with the request (in addition to those needed for authentication, compression, or other options specified with the call).
    :type headers: dict
    :param auth:
        Controls the ``Authentication`` header or other means of authentication supplied with the request. If ``True``
        (default), a token is obtained from the ``DX_SECURITY_CONTEXT``. If the value evaluates to false, no action is
        taken to prepare authentication for the request. Otherwise, the value is assumed to be callable, and called with
        three arguments (method, url, headers) and expected to prepare the authentication headers by reference.
    :type auth: tuple, object, True (default), or None
    :param timeout: HTTP request timeout, in seconds
    :type timeout: float
    :param config: *config* value to pass through to :meth:`requests.request`
    :type config: dict
    :param use_compression: Deprecated
    :type use_compression: string or None
    :param jsonify_data: If True, *data* is converted from a Python list or dict to a JSON string
    :type jsonify_data: boolean
    :param want_full_response: If True, the full :class:`requests.Response` object is returned (otherwise, only the content of the response body is returned)
    :type want_full_response: boolean
    :param decode_response_body: If True (and *want_full_response* is False), the response body is decoded and, if it is a JSON string, deserialized. Otherwise, the response body is uncompressed if transport compression is on, and returned raw.
    :type decode_response_body: boolean
    :param prepend_srv: If True, prepends the API server location to the URL
    :type prepend_srv: boolean
    :param session_handler: Deprecated.
    :param max_retries: Maximum number of retries to perform for a request. A "failed" request is retried if any of the following is true:

                        - A response is received from the server, and the content length received does not match the "Content-Length" header.
                        - A response is received from the server, and the response has an HTTP status code in 5xx range.
                        - A response is received from the server, the "Content-Length" header is not set, and the response JSON cannot be parsed.
                        - No response is received from the server, and either *always_retry* is True or the request *method* is "GET".

    :type max_retries: int
    :param always_retry: If True, indicates that it is safe to retry a request on failure

                        - Note: It is not guaranteed that the request will *always* be retried on failure; rather, this is an indication to the function that it would be safe to do so.

    :type always_retry: boolean
    :returns: Response from API server in the format indicated by *want_full_response* and *decode_response_body*.
    :raises: :exc:`exceptions.DXAPIError` or a subclass if the server returned a non-200 status code; :exc:`requests.exceptions.HTTPError` if an invalid response was received from the server; or :exc:`requests.exceptions.ConnectionError` if a connection cannot be established.

    Wrapper around :meth:`requests.request()` that makes an HTTP
    request, inserting authentication headers and (by default)
    converting *data* to JSON.

    .. note:: Bindings methods that make API calls make the underlying
       HTTP request(s) using :func:`DXHTTPRequest`, and most of them
       will pass any unrecognized keyword arguments you have supplied
       through to :func:`DXHTTPRequest`.

    '''
    if headers is None:
        headers = {}

    global _UPGRADE_NOTIFY

    seq_num = _get_sequence_number()

    url = APISERVER + resource if prepend_srv else resource
    method = method.upper()  # Convert method name to uppercase, to ease string comparisons later

    if auth is True:
        auth = AUTH_HELPER

    if auth:
        auth(_RequestForAuth(method, url, headers))

    pool_args = {arg: kwargs.pop(arg, None) for arg in ("verify", "cert_file", "key_file")}
    test_retry = kwargs.pop("_test_retry_http_request", False)

    # data is a sequence/buffer or a dict
    # serialized_data is a sequence/buffer

    if jsonify_data:
        serialized_data = json.dumps(data)
        if 'Content-Type' not in headers and method == 'POST':
            headers['Content-Type'] = 'application/json'
    else:
        serialized_data = data

    # If the input is a buffer, its data gets consumed by
    # requests.request (moving the read position). Record the initial
    # buffer position so that we can return to it if the request fails
    # and needs to be retried.
    rewind_input_buffer_offset = None
    if hasattr(data, 'seek') and hasattr(data, 'tell'):
        rewind_input_buffer_offset = data.tell()

    # Maintain two separate counters for the number of tries...

    try_index = 0  # excluding 503 errors. The number of tries as given here
                   # cannot exceed (max_retries + 1).
    try_index_including_503 = 0  # including 503 errors. This number is used to
                                 # do exponential backoff.

    retried_responses = []
    _url = None
    while True:
        success, time_started = True, None
        response = None
        req_id = None
        try:
            time_started = time.time()
            _method, _url, _headers = _process_method_url_headers(method, url, headers)

            _debug_print_request(_DEBUG, seq_num, time_started, _method, _url, _headers, jsonify_data, data)

            body = _maybe_truncate_request(_url, serialized_data)

            # throws BadStatusLine if the server returns nothing
            try:
                pool_manager = _get_pool_manager(**pool_args)

                _headers['User-Agent'] = USER_AGENT
                _headers['DNAnexus-API'] = API_VERSION

                # Converted Unicode headers to ASCII and throw an error if not possible
                def ensure_ascii(i):
                    if not isinstance(i, bytes):
                        i = i.encode('ascii')
                    return i

                _headers = {ensure_ascii(k): ensure_ascii(v) for k, v in _headers.items()}
                if USING_PYTHON2:
                    encoded_url = _url
                else:
                    # This is needed for python 3 urllib
                    _headers.pop(b'host', None)
                    _headers.pop(b'content-length', None)

                    # The libraries downstream (http client) require elimination of non-ascii
                    # chars from URL.
                    # We check if the URL contains non-ascii characters to see if we need to
                    # quote it. It is important not to always quote the path (here: parts[2])
                    # since it might contain elements (e.g. HMAC for api proxy) containing
                    # special characters that should not be quoted.
                    try:
                        ensure_ascii(_url)
                        encoded_url = _url
                    except UnicodeEncodeError:
                        import urllib.parse
                        parts = list(urllib.parse.urlparse(_url))
                        parts[2] = urllib.parse.quote(parts[2])
                        encoded_url = urllib.parse.urlunparse(parts)

                response = pool_manager.request(_method, encoded_url, headers=_headers, body=body,
                                                timeout=timeout, retries=False, **kwargs)

            except urllib3.exceptions.ClosedPoolError:
                # If another thread closed the pool before the request was
                # started, will throw ClosedPoolError
                raise exceptions.UrllibInternalError("ClosedPoolError")

            _raise_error_for_testing(try_index, method)
            req_id = response.headers.get("x-request-id", "unavailable")

            if (_UPGRADE_NOTIFY
               and response.headers.get('x-upgrade-info', '').startswith('A recommended update is available')
               and '_ARGCOMPLETE' not in os.environ):
                logger.info(response.headers['x-upgrade-info'])
                try:
                    with file(_UPGRADE_NOTIFY, 'a'):
                        os.utime(_UPGRADE_NOTIFY, None)
                except:
                    pass
                _UPGRADE_NOTIFY = False

            # If an HTTP code that is not in the 200 series is received and the content is JSON, parse it and throw the
            # appropriate error.  Otherwise, raise the usual exception.
            if response.status // 100 != 2:
                # response.headers key lookup is case-insensitive
                if response.headers.get('content-type', '').startswith('application/json'):
                    try:
                        content = response.data.decode('utf-8')
                    except AttributeError:
                        raise exceptions.UrllibInternalError("Content is none", response.status)
                    try:
                        content = json.loads(content)
                    except ValueError:
                        # The JSON is not parsable, but we should be able to retry.
                        raise exceptions.BadJSONInReply("Invalid JSON received from server", response.status)
                    try:
                        error_class = getattr(exceptions, content["error"]["type"], exceptions.DXAPIError)
                    except (KeyError, AttributeError, TypeError):
                        raise exceptions.HTTPError(response.status, content)
                    raise error_class(content, response.status, time_started, req_id)
                else:
                    try:
                        content = response.data.decode('utf-8')
                    except AttributeError:
                        raise exceptions.UrllibInternalError("Content is none", response.status)
                    raise exceptions.HTTPError("{} {} [Time={} RequestID={}]\n{}".format(response.status,
                                                                                response.reason,
                                                                                time_started,
                                                                                req_id,
                                                                                content))

            if want_full_response:
                return response
            else:
                if 'content-length' in response.headers:
                    if int(response.headers['content-length']) != len(response.data):
                        range_str = (' (%s)' % (headers['Range'],)) if 'Range' in headers else ''
                        raise exceptions.ContentLengthError(
                            "Received response with content-length header set to %s but content length is %d%s. " +
                            "[Time=%f RequestID=%s]" %
                            (response.headers['content-length'], len(response.data), range_str, time_started, req_id)
                        )

                content = response.data

                response_was_json = False

                if decode_response_body:
                    content = content.decode('utf-8')
                    if response.headers.get('content-type', '').startswith('application/json'):
                        try:
                            content = json.loads(content)
                        except ValueError:
                            # The JSON is not parsable, but we should be able to retry.
                            raise exceptions.BadJSONInReply("Invalid JSON received from server", response.status)
                        else:
                            response_was_json = True

                req_id = response.headers.get('x-request-id') or "--"

                _debug_print_response(_DEBUG, seq_num, time_started, req_id, response.status, response_was_json,
                                      _method, _url, content)

                if test_retry:
                    retried_responses.append(content)
                    if len(retried_responses) == 1:
                        continue
                    else:
                        _set_retry_response(retried_responses[0])
                        return retried_responses[1]

                return content
            raise AssertionError('Should never reach this line: expected a result to have been returned by now')
        except Exception as e:
            # Avoid reusing connections in the pool, since they may be
            # in an inconsistent state (observed as "ResponseNotReady"
            # errors).
            _get_pool_manager(**pool_args).clear()
            success = False
            exception_msg = _extract_msg_from_last_exception()
            if isinstance(e, _expected_exceptions):
                # Total number of allowed tries is the initial try PLUS
                # up to (max_retries) subsequent retries.
                total_allowed_tries = max_retries + 1
                ok_to_retry = False
                is_retryable = always_retry or (method == 'GET') or _is_retryable_exception(e)
                # Because try_index is not incremented until we escape
                # this iteration of the loop, try_index is equal to the
                # number of tries that have failed so far, minus one.
                if try_index + 1 < total_allowed_tries:
                    # BadStatusLine ---  server did not return anything
                    # BadJSONInReply --- server returned JSON that didn't parse properly
                    if (response is None
                       or isinstance(e, (exceptions.ContentLengthError, BadStatusLine, exceptions.BadJSONInReply,
                                         urllib3.exceptions.ProtocolError, exceptions.UrllibInternalError))):
                        ok_to_retry = is_retryable
                    else:
                        ok_to_retry = 500 <= response.status < 600

                    # The server has closed the connection prematurely
                    if (response is not None
                       and response.status == 400 and is_retryable and method == 'PUT'
                       and isinstance(e, requests.exceptions.HTTPError)):
                        if 'RequestTimeout' in exception_msg:
                            logger.info("Retrying 400 HTTP error, due to slow data transfer. " +
                                        "Request Time=%f Request ID=%s", time_started, req_id)
                        else:
                            logger.info("400 HTTP error, of unknown origin, exception_msg=[%s]. " +
                                        "Request Time=%f Request ID=%s", exception_msg, time_started, req_id)
                        ok_to_retry = True

                    # Unprocessable entity, request has semantical errors
                    if response is not None and response.status == 422:
                        ok_to_retry = False

                if ok_to_retry:
                    if rewind_input_buffer_offset is not None:
                        data.seek(rewind_input_buffer_offset)

                    delay = _calculate_retry_delay(response, try_index_including_503 + 1)

                    range_str = (' (range=%s)' % (headers['Range'],)) if 'Range' in headers else ''
                    if response is not None and response.status == 503:
                        waiting_msg = 'Waiting %d seconds before retry...' % (delay,)
                    else:
                        waiting_msg = 'Waiting %d seconds before retry %d of %d...' % (
                            delay, try_index + 1, max_retries)

                    logger.warning("[%s] %s %s: %s. %s %s",
                                   time.ctime(), method, _url, exception_msg, waiting_msg, range_str)
                    time.sleep(delay)
                    try_index_including_503 += 1
                    if response is None or response.status != 503:
                        try_index += 1
                    continue

            # All retries have been exhausted OR the error is deemed not
            # retryable. Print the latest error and propagate it back to the caller.
            if not isinstance(e, exceptions.DXAPIError):
                logger.error("[%s] %s %s: %s.", time.ctime(), method, _url, exception_msg)

            if isinstance(e, urllib3.exceptions.ProtocolError) and \
                'Connection reset by peer' in exception_msg:
                # If the protocol error is 'connection reset by peer', most likely it is an
                # error in the ssl handshake due to unsupported TLS protocol.
                _test_tls_version()

            # Retries have been exhausted, and we are unable to get a full
            # buffer from the data source. Raise a special exception.
            if isinstance(e, urllib3.exceptions.ProtocolError) and \
               'Connection broken: IncompleteRead' in exception_msg:
                raise exceptions.DXIncompleteReadsError(exception_msg)
            raise
        finally:
            if success and try_index > 0:
                logger.info("[%s] %s %s: Recovered after %d retries", time.ctime(), method, _url, try_index)

        raise AssertionError('Should never reach this line: should have attempted a retry or reraised by now')
    raise AssertionError('Should never reach this line: should never break out of loop')

Response: A basic HTTP request.


Instruction:
Write a Python 3 function that can
set the API server info for the current node.

Response:
def set_api_server_info(host=None, port=None, protocol=None):
    '''
    :param host: API server hostname
    :type host: string
    :param port: API server port. If not specified, *port* is guessed based on *protocol*.
    :type port: string
    :param protocol: Either "http" or "https"
    :type protocol: string

    Overrides the current settings for which API server to communicate
    with. Any parameters that are not explicitly specified are not
    overridden.
    '''
    global APISERVER_PROTOCOL, APISERVER_HOST, APISERVER_PORT, APISERVER
    if host is not None:
        APISERVER_HOST = host
    if port is not None:
        APISERVER_PORT = port
    if protocol is not None:
        APISERVER_PROTOCOL = protocol
    if port is None or port == '':
        APISERVER = APISERVER_PROTOCOL + "://" + APISERVER_HOST
    else:
        APISERVER = APISERVER_PROTOCOL + "://" + APISERVER_HOST + ":" + str(APISERVER_PORT)


Instruction:
Can you write a function in Python 3 where it
gets the auth server name from the currently configured API server name.

Response:
def get_auth_server_name(host_override=None, port_override=None, protocol='https'):
    """
    Chooses the auth server name from the currently configured API server name.

    Raises DXError if the auth server name cannot be guessed and the overrides
    are not provided (or improperly provided).
    """
    if host_override is not None or port_override is not None:
        if host_override is None or port_override is None:
            raise exceptions.DXError("Both host and port must be specified if either is specified")
        return protocol + '://' + host_override + ':' + str(port_override)
    elif APISERVER_HOST == 'stagingapi.dnanexus.com':
        return 'https://stagingauth.dnanexus.com'
    elif APISERVER_HOST == 'api.dnanexus.com':
        return 'https://auth.dnanexus.com'
    elif APISERVER_HOST == 'stagingapi.cn.dnanexus.com':
        return 'https://stagingauth.cn.dnanexus.com:7001'
    elif APISERVER_HOST == 'api.cn.dnanexus.com':
        return 'https://auth.cn.dnanexus.com:8001'
    elif APISERVER_HOST == "localhost" or APISERVER_HOST == "127.0.0.1":
        if "DX_AUTHSERVER_HOST" not in os.environ or "DX_AUTHSERVER_PORT" not in os.environ:
            err_msg = "Must set authserver env vars (DX_AUTHSERVER_HOST, DX_AUTHSERVER_PORT) if apiserver is {apiserver}."
            raise exceptions.DXError(err_msg.format(apiserver=APISERVER_HOST))
        else:
            return os.environ["DX_AUTHSERVER_HOST"] + ":" + os.environ["DX_AUTHSERVER_PORT"]
    else:
        err_msg = "Could not determine which auth server is associated with {apiserver}."
        raise exceptions.DXError(err_msg.format(apiserver=APISERVER_HOST))


Instruction:
How would you explain what the following Python 3 function does
def append_underlying_workflow_describe(globalworkflow_desc):
    if not globalworkflow_desc or \
            globalworkflow_desc['class'] != 'globalworkflow' or \
            not 'regionalOptions' in globalworkflow_desc:
        return globalworkflow_desc

    for region, config in globalworkflow_desc['regionalOptions'].items():
        workflow_id = config['workflow']
        workflow_desc = dxpy.api.workflow_describe(workflow_id)
        globalworkflow_desc['regionalOptions'][region]['workflowDescribe'] = workflow_desc
    return globalworkflow_desc

Response: Adds the workflowDescribe field to the config for each region of the globalworkflow.


Instruction:
Can you tell what is the following Python 3 function doing
def _construct_jbor(job_id, field_name_and_maybe_index):
    '''
    :param job_id: Job ID
    :type job_id: string
    :param field_name_and_maybe_index: Field name, plus possibly ".N" where N is an array index
    :type field_name_and_maybe_index: string
    :returns: dict of JBOR
    '''
    link = {"$dnanexus_link": {"job": job_id}}
    if '.' in field_name_and_maybe_index:
        split_by_dot = field_name_and_maybe_index.rsplit('.', 1)
        link["$dnanexus_link"]["field"] = split_by_dot[0]
        link["$dnanexus_link"]["index"] = int(split_by_dot[1])
    else:
        link["$dnanexus_link"]["field"] = field_name_and_maybe_index
    return link

Response: Constructs a JBOR object from the job ID and field name.


Instruction:
Implement a function in Python 3 to
update the internal inputs dictionary with the key value pairs from new_inputs overwriting existing keys.

Response:
def update(self, new_inputs, strip_prefix=True):
        """
        Updates the inputs dictionary with the key/value pairs from new_inputs, overwriting existing keys.
        """
        if strip_prefix and self.input_name_prefix is not None:
            for i in new_inputs:
                if i.startswith(self.input_name_prefix):
                    self.inputs[i[len(self.input_name_prefix):]] = new_inputs[i]
        else:
            self.inputs.update(new_inputs)


Instruction:
Explain what the following Python 3 code does
def _update_requires_resolution_inputs(self):
        input_paths = [quad[1] for quad in self.requires_resolution]
        results = resolve_multiple_existing_paths(input_paths)
        for input_name, input_value, input_class, input_index in self.requires_resolution:
            project = results[input_value]['project']
            folderpath = results[input_value]['folder']
            entity_result = results[input_value]['name']
            if input_class is None:
                if entity_result is not None:
                    if isinstance(entity_result, basestring):
                        # Case: -ifoo=job-012301230123012301230123
                        # Case: -ifoo=analysis-012301230123012301230123
                        assert(is_job_id(entity_result) or
                               (is_analysis_id(entity_result)))
                        input_value = entity_result
                    elif is_hashid(input_value):
                        input_value = {'$dnanexus_link': entity_result['id']}
                    elif 'describe' in entity_result:
                        # Then findDataObjects was called (returned describe hash)
                        input_value = {"$dnanexus_link": {"project": entity_result['describe']['project'],
                                                          "id": entity_result['id']}}
                    else:
                        # Then resolveDataObjects was called in a batch (no describe hash)
                        input_value = {"$dnanexus_link": {"project": entity_result['project'],
                                                          "id": entity_result['id']}}
                if input_index >= 0:
                    if self.inputs[input_name][input_index] is not None:
                        raise AssertionError("Expected 'self.inputs' to have saved a spot for 'input_value'.")
                    self.inputs[input_name][input_index] = input_value
                else:
                    if self.inputs[input_name] is not None:
                        raise AssertionError("Expected 'self.inputs' to have saved a spot for 'input_value'.")
                    self.inputs[input_name] = input_value
            else:
                msg = 'Value provided for input field "' + input_name + '" could not be parsed as ' + \
                      input_class + ': '
                if input_value == '':
                    raise DXCLIError(msg + 'empty string cannot be resolved')
                if entity_result is None:
                    raise DXCLIError(msg + 'could not resolve \"' + input_value + '\" to a name or ID')
                try:
                    dxpy.bindings.verify_string_dxid(entity_result['id'], input_class)
                except DXError as details:
                    raise DXCLIError(msg + str(details))
                if is_hashid(input_value):
                    input_value = {'$dnanexus_link': entity_result['id']}
                elif 'describe' in entity_result:
                    # Then findDataObjects was called (returned describe hash)
                    input_value = {'$dnanexus_link': {"project": entity_result['describe']['project'],
                                                      "id": entity_result['id']}}
                else:
                    # Then resolveDataObjects was called in a batch (no describe hash)
                    input_value = {"$dnanexus_link": {"project": entity_result['project'],
                                                      "id": entity_result['id']}}
                if input_index != -1:
                    # The class is an array, so append the resolved value
                    self.inputs[input_name].append(input_value)
                else:
                    self.inputs[input_name] = input_value

Response: Updates self. inputs with resolved input values.


Instruction:
Write a Python 3 script to
escape the given unicode string.

Response:
def escape_unicode_string(u):
    """
    Escapes the nonprintable chars 0-31 and 127, and backslash;
    preferably with a friendly equivalent such as '\n' if available, but
    otherwise with a Python-style backslashed hex escape.
    """
    def replacer(matchobj):
        if ord(matchobj.group(1)) == 127:
            return "\\x7f"
        if ord(matchobj.group(1)) == 92: # backslash
            return "\\\\"
        return REPLACEMENT_TABLE[ord(matchobj.group(1))]
    return re.sub("([\\000-\\037\\134\\177])", replacer, u)


Instruction:
Make a summary of the following Python 3 code
def format_tree(tree, root=None):
    ''' Tree pretty printer.
    Expects trees to be given as mappings (dictionaries). Keys will be printed; values will be traversed if they are
    mappings. To preserve order, use collections.OrderedDict.

    Example:

        print format_tree(collections.OrderedDict({'foo': 0, 'bar': {'xyz': 0}}))

    '''
    formatted_tree = [root] if root is not None else []
    def _format(tree, prefix='    '):
        nodes = list(tree.keys())
        for i in range(len(nodes)):
            node = nodes[i]
            if i == len(nodes)-1 and len(prefix) > 1:
                my_prefix = prefix[:-4] + '└── '
                my_multiline_prefix = prefix[:-4] + '    '
            else:
                my_prefix = prefix[:-4] + '├── '
                my_multiline_prefix = prefix[:-4] + '│   '
            n = 0
            for line in node.splitlines():
                if n == 0:
                    formatted_tree.append(my_prefix + line)
                else:
                    formatted_tree.append(my_multiline_prefix + line)
                n += 1

            if isinstance(tree[node], collections.Mapping):
                subprefix = prefix
                if i < len(nodes)-1 and len(prefix) > 1 and prefix[-4:] == '    ':
                    subprefix = prefix[:-4] + '│   '
                _format(tree[node], subprefix + '    ')
    _format(tree)
    return '\n'.join(formatted_tree)

Response: Pretty printer for the tree.


Instruction:
Make a summary of the following Python 3 code
def format_table(table, column_names=None, column_specs=None, max_col_width=32,
                 report_dimensions=False):
    ''' Table pretty printer.
    Expects tables to be given as arrays of arrays.

    Example:

        print format_table([[1, "2"], [3, "456"]], column_names=['A', 'B'])

    '''
    if len(table) > 0:
        col_widths = [0] * len(list(table)[0])
    elif column_specs is not None:
        col_widths = [0] * (len(column_specs) + 1)
    elif column_names is not None:
        col_widths = [0] * len(column_names)
    my_column_names = []
    if column_specs is not None:
        column_names = ['Row']
        column_names.extend([col['name'] for col in column_specs])
        column_specs = [{'name': 'Row', 'type': 'float'}] + column_specs
    if column_names is not None:
        for i in range(len(column_names)):
            my_col = str(column_names[i])
            if len(my_col) > max_col_width:
                my_col = my_col[:max_col_width-1] + '…'
            my_column_names.append(my_col)
            col_widths[i] = max(col_widths[i], len(my_col))
    my_table = []
    for row in table:
        my_row = []
        for i in range(len(row)):
            my_item = escape_unicode_string(str(row[i]))
            if len(my_item) > max_col_width:
                my_item = my_item[:max_col_width-1] + '…'
            my_row.append(my_item)
            col_widths[i] = max(col_widths[i], len(my_item))
        my_table.append(my_row)

    def border(i):
        return WHITE() + i + ENDC()

    type_colormap = {'boolean': BLUE(),
                     'integer': YELLOW(),
                     'float': WHITE(),
                     'string': GREEN()}
    for i in 'uint8', 'int16', 'uint16', 'int32', 'uint32', 'int64':
        type_colormap[i] = type_colormap['integer']
    type_colormap['double'] = type_colormap['float']

    def col_head(i):
        if column_specs is not None:
            return BOLD() + type_colormap[column_specs[i]['type']] + column_names[i] + ENDC()
        else:
            return BOLD() + WHITE() + column_names[i] + ENDC()

    formatted_table = [border('┌') + border('┬').join(border('─')*i for i in col_widths) + border('┐')]
    if len(my_column_names) > 0:
        padded_column_names = [col_head(i) + ' '*(col_widths[i]-len(my_column_names[i])) for i in range(len(my_column_names))]
        formatted_table.append(border('│') + border('│').join(padded_column_names) + border('│'))
        formatted_table.append(border('├') + border('┼').join(border('─')*i for i in col_widths) + border('┤'))

    for row in my_table:
        padded_row = [row[i] + ' '*(col_widths[i]-len(row[i])) for i in range(len(row))]
        formatted_table.append(border('│') + border('│').join(padded_row) + border('│'))
    formatted_table.append(border('└') + border('┴').join(border('─')*i for i in col_widths) + border('┘'))

    if report_dimensions:
        return '\n'.join(formatted_table), len(formatted_table), sum(col_widths) + len(col_widths) + 1
    else:
        return '\n'.join(formatted_table)

Response:
Table pretty printer.
    Expects tables to be given as arrays of arrays.

    Example:

        print format_table([[1, "2"], [3, "456"]], column_names=['A', 'B'])


Instruction:
Can you generate the documentation for the following Python 3 function
def flatten_json_array(json_string, array_name):

    result = re.sub('"{}": \\[\r?\n\\s*'.format(array_name), '"{}": ['.format(array_name), json_string, flags=re.MULTILINE)
    flatten_regexp = re.compile('"{}": \\[(.*)(?<=,)\r?\n\\s*'.format(array_name), flags=re.MULTILINE)
    while flatten_regexp.search(result):
        result = flatten_regexp.sub('"{}": [\\1 '.format(array_name), result)
    result = re.sub('"{}": \\[(.*)\r?\n\\s*\\]'.format(array_name), '"{}": [\\1]'.format(array_name), result, flags=re.MULTILINE)
    return result

Response: Flattens all arrays with the same name in the JSON string


Instruction:
Implement a function in Python 3 to
create a new remote workflow object with the specified title summary and description.

Response:
def new_dxworkflow(title=None, summary=None, description=None, output_folder=None, init_from=None, **kwargs):
    '''
    :param title: Workflow title (optional)
    :type title: string
    :param summary: Workflow summary (optional)
    :type summary: string
    :param description: Workflow description (optional)
    :type description: string
    :param output_folder: Default output folder of the workflow (optional)
    :type output_folder: string
    :param init_from: Another analysis workflow object handler or and analysis (string or handler) from which to initialize the metadata (optional)
    :type init_from: :class:`~dxpy.bindings.dxworkflow.DXWorkflow`, :class:`~dxpy.bindings.dxanalysis.DXAnalysis`, or string (for analysis IDs only)
    :rtype: :class:`DXWorkflow`

    Additional optional parameters not listed: all those under
    :func:`dxpy.bindings.DXDataObject.new`, except `details`.

    Creates a new remote workflow object with project set to *project*
    and returns the appropriate handler.

    Example:

        r = dxpy.new_dxworkflow(title="My Workflow", description="This workflow contains...")

    Note that this function is shorthand for::

        dxworkflow = DXWorkflow()
        dxworkflow.new(**kwargs)
    '''
    dxworkflow = DXWorkflow()
    dxworkflow.new(title=title, summary=summary, description=description, output_folder=output_folder, init_from=init_from, **kwargs)
    return dxworkflow


Instruction:
Explain what the following Python 3 code does
def _new(self, dx_hash, **kwargs):

        def _set_dx_hash(kwargs, dxhash, key, new_key=None):
            new_key = key if new_key is None else new_key
            if key in kwargs:
                if kwargs[key] is not None:
                    dxhash[new_key] = kwargs[key]
                del kwargs[key]

        if "init_from" in kwargs:
            if kwargs["init_from"] is not None:
                if not (isinstance(kwargs["init_from"], (DXWorkflow, DXAnalysis)) or \
                        (isinstance(kwargs["init_from"], basestring) and \
                         re.compile('^analysis-[0-9A-Za-z]{24}$').match(kwargs["init_from"]))):
                    raise DXError("Expected init_from to be an instance of DXWorkflow or DXAnalysis, or to be a string analysis ID.")
                if isinstance(kwargs["init_from"], basestring):
                    dx_hash["initializeFrom"] = {"id": kwargs["init_from"]}
                else:
                    dx_hash["initializeFrom"] = {"id": kwargs["init_from"].get_id()}
                    if isinstance(kwargs["init_from"], DXWorkflow):
                        dx_hash["initializeFrom"]["project"] = kwargs["init_from"].get_proj_id()
            del kwargs["init_from"]

        _set_dx_hash(kwargs, dx_hash, "title")
        _set_dx_hash(kwargs, dx_hash, "summary")
        _set_dx_hash(kwargs, dx_hash, "description")
        _set_dx_hash(kwargs, dx_hash, "output_folder", "outputFolder")
        _set_dx_hash(kwargs, dx_hash, "stages")
        _set_dx_hash(kwargs, dx_hash, "workflow_inputs", "inputs")
        _set_dx_hash(kwargs, dx_hash, "workflow_outputs", "outputs")

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

Response: Create a new remote workflow object.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _get_stage_id(self, stage):
        '''
        :param stage: A stage ID, name, or index (stage index is the number n for the nth stage, starting from 0; can be provided as an int or a string)
        :type stage: int or string
        :returns: The stage ID (this is a no-op if it was already a stage ID)
        :raises: :class:`~dxpy.exceptions.DXError` if *stage* could not be parsed, resolved to a stage ID, or it could not be found in the workflow
        '''
        # first, if it is a string, see if it is an integer
        if isinstance(stage, basestring):
            try:
                stage = int(stage)
            except:
                # we'll try parsing it as a string later
                pass

        if not isinstance(stage, basestring):
            # Try to parse as stage index; ensure that if it's not a
            # string that it is an integer at this point.
            try:
                stage_index = int(stage)
            except:
                raise DXError('DXWorkflow: the given stage identifier was neither a string stage ID nor an integer index')
            if stage_index < 0 or stage_index >= len(self.stages):
                raise DXError('DXWorkflow: the workflow contains ' + str(len(self.stages)) + \
                              ' stage(s), and the numerical value of the given stage identifier is out of range')
            return self.stages[stage_index].get("id")

        if re.compile('^([a-zA-Z_]|stage-)[0-9a-zA-Z_]*$').match(stage) is not None:
            # Check if there exists a stage with this stage id
            stage_id_exists = any([stg['id'] for stg in self.stages if stg.get('id') == stage])
            if stage_id_exists:
                return stage

        # A stage with the provided ID can't be found in the workflow, so look for it as a name
        stage_ids_matching_name = [stg['id'] for stg in self.stages if stg.get('name') == stage]
        if len(stage_ids_matching_name) == 0:
            raise DXError('DXWorkflow: the given stage identifier ' + stage + ' could not be found as a stage ID nor as a stage name')
        elif len(stage_ids_matching_name) > 1:
            raise DXError('DXWorkflow: more than one workflow stage was found to have the name "' + stage + '"')
        else:
            return stage_ids_matching_name[0]

Response: Get the stage ID from the given stage.


Instruction:
Write a Python 3 script to
add a new stage to the workflow.

Response:
def add_stage(self, executable, stage_id=None, name=None, folder=None, stage_input=None, instance_type=None,
                  edit_version=None, **kwargs):
        '''
        :param executable: string or a handler for an app or applet
        :type executable: string, DXApplet, or DXApp
        :param stage_id: id for the stage (optional)
        :type stage_id: string
        :param name: name for the stage (optional)
        :type name: string
        :param folder: default output folder for the stage; either a relative or absolute path (optional)
        :type folder: string
        :param stage_input: input fields to bind as default inputs for the executable (optional)
        :type stage_input: dict
        :param instance_type: Default instance type on which all jobs will be run for this stage, or a dict mapping function names to instance type requests
        :type instance_type: string or dict
        :param edit_version: if provided, the edit version of the workflow that should be modified; if not provided, the current edit version will be used (optional)
        :type edit_version: int
        :returns: ID of the added stage
        :rtype: string
        :raises: :class:`~dxpy.exceptions.DXError` if *executable* is not an expected type :class:`~dxpy.exceptions.DXAPIError` for errors thrown from the API call

        Adds the specified executable as a new stage in the workflow.
        '''
        if isinstance(executable, basestring):
            exec_id = executable
        elif isinstance(executable, DXExecutable):
            exec_id = executable.get_id()
        else:
            raise DXError("dxpy.DXWorkflow.add_stage: executable must be a string or an instance of DXApplet or DXApp")
        add_stage_input = {"executable": exec_id}
        if stage_id is not None:
            add_stage_input["id"] = stage_id
        if name is not None:
            add_stage_input["name"] = name
        if folder is not None:
            add_stage_input["folder"] = folder
        if stage_input is not None:
            add_stage_input["input"] = stage_input
        if instance_type is not None:
            add_stage_input["systemRequirements"] = SystemRequirementsDict.from_instance_type(instance_type).as_dict()
        self._add_edit_version_to_request(add_stage_input, edit_version)
        try:
            result = dxpy.api.workflow_add_stage(self._dxid, add_stage_input, **kwargs)
        finally:
            self.describe() # update cached describe
        return result['stage']


Instruction:
Make a summary of the following Python 3 code
def get_stage(self, stage, **kwargs):
        '''
        :param stage: A number for the stage index (for the nth stage, starting from 0), or a string of the stage index, name, or ID
        :type stage: int or string
        :returns: Hash of stage descriptor in workflow
        '''
        stage_id = self._get_stage_id(stage)
        result = next((stage for stage in self.stages if stage['id'] == stage_id), None)
        if result is None:
            raise DXError('The stage ID ' + stage_id + ' could not be found')
        return result

Response: Get the stage descriptor in the workflow.


Instruction:
Here you have a function in Python 3, explain what it does
def remove_stage(self, stage, edit_version=None, **kwargs):
        '''
        :param stage: A number for the stage index (for the nth stage, starting from 0), or a string of the stage index, name, or ID
        :type stage: int or string
        :param edit_version: if provided, the edit version of the workflow that should be modified; if not provided, the current edit version will be used (optional)
        :type edit_version: int
        :returns: Stage ID that was removed
        :rtype: string

        Removes the specified stage from the workflow
        '''
        stage_id = self._get_stage_id(stage)
        remove_stage_input = {"stage": stage_id}
        self._add_edit_version_to_request(remove_stage_input, edit_version)
        try:
            dxpy.api.workflow_remove_stage(self._dxid, remove_stage_input, **kwargs)
        finally:
            self.describe() # update cached describe
        return stage_id

Response: Removes the specified stage from the workflow.


Instruction:
Create a Python 3 function for
moving the specified stage to a new index.

Response:
def move_stage(self, stage, new_index, edit_version=None, **kwargs):
        '''
        :param stage: A number for the stage index (for the nth stage, starting from 0), or a string of the stage index, name, or ID
        :type stage: int or string
        :param new_index: The new position in the order of stages that the specified stage should have (where 0 indicates the first stage)
        :type new_index: int
        :param edit_version: if provided, the edit version of the workflow that should be modified; if not provided, the current edit version will be used (optional)
        :type edit_version: int

        Removes the specified stage from the workflow
        '''
        stage_id = self._get_stage_id(stage)
        move_stage_input = {"stage": stage_id,
                            "newIndex": new_index}
        self._add_edit_version_to_request(move_stage_input, edit_version)
        try:
            dxpy.api.workflow_move_stage(self._dxid, move_stage_input, **kwargs)
        finally:
            self.describe()


Instruction:
Can you generate a brief explanation for the following Python 3 code
def update(self, title=None, unset_title=False, summary=None, description=None,
               output_folder=None, unset_output_folder=False,
               workflow_inputs=None, unset_workflow_inputs=False,
               workflow_outputs=None, unset_workflow_outputs=False,
               stages=None, edit_version=None, **kwargs):
        '''
        :param title: workflow title to set; cannot be provided with *unset_title* set to True
        :type title: string
        :param unset_title: whether to unset the title; cannot be provided with string value for *title*
        :type unset_title: boolean
        :param summary: workflow summary to set
        :type summary: string
        :param description: workflow description to set
        :type description: string
        :param output_folder: new default output folder for the workflow
        :type output_folder: string
        :param unset_folder: whether to unset the default output folder; cannot be True with string value for *output_folder*
        :type unset_folder: boolean
        :param stages: updates to the stages to make; see API documentation for /workflow-xxxx/update for syntax of this field; use :meth:`update_stage()` to update a single stage
        :type stages: dict
        :param workflow_inputs: updates to the workflow input to make; see API documentation for /workflow-xxxx/update for syntax of this field
        :type workflow_inputs: dict
        :param workflow_outputs: updates to the workflow output to make; see API documentation for /workflow-xxxx/update for syntax of this field
        :type workflow_outputs: dict
        :param edit_version: if provided, the edit version of the workflow that should be modified; if not provided, the current edit version will be used (optional)
        :type edit_version: int

        Make general metadata updates to the workflow
        '''
        update_input = {}
        if title is not None and unset_title:
            raise DXError('dxpy.DXWorkflow.update: cannot provide both "title" and set "unset_title"')
        if output_folder is not None and unset_output_folder:
            raise DXError('dxpy.DXWorkflow.update: cannot provide both "output_folder" and set "unset_output_folder"')
        if workflow_inputs is not None and unset_workflow_inputs:
            raise DXError('dxpy.DXWorkflow.update: cannot provide both "workflow_inputs" and set "unset_workflow_inputs"')
        if workflow_outputs is not None and unset_workflow_outputs:
            raise DXError('dxpy.DXWorkflow.update: cannot provide both "workflow_outputs" and set "unset_workflow_outputs"')

        if title is not None:
            update_input["title"] = title
        elif unset_title:
            update_input["title"] = None
        if summary is not None:
            update_input["summary"] = summary
        if description is not None:
            update_input["description"] = description
        if output_folder is not None:
            update_input["outputFolder"] = output_folder
        elif unset_output_folder:
            update_input["outputFolder"] = None
        if stages is not None:
            update_input["stages"] = stages
        if workflow_inputs is not None:
            update_input["inputs"] = workflow_inputs
        elif unset_workflow_inputs:
            update_input["inputs"] = None
        if workflow_outputs is not None:
            update_input["outputs"] = workflow_outputs
        elif unset_workflow_outputs:
            update_input["outputs"] = None

        # only perform update if there are changes to make
        if update_input:
            self._add_edit_version_to_request(update_input, edit_version)
            try:
                dxpy.api.workflow_update(self._dxid, update_input, **kwargs)
            finally:
                self.describe()

Response: Updates the metadata of a specific workflow entry.


Instruction:
Create a Python 3 function to
update the workflow entry for a specific stage.

Response:
def update_stage(self, stage, executable=None, force=False,
                     name=None, unset_name=False, folder=None, unset_folder=False, stage_input=None,
                     instance_type=None, edit_version=None, **kwargs):
        '''
        :param stage: A number for the stage index (for the nth stage, starting from 0), or a string stage index, name, or ID
        :type stage: int or string
        :param executable: string or a handler for an app or applet
        :type executable: string, DXApplet, or DXApp
        :param force: whether to use *executable* even if it is incompatible with the previous executable's spec
        :type force: boolean
        :param name: new name for the stage; cannot be provided with *unset_name* set to True
        :type name: string
        :param unset_name: whether to unset the stage name; cannot be True with string value for *name*
        :type unset_name: boolean
        :param folder: new default output folder for the stage; either a relative or absolute path (optional)
        :type folder: string
        :param unset_folder: whether to unset the stage folder; cannot be True with string value for *folder*
        :type unset_folder: boolean
        :param stage_input: input fields to bind as default inputs for the executable (optional)
        :type stage_input: dict
        :param instance_type: Default instance type on which all jobs will be run for this stage, or a dict mapping function names to instance type requests
        :type instance_type: string or dict
        :param edit_version: if provided, the edit version of the workflow that should be modified; if not provided, the current edit version will be used (optional)
        :type edit_version: int

        Removes the specified stage from the workflow
        '''
        stage_id = self._get_stage_id(stage)

        if name is not None and unset_name:
            raise DXError('dxpy.DXWorkflow.update_stage: cannot provide both "name" and set "unset_name"')
        if folder is not None and unset_folder:
            raise DXError('dxpy.DXWorkflow.update_stage: cannot provide both "folder" and set "unset_folder"')

        if executable is not None:
            if isinstance(executable, basestring):
                exec_id = executable
            elif isinstance(executable, DXExecutable):
                exec_id = executable.get_id()
            else:
                raise DXError("dxpy.DXWorkflow.update_stage: executable (if provided) must be a string or an instance of DXApplet or DXApp")
            update_stage_exec_input = {"stage": stage_id,
                                       "executable": exec_id,
                                       "force": force}
            self._add_edit_version_to_request(update_stage_exec_input, edit_version)
            try:
                dxpy.api.workflow_update_stage_executable(self._dxid, update_stage_exec_input, **kwargs)
            finally:
                self.describe() # update cached describe

        # Construct hash and update the workflow's stage if necessary
        update_stage_input = {}
        if name is not None:
            update_stage_input["name"] = name
        elif unset_name:
            update_stage_input["name"] = None
        if folder:
            update_stage_input["folder"] = folder
        elif unset_folder:
            update_stage_input["folder"] = None
        if stage_input:
            update_stage_input["input"] = stage_input
        if instance_type is not None:
            update_stage_input["systemRequirements"] = SystemRequirementsDict.from_instance_type(instance_type).as_dict()
        if update_stage_input:
            update_input = {"stages": {stage_id: update_stage_input}}
            self._add_edit_version_to_request(update_input, edit_version)
            try:
                dxpy.api.workflow_update(self._dxid, update_input, **kwargs)
            finally:
                self.describe()


Instruction:
Make a summary of the following Python 3 code
def _get_input_name(self, input_str, region=None, describe_output=None):
        '''
        :param input_str: A string of one of the forms: "<exported input field name>", "<explicit workflow input field name>", "<stage ID>.<input field name>", "<stage index>.<input field name>", "<stage name>.<input field name>"
        :type input_str: string
        :returns: If the given form was one of those which uses the stage index or stage name, it is translated to the stage ID for use in the API call (stage name takes precedence)
        '''
        if '.' in input_str:
            stage_identifier, input_name = input_str.split('.', 1)
            # Try to parse as a stage ID or name
            return self._get_stage_id(stage_identifier) + '.' + input_name

        return input_str

Response: Returns the input name for the given input string.


Instruction:
Make a summary of the following Python 3 code
def run(self, workflow_input, *args, **kwargs):
        '''
        :param workflow_input: Dictionary of the workflow's input arguments; see below for more details
        :type workflow_input: dict
        :param instance_type: Instance type on which all stages' jobs will be run, or a dict mapping function names to instance types. These may be overridden on a per-stage basis if stage_instance_types is specified.
        :type instance_type: string or dict
        :param stage_instance_types: A dict mapping stage IDs, names, or indices to either a string (representing an instance type to be used for all functions in that stage), or a dict mapping function names to instance types.
        :type stage_instance_types: dict
        :param stage_folders: A dict mapping stage IDs, names, indices, and/or the string "*" to folder values to be used for the stages' output folders (use "*" as the default for all unnamed stages)
        :type stage_folders: dict
        :param rerun_stages: A list of stage IDs, names, indices, and/or the string "*" to indicate which stages should be run even if there are cached executions available
        :type rerun_stages: list of strings
        :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
        :returns: Object handler of the newly created analysis
        :rtype: :class:`~dxpy.bindings.dxanalysis.DXAnalysis`

        Run the associated workflow. See :meth:`dxpy.bindings.dxapplet.DXExecutable.run` for additional args.

        When providing input for the workflow, keys should be of one of the following forms:

        * "N.name" where *N* is the stage number, and *name* is the
          name of the input, e.g. "0.reads" if the first stage takes
          in an input called "reads"

        * "stagename.name" where *stagename* is the stage name, and
          *name* is the name of the input within the stage

        * "stageID.name" where *stageID* is the stage ID, and *name*
          is the name of the input within the stage

        * "name" where *name* is the name of a workflow level input
          (defined in inputs) or the name that has been
          exported for the workflow (this name will appear as a key
          in the "inputSpec" of this workflow's description if it has
          been exported for this purpose)

        '''
        return super(DXWorkflow, self).run(workflow_input, *args, **kwargs)

Response: Runs the associated workflow.


Instruction:
Can you tell what is the following Python 3 function doing
def get_folder_matches(text, delim_pos, dxproj, folderpath):
    '''
    :param text: String to be tab-completed; still in escaped form
    :type text: string
    :param delim_pos: index of last unescaped "/" in text
    :type delim_pos: int
    :param dxproj: DXProject handler to use
    :type dxproj: DXProject
    :param folderpath: Unescaped path in which to search for folder matches
    :type folderpath: string
    :returns: List of matches
    :rtype: list of strings

    Members of the returned list are guaranteed to start with *text*
    and be in escaped form for consumption by the command-line.
    '''
    try:
        folders = dxproj.list_folder(folder=folderpath, only='folders')['folders']
        folder_names = [name[name.rfind('/') + 1:] for name in folders]
        if text != '' and delim_pos != len(text) - 1:
            folder_names += ['.', '..']
        prefix = text[:delim_pos + 1]
        return [prefix + f + '/' for f in folder_names if (prefix + f + '/').startswith(text)]
    except:
        return []

Response: Returns a list of strings that are part of the given text in the specified folder.


Instruction:
How would you code a function in Python 3 to
return a list of data objects that match the given text.

Response:
def get_data_matches(text, delim_pos, dxproj, folderpath, classname=None,
                     typespec=None, visibility=None):
    '''
    :param text: String to be tab-completed; still in escaped form
    :type text: string
    :param delim_pos: index of last unescaped "/" or ":" in text
    :type delim_pos: int
    :param dxproj: DXProject handler to use
    :type dxproj: DXProject
    :param folderpath: Unescaped path in which to search for data object matches
    :type folderpath: string
    :param classname: Data object class by which to restrict the search (None for no restriction on class)
    :type classname: string
    :param visibility: Visibility to constrain the results to; default is "visible" for empty strings, "either" for nonempty
    :type visibility: string
    :returns: List of matches
    :rtype: list of strings

    Members of the returned list are guaranteed to start with *text*
    and be in escaped form for consumption by the command-line.
    '''
    #unescaped_text = unescape_completion_name_str(text[delim_pos + 1:])
    unescaped_text = text[delim_pos + 1:]

    if visibility is None:
        if text != '' and delim_pos != len(text) - 1:
            visibility = "either"
        else:
            visibility = "visible"

    try:
        results = list(dxpy.find_data_objects(project=dxproj.get_id(),
                                              folder=folderpath,
                                              name=unescaped_text + "*",
                                              name_mode="glob",
                                              recurse=False,
                                              visibility=visibility,
                                              classname=classname,
                                              limit=100,
                                              describe=dict(fields=dict(name=True)),
                                              typename=typespec))
        prefix = '' if text == '' else text[:delim_pos + 1]
        return [prefix + escape_name(result['describe']['name']) for result in results]
    except:
        return []


Instruction:
Can you tell what is the following Python 3 function doing
def verify_string_dxid(dxid, expected_classes):
    '''
    :param dxid: Value to verify as a DNAnexus ID of class *expected_class*
    :param expected_classes: Single string or list of strings of allowed classes of the ID, e.g. "file" or ["project", "container"]
    :type expected_classes: string or list of strings
    :raises: :exc:`~dxpy.exceptions.DXError` if *dxid* is not a string or is not a valid DNAnexus ID of the expected class
    '''
    if isinstance(expected_classes, basestring):
        expected_classes = [expected_classes]
    if not isinstance(expected_classes, list) or len(expected_classes) == 0:
        raise DXError('verify_string_dxid: expected_classes should be a string or list of strings')
    if not (isinstance(dxid, basestring) and
            re.match('^(' + '|'.join(expected_classes) + ')-[0-9a-zA-Z]{24}$', dxid)):
        if len(expected_classes) == 1:
            str_expected_classes = expected_classes[0]
        elif len(expected_classes) == 2:
            str_expected_classes = ' or '.join(expected_classes)
        else:
            str_expected_classes = ', '.join(expected_classes[:-1]) + ', or ' + expected_classes[-1]

        raise DXError('Invalid ID of class %s: %r' % (str_expected_classes, dxid))

Response: Verifies that the given string is a valid DNAnexus ID of the class expected_class.


Instruction:
Explain what the following Python 3 code does
def set_id(self, dxid):
        '''
        :param dxid: New ID to be associated with the handler
        :type dxid: string

        Discards the currently stored ID and associates the handler with *dxid*
        '''
        if dxid is not None:
            verify_string_dxid(dxid, self._class)

        self._dxid = dxid

Response: Sets the ID of the currently stored handler.


Instruction:
How would you explain what the following Python 3 function does
def new(self, **kwargs):
        '''
        :param project: Project ID in which to create the new remote object
        :type project: string
        :param name: Name for the object
        :type name: string
        :param tags: Tags to add for the object
        :type tags: list of strings
        :param types: Types to add to the object
        :type types: list of strings
        :param hidden: Whether the object is to be hidden
        :type hidden: boolean
        :param properties: Properties given as key-value pairs of strings
        :type properties: dict
        :param details: Details to set for the object
        :type details: dict or list
        :param folder: Full path to the destination folder
        :type folder: string
        :param parents: If True, recursively create all parent folders if they are missing
        :type parents: boolean

        :rtype: :class:`DXDataObject`

        Creates a data object with the given fields. Only *project* is
        required, and only if no default project or workspace is set;
        the remaining arguments are optional and have default behavior
        as specified in the API documentation for the ``/new`` method of
        each data object class.

        '''
        if not hasattr(self, '_class'):
            raise NotImplementedError(
                "DXDataObject is an abstract class; a subclass should" + \
                    "be initialized instead.")

        dx_hash, remaining_kwargs = self._get_creation_params(kwargs)
        self._new(dx_hash, **remaining_kwargs)

Response: Creates a new object in the specified project.


Instruction:
Write a Python 3 script to
set the ID and project of the currently stored object.

Response:
def set_ids(self, dxid, project=None):
        '''
        :param dxid: Object ID or a DNAnexus link (a dict with key "$dnanexus_link"); if a project ID is provided in the DNAnexus link, it will be used as *project* unless *project* has been explictly provided
        :type dxid: string or dict
        :param project: Project ID
        :type project: string

        Discards the currently stored ID and associates the handler with
        *dxid*. Associates the handler with the copy of the object in
        *project* (if no project is explicitly specified, the default
        data container is used).

        '''
        if is_dxlink(dxid):
            dxid, project_from_link = get_dxlink_ids(dxid)
            if project is None:
                project = project_from_link

        if dxid is not None:
            verify_string_dxid(dxid, self._class)
        self._dxid = dxid

        if project is None:
            self._proj = dxpy.WORKSPACE_ID
        elif project is not None:
            verify_string_dxid(project, ['project', 'container'])
            self._proj = project


Instruction:
Write a Python 3 function that can
return a dict containing the description of the object.

Response:
def describe(self, incl_properties=False, incl_details=False, fields=None, default_fields=None, **kwargs):
        """
        :param fields: set of fields to include in the output, for
            example ``{'name', 'modified'}``. The field ``id`` is always
            implicitly included. If ``fields`` is specified, the default
            fields are not included (that is, only the fields specified
            here, and ``id``, are included) unless ``default_fields`` is
            additionally set to True.
        :type fields: set or sequence of str
        :param default_fields: if True, include the default fields in
            addition to fields requested in ``fields``, if any; if
            False, only the fields specified in ``fields``, if any, are
            returned (defaults to False if ``fields`` is specified, True
            otherwise)
        :type default_fields: bool
        :param incl_properties: if true, includes the properties of the
            object in the output (deprecated; use
            ``fields={'properties'}, default_fields=True`` instead)
        :type incl_properties: bool
        :param incl_details: if true, includes the details of the object
            in the output (deprecated; use ``fields={'details'},
            default_fields=True`` instead)
        :type incl_details: bool
        :returns: Description of the remote object
        :rtype: dict

        Return a dict with a description of the remote data object.

        The result includes the key-value pairs as specified in the API
        documentation for the ``/describe`` method of each data object
        class. The API defines some default set of fields that will be
        included (at a minimum, "id", "class", etc. should be available,
        and there may be additional fields that vary based on the
        class); the set of fields may be customized using ``fields`` and
        ``default_fields``.

        Any project-specific metadata fields (name, properties, and
        tags) are obtained from the copy of the object in the project
        associated with the handler, if possible.

        """

        if self._dxid is None:
            raise DXError('This {handler} handler has not been initialized with a {_class} ID and cannot be described'.format(
                handler=self.__class__.__name__,
                _class=self._class)
            )

        if (incl_properties or incl_details) and (fields is not None or default_fields is not None):
            raise ValueError('Cannot specify properties or details in conjunction with fields or default_fields')

        if incl_properties or incl_details:
            describe_input = dict(properties=incl_properties, details=incl_details)
        else:
            describe_input = {}
            if default_fields is not None:
                describe_input['defaultFields'] = default_fields
            if fields is not None:
                describe_input['fields'] = {field_name: True for field_name in fields}

        if self._proj is not None:
            describe_input["project"] = self._proj

        self._desc = self._describe(self._dxid, describe_input, **kwargs)

        return self._desc


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

        self._add_types(self._dxid, {"types": types}, **kwargs)

Response: Adds each of the specified types to the object.


Instruction:
Given the following Python 3 function, write the documentation
def remove_types(self, types, **kwargs):

        self._remove_types(self._dxid, {"types": types}, **kwargs)

Response: Removes the specified types from the object.


Instruction:
Create a Python 3 function for
setting the details for the object with the specified value.

Response:
def set_details(self, details, **kwargs):
        """
        :param details: Details to set for the object
        :type details: dict or list
        :raises: :class:`~dxpy.exceptions.DXAPIError` if the object is not in the "open" state

        Sets the details for the remote object with the specified value.
        If the input contains the string ``"$dnanexus_link"`` as a key
        in a hash, it must be the only key in the hash, and its value
        must be a valid ID of an existing object.

        """

        return self._set_details(self._dxid, details, **kwargs)


Instruction:
Write a Python 3 function that can
rename the object in the specified project.

Response:
def rename(self, name, **kwargs):
        """
        :param name: New name for the object
        :type name: string

        Renames the remote object.

        The name is changed on the copy of the object in the project
        associated with the handler.

        """

        return self._rename(self._dxid, {"project": self._proj,
                                         "name": name}, **kwargs)


Instruction:
Write a Python 3 function that can
set the properties of the object for the given key - value pairs.

Response:
def set_properties(self, properties, **kwargs):
        """
        :param properties: Property names and values given as key-value pairs of strings
        :type properties: dict

        Given key-value pairs in *properties* for property names and
        values, the properties are set on the object for the given
        property names. Any property with a value of :const:`None`
        indicates the property will be deleted.

        .. note:: Any existing properties not mentioned in *properties*
           are not modified by this method.

        The properties are written to the copy of the object in the
        project associated with the handler.

        The following example sets the properties for "name" and
        "project" for a remote file::

            dxfile.set_properties({"name": "George", "project": "cancer"})

        Subsequently, the following would delete the property "project"::

            dxfile.set_properties({"project": None})

        """

        self._set_properties(self._dxid, {"project": self._proj,
                                          "properties": properties},
                             **kwargs)


Instruction:
Can you implement a function in Python 3 that
adds each of the specified tags to the remote object.

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

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

        The tags are added to the copy of the object in the project
        associated with the handler.

        """

        self._add_tags(self._dxid, {"project": self._proj, "tags": tags},
                       **kwargs)


Instruction:
Can you implement a function in Python 3 that
removes the specified tags from the object.

Response:
def remove_tags(self, tags, **kwargs):
        """
        :param tags: Tags to remove from the object
        :type tags: list of strings

        Removes each of the specified tags from the remote object. Takes
        no action for tags that the object does not currently have.

        The tags are removed from the copy of the object in the project
        associated with the handler.

        """

        self._remove_tags(self._dxid, {"project": self._proj, "tags": tags},
                          **kwargs)


Instruction:
Implement a function in Python 3 to
remove the object from the project.

Response:
def remove(self, **kwargs):
        '''
        :raises: :exc:`~dxpy.exceptions.DXError` if no project is associated with the object

        Permanently removes the associated remote object from the
        associated project.
        '''

        if self._proj is None:
            raise DXError("Remove called when a project ID was not associated with this object handler")

        dxpy.api.project_remove_objects(self._proj, {"objects": [self._dxid]},
                                        **kwargs)

        # Reset internal state
        self._dxid = None
        self._proj = None
        self._desc = {}


Instruction:
Here you have a function in Python 3, explain what it does
def move(self, folder, **kwargs):
        '''
        :param folder: Folder route to which to move the object
        :type folder: string
        :raises: :exc:`~dxpy.exceptions.DXError` if no project is associated with the object

        Moves the associated remote object to *folder*.

        '''

        if self._proj is None:
            raise DXError("Move called when a project ID was not associated with this object handler")

        dxpy.api.project_move(self._proj, {"objects": [self._dxid],
                                           "destination": folder},
                              **kwargs)

Response: Moves the associated remote object to the specified folder.


Instruction:
Write a Python 3 script to
clone the object to the destination project and returns a new object handler for the new object.

Response:
def clone(self, project, folder="/", **kwargs):
        '''
        :param project: Destination project ID
        :type project: string
        :param folder: Folder route to which to move the object
        :type folder: string
        :raises: :exc:`~dxpy.exceptions.DXError` if no project is associated with the object
        :returns: An object handler for the new cloned object
        :rtype: :class:`DXDataObject`

        Clones the associated remote object to *folder* in *project* and
        returns an object handler for the new object in the destination
        project.

        '''

        if self._proj is None:
            raise DXError("Clone called when a project ID was not associated with this object handler")

        dxpy.api.project_clone(self._proj,
                               {"objects": [self._dxid],
                                "project": project,
                                "destination": folder},
                               **kwargs)
        cloned_copy = copy.copy(self)
        cloned_copy.set_ids(cloned_copy.get_id(), project)
        return cloned_copy


Instruction:
Explain what the following Python 3 code does
def get_session_conf_dir(self, cleanup=False):
        sessions_dir = os.path.join(self._user_conf_dir, "sessions")
        try:
            from psutil import Process, pid_exists

            if cleanup:
                try:
                    session_dirs = os.listdir(sessions_dir)
                except OSError as e:
                    # Silently skip cleanup and continue if we are unable to
                    # enumerate the session directories for any reason
                    # (including, most commonly, because the sessions dir
                    # doesn't exist)
                    session_dirs = []
                for session_dir in session_dirs:
                    try:
                        session_pid = int(session_dir)
                    except ValueError:
                        # If dir name doesn't look like an int, leave it
                        # alone
                        continue
                    if not pid_exists(session_pid):
                        rmtree(os.path.join(sessions_dir, session_dir), ignore_errors=True)

            parent_process = Process(os.getpid()).parent()
            default_session_dir = os.path.join(sessions_dir, str(parent_process.pid))
            while parent_process is not None and parent_process.pid != 0:
                session_dir = os.path.join(sessions_dir, str(parent_process.pid))
                if os.path.exists(session_dir):
                    return session_dir
                parent_process = parent_process.parent()
            return default_session_dir
        except (ImportError, IOError, AttributeError) as e:
            # We don't bundle psutil with Windows, so failure to import
            # psutil would be expected.
            if platform.system() != 'Windows':
                warn(fill("Error while retrieving session configuration: " + format_exception(e)))
        except Exception as e:
            warn(fill("Unexpected error while retrieving session configuration: " + format_exception(e)))
        return self._get_ppid_session_conf_dir(sessions_dir)

Response: Tries to find the session configuration directory by looking in ~/.dnanexus_config and looking in ~/.dnanexus_config for the immediate parent of this process and then its parent.


Instruction:
Given the following Python 3 function, write the documentation
def dxlink(object_id, project_id=None, field=None):
    '''
    :param object_id: Object ID or the object handler itself
    :type object_id: string or :class:`~dxpy.bindings.DXDataObject`
    :param project_id: A project ID, if creating a cross-project DXLink
    :type project_id: string
    :param field: A field name, if creating a job-based object reference
    :type field: string
    :returns: A dict formatted as a symbolic DNAnexus object reference
    :rtype: dict

    Creates a DXLink to the specified object.

    If `object_id` is already a link, it is returned without modification.

    If `object_id is a `~dxpy.bindings.DXDataObject`, the object ID is
    retrieved via its `get_id()` method.

    If `field` is not `None`, `object_id` is expected to be of class 'job'
    and the link created is a Job Based Object Reference (JBOR), which is
    of the form::

        {'$dnanexus_link': {'job': object_id, 'field': field}}

    If `field` is `None` and `project_id` is not `None`, the link created
    is a project-specific link of the form::

        {'$dnanexus_link': {'project': project_id, 'id': object_id}}
    '''
    if is_dxlink(object_id):
        return object_id
    if isinstance(object_id, DXDataObject):
        object_id = object_id.get_id()
    if not any((project_id, field)):
        return {'$dnanexus_link': object_id}
    elif field:
        dxpy.verify_string_dxid(object_id, "job")
        return {'$dnanexus_link': {'job': object_id, 'field': field}}
    else:
        return {'$dnanexus_link': {'project': project_id, 'id': object_id}}

Response: Returns a dict formatted as a symbolic DNAnexus object reference.


Instruction:
Can you create a Python 3 function that
returns True if x is a DNAnexus link.

Response:
def is_dxlink(x):
    '''
    :param x: A potential DNAnexus link

    Returns whether *x* appears to be a DNAnexus link (is a dict with
    key ``"$dnanexus_link"``) with a referenced data object.
    '''
    if not isinstance(x, dict):
        return False
    if '$dnanexus_link' not in x:
        return False
    link = x['$dnanexus_link']
    if isinstance(link, basestring):
        return True
    elif isinstance(link, dict):
        return any(key in link for key in ('id', 'job'))
    return False


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_dxlink_ids(link):
    '''
    :param link: A DNAnexus link
    :type link: dict
    :returns: (Object ID, Project ID) if the link is to a data object (or :const:`None`
        if no project specified in the link), or (Job ID, Field) if the link is
        a job-based object reference (JBOR).
    :rtype: tuple

    Get the object ID and detail from a link. There are three types of links:

    * Simple link of the form ``{"$dnanexus_link": "file-XXXX"}`` returns
      ``("file-XXXX", None)``.
    * Data object link of the form ``{"$dnanexus_link': {"id": "file-XXXX",
      "project": "project-XXXX"}}`` returns ``("file-XXXX", "project-XXXX")``.
    * Job-based object reference (JBOR) of the form ``{"$dnanexus_link":
      {"job": "job-XXXX", "field": "foo"}}`` returns ``("job-XXXX", "foo")``.
    '''
    if not is_dxlink(link):
        raise DXError('Invalid link: %r' % link)
    if isinstance(link['$dnanexus_link'], basestring):
        return link['$dnanexus_link'], None
    elif 'id' in link['$dnanexus_link']:
        return link['$dnanexus_link']['id'], link['$dnanexus_link'].get('project')
    else:
        return link['$dnanexus_link']['job'], link['$dnanexus_link']['field']

Response: Get the object ID and project ID from a DNXLink object.


Instruction:
Implement a Python 3 function for
returning an object handler for the object identified by id_or_link.

Response:
def get_handler(id_or_link, project=None):
    '''
    :param id_or_link: String containing an object ID or dict containing a DXLink
    :type id_or_link: string or dict
    :param project: String project ID to use as the context if the the object is a data object
    :type project: string
    :rtype: :class:`~dxpy.bindings.DXObject`, :class:`~dxpy.bindings.DXApp`, or :class:`~dxpy.bindings.DXGlobalWorkflow`

    Parses a string or DXLink dict. Creates and returns an object handler for it.

    Example::

        get_handler("file-1234")
    '''
    try:
        cls = _guess_link_target_type(id_or_link)
    except Exception as e:
        raise DXError("Could not parse link {}: {}".format(id_or_link, e))

    if cls in [dxpy.DXApp, dxpy.DXGlobalWorkflow]:
        # This special case should translate identifiers of the form
        # "app-name" or "app-name/version_or_tag" to the appropriate
        # arguments
        if dxpy.utils.resolver.is_hashid(id_or_link):
            return cls(id_or_link)
        else:
            slash_pos = id_or_link.find('/')
            dash_pos = id_or_link.find('-')
            if slash_pos == -1:
                return cls(name=id_or_link[dash_pos+1:])
            else:
                return cls(name=id_or_link[dash_pos+1:slash_pos],
                           alias=id_or_link[slash_pos + 1:])
    elif project is None or cls in [dxpy.DXJob, dxpy.DXAnalysis, dxpy.DXProject, dxpy.DXContainer]:
        # This case is important for the handlers which do not
        # take a project field
        return cls(id_or_link)
    else:
        return cls(id_or_link, project=project)


Instruction:
Can you create a Python 3 function that
returns a string containing the description of the object.

Response:
def describe(id_or_link, **kwargs):
    '''
    :param id_or_link: String containing an object ID or dict containing a DXLink,
                       or a list of object IDs or dicts containing a DXLink.

    Given an object ID, calls :meth:`~dxpy.bindings.DXDataObject.describe` on the object.

    Example::

        describe("file-1234")

    Given a list of object IDs, calls :meth:`~dxpy.api.system_describe_data_objects`.

    Example::

        describe(["file-1234", "workflow-5678"])

    Note: If id_or_link is a list and **kwargs contains a "fields" parameter, these
    fields will be returned in the response for each data object in addition to the
    fields included by default. Additionally, describe options can be provided for
    each data object class in the "classDescribeOptions" kwargs argument. See
    https://wiki.dnanexus.com/API-Specification-v1.0.0/System-Methods#API-method:-/system/describeDataObjects
    for input parameters used with the multiple object describe method.
    '''
    # If this is a list, extract the ids.
    # TODO: modify the procedure to use project ID when possible
    if isinstance(id_or_link, basestring) or is_dxlink(id_or_link):
        handler = get_handler(id_or_link)
        return handler.describe(**kwargs)
    else:
        links = []
        for link in id_or_link:
            # If this entry is a dxlink, then get the id.
            if is_dxlink(link):
                # Guaranteed by is_dxlink that one of the following will work
                if isinstance(link['$dnanexus_link'], basestring):
                    link = link['$dnanexus_link']
                else:
                    link = link['$dnanexus_link']['id']
            links.append(link)

        # Prepare input to system_describe_data_objects, the same fields will be passed
        # for all data object classes; if a class doesn't include a field in its describe
        # output, it will be ignored
        describe_input = \
            dict([(field, True) for field in kwargs['fields']]) if kwargs.get('fields', []) else True
        describe_links_input = [{'id': link, 'describe': describe_input} for link in links]
        bulk_describe_input = {'objects': describe_links_input}

        if 'classDescribeOptions' in kwargs:
            bulk_describe_input['classDescribeOptions'] = kwargs['classDescribeOptions']

        data_object_descriptions = dxpy.api.system_describe_data_objects(bulk_describe_input)
        return [desc['describe'] for desc in data_object_descriptions['results']]


Instruction:
How would you implement a function in Python 3 that
returns a dictionary containing the attributes of the project or container.

Response:
def describe(self, **kwargs):
        """
        :returns: A hash containing attributes of the project or container.
        :rtype: dict

        Returns a hash with key-value pairs as specified by the API
        specification for the `/project-xxxx/describe
        <https://wiki.dnanexus.com/API-Specification-v1.0.0/Projects#API-method%3A-%2Fproject-xxxx%2Fdescribe>`_
        method. This will usually include keys such as "id", "name",
        "class", "billTo", "created", "modified", and "dataUsage".

        """
        # TODO: link to /container-xxxx/describe
        api_method = dxpy.api.container_describe
        if isinstance(self, DXProject):
            api_method = dxpy.api.project_describe
        self._desc = api_method(self._dxid, **kwargs)
        return self._desc


Instruction:
Can you generate the documentation for the following Python 3 function
def new_folder(self, folder, parents=False, **kwargs):
        api_method = dxpy.api.container_new_folder
        if isinstance(self, DXProject):
            api_method = dxpy.api.project_new_folder

        api_method(self._dxid, {"folder": folder,
                                "parents": parents},
                   **kwargs)

Response: Creates a new folder in the specified folder.


Instruction:
Write a Python 3 script to
list the contents of the specified folder.

Response:
def list_folder(self, folder="/", describe=False, only="all", includeHidden=False, **kwargs):
        """
        :param folder: Full path to the folder to list
        :type folder: string
        :param describe: If True, returns the output of ``/describe`` on each object (see below for notes)
        :type describe: bool or dict
        :param only: Indicate "objects" for only objects, "folders" for only folders, or "all" for both
        :type only: string
        :param includeHidden: Indicate whether hidden objects should be returned
        :type includeHidden: bool
        :returns: A hash with key "objects" for the list of object IDs and key "folders" for the list of folder routes
        :rtype: dict

        Returns a hash containing a list of objects that reside directly
        inside the specified folder, and a list of strings representing
        the full paths to folders that reside directly inside the
        specified folder.

        By default, the list of objects is provided as a list containing
        one hash ``{"id": "class-XXXX"}`` with the ID of each matching
        object. If *describe* is not False, the output of ``/describe``
        is also included in an additional field "describe" for each
        object. If *describe* is True, ``/describe`` is called with the
        default arguments. *describe* may also be a hash, indicating the
        input hash to be supplied to each ``/describe`` call.

        """
        # TODO: it would be nice if we could supply describe
        # fields/defaultFields in a similar way to what we pass to the
        # high-level describe method, rather than having to construct
        # the literal API input

        api_method = dxpy.api.container_list_folder
        if isinstance(self, DXProject):
            api_method = dxpy.api.project_list_folder

        return api_method(self._dxid, {"folder": folder,
                                       "describe": describe,
                                       "only": only,
                                       "includeHidden": includeHidden},
                          **kwargs)


Instruction:
Explain what the following Python 3 code does
def move(self, destination, objects=[], folders=[], **kwargs):
        api_method = dxpy.api.container_move
        if isinstance(self, DXProject):
            api_method = dxpy.api.project_move

        api_method(self._dxid, {"objects": objects,
                                "folders": folders,
                                "destination": destination},
                   **kwargs)

Response: Moves the specified objects and folders into the specified destination folder.


Instruction:
Create a Python 3 function to
move the contents of the specified folder to the specified destination folder.

Response:
def move_folder(self, folder, destination, **kwargs):
        """
        :param folder: Full path to the folder to move
        :type folder: string
        :param destination: Full path to the destination folder that will contain *folder*
        :type destination: string

        Moves *folder* to reside in *destination* in the same project or
        container. All objects and subfolders inside *folder* are also
        moved.

        """
        api_method = dxpy.api.container_move
        if isinstance(self, DXProject):
            api_method = dxpy.api.project_move

        api_method(self._dxid, {"folders": [folder],
                                "destination": destination},
                   **kwargs)


Instruction:
How would you explain what the following Python 3 function does
def remove_folder(self, folder, recurse=False, force=False, **kwargs):
        api_method = dxpy.api.container_remove_folder
        if isinstance(self, DXProject):
            api_method = dxpy.api.project_remove_folder

        completed = False
        while not completed:
            resp = api_method(self._dxid,
                              {"folder": folder, "recurse": recurse, "force": force, "partial": True},
                              always_retry=force,  # api call is idempotent under 'force' semantics
                              **kwargs)
            if 'completed' not in resp:
                raise DXError('Error removing folder')
            completed = resp['completed']

Response: Removes the specified folder from the project or container.


Instruction:
Write a Python 3 script to
remove the specified objects from the project or container.

Response:
def remove_objects(self, objects, force=False, **kwargs):
        """
        :param objects: List of object IDs to remove from the project or container
        :type objects: list of strings
        :param force: If True, will suppress errors for objects that do not exist
        :type force: bool

        Removes the specified objects from the project or container.

        Removal propagates to any hidden objects that become unreachable
        from any visible object in the same project or container as a
        result of this operation.

        """
        api_method = dxpy.api.container_remove_objects
        if isinstance(self, DXProject):
            api_method = dxpy.api.project_remove_objects

        api_method(self._dxid,
                   {"objects": objects, "force": force},
                   always_retry=force,  # api call is idempotent under 'force' semantics
                   **kwargs)


Instruction:
Here you have a function in Python 3, explain what it does
def clone(self, container, destination="/", objects=[], folders=[], parents=False, **kwargs):
        api_method = dxpy.api.container_clone
        if isinstance(self, DXProject):
            api_method = dxpy.api.project_clone

        return api_method(self._dxid,
                          {"objects": objects,
                           "folders": folders,
                           "project": container,
                           "destination": destination,
                           "parents": parents},
                          **kwargs)

Response: Clones the specified objects and folders in the specified container into the specified destination folder.


Instruction:
Write a Python 3 function for
creating a new project with the given parameters.

Response:
def new(self, name, summary=None, description=None, protected=None,
            restricted=None, download_restricted=None, contains_phi=None, tags=None,
            properties=None, bill_to=None, **kwargs):
        """
        :param name: The name of the project
        :type name: string
        :param summary: If provided, a short summary of what the project contains
        :type summary: string
        :param description: If provided, the new project description
        :type name: string
        :param protected: If provided, whether the project should be protected
        :type protected: boolean
        :param restricted: If provided, whether the project should be restricted
        :type restricted: boolean
        :param download_restricted: If provided, whether external downloads should be restricted
        :type download_restricted: boolean
        :param contains_phi: If provided, whether the project should be marked as containing protected health information (PHI)
        :type contains_phi: boolean
        :param tags: If provided, tags to associate with the project
        :type tags: list of strings
        :param properties: If provided, properties to associate with the project
        :type properties: dict
        :param bill_to: If provided, ID of the entity to which any costs associated with this project will be billed; must be the ID of the requesting user or an org of which the requesting user is a member with allowBillableActivities permission
        :type bill_to: string

        Creates a new project. Initially only the user performing this action
        will be in the permissions/member list, with ADMINISTER access.
        See the API documentation for the `/project/new
        <https://wiki.dnanexus.com/API-Specification-v1.0.0/Projects#API-method%3A-%2Fproject%2Fnew>`_
        method for more info.

        """
        input_hash = {}
        input_hash["name"] = name
        if summary is not None:
            input_hash["summary"] = summary
        if description is not None:
            input_hash["description"] = description
        if protected is not None:
            input_hash["protected"] = protected
        if restricted is not None:
            input_hash["restricted"] = restricted
        if download_restricted is not None:
            input_hash["downloadRestricted"] = download_restricted
        if contains_phi is not None:
            input_hash["containsPHI"] = contains_phi
        if bill_to is not None:
            input_hash["billTo"] = bill_to
        if tags is not None:
            input_hash["tags"] = tags
        if properties is not None:
            input_hash["properties"] = properties

        self.set_id(dxpy.api.project_new(input_hash, **kwargs)["id"])
        self._desc = {}
        return self._dxid


Instruction:
How would you explain what the following Python 3 function does
def update(self, name=None, summary=None, description=None, protected=None,
               restricted=None, download_restricted=None, version=None, **kwargs):
        """
        :param name: If provided, the new project name
        :type name: string
        :param summary: If provided, the new project summary
        :type summary: string
        :param description: If provided, the new project description
        :type name: string
        :param protected: If provided, whether the project should be protected
        :type protected: boolean
        :param restricted: If provided, whether the project should be restricted
        :type restricted: boolean
        :param download_restricted: If provided, whether external downloads should be restricted
        :type download_restricted: boolean
        :param version: If provided, the update will only occur if the value matches the current project's version number
        :type version: int

        Updates the project with the new fields. All fields are
        optional. Fields that are not provided are not changed.
        See the API documentation for the `/project-xxxx/update
        <https://wiki.dnanexus.com/API-Specification-v1.0.0/Projects#API-method%3A-%2Fproject-xxxx%2Fupdate>`_
        method for more info.

        """
        update_hash = {}
        if name is not None:
            update_hash["name"] = name
        if summary is not None:
            update_hash["summary"] = summary
        if description is not None:
            update_hash["description"] = description
        if protected is not None:
            update_hash["protected"] = protected
        if restricted is not None:
            update_hash["restricted"] = restricted
        if download_restricted is not None:
            update_hash["downloadRestricted"] = download_restricted
        if version is not None:
            update_hash["version"] = version
        dxpy.api.project_update(self._dxid, update_hash, **kwargs)

Response: Updates the current project s attributes with the values provided.


Instruction:
Can you tell what is the following Python 3 function doing
def invite(self, invitee, level, send_email=True, **kwargs):

        return dxpy.api.project_invite(self._dxid,
                                       {"invitee": invitee, "level": level,
                                        "suppressEmailNotification": not send_email},
                                       **kwargs)

Response: Invites the specified person to the project.


Instruction:
Can you write a function in Python 3 where it
decreases the permissions of a project member.

Response:
def decrease_perms(self, member, level, **kwargs):
        """
        :param member: Username (of the form "user-USERNAME") of the project member whose permissions will be decreased.
        :type member: string
        :param level: Permissions level that the member will have after this operation (None, "VIEW", "UPLOAD", or "CONTRIBUTE")
        :type level: string or None

        Decreases the permissions that the specified user has in the project.

        """

        input_hash = {}
        input_hash[member] = level

        return dxpy.api.project_decrease_permissions(self._dxid,
                                                     input_hash,
                                                     **kwargs)


Instruction:
Here you have a function in Python 3, explain what it does
def set_properties(self, properties, **kwargs):

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

Response: Set the properties of the project for the given key - value pairs.