One instrument, one repository
A PLESTY module is a whole project: its own repository, its own version, its own documentation, its own release. A powermeter is not a file inside a lab's codebase — it is plesty-pm100d, installable by anyone, at a version they choose.
That costs more repositories than a single shared codebase would. What it buys is the thing a lab actually needs:
- A bench installs exactly what it needs. Three instruments means three
packages at three pinned versions, not one codebase carrying drivers for hardware this bench has never seen.
- Versions move independently. Fixing a spectrometer does not oblige
anyone with a rotation stage to upgrade anything.
- A module outlives the experiment it was written for. The one that
measured something in 2024 is still installable, at the version it was measured with, because nothing rewrote it in place.
- Ownership is legible. One repository has one changelog, one issue
tracker and one set of maintainers.
What a module declares about itself
Everything the platform decides about a module, it decides from the module's own metadata rather than from where the module happens to sit.
[tool.plesty]
standard = "quantum"
module_type = "device"
module_type is one of device, analyzer, experiment or core, and it selects which rules apply. A device is held to the device contract — schemas, a status contract, a documented API pipeline. An analyzer is held to the analyzer contract: a public Analyzer subclass with declared input and output schemas, exercised on schema-generated synthetic inputs. An experiment is held to the experiment contract instead. Declaring nothing means the type-specific gates report N/A rather than failing, which is what lets a utility package live under the same standard without pretending to be an instrument.
standard is the quality tier the module is checked against. It is derived from the release version when it is not set — below 0.1.0 pixel, below 1.0.0 nebula, from 1.0.0 quantum — so a module tightens as it matures rather than being held to a release standard on its first day. See Quality Gates for what each tier demands.
What a device module declares to the world
A device is the one module type that other programs drive at runtime, so it publishes two machine-readable schemas next to its code:
| File | Declares |
|---|---|
schema_param.json |
Settings: type, unit, default, allowed range, the instrument command behind it, and a description |
schema_func.json |
Operations: input parameters with their types and ranges, and what comes back |
Those files are the contract. They are what the server validates incoming calls against, what describe() returns to a client that has never heard of this instrument, and what the published documentation is generated from — which is why documentation cannot drift from what the server accepts. A client asks the server what it can do; nothing about a specific instrument is compiled into the client.
Names follow from one decision
Every module shares the plesty namespace, and the rest is derived:
| Artifact | Convention | Example |
|---|---|---|
| Project directory | plesty- |
plesty-power-meter |
| Source package | plesty/ |
plesty/power_meter/ |
| PyPI distribution | plesty- |
plesty-power-meter |
| Python import | plesty. |
plesty.power_meter |
plesty init strips the plesty- prefix to infer the module name, so naming the project names all four. The shared namespace is why plesty.pm100d and plesty.lib coexist without either owning the plesty package.
Read next
- Build a Device — the same contract from the inside:
scaffold, base class, schemas, server, tests.
- Quality Gates — what
standardselects, gate
by gate.
- TCP Communication — the protocol a device module
serves.