Your first module¶
Tutorial. How a module registers itself, using the ERPNext connector as the worked example. Honest scope: the entry-point mechanism is small, and the "module" boundary is still a target the code is moving toward (see the architecture page).
What "module" means here, today¶
fsmes info lists modules by reading the fsmes.modules entry-point group.
As of 2026-09-07 one thing registers there: the ERPNext connector. The ERP
factory resolves any MES_ERP_MODE it does not know built in (rest,
file, off) by looking up an entry point of that name, so a connector in
a separate package plugs in without a change here.
That is the whole mechanism. Quality, maintenance and scheduling are not yet separately installable packages; they ship in the kernel wheel. Turning them into entry-point modules is on the roadmap, not done.
The worked example: ERPNext¶
pyproject.toml:
[project.entry-points."fsmes.modules"]
erpnext = "fsmes.integrations.erp.erpnext_adapter:from_settings"
from_settings(settings) builds an adapter that satisfies the ErpAdapter
protocol. Three methods move the work:
class ErpAdapter(Protocol):
def fetch_orders(self) -> list[ProductionRequest]: ...
def acknowledge(self, order_code: str) -> None: ...
def send_confirmation(self, confirmation: Confirmation) -> None: ...
Three more describe the far side — requirements(), setup() and
check() — and they have defaults, so a transport that needs nothing on
the ERP side can ignore them. They are what fsmes erp requirements,
fsmes erp setup and fsmes erp check run.
Writing an ERP connector is the whole story, including
the conformance suite a connector has to pass.
The models are typed (contract.py); every MES-side rule lives in
services.erp, so an adapter is transport only.
Write your own connector, in its own package¶
- New package, say
fsmes-sap, depending onfactorysemantics-mes. - Implement the port against
fsmes.integrations.erp.contract, and runfsmes.integrations.erp.conformanceagainst it — see writing an ERP connector. -
Register:
[project.entry-points."fsmes.modules"] sap = "fsmes_sap.adapter:from_settings" -
pip install fsmes-sap;fsmes infonow listserpnext, sap;MES_ERP_MODE=sapselects it.
Settings your connector needs come from the same MES_ environment; read
them off the Settings object you are handed, or from os.environ if they
are yours alone.
What to test¶
The ERPNext connector's tests (tests/test_erpnext.py) run against a fake
ERPNext in-process: the shape to copy. Name tests after the promise they
pin, not the function they call — house rule 5.
See also¶
- Writing an ERP connector — the port in full, and the bar
- Decision records 0002, 0008 and 0020
- The ERPNext connector