box / box-python-sdk

Box SDK for Python
http://opensource.box.com/box-python-sdk/
Apache License 2.0
413 stars 214 forks source link

how to download a specific file version using python sdk #838

Closed 7orG closed 11 months ago

7orG commented 11 months ago

Description of the Issue

Hello, I need to recover the history of a file, and for that, I'm trying to download a specific file version, which I will iterate with all the versions of the file (I already know how to get them), but I'm unable to do so.

Could you please help me out?

Thank you in advance.

Versions Used

Python SDK: 3.8.1 Python: 3.11.4

antusus commented 11 months ago

Hi,

we have some examples in our documentation: https://github.com/box/box-python-sdk/blob/main/docs/usage/files.md#download-a-file you can pass file version you want to download.

7orG commented 11 months ago

Hi, thank you for your fast answer,

here is my code:

from boxsdk import Client, OAuth2

try:
    # Initialize OAuth2 with your client ID, secret and access token
    oauth = OAuth2(
        client_id='CLIENT_ID',
        client_secret='CLIENT_SECRET',
        access_token='ACCESS_TOKEN',
    )

    # Create a new Box client instance
    client = Client(oauth)

    # Set the user ID you want to access
    user_id = 'USER_ID'

    # Retrieve the user object from Box
    user_object = client.user(user_id=user_id).get()

    # Create another client instance that operates as the user
    user_client = client.as_user(user_object)

    # Set the file ID for the file you want to download
    file_id = 'FILE_ID'
    file_version = client.file_version('FILE_VERSION')
    version_content = user_client.file(file_id).content(file_version=file_version)

    # Set the path where you want to store the downloaded file on your local machine
    output_file_path = 'path/Inventory.xls'

    with open(output_file_path, 'wb') as output_file:
        version_content.download_to(output_file)
        # Print a success message once the file has been downloaded
        print(f'Downloaded file {version_content.name} to {output_file_path}')

except Exception as e:
    # If anything goes wrong, print the error message
    print(f"An error occurred: {e}")

and the error thrown:

An error occurred: 'bytes' object has no attribute 'download_to'

I need the XLS file to be able to open with Excel, not binary.

Thank you again

7orG commented 11 months ago

Hi, I got it using the library request from python:

import requests

url = "https://api.box.com/2.0/files/file_id/content?version=version_id"

headers = {
    "Authorization": "Bearer ACCESS_TOKEN",
    "As-User": "USER_ID"
}

try:
    response = requests.get(url, headers=headers)

    # If the response was successful, no Exception will be raised
    response.raise_for_status()

except requests.HTTPError as http_err:
    print(f'HTTP error occurred: {http_err}')
except requests.RequestException as err:
    # A RequestException is a base class for all exceptions in the requests module.
    print(f'An error occurred: {err}')

# If there were no issues with the request, we can proceed with saving the file
else:
    with open('Inventory Balances.xls', 'wb') as f:
        f.write(response.content)
    print('File successfully saved.')

Thank you!!

lukaszsocha2 commented 11 months ago

Hi @7orG, you could have achieved same result with:

    # Set the file ID for the file you want to download
    file_id = 'FILE_ID'
    file_version = client.file_version('FILE_VERSION')
    file = user_client.file(file_id)

    # Set the path where you want to store the downloaded file on your local machine
    output_file_path = 'path/Inventory.xls'

    with open(output_file_path, 'wb') as output_file:
        file.download_to(output_file, file_version=file_version)
        # Print a success message once the file has been downloaded
        print(f'Downloaded file {file.name} to {output_file_path}')