# Plugins

Briefcase ships with support for a range of platforms, output formats and GUI toolkits. Internally, these features are implemented using a plugin interface; as a result, it is possible for third-party projects to add their own features to Briefcase by implementing plugins that satisfy those interfaces.

Each plugin is defined using an [entry point](https://packaging.python.org/en/latest/specifications/entry-points/) definition in `pyproject.toml`.

## `briefcase.bootstraps` { #bootstrap-interface }

The Briefcase [new project wizard][new] asks users to select a GUI toolkit. The option selected at this step alters the content of the code generated by the wizard, generating framework-specific requirements, system packages, and stub code for a new application using that GUI framework. These additions are configured using a `briefcase.bootstrap` plugin.

To add a custom `briefcase.bootstrap` plugin, add a `[project.entry-points."briefcase.bootstraps"]` section to your `pyproject.toml` file; each name/value pair under that section will be interpreted as a bootstrap. The name of each bootstrap setting is the label that will be surfaced to the user in the wizard. The value is a string identifying a class that implements the `briefcase.bootstraps.base.BaseGuiBootstrap` abstract base class.

For example, the Toga bootstrap is implemented using the following configuration:

```toml
[project.entry-points."briefcase.bootstraps"]
Toga = "briefcase.bootstraps.toga:TogaGuiBootstrap"
```

## `briefcase.debuggers` { #debugger-interface }

Briefcase supports running apps with a debugger attached. The debugger used at run time is selected using a `briefcase.debuggers` plugin.

To add a custom `briefcase.debuggers` plugin, add a `[project.entry-points."briefcase.debuggers"]` section to your `pyproject.toml` file; each name/value pair under that section will be interpreted as a debugger. The name of each debugger setting is the identifier used to select the debugger at the command line. The value is a string identifying a class that implements the `briefcase.debuggers.base.BaseDebugger` abstract base class.

A `BaseDebugger` subclass must implement the following abstract properties:

- `name` - a `str` returning the human-readable name of the debugger.
- `connection_mode` - a `briefcase.debuggers.base.DebuggerConnectionMode` value indicating how the debugger connects to the app. The two possible values are `DebuggerConnectionMode.SERVER` (the app listens for incoming debugger connections) and `DebuggerConnectionMode.CLIENT` (the app connects to a running debugger).
- `debugger_support_pkg` - a `str` returning the pip requirement specifier for the package that provides in-app debugger support.

For example, the `pdb` debugger is implemented using the following configuration:

```toml
[project.entry-points."briefcase.debuggers"]
pdb = "briefcase.debuggers.pdb:PdbDebugger"
```

The `debugger_support_pkg` package will be installed into the runtime environment for an app. It is responsible for triggering debugger behavior on any process started in the environment. Depending on the `connection_mode`, this means either waiting for an incoming debugger connection (in the case of a `SERVER`), or a initiating a debugger connection (in the case of `CLIENT`). A debugger should be started if the runtime environment contains the `BRIEFCASE_DEBUGGER` environment variable; the value of that variable will be a JSON-encoded dictionary of configuration parameters:

- `debugger` - The identifying name of the debugger being registered (e.g., `pdb`)
- `host` - The name of the host where the debugger is running
- `port` - The port where the debugger is running
- `host_os` - The value of [`platform.system()`][platform.system] on the machine where the debugger is running
- `app_path_mappings` - A mapping between application code paths in the app, and the source files on the development machine
- `app_packages_path_mappings` - A mapping between code paths for app dependencies, and original versions installed on the development machine

## `briefcase.platforms` and `briefcase.formats.*` { #platform-interface }

Each command implemented by Briefcase is specialized by a platform and output format. This implementation is defined using a pair of plugins - a `briefcase.platforms` definition describing a platform, and a `briefcase.format.<platform>` definition that defines the output formats for that platform.

The `briefcase.platforms` entry point defines the existence of a platform. Each name in this section is name of a platform that can be used when invoking Briefcase commands. The value is a fully-qualified Python module name that must defines a single constant `DEFAULT_OUTPUT_FORMAT`.

Each platform name is then incorporated into the name of a separate `format` entry point. Each entry in the `format` section for a platform is the name of an output format that can be used when invoking Briefcase commands. The value is a fully-qualified Python module name that defines 7 symbols:

- `create` - a subclass of `briefcase.commands.create.CreateCommand`
- `update` - a subclass of `briefcase.commands.create.UpdateCommand`
- `open` - a subclass of `briefcase.commands.create.OpenCommand`
- `build` - a subclass of `briefcase.commands.create.BuildCommand`
- `run` - a subclass of `briefcase.commands.create.RunCommand`
- `package` - a subclass of `briefcase.commands.create.PackageCommand`
- `publish` - a subclass of `briefcase.commands.create.PublishCommand`

For example, the macOS Xcode output format is implemented using the following configuration:

```toml
[project.entry-points."briefcase.platforms"]
macOS = "briefcase.platforms.macOS"

[project.entry-points."briefcase.formats.macOS"]
xcode = "briefcase.platforms.macOS.xcode"
```

## `briefcase.channels.*` { #publication-channel-interface }

Briefcase provides a plugin interface that enables publishing apps to distribution channels (e.g., the iOS App Store or Google Play Store) via the [publish][publish] command.

--8<-- "_snippets/available-channels.md"

Publication channel entry points are scoped by platform and output format. To add a custom publication channel plugin, add a `[project.entry-points."briefcase.channels.<platform>.<format>"]` section to your `pyproject.toml` file; each name/value pair under that section will be interpreted as a publication channel. The name of each setting is the identifier used to select the channel with `--channel` on the command line. The value is a string identifying a class that implements the `briefcase.channels.base.BasePublicationChannel` abstract base class.

A `BasePublicationChannel` subclass must implement:

- `name` - an abstract `str` property returning the human-readable name of the channel.
- `publish_app(app, command, **options)` - an abstract method that performs the actual publication. `app` is the `AppConfig` for the application being published; `command` satisfies the `PublishCommandAPI` protocol (see below).

The `PublishCommandAPI` protocol (`briefcase.channels.base.PublishCommandAPI`) defines the stable API surface that plugins can rely on from the `command` parameter:

- `console` - the console object for user interaction
- `tools` - the tool registry
- `dist_path` - the path to the distribution output directory
- `distribution_path(app)` - returns the path to the distributable artefact for the given app

If only one channel is registered for a platform/format combination, it is selected automatically. If multiple channels are available, the user must specify `--channel` on the command line.

For example, the iOS App Store channel is implemented using the following configuration:

```toml
[project.entry-points."briefcase.channels.iOS.Xcode"]
appstore = "briefcase.channels.appstore:AppStorePublicationChannel"
```
