Uploads a file

        :param item: path to the item you want to upload
        :type item: str or Path
        :param chunk_size: Only applies if file is bigger than 4MB.
         Chunk size for uploads. Must be a multiple of 327.680 bytes
        :return: uploaded file
        :rtype: DriveItem

def upload_file(self, item, chunk_size=DEFAULT_UPLOAD_CHUNK_SIZE):
        """ Uploads a file

        :param item: path to the item you want to upload
        :type item: str or Path
        :param chunk_size: Only applies if file is bigger than 4MB.
         Chunk size for uploads. Must be a multiple of 327.680 bytes
        :return: uploaded file
        :rtype: DriveItem
        """

        if item is None:
            raise ValueError('Item must be a valid path to file')
        item = Path(item) if not isinstance(item, Path) else item

        if not item.exists():
            raise ValueError('Item must exist')
        if not item.is_file():
            raise ValueError('Item must be a file')

        file_size = item.stat().st_size

        if file_size <= UPLOAD_SIZE_LIMIT_SIMPLE:
            # Simple Upload
            url = self.build_url(
                self._endpoints.get('simple_upload').format(id=self.object_id,
                                                            filename=item.name))
            # headers = {'Content-type': 'text/plain'}
            headers = {'Content-type': 'application/octet-stream'}
            # headers = None
            with item.open(mode='rb') as file:
                data = file.read()

            response = self.con.put(url, headers=headers, data=data)
            if not response:
                return None

            data = response.json()

            return self._classifier(data)(parent=self,
                                          **{self._cloud_data_key: data})
        else:
            # Resumable Upload
            url = self.build_url(
                self._endpoints.get('create_upload_session').format(
                    id=self.object_id, filename=item.name))

            response = self.con.post(url)
            if not response:
                return None

            data = response.json()

            upload_url = data.get(self._cc('uploadUrl'), None)
            if upload_url is None:
                log.error('Create upload session response without '
                          'upload_url for file {}'.format(item.name))
                return None

            current_bytes = 0
            with item.open(mode='rb') as file:
                while True:
                    data = file.read(chunk_size)
                    if not data:
                        break
                    transfer_bytes = len(data)
                    headers = {
                        'Content-type': 'application/octet-stream',
                        'Content-Length': str(len(data)),
                        'Content-Range': 'bytes {}-{}/{}'
                                         ''.format(current_bytes,
                                                   current_bytes +
                                                   transfer_bytes - 1,
                                                   file_size)
                    }
                    current_bytes += transfer_bytes

                    # this request mut NOT send the authorization header.
                    # so we use a naive simple request.
                    response = self.con.naive_request(upload_url, 'PUT',
                                                      data=data,
                                                      headers=headers)
                    if not response:
                        return None

                    if response.status_code != 202:
                        # file is completed
                        data = response.json()
                        return self._classifier(data)(parent=self, **{
                            self._cloud_data_key: data})