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

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())

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

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}')

@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!

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

@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")

@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

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