0.4.0 migration notes
0.4.0 closes the m-3 milestone (developer workflow and plugin packaging).
It is a Python-only release, tag python-v0.4.0: no file under
packages/qgis-sdk-typescript or packages/qgis-sdk-alias changed since
ts-v0.3.0, so @archont561/qgis-sdk stays at 0.3.0 and generated web
projects keep pinning it (decision-25).
PLUGIN_DESCRIPTION_SCHEMA_VERSION, BRIDGE_PROTOCOL_VERSION and
HOST_SCHEMA_VERSION all stay 1.
Two changes are breaking for code written against 0.3.0, each documented
below with its one-line fix: the developer tools moved to qgis_sdk_tools
(python -m qgis_sdk is gone, the pytest plugin path changed), and the
runtime binds PluginContext as the ctx class attribute instead of passing
it to the constructor. Everything a plugin imports from qgis_sdk.* at
0.3.0 is still there; the additions are listed. The notes are in reverse
landing order.
- Manifests:
pyproject.tomlandrecipe.yamlcarry0.4.0; the bridge’spackage.jsonand the alias carry0.3.0. Verify withpython scripts/release.py verify-versions --scope python --version 0.4.0and--scope typescript --version 0.3.0. qgis-sdk buildis new; see “Building an installable ZIP”. Projects generated byqgis-sdk newnow ignoredist/. A plugin that importsqgis_sdk_toolsorqgis_sdk.testingfrom package code is refused at build time (DEP001/DEP002): those never ship.qgis-sdk devreloads on save and quiesces first. The Desktop bootstrap is now the importable moduleqgis_sdk_tools.devtools.reloader(policy, tested without QGIS) plus.devtools.bootstrap(the QGIS glue the--codeprobe reaches);plan_dev(...)and theqgis/desktoptest plans put the SDK’s own import locations on the QGIS process’sPYTHONPATH. The request JSON gainswatch(defaultTrue;--no-watch). New runtime API, additive:ResourceScope.on_quiesce(check, *, resume=None),scope.quiesce(),scope.resume(),PluginRuntime.quiesce()/resume();QuiesceOutcomenow lives inqgis_sdk.core.scope(still exported fromqgis_sdk.core). A rootJobServiceregisters on its scope, and its blockers name the handle id (job sum#1 ...) instead of the scheduler’s number.- The developer tools moved to
qgis_sdk_tools(decision-35, step 1).qgis_sdk.scaffold,qgis_sdk.check,qgis_sdk.cli,qgis_sdk.devtools,qgis_sdk.pytest_pluginandqgis_sdk.bridge.generateare nowqgis_sdk_tools.scaffold,.check,.cli,.devtools,.pytest_pluginandqgis_sdk_tools.generate;FakeCliRuntimeisqgis_sdk_tools.testing.FakeCliRuntime.python -m qgis_sdkis gone - use theqgis-sdkscript orpython -m qgis_sdk_tools. Generated projects now carryaddopts = "-p qgis_sdk_tools.pytest_plugin"; a project generated from an unreleased build with the old path repoints that one line. The runtime API (qgis_sdk.*that a plugin imports) is unchanged;qgis_sdk.environmentis new and holds theQGIS_SDK_DEV_SERVER/QGIS_SDK_TEST_TARGETnames the generatedwebview.pyand the tools share. The one wheel still ships both trees until the distributions split. qgis-sdk testandqgis-sdk dev. New commands overqgis_sdk_tools.devtools(installs,testrun,dev) and the pytest pluginqgis_sdk_tools.pytest_plugin(both landed underqgis_sdk.and moved in the same release, see the previous note); see “Running tests” and “Developing against QGIS”. Projects generated byqgis-sdk newnow carry a.gitignore,addopts = "-p qgis_sdk_tools.pytest_plugin"and a commented[tool.qgis-sdk] qgis-prefix; the generatedwebview.pyhonoursQGIS_SDK_DEV_SERVER. Existing projects opt in by adding theaddoptsline (or passing-p qgis_sdk_tools.pytest_plugin).CliRuntimegainsstart_process;FakeCliRuntimerecords started processes in.startedand the environments passed torun_processin.environments.- Curated services on
PluginContext.layers,project,settings,styles,algorithmsandworkersare new optional fields withrequire_<name>()accessors; existing constructor calls are unaffected.HostServices.from_context(ctx)builds the web-view surface over the same instances,NetworkClient.transportis public, andqgis_sdk.adapters.qgis.native_plugin_contextwires all of them inside QGIS. Projects generated byqgis-sdk newnow carry aproject_layersaction and abuild_contextthat uses it when aQgsApplicationis running. PluginContextis a class attribute. The runtime no longer callsplugin_class(context); it setsplugin_class.ctx = contextand callsplugin_class(). Replacedef __init__(self, ctx): self.ctx = ctxwith a barectx: PluginContextannotation (anddef __init__(self)if you still need one —self.ctxis already there). A constructor that keeps thectxparameter failsstart()with aQgisSdkPluginLifecycleErrornaming the change.AlgorithmContextandJobContextare unchanged: they are built fresh per invocation/attempt and still arrive through the constructor (decision-11, decision-13).- Declaration ids and titles are optional.
@plugin,@action,@stream,@algorithm(removed again in 0.6.0),@joband@provider.algorithmderive a missingid=/title=from the decorated name (see “Ids and titles default from the name”) and the class and method decorators accept the bare form. Existing explicit declarations are unchanged;events=is now the only required keyword of@stream. qgis-sdk new --web. The scaffold grows a questionnaire and the--web,--placement,--package-manager,--install/--no-installand--no-inputflags;ScaffoldOptionsgainsweb: WebOptions | Noneand the plan aweb/Vite app plus<plugin>/webview.py(see “Web UI”). Without--webthe plan is unchanged.webandtestsjoin the reserved package names.CliRuntimegainsinp,interactiveandrun_process;FakeCliRuntime(input=, interactive=, run_process=)records spawned processes in.processes.qgis-sdk checkandqgis_sdk.check. New non-mutating project check with stable diagnostics (QGIS001,ARCH001,META00x,PROJECT001,CONFIG001,SYNTAX001); see “Project checks”. Commands now receive aqgis_sdk.cli.CliRuntimethroughctx.obj;qgis_sdk.testinggainsFakeCliRuntime.- CLI rename: the project generator is
qgis-sdk new <directory>(python -m qgis_sdk new).qgis-sdk scaffoldkeeps working as a hidden, deprecated alias so existing scripts do not break; it will be removed in a later minor. The Python API (qgis_sdk.scaffold) is unchanged.