Skip to main content

qgis-plugin-dev-tools

QGIS plugin development and packaging tools, which make managing runtime dependencies easy.

Prerequisites

Your plugin package must be available to import from the python environment this tool is run in. For example, running python -c "import your_plugin_package_name" should not fail. Additionally, any dependency libraries must also be available in the python environment, so a dependency to some_pypi_package needs something like pip install some_pypi_package for this tool to work.

Limitations

Bundling works by copying the code as-is and replacing the imports in all bundled files, so native library dependencies and other special cases might not work. To be safe, only depend on pure python libraries. Also verify the result zip works, since some import statements or sys.modules usage might not be supported.

Setup

Install this library with pip install qgis-plugin-dev-tools.

Create a pyproject.toml tool section:

[tool.qgis_plugin_dev_tools]
plugin_package_name = "your_plugin_package_name"

If the plugin runtime depends on external libraries, add the distribution names to runtime_requires list as abstract dependencies.

[tool.qgis_plugin_dev_tools]
plugin_package_name = "your_plugin_package_name"
runtime_requires = [
    "some_pypi_package"
]

If the plugin runtime dependencies have many dependencies themselves, it is possible to include those recursively with auto_add_recursive_runtime_dependencies. Alternatively, all the requirements can be listed in runtime_requires.

[tool.qgis_plugin_dev_tools]
plugin_package_name = "your_plugin_package_name"
runtime_requires = [
    "some_pypi_package"
]
auto_add_recursive_runtime_dependencies = true

If the plugin runtime dependencies do not work with the aforementioned configuration, the dependencies can be added to the Python Path with use_dangerous_vendor_sys_path_append flag. This method might be unsafe if there are conflicts between dependency versions of different plugins.

[tool.qgis_plugin_dev_tools]
plugin_package_name = "your_plugin_package_name"
runtime_requires = [
    "some_pypi_package_with_binary_files"
]
use_dangerous_vendor_sys_path_append = true

By default build version number is read from changelog top-most second level heading having format ## version anything. This behaviour is configurable with version_number_source to use plugin package distribution metadata or the static version in the [project] section of pyproject.toml. Optionally, the version number can also be provided as an argument for the build script using qpdt b --version 0.1.0-rc2.

[tool.qgis_plugin_dev_tools]
plugin_package_name = "your_plugin_package_name"
version_number_source = "distribution"  # or "pyproject" or "changelog" (default if missing)

Changelog path can be configured with changelog_file_path option. By default it is assumed to be CHANGELOG.md in the same directory as pyproject.toml.

[tool.qgis_plugin_dev_tools]
plugin_package_name = "your_plugin_package_name"
changelog_file_path = "../../CHANGELOG.md"

QGIS plugins are required to have a LICENSE file included in the plugin package. However, usually it is more convenient to keep the license file in the root of the repository. LICENSE can be copied automatically to the plugin zip while packaging if such file is found. A relative path to the license file can also be configured with license_file_path option.

[tool.qgis_plugin_dev_tools]
plugin_package_name = "your_plugin_package_name"
license_file_path = "docs/my-license.md"

Plugin packaging

Run qgis-plugin-dev-tools build (short qpdt b) to package the plugin and any runtime dependencies to a standard QGIS plugin zip file, that can be installed and published.

By default config is read from pyproject.toml, changelog notes from CHANGELOG.md, version from changelog, and package is created in a dist directory in the current working directory. Changelog contents and version number are inserted to the metadata.txt file, so the version and changelog sections do not need manual updates.

Plugin publishing

Run qgis-plugin-dev-tools publish <file> (short qpdt publish <file>) to publish a previously built plugin zip file to QGIS plugin repository.

By default username and password are read from QPDT_PUBLISH_USERNAME and QPDT_PUBLISH_PASSWORD environment variables.

Updating translations

Run qgis-plugin-dev-tools transup (short qpdt ts) to creat or update ts files for translating the plugin. This command can be configured with:

