mycorrhizal 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 (40) hide show
  1. mycorrhizal-0.1.0/.github/workflows/python-publish.yml +70 -0
  2. mycorrhizal-0.1.0/.gitignore +4 -0
  3. mycorrhizal-0.1.0/PKG-INFO +198 -0
  4. mycorrhizal-0.1.0/README.md +188 -0
  5. mycorrhizal-0.1.0/pyproject.toml +66 -0
  6. mycorrhizal-0.1.0/src/mycorrhizal/__init__.py +3 -0
  7. mycorrhizal-0.1.0/src/mycorrhizal/common/__init__.py +68 -0
  8. mycorrhizal-0.1.0/src/mycorrhizal/common/interface_builder.py +203 -0
  9. mycorrhizal-0.1.0/src/mycorrhizal/common/interfaces.py +412 -0
  10. mycorrhizal-0.1.0/src/mycorrhizal/common/timebase.py +99 -0
  11. mycorrhizal-0.1.0/src/mycorrhizal/common/wrappers.py +532 -0
  12. mycorrhizal-0.1.0/src/mycorrhizal/enoki/__init__.py +0 -0
  13. mycorrhizal-0.1.0/src/mycorrhizal/enoki/core.py +1545 -0
  14. mycorrhizal-0.1.0/src/mycorrhizal/enoki/testing_utils.py +529 -0
  15. mycorrhizal-0.1.0/src/mycorrhizal/enoki/util.py +220 -0
  16. mycorrhizal-0.1.0/src/mycorrhizal/hypha/__init__.py +0 -0
  17. mycorrhizal-0.1.0/src/mycorrhizal/hypha/core/__init__.py +107 -0
  18. mycorrhizal-0.1.0/src/mycorrhizal/hypha/core/builder.py +404 -0
  19. mycorrhizal-0.1.0/src/mycorrhizal/hypha/core/runtime.py +890 -0
  20. mycorrhizal-0.1.0/src/mycorrhizal/hypha/core/specs.py +234 -0
  21. mycorrhizal-0.1.0/src/mycorrhizal/hypha/util.py +38 -0
  22. mycorrhizal-0.1.0/src/mycorrhizal/rhizomorph/README.md +220 -0
  23. mycorrhizal-0.1.0/src/mycorrhizal/rhizomorph/__init__.py +0 -0
  24. mycorrhizal-0.1.0/src/mycorrhizal/rhizomorph/core.py +1729 -0
  25. mycorrhizal-0.1.0/src/mycorrhizal/rhizomorph/util.py +45 -0
  26. mycorrhizal-0.1.0/src/mycorrhizal/spores/__init__.py +124 -0
  27. mycorrhizal-0.1.0/src/mycorrhizal/spores/cache.py +208 -0
  28. mycorrhizal-0.1.0/src/mycorrhizal/spores/core.py +419 -0
  29. mycorrhizal-0.1.0/src/mycorrhizal/spores/dsl/__init__.py +48 -0
  30. mycorrhizal-0.1.0/src/mycorrhizal/spores/dsl/enoki.py +514 -0
  31. mycorrhizal-0.1.0/src/mycorrhizal/spores/dsl/hypha.py +399 -0
  32. mycorrhizal-0.1.0/src/mycorrhizal/spores/dsl/rhizomorph.py +351 -0
  33. mycorrhizal-0.1.0/src/mycorrhizal/spores/encoder/__init__.py +11 -0
  34. mycorrhizal-0.1.0/src/mycorrhizal/spores/encoder/base.py +42 -0
  35. mycorrhizal-0.1.0/src/mycorrhizal/spores/encoder/json.py +159 -0
  36. mycorrhizal-0.1.0/src/mycorrhizal/spores/extraction.py +484 -0
  37. mycorrhizal-0.1.0/src/mycorrhizal/spores/models.py +288 -0
  38. mycorrhizal-0.1.0/src/mycorrhizal/spores/transport/__init__.py +10 -0
  39. mycorrhizal-0.1.0/src/mycorrhizal/spores/transport/base.py +46 -0
  40. mycorrhizal-0.1.0/uv.lock +478 -0
