kapps-semantic-middleware 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. kapps_semantic_middleware-0.1.0/.env.example +14 -0
  2. kapps_semantic_middleware-0.1.0/.github/workflows/hygiene.yml +40 -0
  3. kapps_semantic_middleware-0.1.0/.github/workflows/publish.yml +30 -0
  4. kapps_semantic_middleware-0.1.0/.gitignore +22 -0
  5. kapps_semantic_middleware-0.1.0/.python-version +1 -0
  6. kapps_semantic_middleware-0.1.0/AGENTS.md +170 -0
  7. kapps_semantic_middleware-0.1.0/CHANGELOG.md +46 -0
  8. kapps_semantic_middleware-0.1.0/CLAUDE.md +1 -0
  9. kapps_semantic_middleware-0.1.0/CONTEXT-MAP.md +59 -0
  10. kapps_semantic_middleware-0.1.0/LICENSE +21 -0
  11. kapps_semantic_middleware-0.1.0/PKG-INFO +142 -0
  12. kapps_semantic_middleware-0.1.0/README.md +117 -0
  13. kapps_semantic_middleware-0.1.0/demo/__init__.py +9 -0
  14. kapps_semantic_middleware-0.1.0/demo/transferunits/CONTEXT.md +77 -0
  15. kapps_semantic_middleware-0.1.0/demo/transferunits/README.md +220 -0
  16. kapps_semantic_middleware-0.1.0/demo/transferunits/__init__.py +24 -0
  17. kapps_semantic_middleware-0.1.0/demo/transferunits/__main__.py +43 -0
  18. kapps_semantic_middleware-0.1.0/demo/transferunits/algorithm.py +398 -0
  19. kapps_semantic_middleware-0.1.0/demo/transferunits/control_station.py +206 -0
  20. kapps_semantic_middleware-0.1.0/demo/transferunits/controller.py +1105 -0
  21. kapps_semantic_middleware-0.1.0/demo/transferunits/factory.ttl +16 -0
  22. kapps_semantic_middleware-0.1.0/demo/transferunits/index.py +170 -0
  23. kapps_semantic_middleware-0.1.0/demo/transferunits/launcher.py +485 -0
  24. kapps_semantic_middleware-0.1.0/demo/transferunits/middleware.py +187 -0
  25. kapps_semantic_middleware-0.1.0/demo/transferunits/plc/__init__.py +10 -0
  26. kapps_semantic_middleware-0.1.0/demo/transferunits/plc/__main__.py +87 -0
  27. kapps_semantic_middleware-0.1.0/demo/transferunits/plc/panel.py +202 -0
  28. kapps_semantic_middleware-0.1.0/demo/transferunits/plc/static/transferunit.svg +99 -0
  29. kapps_semantic_middleware-0.1.0/demo/transferunits/plc/templates/panel.html +181 -0
  30. kapps_semantic_middleware-0.1.0/demo/transferunits/plc/transfer_unit.py +449 -0
  31. kapps_semantic_middleware-0.1.0/demo/transferunits/seed.py +259 -0
  32. kapps_semantic_middleware-0.1.0/demo/transferunits/station_board.py +631 -0
  33. kapps_semantic_middleware-0.1.0/demo/transferunits/templates/index.html +311 -0
  34. kapps_semantic_middleware-0.1.0/demo/transferunits/templates/station_board.html +404 -0
  35. kapps_semantic_middleware-0.1.0/demo/transferunits/transferunit.ttl +114 -0
  36. kapps_semantic_middleware-0.1.0/docs/mechanics/01-instantiation-and-lifecycle.md +75 -0
  37. kapps_semantic_middleware-0.1.0/docs/mechanics/02-workflow-registration.md +103 -0
  38. kapps_semantic_middleware-0.1.0/docs/mechanics/03-state-and-parameters.md +79 -0
  39. kapps_semantic_middleware-0.1.0/docs/mechanics/04-connector-binding.md +131 -0
  40. kapps_semantic_middleware-0.1.0/docs/mechanics/05-operation-coordination.md +108 -0
  41. kapps_semantic_middleware-0.1.0/docs/mechanics/06-views-and-projection.md +86 -0
  42. kapps_semantic_middleware-0.1.0/docs/mechanics/07-writing-to-the-graph-and-to-devices.md +48 -0
  43. kapps_semantic_middleware-0.1.0/docs/mechanics/08-provisioning-and-seeding.md +109 -0
  44. kapps_semantic_middleware-0.1.0/docs/site/_static/custom.css +93 -0
  45. kapps_semantic_middleware-0.1.0/docs/site/_static/sfb-logo.png +0 -0
  46. kapps_semantic_middleware-0.1.0/docs/site/_static/switcher.json +8 -0
  47. kapps_semantic_middleware-0.1.0/docs/site/concepts.md +54 -0
  48. kapps_semantic_middleware-0.1.0/docs/site/conf.py +160 -0
  49. kapps_semantic_middleware-0.1.0/docs/site/guide/01-instantiation-and-lifecycle.md +80 -0
  50. kapps_semantic_middleware-0.1.0/docs/site/guide/02-workflow-registration.md +108 -0
  51. kapps_semantic_middleware-0.1.0/docs/site/guide/03-state-and-parameters.md +83 -0
  52. kapps_semantic_middleware-0.1.0/docs/site/guide/04-connector-binding.md +136 -0
  53. kapps_semantic_middleware-0.1.0/docs/site/guide/05-operation-coordination.md +113 -0
  54. kapps_semantic_middleware-0.1.0/docs/site/guide/06-views-and-projection.md +90 -0
  55. kapps_semantic_middleware-0.1.0/docs/site/guide/07-writing-to-the-graph-and-to-devices.md +52 -0
  56. kapps_semantic_middleware-0.1.0/docs/site/guide/08-provisioning-and-seeding.md +115 -0
  57. kapps_semantic_middleware-0.1.0/docs/site/guide/index.md +164 -0
  58. kapps_semantic_middleware-0.1.0/docs/site/index.md +140 -0
  59. kapps_semantic_middleware-0.1.0/docs/site/publish-workflow.yml +140 -0
  60. kapps_semantic_middleware-0.1.0/docs/site/reference/activity.md +9 -0
  61. kapps_semantic_middleware-0.1.0/docs/site/reference/connectors/knowledge_graph_connector.md +9 -0
  62. kapps_semantic_middleware-0.1.0/docs/site/reference/connectors/mqtt_binding.md +9 -0
  63. kapps_semantic_middleware-0.1.0/docs/site/reference/connectors/rest_binding.md +9 -0
  64. kapps_semantic_middleware-0.1.0/docs/site/reference/connectors/semantic.md +9 -0
  65. kapps_semantic_middleware-0.1.0/docs/site/reference/connectors/wiring.md +9 -0
  66. kapps_semantic_middleware-0.1.0/docs/site/reference/index.md +50 -0
  67. kapps_semantic_middleware-0.1.0/docs/site/reference/middleware.md +9 -0
  68. kapps_semantic_middleware-0.1.0/docs/site/reference/modes.md +9 -0
  69. kapps_semantic_middleware-0.1.0/docs/site/reference/projection.md +9 -0
  70. kapps_semantic_middleware-0.1.0/docs/site/reference/registration.md +9 -0
  71. kapps_semantic_middleware-0.1.0/docs/site/reference/rest_router.md +9 -0
  72. kapps_semantic_middleware-0.1.0/docs/site/reference/seeding.md +9 -0
  73. kapps_semantic_middleware-0.1.0/docs/site/reference/shacl_interop/shape_from_typehints.md +9 -0
  74. kapps_semantic_middleware-0.1.0/docs/site/reference/vocabulary.md +9 -0
  75. kapps_semantic_middleware-0.1.0/docs/site/requirements.txt +10 -0
  76. kapps_semantic_middleware-0.1.0/docs/site/scenarios/factory.md +153 -0
  77. kapps_semantic_middleware-0.1.0/docs/site/scenarios/index.md +16 -0
  78. kapps_semantic_middleware-0.1.0/examples/CONTEXT.md +45 -0
  79. kapps_semantic_middleware-0.1.0/examples/__init__.py +8 -0
  80. kapps_semantic_middleware-0.1.0/examples/demo_handover.ttl +42 -0
  81. kapps_semantic_middleware-0.1.0/examples/demo_scenario1.ttl +66 -0
  82. kapps_semantic_middleware-0.1.0/examples/demo_scenario2.ttl +75 -0
  83. kapps_semantic_middleware-0.1.0/examples/docker/docker-compose.yml +36 -0
  84. kapps_semantic_middleware-0.1.0/examples/docker/graphdb-repo-config.ttl +74 -0
  85. kapps_semantic_middleware-0.1.0/examples/docs/transferunit-ontology.md +275 -0
  86. kapps_semantic_middleware-0.1.0/examples/handlers.py +64 -0
  87. kapps_semantic_middleware-0.1.0/examples/scenario1_hello_world.ipynb +432 -0
  88. kapps_semantic_middleware-0.1.0/examples/scenario1_hello_world.py +282 -0
  89. kapps_semantic_middleware-0.1.0/examples/scenario2_door.ipynb +438 -0
  90. kapps_semantic_middleware-0.1.0/examples/scenario2_door.py +285 -0
  91. kapps_semantic_middleware-0.1.0/examples/seed.py +269 -0
  92. kapps_semantic_middleware-0.1.0/examples/transferunit.ttl +114 -0
  93. kapps_semantic_middleware-0.1.0/pyproject.toml +214 -0
  94. kapps_semantic_middleware-0.1.0/scripts/release_checks.py +419 -0
  95. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/CONTEXT.md +349 -0
  96. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/__init__.py +38 -0
  97. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/activity.py +384 -0
  98. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/connectors/__init__.py +42 -0
  99. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/connectors/knowledge_graph_connector.py +140 -0
  100. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/connectors/mqtt_binding.py +371 -0
  101. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/connectors/rest_binding.py +437 -0
  102. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/connectors/semantic.py +346 -0
  103. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/connectors/wiring.py +506 -0
  104. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/credentials.py +90 -0
  105. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/docs/mqtt-payloads.md +98 -0
  106. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/examples_cli.py +199 -0
  107. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/middleware.py +1255 -0
  108. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/modes.py +47 -0
  109. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/ontology/core.ttl +755 -0
  110. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/ontology/mes.ttl +90 -0
  111. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/ontology/service.ttl +178 -0
  112. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/projection.py +314 -0
  113. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/py.typed +0 -0
  114. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/registration.py +877 -0
  115. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/rest_router.py +356 -0
  116. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/seeding.py +99 -0
  117. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/shacl_interop/CONTEXT.md +33 -0
  118. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/shacl_interop/__init__.py +5 -0
  119. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/shacl_interop/shape_from_typehints.py +159 -0
  120. kapps_semantic_middleware-0.1.0/src/kapps_semantic_middleware/vocabulary.py +213 -0
  121. kapps_semantic_middleware-0.1.0/tests/conftest.py +215 -0
  122. kapps_semantic_middleware-0.1.0/tests/test_activity_feed.py +559 -0
  123. kapps_semantic_middleware-0.1.0/tests/test_algorithm_loop.py +224 -0
  124. kapps_semantic_middleware-0.1.0/tests/test_controller_discovery.py +339 -0
  125. kapps_semantic_middleware-0.1.0/tests/test_controller_rebuild_view.py +194 -0
  126. kapps_semantic_middleware-0.1.0/tests/test_controller_view.py +471 -0
  127. kapps_semantic_middleware-0.1.0/tests/test_demo_activity_feed_wiring.py +101 -0
  128. kapps_semantic_middleware-0.1.0/tests/test_demo_broker_transport.py +98 -0
  129. kapps_semantic_middleware-0.1.0/tests/test_event_trigger_integration.py +418 -0
  130. kapps_semantic_middleware-0.1.0/tests/test_examples_cli.py +118 -0
  131. kapps_semantic_middleware-0.1.0/tests/test_examples_serve_their_middlewares.py +138 -0
  132. kapps_semantic_middleware-0.1.0/tests/test_factory_deregistration.py +220 -0
  133. kapps_semantic_middleware-0.1.0/tests/test_factory_smoke.py +791 -0
  134. kapps_semantic_middleware-0.1.0/tests/test_failure_dump_unit.py +61 -0
  135. kapps_semantic_middleware-0.1.0/tests/test_favicon_routes.py +76 -0
  136. kapps_semantic_middleware-0.1.0/tests/test_graphdb_credentials.py +92 -0
  137. kapps_semantic_middleware-0.1.0/tests/test_handover_integration.py +143 -0
  138. kapps_semantic_middleware-0.1.0/tests/test_lap_measurement.py +150 -0
  139. kapps_semantic_middleware-0.1.0/tests/test_launcher_factory.py +377 -0
  140. kapps_semantic_middleware-0.1.0/tests/test_launcher_index_guard.py +68 -0
  141. kapps_semantic_middleware-0.1.0/tests/test_launcher_index_links.py +44 -0
  142. kapps_semantic_middleware-0.1.0/tests/test_launcher_seeding.py +272 -0
  143. kapps_semantic_middleware-0.1.0/tests/test_liveness_integration.py +106 -0
  144. kapps_semantic_middleware-0.1.0/tests/test_middleware_connector_flavours.py +148 -0
  145. kapps_semantic_middleware-0.1.0/tests/test_modes.py +59 -0
  146. kapps_semantic_middleware-0.1.0/tests/test_northbound_sync_integration.py +289 -0
  147. kapps_semantic_middleware-0.1.0/tests/test_optional_transport_stacks.py +245 -0
  148. kapps_semantic_middleware-0.1.0/tests/test_panel_convergence.py +105 -0
  149. kapps_semantic_middleware-0.1.0/tests/test_persistence_factory_warning.py +154 -0
  150. kapps_semantic_middleware-0.1.0/tests/test_plc_guard.py +62 -0
  151. kapps_semantic_middleware-0.1.0/tests/test_queue_durability_integration.py +152 -0
  152. kapps_semantic_middleware-0.1.0/tests/test_recursive_rest_router.py +720 -0
  153. kapps_semantic_middleware-0.1.0/tests/test_recursive_rest_router_integration.py +306 -0
  154. kapps_semantic_middleware-0.1.0/tests/test_rest_binding.py +357 -0
  155. kapps_semantic_middleware-0.1.0/tests/test_scenario1_integration.py +164 -0
  156. kapps_semantic_middleware-0.1.0/tests/test_scenario2_integration.py +202 -0
  157. kapps_semantic_middleware-0.1.0/tests/test_scenario3_roundtrip_integration.py +272 -0
  158. kapps_semantic_middleware-0.1.0/tests/test_scenario3_seed_integration.py +147 -0
  159. kapps_semantic_middleware-0.1.0/tests/test_scenario3_wiring_integration.py +683 -0
  160. kapps_semantic_middleware-0.1.0/tests/test_semantic_connectors.py +729 -0
  161. kapps_semantic_middleware-0.1.0/tests/test_service_identity.py +183 -0
  162. kapps_semantic_middleware-0.1.0/tests/test_shape_from_typehints.py +72 -0
  163. kapps_semantic_middleware-0.1.0/tests/test_southbound_echo_integration.py +371 -0
  164. kapps_semantic_middleware-0.1.0/tests/test_station_board_guard.py +178 -0
  165. kapps_semantic_middleware-0.1.0/tests/test_station_board_set_route.py +139 -0
  166. kapps_semantic_middleware-0.1.0/tests/test_station_board_state_route.py +630 -0
  167. kapps_semantic_middleware-0.1.0/tests/test_transfer_unit_plc.py +335 -0
  168. kapps_semantic_middleware-0.1.0/tests/test_vocabulary.py +88 -0
  169. kapps_semantic_middleware-0.1.0/tests/test_write_status.py +301 -0
  170. kapps_semantic_middleware-0.1.0/uv.lock +3729 -0
