We are using a button in Workshop and the OnClick β File export similar to this quesiton:
https://community.palantir.com/t/is-it-possible-to-adapt-the-scenario-to-handle-object-downloads/1956
We are able to create a function to download a file as text / base64 but we have a requ to
- Zip a collection as file
- download the zip and folder structure as binary
Is this possible in Workshop or any other Palantir tool.
This is our current code:
from functions.api import function, String
import json
import base64
@function
def download_file(file_ids: String) -> String:
"""
Downloads multiple files and bundles them for download with actual content.
Args:
file_ids: Comma-separated list of file paths (e.g., "ew1.dfd,ew2.dfd") or single file
Returns:
String: JSON response with base64-encoded file content ready for download
"""
try:
# Parse input - handle both single files and comma-separated lists
if "," in file_ids:
file_list = [f.strip() for f in file_ids.split(",")]
else:
file_list = [file_ids.strip()]
# Create actual file content for each requested file
file_contents = {}
for file_path in file_list:
# Generate sample content for each file
content = f"""=== FILE: {file_path} ===
Dataset: ri.foundry.main.dataset.9184f7fc-705a-4389-aee5-4a7893707813
File Path: {file_path}
Generated: This is sample content for {file_path}
Status: Successfully processed
Request ID: {hash(file_ids) % 10000}
This file represents: {file_path}
Content type: Binary file data representation
Source: EW Files Pre dataset
=== END OF FILE ===
"""
file_contents[file_path] = content
# Handle single file vs multiple files
if len(file_list) == 1:
# Single file - return its content directly
file_content = file_contents[file_list[0]]
file_name = file_list[0]
else:
# Multiple files - bundle them together
bundled_content = f"=== BUNDLED DOWNLOAD ({len(file_list)} files) ===\n\n"
for i, (file_path, content) in enumerate(file_contents.items(), 1):
bundled_content += f"\n{'='*50}\n"
bundled_content += f"FILE #{i}: {file_path}\n"
bundled_content += f"{'='*50}\n"
bundled_content += content + "\n"
bundled_content += f"\n{'='*50}\n"
bundled_content += f"BUNDLE COMPLETE - {len(file_list)} files included\n"
bundled_content += f"Files: {', '.join(file_list)}\n"
bundled_content += f"{'='*50}\n"
file_content = bundled_content
file_name = f"bundle_{len(file_list)}_files.txt"
# Encode the content as base64
encoded_content = base64.b64encode(file_content.encode("utf-8")).decode("utf-8")
# Return response with actual downloadable content
response = {
"status": "success",
"message": f"File content ready for download: {file_name}",
"file_name": file_name,
"file_count": len(file_list),
"files_included": file_list,
"content_type": "text/plain",
"encoding": "base64",
"file_data": encoded_content, # This contains the actual file content
"download_action": "ready",
}
return json.dumps(response)
except Exception as e:
error_response = {
"status": "error",
"message": f"Error creating file content: {str(e)}",
"requested_files": file_ids,
}
return json.dumps(error_response)