[tool.qgis_plugin_dev_tools]
translation_language_codes = [
    "fi",
]
translation_search_paths = [
    "src/your_plugin_package_name"
]
translation_destination_path = "src/your_plugin_package_name/resources/i18n"
# translation_pylupdate_command = "/usr/bin/pylupdate6" # Override of pylupdate5 command

By default, on Windows translation uses python script PyQt5.pylupdate_main and on other platforms pylupdate5 or pylupdate6 executable.

Updating translations only when there are changes

If you want to update translation files only if there are new strings to be translated, you can use qpdt transup --check-changes (short qpdt ts --check-changes). This flag omits all the line number and refactoring changes in the translation files, since it won't affect how translations work. This is useful if used together with tools like pre-commit.

Compiling translations

Run qgis-plugin-dev-tools transcompile (short qpdt tc) to compile ts files into qm files that can be used the plugin. This command reads the same configuration as transup command.

Plugin development mode

Run qgis-plugin-dev-tools start (short qpdt s) to launch QGIS with the plugin installed and ready for development.

By default config is read from pyproject.toml and runtime config from .env in the current working directory. Extra environment files can be passed using -e flag. .env must configure the executable path, and may configure debugger, profile name and any extra runtime variables necessary for the plugin.

QGIS_EXECUTABLE_PATH= # path to qgis-bin/qgis-bin-ltr or .exe equivalents, necessary
# DEBUGGER_LIBRARY= # debugpy/pydevd to start a debugger on init, library must be installed to the environment
# DEVELOPMENT_PROFILE_NAME= # name of the profile that qgis is launched with, otherwise uses default
# QGIS_LOCALE= # locale code of QGIS, otherwise uses default
# QGIS_GUI_INI= # path to ini file containing QGIS UI customizations

# any other variables are added to the runtime QGIS environment
# SOMETHING=something

.env can also be configured with pyproject.toml configuration env_file_path option..

[tool.qgis_plugin_dev_tools]
plugin_package_name = "your_plugin_package_name"
env_file_path = "../../.env"

Development mode bootstraps the launched QGIS to have access to any packages available to the launching python environment, setups enviroment variables, configures a debugger, and installs and enables the developed plugin package.

Additionally editable installs for the plugin dependencies are supported. For example with a dependency to some_pypi_package, use pip install -e /path/to/some_pypi_package to provide some_pypi_package in editable mode from a local directory, and use Plugin Reloader to refresh new code when its changed on disk. This will also reload the declared dependencies.

Developing multiple plugins

Development mode also enables using and developing multiple plugins easily if certain requirements are satisfied for all extra plugins:

  • Extra plugin must be installable python packages
  • Extra plugin must have entry point in group "qgis_plugin_dev_tools"
  • Extra plugin needs to be installed in the same python environment where this tool is run in

Extra plugins are loaded on launch and reloaded together with the main plugin if Plugin Reloader is used.

You can disable plugin auto-load by using pyproject.toml configuration (for example when using a dependency, that also provides a plugin entrypoint):

[tool.qgis_plugin_dev_tools]
disabled_extra_plugins = [
  "unwanted_plugin_package_name",
]

Use with pre-commit

Some of the qgis-plugin-dev-tools commands are exposed as pre-commit hooks to be run with tools like pre-commit and prek. workflow, add something like the below to the repos list in the project's .pre-commit-config.yaml:

- repo: https://github.com/nlsfi/qgis-plugin-dev-tools
  rev: v0.11.0
  hooks:
  - id: update-translations # runs "qgis-plugin-dev-tools transup" command
    # language: system # on Windows you might want to set this to access PyQt5.pylupdate_main
    # args: ["--pyproject-toml", "path/to/pyproject.toml"] # optionally give path to pyproject.toml
    # The flag --check-changes flag is used, to leave it out, set args: []

Normalize XML files

This repository provides a hook for normalizing XML files. By default, the hook is applied to .xml, .qml, and .ui files; note that QML files may contain non-valid XML. In addition to formatting, the hook supports removing specific tags from the xml using the --remove-tag argument. Example usage:

- repo: https://github.com/nlsfi/qgis-plugin-dev-tools
  rev: v0.12.0
  hooks:
    - id: normalize-xml
      args: [
        "--remove-tag", "fieldConfiguration"
      ]

