Packaging¶
This page shows how to turn a finished d/Python program into an installable application package. After it you will know the command, the small metadata file it needs, how to bundle assets and icons, what signing does and does not do, and what the command line cannot do for you yet.
A d/Python program, console or windowed, ships in the same application package format as a d/BASIC one (d/BASIC is d/OS's other language and shares the same runtime). The format is called DPK2, and the same writer, the same verifier, the same store and the same launcher handle both. The packager grants no trust of its own: it reads the program's required permissions from the compiled bytecode, includes the exact bytes of every library, and adds a developer signature if you give it a key.
The command¶
dpython package app.py --metadata app.json -o app.dapp
dpython package build/app.dbc --metadata app.json -o app.dapp --sign-key developer.key
You can package from source or from a compiled program file, .dbc, with its lib/ folder beside it. The package contains APP.DBC and every library it needs, with exact bytes and dependency hashes. Whether the program is a console program, a window program or both is taken from the compiled file; metadata cannot turn a console program into a window program or add a permission.
Metadata¶
app_id is your assigned application id. It must not be zero; its high sixteen bits identify the publisher and its low sixteen bits the application. label is the display name and version has three parts. The optional fields are about, documents_namespace, keywords, min_runtime and signature_epoch; the shared package writer checks each one against its required format.
Resources and icons¶
{
"app_id": 1951626256,
"label": "Python assets",
"version": [1, 0, 0],
"resources": [
{"format": "BYTES", "path": "assets/readme.txt"},
{"format": "MASK1", "path": "assets/logo.mask"},
{"format": "PCM16", "path": "assets/tone.pcm"}
],
"icons": [
{"face": "LAUNCHER", "path": "assets/launcher.icon"},
{"face": "DOCK", "path": "assets/dock.icon"}
]
}
Asset paths are relative to the metadata file. Each resource is named by its file's lower-cased basename; names must be unique, 1 to 15 bytes from a-z, 0-9, ., - and _, and there can be at most 32 of them. BYTES is any data, MASK1 a one-bit mask, PCM16 signed 16-bit little-endian mono samples; all three are copied unchanged into the package's resource file, RES.DRD. Icon faces are LAUNCHER (72 bytes), DOCK (32) and LARGE (72), each at most once, given as numeric text or raw bytes. Each asset, all assets together and the finished package are each limited to 262,144 bytes.
The command declines unknown fields, invalid or missing files, duplicate names, and an output path that is also one of its inputs, and it writes the whole package to a staging file before replacing an existing output.
Signatures¶
--sign-key reads a raw 32-byte Ed25519 seed or a raw 64-byte secret key, using the same reader d/BASIC uses; either form of the same key produces an identical package. Leave the key out and you get a package explicitly marked unsigned, for sideloading. A developer signature proves who signed the package. It does not make the package trusted by a store; the shared installer and the platform's policy decide whether a signed or an unsigned package is allowed in. The command ships no root keys, changes no settings and installs nothing.
The path a package takes¶
- The shared package writer produces the DPK2 manifest, the launch record, the table of contents, the hashes and the optional signature.
- The shared verifier checks the structure, the trust policy, the signature and every file's digest.
- The package store decides where the package goes, keeps the record of what is installed, and checks the placed files.
- The launcher matches that record against the exact catalog it trusts and starts the package's own bytecode with the package's own permissions.
The tests for Python packages install unsigned and developer-signed packages into a host-side medium that behaves like NOR flash, reopen it, find the placed libraries by exact digest, rehash every file, run the placed application through the shared linker and the checks a program passes before it runs, and reject any changed or removed byte. That is what has been tested on a development machine. Recovery, custody of root keys and physical media remain the platform's responsibility and are not covered here.
What the command line does not do¶
Neither the Python nor the d/BASIC command line can launch an installed .dapp directly, because that needs the trusted catalog only the real launcher has. Do not unpack a package and treat running its bytecode as an installed launch. For local development, run the source or its .dbc with the normal host. Bundling resources does not add a RESOURCE provider to the local runtime.