Librechat-copy / gradio_file.py
vaibhavard
origin
91a7855
import gradio as gr
import os
import shutil
# --- Configuration ---
INITIAL_PATH = os.getcwd() # Start in the current working directory
ALLOWED_EXTENSIONS_UPLOAD = None # Allow all file types for upload initially, or set a list like ['.txt', '.pdf']
ALLOWED_EXTENSIONS_DOWNLOAD = None # Allow all for download, or restrict if needed
# --- Helper Functions ---
def list_files_and_folders(path):
"""Lists files and folders in a given directory."""
try:
items = os.listdir(path)
files = []
folders = []
for item in items:
item_path = os.path.join(path, item)
if os.path.isfile(item_path):
files.append(item)
elif os.path.isdir(item_path):
folders.append(item)
return folders, files, path, None # Return folders, files, current path, and no error
except Exception as e:
return [], [], path, str(e) # Return empty lists and error message
def change_directory(path, current_path, direction):
"""Changes the current directory (up or into a folder)."""
new_path = current_path
if direction == "up":
new_path = os.path.dirname(current_path)
elif direction == "enter":
new_path = os.path.join(current_path, path) # Path here is the selected folder
elif direction == "refresh":
new_path = current_path # Just refresh current
if not os.path.exists(new_path) or not os.path.isdir(new_path):
return [], [], current_path, "Invalid directory path."
return list_files_and_folders(new_path)
def upload_file(files, current_path):
"""Uploads files to the current directory."""
if not files:
return [], [], current_path, "No files uploaded."
uploaded_filenames = []
for file in files:
try:
filename = os.path.basename(file.name) # Get original filename
destination_path = os.path.join(current_path, filename)
if ALLOWED_EXTENSIONS_UPLOAD: # Check allowed extensions if specified
file_extension = os.path.splitext(filename)[1].lower()
if file_extension not in ALLOWED_EXTENSIONS_UPLOAD:
return [], [], current_path, f"File type '{file_extension}' not allowed for upload."
shutil.copyfile(file.name, destination_path) # Copy uploaded file
uploaded_filenames.append(filename)
except Exception as e:
return [], [], current_path, f"Error uploading file '{filename}': {str(e)}"
# Refresh file list after upload
return list_files_and_folders(current_path)
def download_file(file_path, current_path):
"""Returns the file path for download."""
full_file_path = os.path.join(current_path, file_path) # Construct full path
if not os.path.isfile(full_file_path):
return None, "File not found for download."
if ALLOWED_EXTENSIONS_DOWNLOAD: # Check allowed extensions if specified
file_extension = os.path.splitext(full_file_path)[1].lower()
if file_extension not in ALLOWED_EXTENSIONS_DOWNLOAD:
return None, f"File type '{file_extension}' not allowed for download."
return full_file_path, None
# --- Gradio Interface ---
with gr.Blocks() as demo:
current_directory = gr.State(INITIAL_PATH)
with gr.Row():
current_path_display = gr.Textbox(value=INITIAL_PATH, label="Current Path", interactive=False, scale=4)
refresh_button = gr.Button("Refresh", scale=1)
up_button = gr.Button("Up", scale=1)
with gr.Row():
with gr.Column(scale=1):
folder_output = gr.List([], headers=["Folders"], label="Folders", elem_id="folder-list", interactive=False) # Removed type="value"
file_output = gr.List([], headers=["Files"], label="Files", elem_id="file-list", interactive=False) # Removed type="value"
with gr.Column(scale=2):
upload_component = gr.File(label="Upload Files", file_count="multiple") # Allows multiple file uploads
download_button = gr.File(label="Download Selected File")
error_output = gr.Markdown(label="Status")
# --- Functionality ---
def update_file_list(current_path):
folders, files, updated_path, error = list_files_and_folders(current_path)
return folders, files, updated_path, updated_path, error
def on_folder_select(folder_name, current_path_state):
return change_directory(folder_name, folder_output.value, "enter") # Corrected: use folder_output.value not folder_name directly
def on_up_button_click(current_path_state):
return change_directory("", current_path_state, "up") # Path is empty for "up"
def on_refresh_button_click(current_path_state):
return change_directory("", current_path_state, "refresh") # Path is empty for "refresh"
def on_file_upload(uploaded_files, current_path_state):
return upload_file(uploaded_files, current_path_state)
def on_file_select_for_download(file_name, current_path_state):
return download_file(file_name, current_path_state)
# --- Event Handlers ---
demo.load(update_file_list, inputs=current_directory, outputs=[folder_output, file_output, current_directory, current_path_display, error_output])
folder_output.select(on_folder_select, [folder_output, current_directory], [folder_output, file_output, current_directory, current_path_display, error_output])
up_button.click(on_up_button_click, inputs=current_directory, outputs=[folder_output, file_output, current_directory, current_path_display, error_output])
refresh_button.click(on_refresh_button_click, inputs=current_directory, outputs=[folder_output, file_output, current_directory, current_path_display, error_output])
upload_component.upload(on_file_upload, [upload_component, current_directory], [folder_output, file_output, current_directory, current_path_display, error_output] ) # clear_value=True to reset upload after submission
file_output.select(on_file_select_for_download, [file_output, current_directory], [download_button, error_output])
if __name__ == "__main__":
demo.launch(share=True,server_port=1337)