107 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			107 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| 
								 | 
							
								import io
							 | 
						||
| 
								 | 
							
								import ntpath
							 | 
						||
| 
								 | 
							
								import base64
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# region Utils for Download component
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def send_file(path, filename=None, type=None):
							 | 
						||
| 
								 | 
							
								    """
							 | 
						||
| 
								 | 
							
								    Convert a file into the format expected by the Download component.
							 | 
						||
| 
								 | 
							
								    :param path: path to the file to be sent
							 | 
						||
| 
								 | 
							
								    :param filename: name of the file, if not provided the original filename is used
							 | 
						||
| 
								 | 
							
								    :param type: type of the file (optional, passed to Blob in the javascript layer)
							 | 
						||
| 
								 | 
							
								    :return: dict of file content (base64 encoded) and meta data used by the Download component
							 | 
						||
| 
								 | 
							
								    """
							 | 
						||
| 
								 | 
							
								    # If filename is not set, read it from the path.
							 | 
						||
| 
								 | 
							
								    if filename is None:
							 | 
						||
| 
								 | 
							
								        filename = ntpath.basename(path)
							 | 
						||
| 
								 | 
							
								    # Read the file contents and send it.
							 | 
						||
| 
								 | 
							
								    with open(path, "rb") as f:
							 | 
						||
| 
								 | 
							
								        return send_bytes(f.read(), filename, type)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def send_bytes(src, filename, type=None, **kwargs):
							 | 
						||
| 
								 | 
							
								    """
							 | 
						||
| 
								 | 
							
								    Convert data written to BytesIO into the format expected by the Download component.
							 | 
						||
| 
								 | 
							
								    :param src: array of bytes or a writer that can write to BytesIO
							 | 
						||
| 
								 | 
							
								    :param filename: the name of the file
							 | 
						||
| 
								 | 
							
								    :param type: type of the file (optional, passed to Blob in the javascript layer)
							 | 
						||
| 
								 | 
							
								    :return: dict of data frame content (base64 encoded) and meta data used by the Download component
							 | 
						||
| 
								 | 
							
								    """
							 | 
						||
| 
								 | 
							
								    content = src if isinstance(src, bytes) else _io_to_str(io.BytesIO(), src, **kwargs)
							 | 
						||
| 
								 | 
							
								    return dict(
							 | 
						||
| 
								 | 
							
								        content=base64.b64encode(content).decode(),
							 | 
						||
| 
								 | 
							
								        filename=filename,
							 | 
						||
| 
								 | 
							
								        type=type,
							 | 
						||
| 
								 | 
							
								        base64=True,
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def send_string(src, filename, type=None, **kwargs):
							 | 
						||
| 
								 | 
							
								    """
							 | 
						||
| 
								 | 
							
								    Convert data written to StringIO into the format expected by the Download component.
							 | 
						||
| 
								 | 
							
								    :param src: a string or a writer that can write to StringIO
							 | 
						||
| 
								 | 
							
								    :param filename: the name of the file
							 | 
						||
| 
								 | 
							
								    :param type: type of the file (optional, passed to Blob in the javascript layer)
							 | 
						||
| 
								 | 
							
								    :return: dict of data frame content (NOT base64 encoded) and meta data used by the Download component
							 | 
						||
| 
								 | 
							
								    """
							 | 
						||
| 
								 | 
							
								    content = src if isinstance(src, str) else _io_to_str(io.StringIO(), src, **kwargs)
							 | 
						||
| 
								 | 
							
								    return dict(content=content, filename=filename, type=type, base64=False)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def _io_to_str(data_io, writer, **kwargs):
							 | 
						||
| 
								 | 
							
								    # Some pandas writers try to close the IO, we do not want that.
							 | 
						||
| 
								 | 
							
								    data_io_close = data_io.close
							 | 
						||
| 
								 | 
							
								    data_io.close = lambda: None
							 | 
						||
| 
								 | 
							
								    # Write data content.
							 | 
						||
| 
								 | 
							
								    writer(data_io, **kwargs)
							 | 
						||
| 
								 | 
							
								    data_value = data_io.getvalue()
							 | 
						||
| 
								 | 
							
								    data_io_close()
							 | 
						||
| 
								 | 
							
								    return data_value
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def send_data_frame(writer, filename, type=None, **kwargs):
							 | 
						||
| 
								 | 
							
								    """
							 | 
						||
| 
								 | 
							
								    Convert data frame into the format expected by the Download component.
							 | 
						||
| 
								 | 
							
								    :param writer: a data frame writer
							 | 
						||
| 
								 | 
							
								    :param filename: the name of the file
							 | 
						||
| 
								 | 
							
								    :param type: type of the file (optional, passed to Blob in the javascript layer)
							 | 
						||
| 
								 | 
							
								    :return: dict of data frame content (base64 encoded) and meta data used by the Download component
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Examples
							 | 
						||
| 
								 | 
							
								    --------
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    >>> df = pd.DataFrame({'a': [1, 2, 3, 4], 'b': [2, 1, 5, 6], 'c': ['x', 'x', 'y', 'y']})
							 | 
						||
| 
								 | 
							
								    ...
							 | 
						||
| 
								 | 
							
								    >>> send_data_frame(df.to_csv, "mydf.csv")  # download as csv
							 | 
						||
| 
								 | 
							
								    >>> send_data_frame(df.to_json, "mydf.json")  # download as json
							 | 
						||
| 
								 | 
							
								    >>> send_data_frame(df.to_excel, "mydf.xls", index=False) # download as excel
							 | 
						||
| 
								 | 
							
								    >>> send_data_frame(df.to_pickle, "mydf.pkl") # download as pickle
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    """
							 | 
						||
| 
								 | 
							
								    name = writer.__name__
							 | 
						||
| 
								 | 
							
								    # Check if the provided writer is known.
							 | 
						||
| 
								 | 
							
								    if name not in _data_frame_senders.keys():
							 | 
						||
| 
								 | 
							
								        raise ValueError(
							 | 
						||
| 
								 | 
							
								            "The provided writer ({}) is not supported, "
							 | 
						||
| 
								 | 
							
								            "try calling send_string or send_bytes directly.".format(name)
							 | 
						||
| 
								 | 
							
								        )
							 | 
						||
| 
								 | 
							
								    # Send data frame using the appropriate send function.
							 | 
						||
| 
								 | 
							
								    return _data_frame_senders[name](writer, filename, type, **kwargs)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								_data_frame_senders = {
							 | 
						||
| 
								 | 
							
								    "to_csv": send_string,
							 | 
						||
| 
								 | 
							
								    "to_json": send_string,
							 | 
						||
| 
								 | 
							
								    "to_html": send_string,
							 | 
						||
| 
								 | 
							
								    "to_excel": send_bytes,
							 | 
						||
| 
								 | 
							
								    "to_feather": send_bytes,
							 | 
						||
| 
								 | 
							
								    "to_parquet": send_bytes,
							 | 
						||
| 
								 | 
							
								    "to_msgpack": send_bytes,
							 | 
						||
| 
								 | 
							
								    "to_stata": send_bytes,
							 | 
						||
| 
								 | 
							
								    "to_pickle": send_bytes,
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# endregion
							 |