到目前为止,我们构建的应用程序只使用了我们自己的代码,加上 BeeWare 提供的代码。但是,在实际应用中,您可能希望使用从 Python 包索引 (PyPI) 下载的第三方库。
让我们修改我们的应用程序以包含第三方库。
访问 API
应用程序需要执行的一项常见任务是在 Web API 上发出请求以检索数据,并将该数据显示给用户。这是一个玩具应用程序,所以我们没有真正的API 可以使用,所以我们将使用{JSON} Placeholder API作为数据源。
{JSON} 占位符 API 有许多可以用作测试数据的“假”API 端点。这些 API 之一是/posts/端点,它返回虚假的博客文章。如果您https://jsonplaceholder.typicode.com/posts/42在浏览器中打开,您将获得描述单个帖子的 JSON 有效负载 - ID 为 42 的博客帖子的一些Lorum ipsum内容。
Python 标准库包含访问 API 所需的所有工具。但是,内置 API 的级别非常低。它们是 HTTP 协议的良好实现——但它们需要用户管理许多低级细节,例如 URL 重定向、会话、身份验证和有效负载编码。作为“普通浏览器用户”,您可能习惯于将这些细节视为理所当然,因为浏览器会为您管理这些细节。
因此,人们开发了第三方库,这些库封装了内置 API,并提供了更简单的 API,更接近日常浏览器体验。我们将使用其中一个库来访问 {JSON} Placeholder API - 一个名为httpx的库。
让我们向我们的应用程序添加一个httpxAPI 调用。app.py在to import的顶部添加一个 导入httpx:
import httpx
然后修改say_hello()回调,使其看起来像这样:
def say_hello(self, widget):if self.name_input.value:name = self.name_input.valueelse:name = 'stranger'with httpx.Client() as client:response = client.get("https://jsonplaceholder.typicode.com/posts/42")payload = response.json()self.main_window.info_dialog("Hello, {}".format(name),payload["body"],)
这将更改say_hello()回调,以便在调用它时,它将:
在 JSON 占位符 API 上发出 GET 请求以获取帖子 42;
让我们在公文包开发者模式下运行我们更新的应用程序,以检查我们的更改是否有效。
苹果系统
(beeware-venv) $ briefcase dev
Traceback (most recent call last):
File ".../venv/bin/briefcase", line 5, in
File ".../venv/lib/python3.9/site-packages/briefcase/__main__.py", line 3, in
File ".../venv/lib/python3.9/site-packages/briefcase/cmdline.py", line 6, in
File ".../venv/lib/python3.9/site-packages/briefcase/commands/__init__.py", line 1, in
File ".../venv/lib/python3.9/site-packages/briefcase/commands/build.py", line 5, in
File ".../venv/lib/python3.9/site-packages/briefcase/commands/base.py", line 14, in
ModuleNotFoundError: No module named 'httpx'
Linux
(beeware-venv) $ briefcase dev
Traceback (most recent call last):
File ".../venv/bin/briefcase", line 5, in
File ".../venv/lib/python3.9/site-packages/briefcase/__main__.py", line 3, in
File ".../venv/lib/python3.9/site-packages/briefcase/cmdline.py", line 6, in
File ".../venv/lib/python3.9/site-packages/briefcase/commands/__init__.py", line 1, in
File ".../venv/lib/python3.9/site-packages/briefcase/commands/build.py", line 5, in
File ".../venv/lib/python3.9/site-packages/briefcase/commands/base.py", line 14, in
ModuleNotFoundError: No module named 'httpx'
视窗
(beeware-venv)C:\...>briefcase dev
Traceback (most recent call last):
File "...\venv\bin\briefcase", line 5, in
File "...\venv\lib\python3.9\site-packages\briefcase\__main__.py", line 3, in
File "...\venv\lib\python3.9\site-packages\briefcase\cmdline.py", line 6, in
File "...\venv\lib\python3.9\site-packages\briefcase\commands\__init__.py", line 1, in
File "...\venv\lib\python3.9\site-packages\briefcase\commands\build.py", line 5, in
File "...\venv\lib\python3.9\site-packages\briefcase\commands\base.py", line 14, in
ModuleNotFoundError: No module named 'httpx'
发生了什么?我们已经添加httpx到我们的代码中,但我们还没有将它添加到我们的开发虚拟环境中。我们可以通过安装来解决这个问题httpx ,pip然后重新运行:briefcase dev
苹果系统
(beeware-venv) $ python -m pip install httpx
(beeware-venv) $ briefcase dev
Linux
(beeware-venv) $ python -m pip install httpx
(beeware-venv) $ briefcase dev
视窗
(beeware-venv)C:\...>python -m pip install httpx
(beeware-venv)C:\...>briefcase dev
当您输入名称并按下按钮时,您应该会看到一个类似于以下内容的对话框:
Hello World 教程 6 对话框,在 Windows 上
我们现在有了一个可以工作的应用程序,使用第三方库,在开发模式下运行!
运行更新的应用程序
让我们将这个更新的应用程序代码打包为一个独立的应用程序。由于我们已经进行了代码更改,我们需要按照教程 4 中的相同步骤进行操作:
苹果系统
更新打包应用程序中的代码:(beeware-venv) $ briefcase update[hello-world] Updating application code...
Installing src/hello_world...[hello-world] Application updated.
重建应用程序:(beeware-venv) $ briefcase build[hello-world] Building AppImage...
...
[hello-world] Built linux/Hello_World-0.0.1-x86_64.AppImage
最后,运行应用程序:(beeware-venv) $ briefcase run[hello-world] Starting app...
但是,当应用程序运行时,您会看到一个崩溃对话框:
Linux
更新打包应用程序中的代码:(beeware-venv) $ briefcase update[hello-world] Updating application code...
Installing src/hello_world...[hello-world] Application updated.
重建应用程序:(beeware-venv) $ briefcase build[hello-world] Building AppImage...
...
[hello-world] Built linux/Hello_World-0.0.1-x86_64.AppImage
最后,运行应用程序:(beeware-venv) $ briefcase run[hello-world] Starting app...Traceback (most recent call last):File "/tmp/.mount_Hello_ifthSH/usr/lib/python3.8/runpy.py", line 194, in _run_module_as_mainreturn _run_code(code, main_globals, None,File "/tmp/.mount_Hello_ifthSH/usr/lib/python3.8/runpy.py", line 87, in _run_codeexec(code, run_globals)File "/tmp/.mount_Hello_ifthSH/usr/app/hello_world/__main__.py", line 1, in
ModuleNotFoundError: No module named 'httpx'Unable to start app hello-world.
视窗
更新打包应用程序中的代码:(beeware-venv)C:...>公文包更新[hello-world] 正在更新应用程序代码…正在安装 src/hello_world…[hello-world] 应用程序已更新。重建应用程序:(beeware-venv)C:\...>briefcase build[hello-world] Built windows/msi/Hello World
最后,运行应用程序:(beeware-venv)C:\...>briefcase run[hello-world] Starting app...Unable to start app hello-world.
再次,该应用程序无法启动,因为httpx已安装 - 但为什么呢?我们不是已经安装了httpx吗?
我们有——但仅限于开发环境。您的开发环境完全在您的机器本地 - 只有在您明确激活它时才会启用。虽然公文包有一种开发模式,但您使用公文包的主要原因是打包您的代码,以便您可以将其提供给其他人。
保证其他人将拥有一个包含所需一切的 Python 环境的唯一方法是构建一个完全隔离的 Python 环境。这意味着有一个完全隔离的 Python 安装和一组完全隔离的依赖项。这就是公文包在运行时正在构建的东西——一个孤立的 Python 环境。这也解释了为什么没有安装 - 它已安装在您的开发 环境中,但未安装在打包的应用程序中。briefcase buildhttpx
所以 - 我们需要告诉公文包我们的应用程序有一个外部依赖项。
更新依赖项
在您的应用程序的根目录中,有一个名为pyproject.toml. 此文件包含您最初运行时提供的所有应用程序配置详细信息。briefcase new
pyproject.toml被分成几个部分;其中一个部分描述了您的应用程序的设置:
[tool.briefcase.app.hello-world]
formal_name = "Hello World"
description = "A Tutorial app"
icon = "src/hello_world/resources/hello-world"
sources = ['src/hello_world']
requires = []
该requires选项描述了我们应用程序的依赖关系。它是一个字符串列表,指定要包含在应用程序中的库(以及可选的版本)。
修改requires设置,使其显示为:
requires = ["httpx",
]
通过添加这个设置,我们告诉公文包“当你构建我的应用程序时,运行 到应用程序包中”。可以在此处使用任何合法输入的内容- 因此,您可以指定:pip install httpxpip install
再往下pyproject.toml看,您会注意到与操作系统相关的其他部分,例如[tool.briefcase.app.hello-world.macOS]和 [tool.briefcase.app.hello-world.windows]。这些部分也有一个 requires设置。这些设置允许您定义其他特定于平台的依赖项 - 例如,如果您需要特定于平台的库来处理应用程序的某些方面,您可以在特定于平台的requires部分中指定该库,并且该设置只会用于该平台。您会注意到这些toga库都在特定于平台的requires部分中指定 - 这是因为显示用户界面所需的库是特定于平台的。
在我们的例子中,我们希望httpx安装在所有平台上,所以我们使用应用级别requires设置。将始终安装应用级别的依赖项;除了应用程序级别的依赖项之外,还安装了特定于平台的依赖项。
现在我们已经告诉公文包我们的附加依赖项,我们可以尝试再次打包我们的应用程序。确保您已将更改保存到 pyproject.toml,然后再次更新您的应用程序 - 这次是传入 -d标志。这告诉公文包更新打包应用程序中的依赖项:
苹果系统
(beeware-venv) $ briefcase update -d[hello-world] Updating dependencies...
Collecting httpxUsing cached httpx-0.19.0-py3-none-any.whl (77 kB)
...
Installing collected packages: sniffio, idna, travertino, rfc3986, h11, anyio, toga-core, rubicon-objc, httpcore, charset-normalizer, certifi, toga-cocoa, httpx
Successfully installed anyio-3.3.2 certifi-2021.10.8 charset-normalizer-2.0.6 h11-0.12.0 httpcore-0.13.7 httpx-0.19.0 idna-3.2 rfc3986-1.5.0 rubicon-objc-0.4.1 sniffio-1.2.0 toga-cocoa-0.3.0.dev28 toga-core-0.3.0.dev28 travertino-0.1.3[hello-world] Updating application code...
Installing src/hello_world...[hello-world] Application updated.
Linux
(beeware-venv) $ briefcase update -d[hello-world] Updating dependencies...
Collecting httpxUsing cached httpx-0.19.0-py3-none-any.whl (77 kB)
...
Installing collected packages: sniffio, idna, travertino, rfc3986, h11, anyio, toga-core, rubicon-objc, httpcore, charset-normalizer, certifi, toga-cocoa, httpx
Successfully installed anyio-3.3.2 certifi-2021.10.8 charset-normalizer-2.0.6 h11-0.12.0 httpcore-0.13.7 httpx-0.19.0 idna-3.2 rfc3986-1.5.0 rubicon-objc-0.4.1 sniffio-1.2.0 toga-cocoa-0.3.0.dev28 toga-core-0.3.0.dev28 travertino-0.1.3[hello-world] Updating application code...
Installing src/hello_world...[hello-world] Application updated.
视窗
(beeware-venv)C:\...>briefcase update -d[hello-world] Updating dependencies...
Collecting httpxUsing cached httpx-0.19.0-py3-none-any.whl (77 kB)
...
Installing collected packages: sniffio, idna, travertino, rfc3986, h11, anyio, toga-core, rubicon-objc, httpcore, charset-normalizer, certifi, toga-cocoa, httpx
Successfully installed anyio-3.3.2 certifi-2021.10.8 charset-normalizer-2.0.6 h11-0.12.0 httpcore-0.13.7 httpx-0.19.0 idna-3.2 rfc3986-1.5.0 rubicon-objc-0.4.1 sniffio-1.2.0 toga-cocoa-0.3.0.dev28 toga-core-0.3.0.dev28 travertino-0.1.3[hello-world] Updating application code...
Installing src/hello_world...[hello-world] Application updated.
更新后,您可以运行并且- 您应该会看到打包的应用程序以及新的对话框行为。briefcase buildbriefcase run
下一步
我们现在有了一个使用第三方库的应用程序!但是,您可能已经注意到,当您按下按钮时,应用程序变得有点反应迟钝。我们能做些什么来解决这个问题吗?转到教程 7以了解...