@@ -0,0 +1,70 @@
1
+ # This workflow will upload a Python Package to PyPI when a release is created
2
+ # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries
3
+
4
+ # This workflow uses actions that are not certified by GitHub.
5
+ # They are provided by a third-party and are governed by
6
+ # separate terms of service, privacy policy, and support
7
+ # documentation.
8
+
9
+ name: Upload Python Package
10
+
11
+ on:
12
+ release:
13
+ types: [published]
14
+
15
+ permissions:
16
+ contents: read
17
+
18
+ jobs:
19
+ release-build:
20
+ runs-on: ubuntu-latest
21
+
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+
25
+ - uses: actions/setup-python@v5
26
+ with:
27
+ python-version: "3.x"
28
+
29
+ - name: Build release distributions
30
+ run: |
31
+ # NOTE: put your own distribution build steps here.
32
+ python -m pip install build
33
+ python -m build
34
+
35
+ - name: Upload distributions
36
+ uses: actions/upload-artifact@v4
37
+ with:
38
+ name: release-dists
39
+ path: dist/
40
+
41
+ pypi-publish:
42
+ runs-on: ubuntu-latest
43
+ needs:
44
+ - release-build
45
+ permissions:
46
+ # IMPORTANT: this permission is mandatory for trusted publishing
47
+ id-token: write
48
+
49
+ # Dedicated environments with protections for publishing are strongly recommended.
50
+ # For more information, see: https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment#deployment-protection-rules
51
+ environment:
52
+ name: pypi
53
+ # OPTIONAL: uncomment and update to include your PyPI project URL in the deployment status:
54
+ # url: https://pypi.org/p/YOURPROJECT
55
+ #
56
+ # ALTERNATIVE: if your GitHub Release name is the PyPI project version string
57
+ # ALTERNATIVE: exactly, uncomment the following line instead:
58
+ # url: https://pypi.org/project/YOURPROJECT/${{ github.event.release.name }}
59
+
60
+ steps:
61
+ - name: Retrieve release distributions
62
+ uses: actions/download-artifact@v4
63
+ with:
64
+ name: release-dists
65
+ path: dist/
66
+
67
+ - name: Publish release distributions to PyPI
68
+ uses: pypa/gh-action-pypi-publish@release/v1
69
+ with:
70
+ packages-dir: dist/
@@ -0,0 +1,4 @@
1
+
2
+ **/__pycache__/
3
+ *.claude_todo/
4
+ *.pyc
@@ -0,0 +1,198 @@
1
+ Metadata-Version: 2.4
2
+ Name: mycorrhizal
3
+ Version: 0.1.0
4
+ Summary: Utilities and DSLs for modelling and implementing safe, performant, structured systems
5
+ Author-email: Jeff Ciesielski <jeffciesielski@gmail.com>
6
+ Requires-Python: >=3.10
7
+ Requires-Dist: pydantic>=2.11.7
8
+ Requires-Dist: typeguard==4.4.4
9
+ Description-Content-Type: text/markdown
10
+
11
+ # Mycorrhizal
12
+
13
+ A Python library for building safe, structured, concurrent, event-driven systems.
14
+
15
+ ## Overview
16
+
17
+ Mycorrhizal provides four domain-specific languages (DSLs) for modeling and implementing different aspects of complex systems:
18
+
19
+ * **Hypha** - Colored Petri nets for workflow modeling and orchestration
20
+ * **Rhizomorph** - Behavior trees for decision-making and control logic
21
+ * **Enoki** - Finite state machines for stateful components
22
+ * **Spores** - Event and object logging for observability and process mining
23
+
24
+ Each DSL can be used independently or combined to build sophisticated systems. All modules share common infrastructure for state management (blackboards) and time abstraction, enabling seamless composition.
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ pip install mycorrhizal
30
+ ```
31
+
32
+ Requires Python 3.10 or later.
33
+
34
+ ## Quick Start
35
+
36
+ ### Behavior Tree (Rhizomorph)
37
+
38
+ Define behavior trees using a decorator-based DSL:
39
+
40
+ ```python
41
+ from mycorrhizal.rhizomorph.core import bt, Runner, Status
42
+
43
+ @bt.tree
44
+ def ThreatResponse():
45
+ @bt.action
46
+ async def assess_threat(bb) -> Status:
47
+ # Analyze threat level
48
+ return Status.SUCCESS if bb.threat_level > 5 else Status.FAILURE
49
+
50
+ @bt.action
51
+ async def engage_countermeasures(bb) -> Status:
52
+ # Respond to threat
53
+ return Status.SUCCESS
54
+
55
+ @bt.root
56
+ @bt.sequence
57
+ def root():
58
+ yield assess_threat
59
+ yield engage_countermeasures
60
+
61
+ # Run the behavior tree
62
+ runner = Runner(ThreatResponse, bb=blackboard)
63
+ await runner.tick_until_complete()
64
+ ```
65
+
66
+ ### Petri Net (Hypha)
67
+
68
+ Model workflows with colored Petri nets:
69
+
70
+ ```python
71
+ from mycorrhizal.hypha.core import pn, Runner, PlaceType
72
+
73
+ @pn.net
74
+ def ProcessingNet(builder):
75
+ # Define places
76
+ pending = builder.place("pending", type=PlaceType.QUEUE)
77
+ processed = builder.place("processed", type=PlaceType.QUEUE)
78
+
79
+ # Define transitions
80
+ @builder.transition()
81
+ async def process(consumed, bb, timebase):
82
+ for token in consumed:
83
+ result = await handle(token)
84
+ yield {processed: result}
85
+
86
+ # Wire the net
87
+ builder.arc(pending, process).arc(processed)
88
+
89
+ # Run the Petri net
90
+ runner = Runner(ProcessingNet, bb=blackboard)
91
+ await runner.start(timebase)
92
+ ```
93
+
94
+ ### Finite State Machine (Enoki)
95
+
96
+ Build stateful components with FSMs:
97
+
98
+ ```python
99
+ from mycorrhizal.enoki.core import enoki, StateMachine, LabeledTransition
100
+
101
+ @enoki.state()
102
+ def IdleState():
103
+ @enoki.on_state
104
+ async def on_state(ctx):
105
+ if ctx.msg == "start":
106
+ return Events.START
107
+ return None
108
+
109
+ @enoki.transitions
110
+ def transitions():
111
+ return [
112
+ LabeledTransition(Events.START, ProcessingState),
113
+ ]
114
+
115
+ # Create and run the FSM
116
+ fsm = StateMachine(initial_state=IdleState, common_data={})
117
+ await fsm.initialize()
118
+ fsm.send_message("start")
119
+ await fsm.tick()
120
+ ```
121
+
122
+ ## Key Features
123
+
124
+ ### Shared Infrastructure
125
+
126
+ All DSLs use common building blocks:
127
+
128
+ * **Blackboards** - Typed shared state using Pydantic models
129
+ * **Interfaces** - Decorator-based access control for blackboard fields
130
+ * **Timebase** - Abstract time for simulation and testing
131
+
132
+ ### Composition
133
+
134
+ Combine DSLs to model complex systems:
135
+
136
+ * Embed behavior trees in Petri net transitions
137
+ * Run state machines within behavior tree actions
138
+ * Use Petri nets to orchestrate FSM-based components
139
+
140
+ ### Observability
141
+
142
+ The Spores module provides OCEL-compliant logging:
143
+
144
+ * Automatic event extraction from DSL execution
145
+ * Object lifecycle tracking
146
+ * Transport layer for custom backends
147
+
148
+ ## Examples
149
+
150
+ The repository contains comprehensive examples:
151
+
152
+ * `examples/hypha/` - Petri net patterns
153
+ * `examples/rhizomorph/` - Behavior tree patterns
154
+ * `examples/enoki/` - State machine patterns
155
+ * `examples/spores/` - Event logging integration
156
+ * `examples/interfaces/` - Type-safe blackboard access
157
+
158
+ Run examples with:
159
+
160
+ ```bash
161
+ uv run python examples/hypha/minimal_hypha_demo.py
162
+ ```
163
+
164
+ See [examples/README.md](examples/README.md) for a complete guide.
165
+
166
+ ## Documentation
167
+
168
+ Full API documentation is available at [docs link here].
169
+
170
+ ## Development
171
+
172
+ ```bash
173
+ # Install dependencies
174
+ uv pip install -e ".[dev]"
175
+
176
+ # Run tests
177
+ pytest
178
+
179
+ # Run with coverage
180
+ pytest --cov=src/mycorrhizal --cov-report=html
181
+ ```
182
+
183
+ ## Project Status
184
+
185
+ This is a 0.1.0 release. The core APIs are stable and well-tested, but some features are still in development:
186
+
187
+ * Current: Four DSLs with decorator-based syntax
188
+ * Current: Comprehensive examples and tests
189
+ * Planned: Cross-DSL interoperability layer
190
+ * Planned: Enhanced composition patterns
191
+
192
+ ## License
193
+
194
+ MIT
195
+
196
+ ## Author
197
+
198
+ Jeff Ciesielski
@@ -0,0 +1,188 @@
1
+ # Mycorrhizal
2
+
3
+ A Python library for building safe, structured, concurrent, event-driven systems.
4
+
5
+ ## Overview
6
+
7
+ Mycorrhizal provides four domain-specific languages (DSLs) for modeling and implementing different aspects of complex systems:
8
+
9
+ * **Hypha** - Colored Petri nets for workflow modeling and orchestration
10
+ * **Rhizomorph** - Behavior trees for decision-making and control logic
11
+ * **Enoki** - Finite state machines for stateful components
12
+ * **Spores** - Event and object logging for observability and process mining
13
+
14
+ Each DSL can be used independently or combined to build sophisticated systems. All modules share common infrastructure for state management (blackboards) and time abstraction, enabling seamless composition.
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ pip install mycorrhizal
20
+ ```
21
+
22
+ Requires Python 3.10 or later.
23
+
24
+ ## Quick Start
25
+
26
+ ### Behavior Tree (Rhizomorph)
27
+
28
+ Define behavior trees using a decorator-based DSL:
29
+
30
+ ```python
31
+ from mycorrhizal.rhizomorph.core import bt, Runner, Status
32
+
33
+ @bt.tree
34
+ def ThreatResponse():
35
+ @bt.action
36
+ async def assess_threat(bb) -> Status:
37
+ # Analyze threat level
38
+ return Status.SUCCESS if bb.threat_level > 5 else Status.FAILURE
39
+
40
+ @bt.action
41
+ async def engage_countermeasures(bb) -> Status:
42
+ # Respond to threat
43
+ return Status.SUCCESS
44
+
45
+ @bt.root
46
+ @bt.sequence
47
+ def root():
48
+ yield assess_threat
49
+ yield engage_countermeasures
50
+
51
+ # Run the behavior tree
52
+ runner = Runner(ThreatResponse, bb=blackboard)
53
+ await runner.tick_until_complete()
54
+ ```
55
+
56
+ ### Petri Net (Hypha)
57
+
58
+ Model workflows with colored Petri nets:
59
+
60
+ ```python
61
+ from mycorrhizal.hypha.core import pn, Runner, PlaceType
62
+
63
+ @pn.net
64
+ def ProcessingNet(builder):
65
+ # Define places
66
+ pending = builder.place("pending", type=PlaceType.QUEUE)
67
+ processed = builder.place("processed", type=PlaceType.QUEUE)
68
+
69
+ # Define transitions
70
+ @builder.transition()
71
+ async def process(consumed, bb, timebase):
72
+ for token in consumed:
73
+ result = await handle(token)
74
+ yield {processed: result}
75
+
76
+ # Wire the net
77
+ builder.arc(pending, process).arc(processed)
78
+
79
+ # Run the Petri net
80
+ runner = Runner(ProcessingNet, bb=blackboard)
81
+ await runner.start(timebase)
82
+ ```
83
+
84
+ ### Finite State Machine (Enoki)
85
+
86
+ Build stateful components with FSMs:
87
+
88
+ ```python
89
+ from mycorrhizal.enoki.core import enoki, StateMachine, LabeledTransition
90
+
91
+ @enoki.state()
92
+ def IdleState():
93
+ @enoki.on_state
94
+ async def on_state(ctx):
95
+ if ctx.msg == "start":
96
+ return Events.START
97
+ return None
98
+
99
+ @enoki.transitions
100
+ def transitions():
101
+ return [
102
+ LabeledTransition(Events.START, ProcessingState),
103
+ ]
104
+
105
+ # Create and run the FSM
106
+ fsm = StateMachine(initial_state=IdleState, common_data={})
107
+ await fsm.initialize()
108
+ fsm.send_message("start")
109
+ await fsm.tick()
110
+ ```
111
+
112
+ ## Key Features
113
+
114
+ ### Shared Infrastructure
115
+
116
+ All DSLs use common building blocks:
117
+
118
+ * **Blackboards** - Typed shared state using Pydantic models
119
+ * **Interfaces** - Decorator-based access control for blackboard fields
120
+ * **Timebase** - Abstract time for simulation and testing
121
+
122
+ ### Composition
123
+
124
+ Combine DSLs to model complex systems:
125
+
126
+ * Embed behavior trees in Petri net transitions
127
+ * Run state machines within behavior tree actions
128
+ * Use Petri nets to orchestrate FSM-based components
129
+
130
+ ### Observability
131
+
132
+ The Spores module provides OCEL-compliant logging:
133
+
134
+ * Automatic event extraction from DSL execution
135
+ * Object lifecycle tracking
136
+ * Transport layer for custom backends
137
+
138
+ ## Examples
139
+
140
+ The repository contains comprehensive examples:
141
+
142
+ * `examples/hypha/` - Petri net patterns
143
+ * `examples/rhizomorph/` - Behavior tree patterns
144
+ * `examples/enoki/` - State machine patterns
145
+ * `examples/spores/` - Event logging integration
146
+ * `examples/interfaces/` - Type-safe blackboard access
147
+
148
+ Run examples with:
149
+
150
+ ```bash
151
+ uv run python examples/hypha/minimal_hypha_demo.py
152
+ ```
153
+
154
+ See [examples/README.md](examples/README.md) for a complete guide.
155
+
156
+ ## Documentation
157
+
158
+ Full API documentation is available at [docs link here].
159
+
160
+ ## Development
161
+
162
+ ```bash
163
+ # Install dependencies
164
+ uv pip install -e ".[dev]"
165
+
166
+ # Run tests
167
+ pytest
168
+
169
+ # Run with coverage
170
+ pytest --cov=src/mycorrhizal --cov-report=html
171
+ ```
172
+
173
+ ## Project Status
174
+
175
+ This is a 0.1.0 release. The core APIs are stable and well-tested, but some features are still in development:
176
+
177
+ * Current: Four DSLs with decorator-based syntax
178
+ * Current: Comprehensive examples and tests
179
+ * Planned: Cross-DSL interoperability layer
180
+ * Planned: Enhanced composition patterns
181
+
182
+ ## License
183
+
184
+ MIT
185
+
186
+ ## Author
187
+
188
+ Jeff Ciesielski
@@ -0,0 +1,66 @@
1
+ [project]
2
+ name = "mycorrhizal"
3
+ version = "0.1.0"
4
+ description = "Utilities and DSLs for modelling and implementing safe, performant, structured systems"
5
+ readme = "README.md"
6
+ authors = [{ name = "Jeff Ciesielski", email = "jeffciesielski@gmail.com" }]
7
+ requires-python = ">=3.10"
8
+ dependencies = [
9
+ "typeguard==4.4.4",
10
+ "pydantic>=2.11.7",
11
+ ]
12
+
13
+
14
+ [tool.hatch.build]
15
+ exclude = ["examples/*", "tests/*"]
16
+
17
+ [build-system]
18
+ requires = ["hatchling"]
19
+ build-backend = "hatchling.build"
20
+
21
+ [dependency-groups]
22
+ dev = [
23
+ "pytest>=8.4.2",
24
+ "pytest-asyncio>=1.3.0",
25
+ "pytest-cov>=4.0.0",
26
+ "pytest-timeout>=2.0.0",
27
+ ]
28
+
29
+ [tool.pytest.ini_options]
30
+ asyncio_mode = "auto"
31
+ testpaths = ["tests"]
32
+ python_files = ["test_*.py"]
33
+ python_classes = ["Test*"]
34
+ python_functions = ["test_*"]
35
+ addopts = [
36
+ "-v",
37
+ "--tb=short",
38
+ "--strict-markers",
39
+ "--cov=src/mycorrhizal",
40
+ "--cov-report=term",
41
+ "--cov-report=html"
42
+ ]
43
+ markers = [
44
+ "slow: marks tests as slow",
45
+ "integration: marks tests as integration tests",
46
+ "performance: marks tests as performance tests",
47
+ "unit: marks tests as unit tests",
48
+ ]
49
+ timeout = 30
50
+
51
+ # Coverage configuration
52
+ [tool.coverage.run]
53
+ source = ["mycorrhizal"]
54
+ omit = ["tests/*", "setup.py"]
55
+
56
+ [tool.coverage.report]
57
+ exclude_lines = [
58
+ "pragma: no cover",
59
+ "def __repr__",
60
+ "raise AssertionError",
61
+ "raise NotImplementedError",
62
+ ]
63
+ show_missing = false
64
+ skip_covered = true
65
+ precision = 2
66
+ fail_under = 0
@@ -0,0 +1,68 @@
1
+ """
2
+ Common utilities and interfaces for Mycorrhizal.
3
+
4
+ This module provides shared components used across all three DSL systems:
5
+ - Hypha (Petri Nets)
6
+ - Rhizomorph (Behavior Trees)
7
+ - Enoki (State Machines)
8
+ """
9
+
10
+ # Import interfaces for easy access
11
+ from mycorrhizal.common.interfaces import (
12
+ Readable,
13
+ Writable,
14
+ FieldAccessor,
15
+ BlackboardProtocol,
16
+ FieldMetadata,
17
+ InterfaceMetadata,
18
+ validate_implements,
19
+ get_interface_fields,
20
+ create_interface_from_model,
21
+ )
22
+
23
+ # Import wrappers for easy access
24
+ from mycorrhizal.common.wrappers import (
25
+ AccessControlError,
26
+ ReadOnlyView,
27
+ WriteOnlyView,
28
+ ConstrainedView,
29
+ CompositeView,
30
+ create_readonly_view,
31
+ create_constrained_view,
32
+ create_view_from_protocol,
33
+ View,
34
+ )
35
+
36
+ # Import interface builder for easy access
37
+ from mycorrhizal.common.interface_builder import (
38
+ blackboard_interface,
39
+ FieldSpec,
40
+ )
41
+
42
+ __all__ = [
43
+ # Interfaces
44
+ "Readable",
45
+ "Writable",
46
+ "FieldAccessor",
47
+ "BlackboardProtocol",
48
+ "FieldMetadata",
49
+ "InterfaceMetadata",
50
+ "validate_implements",
51
+ "get_interface_fields",
52
+ "create_interface_from_model",
53
+
54
+ # Wrappers
55
+ "AccessControlError",
56
+ "ReadOnlyView",
57
+ "WriteOnlyView",
58
+ "ConstrainedView",
59
+ "CompositeView",
60
+ "create_readonly_view",
61
+ "create_constrained_view",
62
+ "create_view_from_protocol",
63
+ "View",
64
+
65
+ # Interface Builder
66
+ "blackboard_interface",
67
+ "FieldSpec",
68
+ ]