教程 7 - 使用第三方库

到目前为止,我们构建的应用程序只使用了我们自己的代码和 BeeWare 提供的代码。不过,在实际应用中,您很可能需要使用从 Python 软件包索引(PyPI)下载的第三方库。

让我们修改应用程序,加入第三方库。

Adding a package

Let's modify our application to say a little bit more than just "Hi, there!".

To generate some more interesting text for the dialog, we're going to use a library called Faker . Faker is a Python package that generates fake content, including names and text blocks. The names and words in the text block are generated from an arbitrary list of words provided by Faker. We're going to use Faker to construct a fake message, as if someone is responding to the user.

我们开始吧 faker 添加到我们的应用程序中。在 app.py 的最上方加入一个导入,用于导入 faker:

import faker

然后修改 say_hello() 回调,使其看起来像这样:

async def say_hello(self, widget):
    fake = faker.Faker()
    await self.main_window.dialog(
        toga.InfoDialog(
            greeting(self.name_input.value),
            f"A message from {fake.name()}: {fake.text()}",
        )
    )

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

(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.13/site-packages/briefcase/__main__.py", line 3, in <module>
    from .cmdline import parse_cmdline
File ".../venv/lib/python3.13/site-packages/briefcase/cmdline.py", line 6, in <module>
    from briefcase.commands import DevCommand, NewCommand, UpgradeCommand
File ".../venv/lib/python3.13/site-packages/briefcase/commands/__init__.py", line 1, in <module>
    from .build import BuildCommand  # noqa
File ".../venv/lib/python3.13/site-packages/briefcase/commands/build.py", line 5, in <module>
    from .base import BaseCommand, full_options
File ".../venv/lib/python3.13/site-packages/briefcase/commands/base.py", line 14, in <module>
    import faker
ModuleNotFoundError: No module named 'faker'

发生了什么?我们已经将 httpx 添加到我们的代码*中,但我们还没有将它添加到我们的开发虚拟环境中。我们可以用 pip 安装 httpx,然后重新运行 briefcase dev

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

输入名称并按下按钮后,您会看到一个类似的对话框:

Hello World 教程 7 对话框,在 macOS 上运行

现在,我们已经有了一个可正常运行的应用程序,它使用第三方库,以开发模式运行!

运行更新后的应用程序

让我们将更新后的应用程序代码打包为独立应用程序。由于我们对代码进行了修改,因此需要遵循 Tutorial 4 中的相同步骤:

更新打包应用程序中的代码:

(beeware-venv) $ briefcase update

[helloworld] Updating application code...
...

[helloworld] Application updated.

重建应用程序:

(beeware-venv) $ briefcase build

[helloworld] Adhoc signing app...
[helloworld] Built build/helloworld/macos/app/Hello World.app

最后,运行应用程序:

(beeware-venv) $ briefcase run

[helloworld] Starting app...
===========================================================================

但是,当程序运行时,你会在控制台中看到一个错误,还有一个崩溃对话框:

MacOS 上的 Hello World Tutorial 7 应用程序崩溃

应用程序再次启动失败,因为已经安装了 httpx - 但为什么呢?我们不是已经安装了 httpx 吗?

我们有,但仅限于开发环境。你的开发环境完全在你的机器本地,只有当你明确激活它时才会启用。虽然公文包有开发模式,但使用公文包的主要原因是打包你的代码,这样你就可以把它交给别人。

要保证别人的 Python 环境包含它所需要的一切,唯一的办法就是构建一个完全隔离的 Python 环境。这意味着有一个完全独立的 Python 安装,和一套完全独立的依赖关系。这就是当你运行 briefcase build 时,Briefcase 正在构建的 - 一个隔离的 Python 环境。这也解释了为什么没有安装 httpx - 它已经安装在你的开发环境中,但没有安装在打包的应用程序中。

因此,我们需要告诉 Briefcase,我们的应用程序有一个外部依赖关系。

更新依赖项

在应用程序的根目录中,有一个名为 pyproject.toml 的文件。该文件包含您最初运行 briefcase new 时提供的所有应用程序配置详细信息。

pyproject.toml "分为多个部分,其中一部分描述了应用程序的设置::

[tool.briefcase.app.helloworld]
formal_name = "Hello World"
description = "A Tutorial app"
long_description = """More details about the app should go here.
"""
sources = ["src/helloworld"]
requires = []

requires "选项描述了应用程序的依赖关系。它是一个字符串列表,其中指定了您希望应用程序包含的库(以及可选的版本)。

修改 requires 设置为::

requires = [
    "faker",
]

通过添加此设置,我们告诉 Briefcase "当你构建我的应用程序时,运行 pip install httpx 到应用程序捆绑包中"。任何可以合法输入到 pip install 的内容都可以在这里使用--因此,你可以指定:

  • 特定的库版本(例如, "httpx===0.19.0" );

  • 一系列库版本(例如, "httpx>=0.19" );

  • 指向 git 仓库的路径(例如,"git+https://github.com/encode/httpx");或

  • 本地文件路径(不过需要注意的是:如果你把代码交给别人,这个路径很可能不存在于他们的机器上!)

pyproject.toml 中的更下面部分,你会注意到与操作系统相关的其他部分,如 [tool.briefcase.app.helloworld.macOS][tool.briefcase.app.helloworld.windows]。这些部分**也有一个 requires 设置。这些设置允许你定义额外的特定平台依赖关系,例如,如果你需要一个特定平台的库来处理应用程序的某些方面,你可以在特定平台的 requires 部分中指定该库,而该设置将仅用于该平台。你会注意到,所有的 toga 库都是在特定平台的 requires 部分中指定的,这是因为显示用户界面所需的库都是特定平台的。

在我们的例子中,我们希望 httpx 安装在所有平台上,因此使用了应用程序级的 requires 设置。应用程序级的依赖项始终会被安装;特定平台的依赖项会在应用程序级的依赖项之外*安装。

既然我们已经告诉了 Briefcase 我们的额外需求,那么我们就可以再次尝试打包应用程序了。确保已将更改保存到 pyproject.toml,然后再次更新应用程序--这一次,传递 -r 标志。这将告诉 Briefcase 更新打包应用程序中的需求:

(beeware-venv) $ briefcase update -r

[helloworld] Updating application code...
Installing src/hello_world...

[helloworld] Updating requirements...
Collecting faker
  Using cached faker-37.3.0-py3-none-any.whl.metadata (15 kB)
...
Installing collected packages: tzdata, travertino, std-nslog, rubicon-objc, fonttools, toga-core, faker, toga-cocoa
Successfully installed faker-37.3.0 fonttools-4.58.1 rubicon-objc-0.5.1 std-nslog-1.0.3 toga-cocoa-0.5.1 toga-core-0.5.1 travertino-0.5.1 tzdata-2025.2

[helloworld] Removing unneeded app content...
...

[helloworld] Application updated.

更新完成后,您可以运行 briefcase buildbriefcase run - 您应该会看到打包后的应用程序,并带有新的对话框行为。

备注

用于更新需求的 -r 选项也会被 build` ``run` 命令接受,因此如果你想一步完成更新、编译和运行,可以使用 ``briefcase run -u -r

Third-Party Python Packages for Mobile and Web

Faker is just one example of a third-party Python package - a collection of code that isn't part what Python provides out of the box. These third-party packages are most commonly distributed using the Python Package Index (PyPI), and installed into your local virtual environment. We've been using pip in this tutorial, but there are other options.

在桌面平台(macOS、Windows、Linux)上,任何可安装的 "pip "都可以添加到您的需求中。在移动和网络平台上,"您的选择略显有限 <https://briefcase.readthedocs.io/en/latest/background/faq.html#can-i-use-third-party-python-packages-in-my-app>`__。

In short; any pure Python package (i.e. any package created from a project written only in Python) can be used without difficulty. Some packages, though, are created from projects that contain both Python and other languages (e.g. C, C++, Rust, etc). Code written in those languages needs to be compiled to platform-specific binary modules before it can be used, and those pre-compiled binary modules are only available on specific platforms. Mobile and web platforms have very different requirements than "standard" desktop platforms. At this time, most Python packages don't provide pre-compiled binaries for mobile and web platforms.

On PyPI, packages are often provided in a pre-built distribution format called wheels. To check whether a package is pure Python, look at the PyPI downloads page for the project. If the wheels provided have a -py3-none-any.whl suffix (e.g., Faker), then they are pure Python wheels. However, if the wheels have version and platform-specific extensions (e.g., Pillow, which has wheels with suffixes like -cp313-cp313-macosx_11_0_arm64.whl and -cp39-cp39-win_amd64.whl), then the wheel contains a binary component. That package cannot be installed on mobile or web platforms unless a wheel compatible with those platforms has been provided.

At this time, most binary packages on PyPI don't provide mobile- or web-compatible wheels. To fill this gap, BeeWare provides binaries for some popular binary modules (including numpy, pandas, and cryptography). These wheels are not distributed on PyPI, but Briefcase will install those wheels if they're available.

BeeWare可以为一些流行的二进制模块(包括 "numpy"、"pandas "和 "加密")提供二进制文件。为移动平台编译软件包通常是可行的,但设置起来并不容易--这已经超出了本入门教程的范围。

下一步

We've now got an app that uses a third-party library! In Tutorial 8 we'll learn how to ensure our app remains responsive as we add more complex application logic.