Skip to content

download_file

autogen.tools.experimental.google.drive.drive_functions.download_file #

download_file(service, file_id, file_name, mime_type, download_folder, subfolder_path=None)

Download or export file based on its MIME type, optionally saving to a subfolder.

Source code in autogen/tools/experimental/google/drive/drive_functions.py
@require_optional_import(
    [
        "googleapiclient",
    ],
    "google-api",
)
def download_file(
    service: Any,
    file_id: str,
    file_name: str,
    mime_type: str,
    download_folder: Path,
    subfolder_path: Optional[str] = None,
) -> str:
    """Download or export file based on its MIME type, optionally saving to a subfolder."""
    file_extension = _get_file_extension(mime_type)
    if file_extension and (not file_name.lower().endswith(file_extension.lower())):
        file_name = f"{file_name}.{file_extension}"

    # Define export formats for Google Docs, Sheets, and Slides
    export_mime_types = {
        "application/vnd.google-apps.document": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",  # Google Docs → Word
        "application/vnd.google-apps.spreadsheet": "text/csv",  # Google Sheets → CSV
        "application/vnd.google-apps.presentation": "application/vnd.openxmlformats-officedocument.presentationml.presentation",  # Google Slides → PowerPoint
    }

    # Google Docs, Sheets, and Slides cannot be downloaded directly using service.files().get_media() because they are Google-native files
    if mime_type in export_mime_types:
        request = service.files().export(fileId=file_id, mimeType=export_mime_types[mime_type])
    else:
        # Download normal files (videos, images, etc.)
        request = service.files().get_media(fileId=file_id)

    # Determine the final destination directory
    destination_dir = download_folder
    if subfolder_path:
        destination_dir = download_folder / subfolder_path
        # Ensure the subfolder exists, create it if necessary
        destination_dir.mkdir(parents=True, exist_ok=True)

    # Construct the full path for the file
    file_path = destination_dir / file_name

    # Save file
    try:
        with io.BytesIO() as buffer:
            downloader = MediaIoBaseDownload(buffer, request)
            done = False
            while not done:
                _, done = downloader.next_chunk()

            buffer.seek(0)

            with open(file_path, "wb") as f:
                f.write(buffer.getvalue())

        # Print out the relative path of the downloaded file
        relative_path = Path(subfolder_path) / file_name if subfolder_path else Path(file_name)
        return f"✅ Downloaded: {relative_path}"

    except Exception as e:
        # Error message if unable to download
        relative_path = Path(subfolder_path) / file_name if subfolder_path else Path(file_name)
        return f"❌ FAILED to download {relative_path}: {e}"