Skip to main content
Solved

Not able to get folder info using access token


Hello!
I created app as “OAuth 2.0 with Client Credentials Grant (Server Authentication)” and used below python code to get the access token and get a folder info.

Im able to get the access token but when I try to get the folder information i get this error

{‘type’: ‘error’, ‘status’: 404, ‘code’: ‘not_found’, ‘context_info’: {‘errors’: [{‘reason’: ‘invalid_parameter’, ‘name’: ‘folder’, ‘message’: “Invalid value ‘d_232374452899’. ‘folder’ with value ‘d_232374452899’ not found”}]}, ‘help_url’: ‘http://developers.box.com/docs/#errors’, ‘message’: ‘Not Found’, ‘request_id’: ‘5el5t3hj87nd3i9z’}

can any one please help me resolve this error?

here is my python code

Best answer by rbarbosa Box

@DCuser122

The folder.get_items returns few details and several object types, like file, folder, and weblink

So we have to do this in 3 steps:

  • From the items grab only files
  • For each item representing a file, grab the details, which includes the modified at
  • Sort that list

Consider this method:

def files_in_folder(client: Client, folder_id: str = "0"):
    try:
        folder = client.folder(folder_id=folder_id).get()
    except BoxAPIException as e:
        if e.status == 404:
            print(f"Folder {folder_id} not found\n")
            return

    print(f"Items in: {folder.name} {folder.id}")
    print("-" * 80)

    # grab the items in the folder
    items = folder.get_items()

    # filter out the files and get their details
    files = [item.get() for item in items if item.type == "file"]

    # sort the files by modified date
    files.sort(key=lambda x: x.modified_at, reverse=True)

    # print the files
    for file in files:
        # file = file.get()
        print(f"{file.type} {file.modified_at} ({file.id}) {file.name} ")

    # get the newest file
    newest_file = files[0]
    print(f"\nNewest file:{file.modified_at} {newest_file.name} {newest_file.id}")

Modifying the main method:

def main():
    # service account
    client = get_box_client(None)
    # me = client.user().get()
    # print(f"Service account: {me.name} {me.id}")
    # folder_content(client)
    # print(f"Service account: {me.name} {me.id}")
    # folder_content(client, FOLDER_ID)

    # as-user
    user = client.user(USER_ID).get()
    as_user_client = client.as_user(user)
    me = as_user_client.user().get()
    print(f"As-User account: {me.name} {me.id}")
    files_in_folder(as_user_client, "165803865043")

Results in:

As-User account: Rui Barbosa 18622116055
Items in: Preview Samples 165803865043
--------------------------------------------------------------------------------
file 2023-05-17T06:50:27-07:00 (1216393081021) BoxAPISingDemoDoc (1) (2).pdf 
file 2023-03-06T11:30:16-08:00 (974225001875) ZIP_renamed.zip 
file 2023-03-06T11:23:12-08:00 (974207525964) Audio_renamed.mp3 
file 2022-08-17T07:28:54-07:00 (997819641379) mov_bbb.mp4 
file 2022-08-16T14:53:38-07:00 (997509657533) BoxAPISingDemoDoc (1) (1).pdf 
file 2022-06-21T14:01:14-07:00 (974226696777) BoxAPISingDemoDoc (1).pdf 
file 2022-06-21T13:55:01-07:00 (974229112148) Single Page.docx 
file 2022-06-21T13:55:00-07:00 (974225083627) JSON.json 
file 2022-06-21T13:55:00-07:00 (974225084827) Preview SDK Sample Excel.xlsx 
file 2022-06-21T13:54:59-07:00 (974228631587) Document (Powerpoint).pptx 
file 2022-06-21T13:54:59-07:00 (974209854641) HTML.html 
file 2022-06-21T13:54:59-07:00 (974227441126) JS-Small.js 

Newest file: BoxAPISingDemoDoc (1) (2).pdf 1216393081021

Not sure if time zones are important in this situation, but consider them.

Let us know if this works for you.

Cheers

View original
Did this topic help you find an answer to your question?

  • Participating Frequently
  • October 25, 2023

here is my python code

import requests
from boxsdk import Client, OAuth2


CLIENT_ID = '***************'
CLIENT_SECRET = '*************'
AUTHORIZATION_URL = 'https://api.box.com/oauth2/token'

# Define the payload for the authentication request
payload = {
    'grant_type': 'client_credentials',
    'client_id': CLIENT_ID,
    'client_secret': CLIENT_SECRET,
    'box_subject_type': 'enterprise',  # Add the appropriate subject type here,
    'box_subject_id':'444444'
}

# Make a POST request to the authorization URL with the headers
response = requests.post(AUTHORIZATION_URL, data=payload)

# Extract the access token from the response
if response.status_code == 200:
    access_token = response.json()['access_token']
    print(f'Access Token: {access_token}')
else:
    print(f'Failed to retrieve access token. Status code: {response.status_code}, Error: {response.text}')

BOX_ACCESS_TOKEN = access_token


# # Define your folder ID
FOLDER_ID = "232374452899"


# Make a request to the Box API to get the list of items in the folder
response = requests.get(
    f"https://api.box.com/2.0/folders/{FOLDER_ID}/items?sort=date&limit=1&direction=DESC",
    headers={"Authorization": f"Bearer {BOX_ACCESS_TOKEN}"}
)

print(response.json())

rbarbosa Box

Hi @DCuser122 , welcome to the forum!

Most likely the service account associated with the CCG authentication, does not have access to the folder.

Have you tried the as-user option and pass the user id of the folder owner?

The are several options to solve this, let us know your use case.

Cheers


  • Participating Frequently
  • October 25, 2023

Thank you @rbarbosa !

I tried this but i get the same error. I’m a collaborator to the app.

# Define the user ID for the 'As-User' header
user_id = '29554489963'  

# Define the headers including the 'As-User' header
headers = {
    'as-user': user_id
}

# Make a POST request to the authorization URL with the headers
response = requests.post(AUTHORIZATION_URL, data=payload, headers=headers)

# Extract the access token from the response
if response.status_code == 200:
    access_token = response.json()['access_token']
    print(f'Access Token: {access_token}')
else:
    print(f'Failed to retrieve access token. Status code: {response.status_code}, Error: {response.text}')

  • Participating Frequently
  • October 26, 2023

@rbarbosa my use case is

we have a enterprise box account and need to download most recent excel file from a folder every week.

To do this, I have created a custom app “OAuth 2.0 with Client Credentials Grant (Server Authentication)” setting and added my account a collaborator.

Please let me if you need any other details.

Looking forward to your response to fix this problem.

thanks!


rbarbosa Box

Hi @DCuser122

Let me try to illustrate what I mean by permission issue.

As a user I’ve created a folder and put some files in there:

Notice the url with the folder id.

Now consider this python script:

"""sample to illustrate service account access to box content"""
import logging
from boxsdk import CCGAuth, Client
from boxsdk.exception import BoxAPIException

logging.basicConfig(level=logging.INFO)
logging.getLogger("boxsdk").setLevel(logging.CRITICAL)

CLIENT_ID = "h5...qi"
CLIENT_SECRET = "Tq...8"

ENTERPRISE_ID = "877840855"
USER_ID = "18622116055"

FOLDER_ID = "232513398018"


def get_box_client(user_id: str = None, enterprise_id: str = ENTERPRISE_ID):
    """get a box client with a service account"""
    auth = CCGAuth(client_id=CLIENT_ID, client_secret=CLIENT_SECRET, user=user_id, enterprise_id=enterprise_id)
    client = Client(auth)
    return client


def folder_content(client: Client, folder_id: str = "0"):
    """get folder content"""
    try:
        folder = client.folder(folder_id=folder_id).get()
    except BoxAPIException as e:
        if e.status == 404:
            print(f"Folder {folder_id} not found\n")
            return

    print(f"Items in: {folder.name} {folder.id}")
    print("-" * 80)
    items = folder.get_items()
    for item in items:
        print(f"{item.type} {item.name} {item.id}")
    print("-" * 80 + "\n")


def main():
    # service account
    client = get_box_client(None)
    me = client.user().get()
    print(f"Service account: {me.name} {me.id}")
    folder_content(client)
    print(f"Service account: {me.name} {me.id}")
    folder_content(client, FOLDER_ID)

    # as-user
    user = client.user(USER_ID).get()
    as_user_client = client.as_user(user)
    me = as_user_client.user().get()
    print(f"As-User account: {me.name} {me.id}")
    folder_content(as_user_client, FOLDER_ID)


if __name__ == "__main__":
    main()

Note that USER_ID = "18622116055" is the owner of the folder, in this case me.

Now if you run this script it results in:

Service account: CCG 20706451735
Items in: All Files 0
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

Service account: CCG 20706451735
Folder 232513398018 not found

As-User account: Rui Barbosa 18622116055
Items in: Folder to store files 232513398018
--------------------------------------------------------------------------------
file Sample A.docx 1345101805458
file Sample B.xlsx 1345083652268
--------------------------------------------------------------------------------

Service account CCG has no files or folders shared (collaborated) with it. Listing the root folder FOLDER_ID=0 shows an empty list.

As expected listing FOLDER_ID = "232513398018" returns a 404 not found.

However, and still using the CCG enterprise client, I point the as-user to the owner of the folder, int this case USER_ID = "18622116055" I can list the folder content.

# as-user
user = client.user(USER_ID).get()
as_user_client = client.as_user(user)
me = as_user_client.user().get()
print(f"As-User account: {me.name} {me.id}")
folder_content(as_user_client, FOLDER_ID)

Resulting in:

As-User account: Rui Barbosa 18622116055
Items in: Folder to store files 232513398018
--------------------------------------------------------------------------------
file Sample A.docx 1345101805458
file Sample B.xlsx 1345083652268
--------------------------------------------------------------------------------

To do this you need to have your CCG app configured as follows:

App Access Level: App+Enterprise Access

Application Scopes: At least Manage users

Advanced Features: Make API calls using the as-user header

If you make changes to these remember to reauthorize your app, so changes take effect:

And then approve them in the admin console:

Let us know if this solves the issue.

Cheers


  • Participating Frequently
  • October 26, 2023

@rbarbosa Thank you so much! It worked.

The problem was I didn’t submit the app for re-auth for authorization. After reauth it worked.

I have another question, how do i get last modified file from your code.

def folder_content(client: Client, folder_id: str = "0"):
    """get folder content"""
    try:
        folder = client.folder(folder_id=folder_id).get()
    except BoxAPIException as e:
        if e.status == 404:
            print(f"Folder {folder_id} not found\n")
            return

    print(f"Items in: {folder.name} {folder.id}")
    print("-" * 80)
    items = folder.get_items()
    for item in items:
        print(f"{item.type} {item.name} {item.id}")
    print("-" * 80 + "\n")

rbarbosa Box

@DCuser122

The folder.get_items returns few details and several object types, like file, folder, and weblink

So we have to do this in 3 steps:

  • From the items grab only files
  • For each item representing a file, grab the details, which includes the modified at
  • Sort that list

Consider this method:

def files_in_folder(client: Client, folder_id: str = "0"):
    try:
        folder = client.folder(folder_id=folder_id).get()
    except BoxAPIException as e:
        if e.status == 404:
            print(f"Folder {folder_id} not found\n")
            return

    print(f"Items in: {folder.name} {folder.id}")
    print("-" * 80)

    # grab the items in the folder
    items = folder.get_items()

    # filter out the files and get their details
    files = [item.get() for item in items if item.type == "file"]

    # sort the files by modified date
    files.sort(key=lambda x: x.modified_at, reverse=True)

    # print the files
    for file in files:
        # file = file.get()
        print(f"{file.type} {file.modified_at} ({file.id}) {file.name} ")

    # get the newest file
    newest_file = files[0]
    print(f"\nNewest file:{file.modified_at} {newest_file.name} {newest_file.id}")

Modifying the main method:

def main():
    # service account
    client = get_box_client(None)
    # me = client.user().get()
    # print(f"Service account: {me.name} {me.id}")
    # folder_content(client)
    # print(f"Service account: {me.name} {me.id}")
    # folder_content(client, FOLDER_ID)

    # as-user
    user = client.user(USER_ID).get()
    as_user_client = client.as_user(user)
    me = as_user_client.user().get()
    print(f"As-User account: {me.name} {me.id}")
    files_in_folder(as_user_client, "165803865043")

Results in:

As-User account: Rui Barbosa 18622116055
Items in: Preview Samples 165803865043
--------------------------------------------------------------------------------
file 2023-05-17T06:50:27-07:00 (1216393081021) BoxAPISingDemoDoc (1) (2).pdf 
file 2023-03-06T11:30:16-08:00 (974225001875) ZIP_renamed.zip 
file 2023-03-06T11:23:12-08:00 (974207525964) Audio_renamed.mp3 
file 2022-08-17T07:28:54-07:00 (997819641379) mov_bbb.mp4 
file 2022-08-16T14:53:38-07:00 (997509657533) BoxAPISingDemoDoc (1) (1).pdf 
file 2022-06-21T14:01:14-07:00 (974226696777) BoxAPISingDemoDoc (1).pdf 
file 2022-06-21T13:55:01-07:00 (974229112148) Single Page.docx 
file 2022-06-21T13:55:00-07:00 (974225083627) JSON.json 
file 2022-06-21T13:55:00-07:00 (974225084827) Preview SDK Sample Excel.xlsx 
file 2022-06-21T13:54:59-07:00 (974228631587) Document (Powerpoint).pptx 
file 2022-06-21T13:54:59-07:00 (974209854641) HTML.html 
file 2022-06-21T13:54:59-07:00 (974227441126) JS-Small.js 

Newest file: BoxAPISingDemoDoc (1) (2).pdf 1216393081021

Not sure if time zones are important in this situation, but consider them.

Let us know if this works for you.

Cheers


  • Participating Frequently
  • October 31, 2023

@rbarbosa Thank you so much for your time!! It works.


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings