使用MSAL认证SharePoint后,通过ctx操作文件夹报TypeError求助
问题分析与解决方法
核心问题1:acquire_token函数返回错误
你的acquire_token函数最后返回的是函数自身acquire_token,而非获取到的令牌数据。这会导致后续初始化SharePoint上下文(ctx)失败,进而让检查函数执行出错时返回None,触发"cannot unpack non-iterable NoneType object"错误。
修复acquire_token函数
修改返回逻辑,返回有效访问令牌,并补充完整认证信息:
def acquire_token(): """ Acquire token via MSAL """ # 替换为你的租户ID,格式如:https://login.microsoftonline.com/xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx authority = 'https://login.microsoftonline.com/your-tenant-id' app = msal.ConfidentialClientApplication( client_id=client_id, client_credential=client_secret, authority=authority ) print("app---->", app) result = app.acquire_token_for_client(scopes) print("token---->", result) # 校验令牌是否获取成功 if "access_token" in result: return result["access_token"] else: raise Exception(f"令牌获取失败: {result.get('error_description', '未知错误')}")
核心问题2:检查函数异常时无返回值
check_folder_presence和check_file_presence捕获异常后仅打印错误,未返回任何值,默认返回None。当你用fold_names, folder_info = check_folder_presence(...)这种方式解包时,就会触发TypeError。
修复检查函数
在异常分支返回空元组,确保始终返回可解包的结构:
def check_folder_presence(relative_url, ctx): try: folder = ctx.web.get_folder_by_server_relative_url(relative_url) fold_names = [] folder_info = [] sub_folders = folder.folders ctx.load(sub_folders) ctx.execute_query() for s_folder in sub_folders: fold_names.append(s_folder.properties["Name"]) folder_info.append(s_folder.properties) return fold_names, folder_info except Exception as e: print('Error in printing the sharepoint library contents: ', e) return [], [] # 返回空列表组成的元组,避免解包失败 def check_file_presence(relative_url, ctx): try: folder = ctx.web.get_folder_by_server_relative_url(relative_url) fold_names = [] folder_info = [] sub_folders = folder.files ctx.load(sub_folders) ctx.execute_query() for s_folder in sub_folders: fold_names.append(s_folder.properties["Name"]) folder_info.append(s_folder.properties) return fold_names, folder_info except Exception as e: print('Error in printing the sharepoint library contents: ', e) return [], [] # 返回空列表组成的元组,避免解包失败
额外验证:SharePoint上下文初始化
确保用MSAL获取的令牌正确初始化ClientContext:
from office365.sharepoint.client_context import ClientContext access_token = acquire_token() # 替换为你的SharePoint站点URL ctx = ClientContext("your-sharepoint-site-url").with_access_token(access_token)
内容的提问来源于stack exchange,提问作者Srinivasan Sundaram
相关产品推荐
相关产品推荐