Development of qgis-plugin-dev-tools

See development readme.

Licensed under GNU GPL v3.0.

Copyright (C) 2022-2026 National Land Survey of Finland.

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

0.13.0 - 2026-09-17

  • Feat: add "pyproject" option for version_number_source

0.12.0 - 2026-03-19

  • Feat: add normalize xml hook

0.11.0 - 2026-03-19

  • Feat: Add command to update translations
  • Feat: Add command to compile translation files
  • Feat: allow specifying pyproject toml with cli

0.10.0 - 2026-03-14

  • Feat: Add env_file_path and changelog_file_path pyproject.toml options

0.9.2 - 2026-02-04

  • Fix: use correct syntax for pydevd debugging

0.9.1 - 2025-01-08

  • Fix: Fix license copying

0.9.0 - 2025-01-08

  • Feat: Copy license into the plugin zip while deploying

0.8.0 - 2024-08-23

  • Feat: Add locale and ui ini options to be able to further customize development environment

0.7.0 - 2024-05-21

  • Fix: Bundle contents by parsing pep-compliant distribution file catalog instead of possibly missing tool-specific top-level.txt
  • Feat: Allow disabling auto-loaded entrypoint plugins

0.6.2 - 2023-09-27

  • Fix: Fix issues with bundling requirements of the requirements recursively

0.6.1 - 2023-09-06

  • update author email

0.6.0 - 2023-02-17

  • Feat: Support dependencies having package references in .ui files

0.5.0 - 2022-11-09

  • Feat: Add publish command to cli
  • Fix: Support build without actually importing the code
  • Fix: Preserve case for key names in metadata file

0.4.0 - 2022-11-01

  • Feat: Add an option to get version from distribution metadata
  • Fix: Rewrite imports correctly when dependency name is a prefix of the plugin package name

0.3.0 - 2022-09-02

  • Feat: Add an option to append vendor package to the Python Path
  • Feat: Add an option to bundle requirements of the requirements recursively
  • Feat: Add module packages and .pyd files to the bundle if found
  • Feat: Add version as an optional build argument
  • Chore: Drop support from Python < 3.9

0.2.1 - 2022-07-07

  • Fix: Correct some plain import rewrites

0.2.0 - 2022-06-13

  • Feat: enable extra plugins in development mode

0.1.2 - 2022-05-30

  • Fix: use UTF-8 encoding for file reads/writes

0.1.1 - 2022-05-16

  • Fix: rewrite runtime requirement imports correctly

0.1.0 - 2022-05-12

  • Initial release: start and build commands with minimal configuration options.

Release files for qgis-plugin-dev-tools 0.13.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for qgis-plugin-dev-tools 0.13.0
File Size Uploaded
qgis_plugin_dev_tools-0.13.0.tar.gz 51.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for qgis-plugin-dev-tools 0.13.0
File Interpreter ABI Platform
qgis_plugin_dev_tools-0.13.0-py3-none-any.whl Python 3 none any Details

Total release size: 107.4 kB

Release files / qgis_plugin_dev_tools-0.13.0.tar.gz

Download URL qgis_plugin_dev_tools-0.13.0.tar.gz
Size 51.5 kB
Tags Source
SHA-256 checksum
How to use checksums
6d76cee4bd3c676778b0c6285693b24384cd05867231b93edc7054332fa5d7c5
BLAKE2b-256 checksum
How to use checksums
e4f6b002da0933e49c15d088df32526dffae6c2d427192841ba9a05a33f254e3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / qgis_plugin_dev_tools-0.13.0-py3-none-any.whl

Download URL qgis_plugin_dev_tools-0.13.0-py3-none-any.whl
Size 55.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ca6e4debdb67abcebc6f16099ec2d7e292200a3fbd11b49a98df1a9b9c667fd9
BLAKE2b-256 checksum
How to use checksums
cca68270e137d5118bab450b3eda7d354a1b41f6b6a189de8b4f5f8a5486be0b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

0.13.2

2 release files

0.13.1

2 release files

This release

0.13.0 This release

2 release files

0.12.0

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.9.2

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page