修改powerbiclient的DeviceCodeLoginAuthentication类实现认证提示信息的Streamlit展示与文件写入
修改powerbiclient的DeviceCodeLoginAuthentication类实现认证提示信息的Streamlit展示与文件写入
嘿,我来帮你搞定这个需求!你想要把powerbiclient里设备流认证的提示信息拿到Streamlit中展示,同时写入到文件里对吧?其实不用直接修改原库的源码,我们可以通过继承原类并重写关键方法来实现,这样既安全又不会影响后续库的更新。
实现思路
原DeviceCodeLoginAuthentication类用print输出认证提示,我们可以自定义一个子类继承它,重写_acquire_token_device_code方法,把print替换成:
- 把提示信息保存到实例变量中,方便Streamlit调用展示
- 将信息写入指定文件
- 保留原有的认证逻辑,确保功能不受影响
完整代码示例
1. 自定义认证类
import json import msal import streamlit as st from powerbiclient.authentication import DeviceCodeLoginAuthentication, DEFAULT_SCOPES class StreamlitDeviceCodeAuth(DeviceCodeLoginAuthentication): def __init__(self, client_id, output_file="powerbi_auth_log.txt"): self.client_id = client_id self.output_file = output_file self.auth_message = "" # 存储认证提示信息的实例变量 super().__init__() # 触发父类初始化流程,自动调用重写后的_acquire_token_device_code def _acquire_token_device_code(self): """重写父类方法,替换print为Streamlit展示+文件写入""" app = msal.PublicClientApplication(client_id=self.client_id) flow = app.initiate_device_flow(scopes=DEFAULT_SCOPES) if "user_code" not in flow: raise ValueError("Fail to create device flow. Err: %s" % json.dumps(flow, indent=4)) # 拼接完整的认证提示信息 self.auth_message = f"Performing device flow authentication. Please follow the instructions below.\n{flow['message']}" # 在Streamlit中展示提示信息 st.write(self.auth_message) # 将提示信息写入指定文件 with open(self.output_file, "w", encoding="utf-8") as f: f.write(self.auth_message) # 执行原有的设备流认证逻辑 result = app.acquire_token_by_device_flow(flow) if "access_token" in result: success_msg = "\nDevice flow authentication successfully completed.\nYou are now logged in.\n\nThe result should be passed only to trusted code in your notebook." st.write(success_msg) # Streamlit展示成功信息 # 追加写入成功信息到文件 with open(self.output_file, "a", encoding="utf-8") as f: f.write(success_msg) self._app = app else: error_message = f"Authentication failed. Try again.\nDetails: {result.get('error_description')}" st.error(error_message) # Streamlit展示错误信息 # 追加写入错误信息到文件 with open(self.output_file, "a", encoding="utf-8") as f: f.write(f"\n{error_message}") raise RuntimeError(error_message)
2. 在Streamlit中使用自定义类
# 替换为你自己的Power BI应用客户端ID CLIENT_ID = "your-client-id-here" if st.button('Entrar em BI'): try: # 初始化自定义认证类,可指定输出文件路径(默认是powerbi_auth_log.txt) auth = StreamlitDeviceCodeAuth(client_id=CLIENT_ID, output_file="my_auth_log.txt") # 如果需要获取访问令牌,直接调用以下方法 # access_token = auth.get_access_token() except Exception as e: st.error(f"认证过程出错:{str(e)}")
关键说明
- 我们通过
auth_message实例变量存储提示信息,你可以随时通过auth.auth_message调用它,完全替代你原来想的st.write(f'{t._acquire_token_device_code.mensagem}')写法 - 文件写入支持自定义路径,相对路径会保存在Streamlit运行的当前目录,也可以指定绝对路径确保位置准确
- 保留了原类的所有认证逻辑,成功/错误信息都会同步展示在Streamlit和文件中
注意事项
- 确保已安装所有依赖:
pip install powerbiclient streamlit msal - 替换代码中的
CLIENT_ID为你实际的Power BI应用客户端ID
备注:内容来源于stack exchange,提问作者Fabrício Gama
相关产品推荐
相关产品推荐

