我的Skyboy应用是小众产品,但我觉得还是挺爽的! (说实话,我有点偏见。毕竟我确实是为自己编写的。)这是一个使用Streamlit框架的 Python Web 应用程序。

最初,没有办法预览 Skyboy 可以用 FPV 无人机飞行遥测数据做什么。虽然文件上传功能有效,但它还没有被广泛化(可能)来处理来自其他用户的遥测日志。有可用的演示数据允许用户预览应用程序的功能,这对于没有自己的遥测日志的任何人特别有用。

访问演示数据

我的第一个任务是决定在哪里存储演示遥测文件。我本可以将它打包到应用程序的 Docker 容器中,但我想开始集成其他 AWS 服务,因此我将文件上传到 S3 存储桶。

我尝试创建一个签名的 URL 以授予应用程序对文件的访问权限,但无法使其工作。我怀疑它与文件的访问权限有关。经过几次尝试,我后退并决定走一条更简单的路线。我创建了一个 IAM 用户,其唯一权限是对该 S3 存储桶的读取访问权限,并将该用户的凭证作为机密存储在 GitHub 上,以便在构建应用程序的映像时将其注入到应用程序中。

从那里,我编写了一个简单的函数,它使用 boto3 创建一个 S3 客户端并将文件下载到内存。我编写了一个“演示”按钮并将其设置为运行下载功能,并确保代码逻辑的可视化部分检查按钮是否已被单击。

消失法

到目前为止,一切顺利:单击按钮下载文件,其余代码读取文件并生成其通常的可视化。现在,让我们看看这些英制单位的数字......

-选择适当的复选框-

... 等一等。所有花哨的指标和图表都去哪儿了?

使用上传的遥测文件,选中该复选框可转换单位并显示英尺、英里/小时等。但是使用演示数据,应用程序将自身重置为其初始外观。很困惑,我试图通过重新安排我的一些逻辑来解决这个错误,但在几次越来越令人沮丧的尝试之后,我关闭了我的电脑,然后离开了一夜。

有状态的解决方案

第二天早上,我通过 Streamlit 的文档重新解决了这个问题。当我阅读有关会话状态的部分时,我突然意识到这个功能正是我所需要的。

每次某些输入(如按钮、复选框或菜单)更改时,Streamlit 应用程序都会从顶部重新运行。我知道这种行为,但在尝试实施演示模式之前没有遇到任何问题。当我仔细查看我的代码时,我发现了错误的根源:我进行了条件逻辑检查以查看是否单击了 Demo 按钮。自然,如果某些其他输入发生了变化,应用程序将重新运行,但在随后的运行中,按钮不会被点击,应用程序也不会加载演示数据。因此,我需要一种方法让应用程序知道演示模式是否已激活并在运行之间持续存在。

我创建了一个demomode变量并将其最初设置为False:

if 'demomode' not in st.session_state:
    st.session_state.demomode = False

进入全屏模式 退出全屏模式

单击 Demo 按钮将此变量的值更改为True,然后只要应用程序的浏览器选项卡保持打开状态,该值就会在运行之间保持不变。应用程序的条件引用此持久变量以确定是否应从缓存中读取或加载演示遥测数据:

if not uploaded_file and not st.session_state.demomode:
    # display initial markdown with text and images

进入全屏模式 退出全屏模式

if st.session_state.demomode or (uploaded_file is not None):
    # read and/or load data from the appropriate source and
    # call the visualization functions

进入全屏模式 退出全屏模式

随着应用程序检查会话状态以查看是否已激活演示模式,用于操作可视化的其他侧边栏输入按预期工作!

总结

在 Skyboy 中实现演示模式的一些经验教训:

  • 阅读和重读文档的好处;

  • 能够在应用程序状态中持久存储信息的价值;

  • 以及在面临艰巨挑战时走开并创造处理时间的力量。

在此处查看 Skyboy GitHub 存储库!

Logo

学AI,认准AI Studio!GPU算力,限时免费领,邀请好友解锁更多惊喜福利 >>>

更多推荐