Skip to main content

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’: c{‘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.


Reply