BeeWare 峰器 中文文档 - 教程 6 - 开始这个(第三方)

到目前为止,我们构建的应用程序只使用了我们自己的代码,加上 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.value
    else:
        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;

  • 将响应解码为 JSON;
  • 提取帖子的正文;和
  • 包括该帖子的正文作为对话框的文本。

让我们在公文包开发者模式下运行我们更新的应用程序,以检查我们的更改是否有效。

苹果系统

(beeware-venv) $ briefcase dev
Traceback (most recent call last):
File ".../venv/bin/briefcase", line 5, in <module>
    from briefcase.__main__ import main
File ".../venv/lib/python3.9/site-packages/briefcase/__main__.py", line 3, in <module>
    from .cmdline import parse_cmdline
File ".../venv/lib/python3.9/site-packages/briefcase/cmdline.py", line 6, in <module>
    from briefcase.commands import DevCommand, NewCommand, UpgradeCommand
File ".../venv/lib/python3.9/site-packages/briefcase/commands/__init__.py", line 1, in <module>
    from .build import BuildCommand  # noqa
File ".../venv/lib/python3.9/site-packages/briefcase/commands/build.py", line 5, in <module>
    from .base import BaseCommand, full_options
File ".../venv/lib/python3.9/site-packages/briefcase/commands/base.py", line 14, in <module>
    import httpx
ModuleNotFoundError: No module named 'httpx'

Linux

(beeware-venv) $ briefcase dev
Traceback (most recent call last):
File ".../venv/bin/briefcase", line 5, in <module>
    from briefcase.__main__ import main
File ".../venv/lib/python3.9/site-packages/briefcase/__main__.py", line 3, in <module>
    from .cmdline import parse_cmdline
File ".../venv/lib/python3.9/site-packages/briefcase/cmdline.py", line 6, in <module>
    from briefcase.commands import DevCommand, NewCommand, UpgradeCommand
File ".../venv/lib/python3.9/site-packages/briefcase/commands/__init__.py", line 1, in <module>
    from .build import BuildCommand  # noqa
File ".../venv/lib/python3.9/site-packages/briefcase/commands/build.py", line 5, in <module>
    from .base import BaseCommand, full_options
File ".../venv/lib/python3.9/site-packages/briefcase/commands/base.py", line 14, in <module>
    import httpx
ModuleNotFoundError: No module named 'httpx'

视窗
 

(beeware-venv)C:\...>briefcase dev
Traceback (most recent call last):
File "...\venv\bin\briefcase", line 5, in <module>
    from briefcase.__main__ import main
File "...\venv\lib\python3.9\site-packages\briefcase\__main__.py", line 3, in <module>
    from .cmdline import parse_cmdline
File "...\venv\lib\python3.9\site-packages\briefcase\cmdline.py", line 6, in <module>
    from briefcase.commands import DevCommand, NewCommand, UpgradeCommand
File "...\venv\lib\python3.9\site-packages\briefcase\commands\__init__.py", line 1, in <module>
    from .build import BuildCommand  # noqa
File "...\venv\lib\python3.9\site-packages\briefcase\commands\build.py", line 5, in <module>
    from .base import BaseCommand, full_options
File "...\venv\lib\python3.9\site-packages\briefcase\commands\base.py", line 14, in <module>
    import httpx
ModuleNotFoundError: No module named 'httpx'


发生了什么?我们已经添加httpx到我们的代码中,但我们还没有将它添加到我们的开发虚拟环境中。我们可以通过安装来解决这个问题httpx ,pip然后重新运行:briefcase dev

苹果系统

(beeware-venv) $ python -m pip install httpx
(beeware-venv) $ briefcase dev

BeeWare 峰器 中文文档 - 教程 6 - 开始这个(第三方)

 

Linux

(beeware-venv) $ python -m pip install httpx
(beeware-venv) $ briefcase dev

BeeWare 峰器 中文文档 - 教程 6 - 开始这个(第三方)

 

视窗

(beeware-venv)C:\...>python -m pip install httpx
(beeware-venv)C:\...>briefcase dev

BeeWare 峰器 中文文档 - 教程 6 - 开始这个(第三方)


当您输入名称并按下按钮时,您应该会看到一个类似于以下内容的对话框:

 

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...
但是,当应用程序运行时,您会看到一个崩溃对话框:

BeeWare 峰器 中文文档 - 教程 6 - 开始这个(第三方)

 

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_main
    return _run_code(code, main_globals, None,
  File "/tmp/.mount_Hello_ifthSH/usr/lib/python3.8/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/tmp/.mount_Hello_ifthSH/usr/app/hello_world/__main__.py", line 1, in <module>
    from hello_world.app import main
  File "/tmp/.mount_Hello_ifthSH/usr/app/hello_world/app.py", line 8, in <module>
    import httpx
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

  • 特定的库版本(例如,"httpx==0.19.0");
  • 一系列库版本(例如,"httpx>=0.19");
  • git 存储库的路径(例如,"git+https://github.com/encode/httpx");或者
  • 本地文件路径(但是 - 请注意:如果您将代码提供给其他人,则此路径可能不会存在于他们的机器上!)

再往下pyproject.toml看,您会注意到与操作系统相关的其他部分,例如[tool.briefcase.app.hello-world.macOS]和 [tool.briefcase.app.hello-world.windows]。这些部分也有一个 requires设置。这些设置允许您定义其他特定于平台的依赖项 - 例如,如果您需要特定于平台的库来处理应用程序的某些方面,您可以在特定于平台的requires部分中指定该库,并且该设置只会用于该平台。您会注意到这些toga库都在特定于平台的requires部分中指定 - 这是因为显示用户界面所需的库是特定于平台的。

在我们的例子中,我们希望httpx安装在所有平台上,所以我们使用应用级别requires设置。将始终安装应用级别的依赖项;除了应用程序级别的依赖项之外,还安装了特定于平台的依赖项。

  • 仅在移动设备上使用 Python(目前!)
  • 在桌面平台(macOS、Windows、Linux)上,任何pip-installable 都可以添加到您的要求中。在移动平台上,您的选择更加有限——您只能使用纯 Python包,即不包含二进制模块的包。
  • 这意味着像numpy、scikit-learn或 之类的库cryptography可以在桌面应用程序中使用,但不能在移动应用程序中使用。这主要是因为移动应用程序需要为多个平台编译的二进制模块,这很难设置。
  • 可以构建一个使用二进制模块的移动 Python 应用程序,但设置起来并不容易——远远超出了像这样的介绍性教程的范围。这是我们想要解决的一个领域——但这不是一项简单的任务。如果您希望将其添加到 BeeWare,请考虑通过成为会员来支持该项目。

现在我们已经告诉公文包我们的附加依赖项,我们可以尝试再次打包我们的应用程序。确保您已将更改保存到 pyproject.toml,然后再次更新您的应用程序 - 这次是传入 -d标志。这告诉公文包更新打包应用程序中的依赖项:

苹果系统

(beeware-venv) $ briefcase update -d

[hello-world] Updating dependencies...
Collecting httpx
  Using 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 httpx
  Using 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 httpx
  Using 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以了解...

上一篇:Markdown语法


下一篇:JAVA 异常和异常处理