@@ -0,0 +1,14 @@
1
+ # GraphDB connection for examples and demo.
2
+ # GraphDB runs with security disabled in the local Docker image, so username/password
3
+ # are placeholders that the client merely requires.
4
+ #
5
+ # Only these three variables are read. The examples and the demo name their own
6
+ # repository in code -- kapps-demo, the one docker/docker-compose.yml creates -- and the
7
+ # test suite names its own. A GRAPHDB_REPOSITORY left in your environment is ignored by
8
+ # all of them (issue #146), because whatever they connect to, they wipe and re-seed.
9
+ #
10
+ # WARNING: point GRAPHDB_URL at a GraphDB you are allowed to overwrite. The repository is
11
+ # pinned, but the server is not.
12
+ GRAPHDB_URL=http://localhost:7200
13
+ GRAPHDB_USERNAME=admin
14
+ GRAPHDB_PASSWORD=root
@@ -0,0 +1,40 @@
1
+ # This workflow is the backstop for commits made directly in the public repo.
2
+ # The pre-push gate in the dev checkout cannot see those commits, so the public
3
+ # repo needs its own CI that runs the same hygiene checks.
4
+ #
5
+ # Checks 2-5. Only check 1 (remotes) is left out: a runner's remote is whatever
6
+ # actions/checkout configured and says nothing about the release. Check 2 is the
7
+ # reason this file exists, and fetch-depth: 0 below is what lets it read the
8
+ # whole history rather than the one commit a shallow checkout would give it.
9
+
10
+ name: hygiene
11
+
12
+ on:
13
+ push:
14
+ pull_request:
15
+
16
+ jobs:
17
+ hygiene:
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+ with:
22
+ fetch-depth: 0
23
+ - uses: actions/setup-python@v5
24
+ with:
25
+ python-version: '3.12'
26
+ - name: Run the release hygiene checks
27
+ run: python scripts/release_checks.py .
28
+
29
+ # A tool published under the org but carrying no cf-tool topic is absent
30
+ # from the front door, which is a thing nobody notices by looking at the
31
+ # repository. release_checks.py is not the place for it: that file is
32
+ # stdlib-only and judges a tree, and this needs the API.
33
+ - name: Front-door registration
34
+ if: startsWith(github.repository, 'circularfactory/')
35
+ run: |
36
+ gh api repos/${{ github.repository }} --jq '.topics[]' | grep -qx cf-tool || {
37
+ echo "::error::Published under circularfactory but carries no cf-tool topic, so it is absent from the front door."
38
+ exit 1; }
39
+ env:
40
+ GH_TOKEN: ${{ github.token }}
@@ -0,0 +1,30 @@
1
+ # Publish to PyPI when publish_release.py pushes a version tag.
2
+ #
3
+ # id-token: write is what makes trusted publishing work, and is why no API token
4
+ # is stored anywhere. The tag push from publish_release.py is what fires this.
5
+ #
6
+ # PyPI supports trusted publishing from GitHub and from gitlab.com only, not from
7
+ # a self-hosted GitLab. That is the whole reason this project is published from a
8
+ # repository here while development happens elsewhere.
9
+
10
+ name: publish
11
+
12
+ on:
13
+ push:
14
+ tags: ['v*']
15
+
16
+ jobs:
17
+ publish:
18
+ runs-on: ubuntu-latest
19
+ environment: pypi
20
+ permissions:
21
+ id-token: write
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+ - uses: actions/setup-python@v5
25
+ with:
26
+ python-version: '3.12'
27
+ - name: Build the distributions
28
+ run: pipx run build
29
+ - name: Publish to PyPI
30
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,22 @@
1
+ .venv/
2
+ __pycache__/
3
+ .pytest_cache/
4
+ .mypy_cache/
5
+ .ruff_cache/
6
+ dist/
7
+ build/
8
+ *.egg-info/
9
+ .ipynb_checkpoints/
10
+ .env
11
+
12
+ # Written by scripts/prepare_release.py: the reviewed branch tip that publish_release.py
13
+ # refuses to move past. Local state about one release run, not a fact about the project.
14
+ .release-state.json
15
+ # Sphinx build output (#116). The docs site is deployed as a Pages artifact,
16
+ # never committed -- the release repo keeps one clean commit of source only.
17
+ docs/site/_build/
18
+ # The scenario pages are the notebooks themselves, copied in from examples/ by
19
+ # conf.py at build time (#141). Generated, so never committed -- same rule as the
20
+ # build output above.
21
+ docs/site/scenarios/hello-world.ipynb
22
+ docs/site/scenarios/door.ipynb
@@ -0,0 +1 @@
1
+ 3.12
@@ -0,0 +1,170 @@
1
+ # AGENTS.md
2
+
3
+ Orientation for an agent building against `kapps_semantic_middleware`.
4
+
5
+ This library lets a piece of Python code running on or next to a shopfloor resource expose its
6
+ functionality through an RDF knowledge graph, and lets other middleware instances discover and
7
+ invoke that functionality through the graph rather than through hardcoded network references.
8
+
9
+ If you are prototyping against this middleware, read the consumption rules below first. They are
10
+ constraints that **do not surface in type signatures** — most of them fail silently, producing
11
+ structurally wrong behavior rather than an exception. Then read the mechanics pages for whichever
12
+ part you are touching.
13
+
14
+ ## Where to read what
15
+
16
+ **Vocabulary — what the words mean.** Read these before the mechanics pages; the mechanics pages
17
+ assume their terms and do not re-define them.
18
+
19
+ | File | Covers |
20
+ |---|---|
21
+ | [`CONTEXT-MAP.md`](CONTEXT-MAP.md) | The five contexts, how they depend on each other, and the three-module ontology layering |
22
+ | [`src/kapps_semantic_middleware/CONTEXT.md`](src/kapps_semantic_middleware/CONTEXT.md) | The core vocabulary: Service, Workflow, Parameter, ClassScope, Projection, Binding descriptor, Operation, Mode |
23
+ | [`src/kapps_semantic_middleware/shacl_interop/CONTEXT.md`](src/kapps_semantic_middleware/shacl_interop/CONTEXT.md) | Precondition and outcome shapes derived from a function's type hints |
24
+ | [`examples/CONTEXT.md`](examples/CONTEXT.md) | The self-contained scenario notebooks |
25
+ | [`demo/transferunits/CONTEXT.md`](demo/transferunits/CONTEXT.md) | The runnable multi-process factory demonstration |
26
+
27
+ **Mechanics — how to use it.** Written in construction order; a reader can go start to finish
28
+ without forward references.
29
+
30
+ | Page | Covers |
31
+ |---|---|
32
+ | [`docs/mechanics/01-instantiation-and-lifecycle.md`](docs/mechanics/01-instantiation-and-lifecycle.md) | Constructing an instance, choosing a mode, what appears in the graph at startup, heartbeat, deregistration |
33
+ | [`docs/mechanics/02-workflow-registration.md`](docs/mechanics/02-workflow-registration.md) | Declaring what a Service exposes, the ontology prerequisites, signature-derived shapes, address vs. endpoint |
34
+ | [`docs/mechanics/03-state-and-parameters.md`](docs/mechanics/03-state-and-parameters.md) | Modelling resource state as Parameters, committed value vs. locator, where a parameter's shape comes from |
35
+ | [`docs/mechanics/04-connector-binding.md`](docs/mechanics/04-connector-binding.md) | The recognition chain, adding a protocol the library does not ship, connector wiring, transports |
36
+ | [`docs/mechanics/05-operation-coordination.md`](docs/mechanics/05-operation-coordination.md) | Dispatch, the event trigger, pull-and-run, the status lifecycle, handover, recovery |
37
+ | [`docs/mechanics/06-views-and-projection.md`](docs/mechanics/06-views-and-projection.md) | Defining a ClassScope, what a view cannot select, what the northbound projection removes |
38
+ | [`docs/mechanics/07-writing-to-the-graph-and-to-devices.md`](docs/mechanics/07-writing-to-the-graph-and-to-devices.md) | Every path that causes a write, naming the field that moved, northbound vs. southbound, IRI handling |
39
+ | [`docs/mechanics/08-provisioning-and-seeding.md`](docs/mechanics/08-provisioning-and-seeding.md) | **Read first if `ogm=` is a mystery.** The bootstrap order, loading the shared ontologies, authoring the domain TBox, and seeding the instance data a Parameter needs |
40
+
41
+ ### A note on the citations you will find in the glossaries
42
+
43
+ The `CONTEXT.md` files cite architecture decision records as **ADR 00nn** and **root ADR
44
+ 000n**. Those records are development-repository material and are **not part of this
45
+ distribution** — no copy of them ships, and the release rewrites every path that pointed
46
+ at one, so a citation here is never a link you can follow.
47
+
48
+ **Do not go looking for them.** The citations are provenance markers, not links. Every mechanism a
49
+ glossary cites a record for is explained in full by the mechanics page covering it — ADR 0004's
50
+ subject is the "Address and endpoint" section of
51
+ [`02-workflow-registration.md`](docs/mechanics/02-workflow-registration.md), ADR 0006's is "The
52
+ graph-facing connector" in [`04-connector-binding.md`](docs/mechanics/04-connector-binding.md), and
53
+ so on. If a citation seems to point at something the mechanics pages do not cover, that is a
54
+ documentation bug worth reporting, not a missing file worth hunting.
55
+
56
+ ## Where the names come from
57
+
58
+ This library re-exports much of its surface from its three dependencies, so the import you need is
59
+ often *not* from `kapps_semantic_middleware`. Use this table rather than guessing.
60
+
61
+ | Name | Import from |
62
+ |---|---|
63
+ | `SemanticMiddleware`, `Mode` | `kapps_semantic_middleware` |
64
+ | `IRI`, `GraphDB` | `kapps_triplestore_interface` |
65
+ | `OGM` | `kapps_ogm` |
66
+ | `ClassScope` | `kapps_ogm.utils.class_scope` |
67
+ | `SyncDirection` | `transitional_sync_middleware.middleware.sync.synced_connector` |
68
+ | `ConnectionInfo` | `transitional_sync_middleware.middleware.registries` |
69
+ | `INF` (the interface vocabulary) | `kapps_semantic_middleware.vocabulary` |
70
+ | `graphdb_for`, `credentials_for` | `kapps_semantic_middleware.credentials` |
71
+ | `DataModel`, `Reference`, `Identifier` | `kapps_semantic_middleware` (re-exported from `transitional_sync_middleware`) |
72
+
73
+ Binding internals, if you are adding a protocol, live under
74
+ `kapps_semantic_middleware.connectors` — `semantic`, `mqtt_binding`, `rest_binding`,
75
+ `knowledge_graph_connector`, `wiring`.
76
+
77
+ > `kapps_semantic_middleware/ontology/` is **not** a Python module. It is the directory holding the
78
+ > three vocabulary files (`core.ttl`, `mes.ttl`, `service.ttl`). Importing from it fails.
79
+
80
+ ## Consumption rules
81
+
82
+ ### These fail silently
83
+
84
+ **`GraphDB.from_env()` connects to whatever `GRAPHDB_REPOSITORY` names, and seeding destroys what it
85
+ connects to.** `seeding.clear_repository` clears the default graph of the client's current
86
+ repository, so a value left over in a shell — from another project, another checkout, a `.bashrc`
87
+ written months ago — silently redirects a wipe. Nothing validates that the repository was the one you
88
+ meant; it only has to exist. Use `credentials.graphdb_for("name")`, which names the repository in
89
+ code and ignores the variable, for anything that seeds, clears, or re-seeds. Note this hazard belongs
90
+ to the *variable*, not the server: pinning the repository does not stop `GRAPHDB_URL` pointing at a
91
+ shared instance.
92
+
93
+ **A `ClassScope` terminates at a Parameter and cannot select within one.** Any chain element below
94
+ a complex property is silently discarded during fetch. A view that tries to reach inside a
95
+ parameter blanknode materializes only as far as the parameter itself, with no error raised. A scope
96
+ chooses *which* parameters, never *which parts* of one.
97
+
98
+ **Connector bindings must be registered at construction, not later.** The framework calls
99
+ `connect()` on everything in the connection registry before it runs `on_start_up` callbacks. A
100
+ connector registered after construction never has `connect()` called, so inbound traffic dies
101
+ silently — the listener task never starts and the queue is never fed — while outbound may limp
102
+ along, making the fault one-directional and quiet.
103
+
104
+ **A Parameter's shape comes from the TBox restriction on its property's range, not from the
105
+ instance data.** Anything the restriction does not declare is dropped at materialization with only
106
+ a warning logged. Metadata a connector needs must be declared in the restriction or it never
107
+ arrives, and the connector fails with nothing raised.
108
+
109
+ **Under the locator pattern a Parameter's value is not in the graph at all.** Fast-changing
110
+ parameters keep only metadata in the graph; the live value exists only in the datamodel and over
111
+ REST. An unobserved parameter materializes as an empty list, which means *not yet read* — not zero,
112
+ and not null. Handle the empty case.
113
+
114
+ **A persistence write must name the region of the model that changed.** The fan-out notifies only
115
+ the connectors that region covers. A write that does not name its field notifies every synced
116
+ connector, so devices are written that nobody touched — and for a settable parameter that
117
+ fabricates a command rather than merely wasting traffic.
118
+
119
+ **The northbound REST payload never carries protocol connection metadata.** Broker addresses,
120
+ topics and endpoints are pruned from the served datamodel *before* any data is fetched. This is
121
+ structural, not a permission check: the northbound model has no field able to carry a broker
122
+ address. It stops a peer *learning* an address from this surface; it does not stop someone who
123
+ already knows it.
124
+
125
+ **OWL existential restrictions do not make a field required.** Only SHACL shapes enforce
126
+ requiredness, and only at admission. A parameter with no observed value does not raise a validation
127
+ error on materialization merely because its restriction declares `owl:someValuesFrom`. Absence of a
128
+ triple means *unknown*, never *false*.
129
+
130
+ **Any prettified or shortened IRI is display only.** Production code carries fully back-resolvable
131
+ IRIs in their mangled form — REST path segments, datamodel field names, `svc:endpoint` triples. A
132
+ consumer that parses a displayed IRI, or round-trips one back into a query, gets a wrong answer
133
+ with no exception raised.
134
+
135
+ ### These fail loudly
136
+
137
+ **Every class you register against must already exist in the ontology.** The middleware creates
138
+ instances automatically but never mints classes. A domain-specific subclass of `svc:Service`,
139
+ `svc:Workflow` or `svc:StateProperty`, and the `cfc:Capability` subclass a Workflow realizes, must
140
+ all pre-exist. Startup fails immediately, naming the missing class.
141
+
142
+ **All knowledge-graph writes go through the OGM.** Raw SPARQL `UPDATE` or direct
143
+ `kapps_triplestore_interface` mutation calls bypass the validated write path, so the written node passes no
144
+ shape check and a property replacement loses its atomicity — the intermediate state fails
145
+ validation. Reads may use the access module directly; only writes are constrained.
146
+
147
+ **`@mw.workflow` and `@mw.state` are resource-mode only.** Each raises `RuntimeError` when called
148
+ on an instance in any other mode, and `ValueError` when a required class IRI is missing.
149
+
150
+ ### Structural facts
151
+
152
+ **Build against `src/kapps_semantic_middleware/`. `examples/` and `demo/` are illustrations, not
153
+ API.** They are teaching vehicles seeded against throwaway repositories, not production patterns to
154
+ copy.
155
+
156
+ **The demo imports as `kapps_semantic_middleware.demonstrations`, not `demo`.** The wheel remaps
157
+ the `demo/` directory into the library namespace. `import demo.transferunits` works only in a
158
+ development checkout.
159
+
160
+ **There is one Service per middleware *instance*, not per Resource.** Several instances may wrap
161
+ one Resource — a controller and a monitor, say — each owning its own Service node, address and
162
+ heartbeat, all linked by `svc:isServiceOf`. Discovery may therefore return several Services for one
163
+ Resource; select by address or by advertised capability rather than assuming exactly one.
164
+
165
+ **Only `resource` and `watchdog` modes are implemented.** `server` is reserved and raises
166
+ `NotImplementedError`. A graph-*consuming* participant — a planner, a controller, a mobile robot —
167
+ is a resource-mode instance with its own Resource, not a server-mode one.
168
+
169
+ **Docker is a prerequisite for running the examples, never for using the library.** The bundled
170
+ `docker compose` file provides the GraphDB the scenarios and the factory need.
@@ -0,0 +1,46 @@
1
+ # Changelog
2
+
3
+ Notable changes to `kapps-semantic-middleware`. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this project uses
5
+ [semantic versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ `prepare_release.py` turns the Unreleased heading below into the dated entry for the version
8
+ being released, and stops the release if there is no such heading. Write the entry as the work
9
+ lands, not at release time.
10
+
11
+ (That sentence deliberately does not spell the heading out. `edit_changelog` insists on finding
12
+ exactly one of it, and prose naming it is a second occurrence — which stopped a release the
13
+ first time this file was written.)
14
+
15
+ ## 0.1.0 — 2026-08-12
16
+
17
+ ### Added
18
+
19
+ - **First public release.** A resource's state is described in an RDF knowledge graph as a
20
+ protocol-interface parameter, and the middleware wires that description to a real device:
21
+ peer discovery through the graph, a northbound REST surface, and southbound connectors that
22
+ keep graph and device in step.
23
+ - Two runnable scenarios and a six-process factory demonstration, copied out of the installed
24
+ package with `kapps-examples` — including the `docker compose` files that stand up the
25
+ GraphDB they need, which previously reached only a reader of the source repository.
26
+ - `kapps-transferunit-factory`, a console script that boots the factory demonstration.
27
+ - Agent-facing documentation inside the distribution: `AGENTS.md`, `CONTEXT-MAP.md` and the
28
+ eight `docs/mechanics/` pages, so a consuming agent reading `site-packages` finds the rules
29
+ that explain what it is reading.
30
+
31
+ ### Changed
32
+
33
+ - The synchronization layer is now `transitional-sync-middleware`, imported as
34
+ `transitional_sync_middleware`. It is the same code this project has always built on — a
35
+ transitional fork of `aas-middleware` carrying four synchronization fixes — published under
36
+ its own name. **It is retired within a few releases; do not build on it directly.**
37
+
38
+ ### Known limitations
39
+
40
+ - Only `resource` and `watchdog` modes are implemented. `server` is reserved and raises
41
+ `NotImplementedError`.
42
+ - A `ClassScope` selects *which* parameters, never *which parts* of one. Any chain element
43
+ below a complex property is discarded during fetch, with nothing raised.
44
+ - Several consumption rules fail silently rather than raising. They are listed in `AGENTS.md`
45
+ under "These fail silently", and reading that section is not optional if you are writing code
46
+ against this library.
@@ -0,0 +1 @@
1
+ See [AGENTS.md](AGENTS.md).
@@ -0,0 +1,59 @@
1
+ # Context Map
2
+
3
+ ## Contexts
4
+
5
+ - [Core Middleware](./src/kapps_semantic_middleware/CONTEXT.md) — the middleware library itself.
6
+ It holds the Service/Workflow/Capability/Operation/Mode registration machinery and the
7
+ execution machinery.
8
+ - [SHACL Interop](./src/kapps_semantic_middleware/shacl_interop/CONTEXT.md) — the temporary SHACL
9
+ seam for workflow precondition shapes and outcome shapes. It generates and parses them. It is
10
+ explicit scaffolding, will move to `kapps_ogm` (see its ADR 0001).
11
+ - [Example Scenarios](./examples/CONTEXT.md) — self-contained demonstration notebooks, plus the
12
+ seed-data logic and the ontology-provisioning logic under them. That logic makes each notebook
13
+ reproducible against a dummy repository, and never against the production state.
14
+ - [TransferUnit Factory](./demo/transferunits/CONTEXT.md) — the runnable multi-process demo. A
15
+ launcher seeds N units and starts one process per participant (ADR 0029). Its decisions live
16
+ with the Core Middleware ADRs, next to ADR 0029.
17
+ - **Module Requirements** — requirements this project places on sibling KAPPS-family
18
+ modules (`kapps_ogm`, the not-yet-created visual-toolbox GUI). Not a code context, and its
19
+ documents are development-repository material that does not ship.
20
+
21
+ ## Relationships
22
+
23
+ - **Core Middleware → SHACL Interop**: Core Middleware calls into SHACL Interop to read or write
24
+ a shape. The shape belongs to a Workflow class or a StateProperty class. The call happens when
25
+ `@mw.workflow` or `@mw.state` registers or resolves one. SHACL Interop has no dependency back
26
+ on Core Middleware. It operates on class IRIs and shapes, and not on types of the Core Middleware.
27
+ - **Example Scenarios → Core Middleware**: Example Scenarios instantiate and exercise Core
28
+ Middleware end-to-end, against the ontology and the instance data they seed themselves. Core Middleware
29
+ has no dependency on Example Scenarios.
30
+ - **TransferUnit Factory → Core Middleware**: the factory runs several instances of the library
31
+ in separate processes. That is one instance per unit, plus a controller. A monitor is
32
+ milestone 2 (ADR 0032) and is not built. Core Middleware has no dependency on the factory.
33
+ - **Module Requirements** records obligations that Core Middleware and SHACL Interop place on
34
+ `kapps_ogm` and the visual-toolbox repo. It does not depend on the code contexts, and no code
35
+ context depends on it. It is a record for work that belongs elsewhere.
36
+
37
+ ## Ontology-module layering
38
+
39
+ The vocabulary of the project is layered across three modules (Core Middleware ADR 0012):
40
+
41
+ - **`cfc:` — Core** (`.../Core#`): published, external, superior — `Operation`/`Capability`/
42
+ `Resource`/`Task`. The system imports and specializes it. The system does not modify it.
43
+ - **`mes:` — MES** (`.../MES#`, `src/kapps_semantic_middleware/ontology/mes.ttl`): a
44
+ **domain** ontology that imports Core and details it out — possession + handover ability.
45
+ What domain experts touch.
46
+ - **`svc:` — Service** (`.../Service#`, `ontology/service.ttl`): middleware-to-middleware
47
+ **reachability and coordination only**, domain code does not touch it. It holds Service, Workflow and
48
+ StateProperty, the address, the endpoint and the heartbeat. It also holds the resolution chain,
49
+ and an Operation's status and provenance.
50
+
51
+ `mes:` and `svc:` are siblings that both import Core. `mes:` is domain-facing, `svc:` is
52
+ middleware-facing.
53
+
54
+ ## Where the decisions are written down
55
+
56
+ The architecture decision records are development-repository material and are not part of
57
+ this distribution. What they decided is described, without the deliberation, in
58
+ [`docs/mechanics/`](docs/mechanics/); [`AGENTS.md`](AGENTS.md) indexes those pages.
59
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Etienne Hoffmann
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,142 @@
1
+ Metadata-Version: 2.5
2
+ Name: kapps-semantic-middleware
3
+ Version: 0.1.0
4
+ Summary: Semantic middleware for industrial data integration, built on transitional-sync-middleware
5
+ Author-email: Etienne Hoffmann <etienne.hoffmann@kit.edu>, Sören Weindel <soeren.weindel@kit.edu>
6
+ Maintainer-email: Etienne Hoffmann <etienne.hoffmann@kit.edu>, Sören Weindel <soeren.weindel@kit.edu>
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Requires-Python: >=3.12
10
+ Requires-Dist: aiomqtt>=2.1.0
11
+ Requires-Dist: fastapi>=0.111.0
12
+ Requires-Dist: httpx>=0.27.0
13
+ Requires-Dist: kapps-ogm>=0.2.0
14
+ Requires-Dist: kapps-triplestore-interface>=2.1.0
15
+ Requires-Dist: transitional-sync-middleware>=0.1.0
16
+ Provides-Extra: examples
17
+ Requires-Dist: amqtt>=0.11.0; extra == 'examples'
18
+ Requires-Dist: rdflib>=7.1.3; extra == 'examples'
19
+ Requires-Dist: uvicorn>=0.29.0; extra == 'examples'
20
+ Provides-Extra: notebooks
21
+ Requires-Dist: jupyter>=1.1.1; extra == 'notebooks'
22
+ Requires-Dist: jupytext>=1.16.0; extra == 'notebooks'
23
+ Requires-Dist: nbconvert>=7.16.0; extra == 'notebooks'
24
+ Description-Content-Type: text/markdown
25
+
26
+ # kapps_semantic_middleware
27
+
28
+ Let a piece of Python running on or beside a shopfloor resource expose what it can do through an
29
+ RDF knowledge graph — and let other instances discover and invoke that capability **through the
30
+ graph**, rather than through hardcoded network addresses.
31
+
32
+ A resource's state is described in the graph as a protocol-interface **parameter**. The middleware
33
+ wires that description to the real device: it discovers peers, serves them over REST, and keeps the
34
+ graph and the device in step.
35
+
36
+ ```bash
37
+ pip install kapps-semantic-middleware
38
+ ```
39
+
40
+ Python 3.12 or newer. Nothing else is required to use the library.
41
+
42
+ ## Run the examples
43
+
44
+ The scenarios and the factory demo need a few more packages and a running GraphDB. One extra
45
+ covers the packages:
46
+
47
+ ```bash
48
+ pip install "kapps-semantic-middleware[examples]"
49
+ ```
50
+
51
+ Copy the runnable files out of the installed package into a directory you own — a notebook inside
52
+ `site-packages` cannot be opened, edited or re-run:
53
+
54
+ ```bash
55
+ kapps-examples ./kapps-examples
56
+ cd kapps-examples
57
+ ```
58
+
59
+ You now have scenario 1 and scenario 2 (each as a `.py` and a `.ipynb`), the seed data they load,
60
+ and a `docker/` directory. Add the `[notebooks]` extra if you want to open the `.ipynb` files in
61
+ Jupyter; the `.py` versions run with `[examples]` alone.
62
+
63
+ ### Start a GraphDB
64
+
65
+ Docker is needed for the examples and the demo, **never for the library itself**.
66
+
67
+ ```bash
68
+ cd docker
69
+ docker compose up -d
70
+ ```
71
+
72
+ GraphDB comes up on <http://localhost:7200> and the `kapps-demo` repository is created for you.
73
+ This works the same on Linux, macOS and Windows.
74
+
75
+ Then point the library at it:
76
+
77
+ ```bash
78
+ export GRAPHDB_URL=http://localhost:7200
79
+ export GRAPHDB_USERNAME=admin
80
+ export GRAPHDB_PASSWORD=root
81
+ ```
82
+
83
+ Three variables, not four. `GraphDBCredentials.from_env()` in `kapps_triplestore_interface` also
84
+ reads `GRAPHDB_REPOSITORY`, and your own code may well use it — but nothing here does. The examples
85
+ and the demo name `kapps-demo` in code, and the test suite names its own. **A `GRAPHDB_REPOSITORY`
86
+ you already have set is ignored rather than obeyed**, because these are the parts that wipe and
87
+ re-seed whatever they connect to.
88
+
89
+ > **Never point `GRAPHDB_URL` at a GraphDB you care about.** The examples and the demo clear the
90
+ > repository they use on every run. `docker compose down -v` wipes the throwaway one; the next run
91
+ > re-seeds it.
92
+
93
+ ### Run a scenario
94
+
95
+ ```bash
96
+ python scenario1_hello_world.py # operation coordination through the graph
97
+ python scenario2_door.py # direct state discovery and control
98
+ ```
99
+
100
+ ### Run the factory demo
101
+
102
+ A small factory as six real processes — one per mock PLC, one per middleware instance, and a
103
+ controller that discovers every unit *in the graph* and drives it over REST. You watch it from a
104
+ browser.
105
+
106
+ ```bash
107
+ kapps-transferunit-factory
108
+ ```
109
+
110
+ ## Where to read what
111
+
112
+ | | |
113
+ |---|---|
114
+ | [`AGENTS.md`](AGENTS.md) | **Start here to build against this.** The consumption rules — including the ones that fail *silently* — and which name to import from where. |
115
+ | [`docs/mechanics/`](docs/mechanics/) | How each mechanism actually works, one page each, in construction order. |
116
+ | [`CONTEXT-MAP.md`](CONTEXT-MAP.md) | The five contexts and how they relate. |
117
+ | `examples/` | Scenario 1 and scenario 2, self-contained. |
118
+ | `demo/transferunits/` | The factory demo. |
119
+
120
+ If you are writing code against this library, read `AGENTS.md` first. Several of its rules are
121
+ constraints that **do not appear in any type signature** and fail by producing quietly wrong
122
+ behaviour rather than an exception.
123
+
124
+ ## Status
125
+
126
+ `0.1.0` is the first public release. It is usable — the scenarios and the factory demo run end to
127
+ end — but the API may still move. See [`CHANGELOG.md`](CHANGELOG.md).
128
+
129
+ ## Contributing
130
+
131
+ Development happens in a private repository and this one is the published half: it carries one
132
+ commit per release and no ancestry, so there is nothing here to branch from.
133
+
134
+ Bug reports and questions are welcome as issues on this repository. A patch is welcome too --
135
+ say what it changes and why, and it will be applied on the development side and credited in
136
+ `CHANGELOG.md` for the release that carries it.
137
+
138
+ ## Acknowledgements
139
+
140
+ This package is developed as part of the INF subproject of the CRC 1574: Circular Factory for the
141
+ Perpetual Product. This work is therefore supported by the Deutsche Forschungsgemeinschaft (DFG,
142
+ German Research Foundation) [grant-number: SFB-1574-471687386].