intersect-sdk 0.7.0__tar.gz → 0.8.1__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.
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/PKG-INFO +11 -3
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/README.md +4 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/pyproject.toml +56 -39
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/__init__.py +20 -18
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/control_plane/brokers/amqp_client.py +1 -1
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/control_plane/brokers/mqtt_client.py +1 -1
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/control_plane/control_plane_manager.py +1 -1
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/data_plane/data_plane_manager.py +1 -1
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/event_metadata.py +1 -1
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/interfaces.py +23 -7
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/messages/userspace.py +3 -3
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/schema.py +57 -39
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/app_lifecycle.py +1 -1
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/capability/base.py +48 -18
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/client.py +5 -50
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/client_callback_definitions.py +3 -19
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/config/shared.py +2 -1
- intersect_sdk-0.8.1/src/intersect_sdk/schema.py +70 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/service.py +240 -87
- intersect_sdk-0.8.1/src/intersect_sdk/service_callback_definitions.py +24 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/version.py +1 -1
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/tests/e2e/test_examples.py +14 -3
- intersect_sdk-0.8.1/tests/fixtures/example_schema.json +1067 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/tests/fixtures/example_schema.py +14 -12
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/tests/integration/test_return_type_mismatch.py +2 -2
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/tests/integration/test_service.py +0 -1
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/tests/unit/test_annotations.py +3 -2
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/tests/unit/test_base_capability_implementation.py +11 -2
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/tests/unit/test_config.py +2 -1
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/tests/unit/test_invalid_schema_runtime.py +4 -1
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/tests/unit/test_lifecycle_message.py +2 -1
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/tests/unit/test_schema_invalids.py +242 -58
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/tests/unit/test_schema_valid.py +8 -11
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/tests/unit/test_userspace_message.py +2 -1
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/tests/unit/test_version_resolver.py +1 -0
- intersect_sdk-0.7.0/src/intersect_sdk/schema.py +0 -78
- intersect_sdk-0.7.0/src/intersect_sdk/service_callback_definitions.py +0 -16
- intersect_sdk-0.7.0/tests/fixtures/example_schema.json +0 -1062
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/LICENSE +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/__init__.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/constants.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/control_plane/__init__.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/control_plane/brokers/__init__.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/control_plane/brokers/broker_client.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/control_plane/discovery_service.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/control_plane/topic_handler.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/data_plane/__init__.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/data_plane/minio_utils.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/exceptions.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/function_metadata.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/logger.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/messages/__init__.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/messages/event.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/messages/lifecycle.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/multi_flag_thread_event.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/pydantic_schema_generator.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/stoppable_thread.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/utils.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/version.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/version_resolver.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/capability/__init__.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/config/__init__.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/config/client.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/config/service.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/constants.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/core_definitions.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/py.typed +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/service_definitions.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/shared_callback_definitions.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/tests/__init__.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/tests/conftest.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/tests/e2e/__init__.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/tests/fixtures/__init__.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/tests/fixtures/return_type_mismatch.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/tests/integration/__init__.py +0 -0
- {intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/tests/unit/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: intersect-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.1
|
|
4
4
|
Summary: Python SDK to interact with INTERSECT
|
|
5
5
|
Keywords: intersect
|
|
6
6
|
Author-Email: Lance Drane <dranelt@ornl.gov>, Marshall McDonnell <mcdonnellmt@ornl.gov>, Seth Hitefield <hitefieldsd@ornl.gov>, Andrew Ayres <ayresaf@ornl.gov>, Gregory Cage <cagege@ornl.gov>, Jesse McGaha <mcgahajr@ornl.gov>, Robert Smith <smithrw@ornl.gov>, Gavin Wiggins <wigginsg@ornl.gov>, Michael Brim <brimmj@ornl.gov>, Rick Archibald <archibaldrk@ornl.gov>, Addi Malviya Thakur <malviyaa@ornl.gov>
|
|
@@ -10,6 +10,10 @@ Classifier: Programming Language :: Python :: 3.8
|
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.9
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.10
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Project-URL: Homepage, https://github.com/INTERSECT-SDK/python-sdk/
|
|
14
|
+
Project-URL: Changelog, https://github.com/INTERSECT-SDK/python-sdk/blob/main/CHANGELOG.md
|
|
15
|
+
Project-URL: Documentation, https://intersect-python-sdk.readthedocs.io/en/latest/
|
|
16
|
+
Project-URL: Issues, https://github.com/INTERSECT-SDK/python-sdk/issues
|
|
13
17
|
Requires-Python: <4.0,>=3.8.10
|
|
14
18
|
Requires-Dist: pydantic>=2.7.0
|
|
15
19
|
Requires-Dist: retrying<2.0.0,>=1.3.4
|
|
@@ -17,13 +21,15 @@ Requires-Dist: paho-mqtt<2.0.0,>=1.6.1
|
|
|
17
21
|
Requires-Dist: minio>=7.2.3
|
|
18
22
|
Requires-Dist: jsonschema[format-nongpl]>=4.21.1
|
|
19
23
|
Requires-Dist: eval-type-backport>=0.1.3; python_version < "3.10"
|
|
24
|
+
Provides-Extra: amqp
|
|
20
25
|
Requires-Dist: pika<2.0.0,>=1.3.2; extra == "amqp"
|
|
26
|
+
Provides-Extra: docs
|
|
21
27
|
Requires-Dist: sphinx>=5.3.0; extra == "docs"
|
|
22
28
|
Requires-Dist: furo>=2023.3.27; extra == "docs"
|
|
23
|
-
Provides-Extra: amqp
|
|
24
|
-
Provides-Extra: docs
|
|
25
29
|
Description-Content-Type: text/markdown
|
|
26
30
|
|
|
31
|
+
[](https://doi.org/10.11578/dc.20240927.1)
|
|
32
|
+
|
|
27
33
|
# INTERSECT-SDK
|
|
28
34
|
|
|
29
35
|
The INTERSECT-SDK is a framework for microservices to integrate themselves into the wider Interconnected Science Ecosystem (INTERSECT).
|
|
@@ -33,6 +39,8 @@ Please note that this README is currently a work in progress.
|
|
|
33
39
|
## What is INTERSECT?
|
|
34
40
|
[INTERSECT](https://www.ornl.gov/intersect) was designed as a specific usecase - as an open federated hardware/software architecture for the laboratory of the future, which connects scientific instruments, robot-controlled laboratories and edge/center computing/data resources to enable autonomous experiments, self-driving laboratories, smart manufacturing, and AI-driven design, discovery and evaluation.
|
|
35
41
|
|
|
42
|
+
For a high-level overview, please see [the architecture website.](https://intersect-architecture.readthedocs.io/en/latest/)
|
|
43
|
+
|
|
36
44
|
## What are the core design philosophies of the SDK?
|
|
37
45
|
|
|
38
46
|
- Event-driven architecture
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
[](https://doi.org/10.11578/dc.20240927.1)
|
|
2
|
+
|
|
1
3
|
# INTERSECT-SDK
|
|
2
4
|
|
|
3
5
|
The INTERSECT-SDK is a framework for microservices to integrate themselves into the wider Interconnected Science Ecosystem (INTERSECT).
|
|
@@ -7,6 +9,8 @@ Please note that this README is currently a work in progress.
|
|
|
7
9
|
## What is INTERSECT?
|
|
8
10
|
[INTERSECT](https://www.ornl.gov/intersect) was designed as a specific usecase - as an open federated hardware/software architecture for the laboratory of the future, which connects scientific instruments, robot-controlled laboratories and edge/center computing/data resources to enable autonomous experiments, self-driving laboratories, smart manufacturing, and AI-driven design, discovery and evaluation.
|
|
9
11
|
|
|
12
|
+
For a high-level overview, please see [the architecture website.](https://intersect-architecture.readthedocs.io/en/latest/)
|
|
13
|
+
|
|
10
14
|
## What are the core design philosophies of the SDK?
|
|
11
15
|
|
|
12
16
|
- Event-driven architecture
|
|
@@ -35,11 +35,17 @@ dependencies = [
|
|
|
35
35
|
"jsonschema[format-nongpl]>=4.21.1",
|
|
36
36
|
"eval-type-backport>=0.1.3;python_version<'3.10'",
|
|
37
37
|
]
|
|
38
|
-
version = "0.
|
|
38
|
+
version = "0.8.1"
|
|
39
39
|
|
|
40
40
|
[project.license]
|
|
41
41
|
text = "BSD-3-Clause"
|
|
42
42
|
|
|
43
|
+
[project.urls]
|
|
44
|
+
Homepage = "https://github.com/INTERSECT-SDK/python-sdk/"
|
|
45
|
+
Changelog = "https://github.com/INTERSECT-SDK/python-sdk/blob/main/CHANGELOG.md"
|
|
46
|
+
Documentation = "https://intersect-python-sdk.readthedocs.io/en/latest/"
|
|
47
|
+
Issues = "https://github.com/INTERSECT-SDK/python-sdk/issues"
|
|
48
|
+
|
|
43
49
|
[project.optional-dependencies]
|
|
44
50
|
amqp = [
|
|
45
51
|
"pika>=1.3.2,<2.0.0",
|
|
@@ -49,42 +55,6 @@ docs = [
|
|
|
49
55
|
"furo>=2023.3.27",
|
|
50
56
|
]
|
|
51
57
|
|
|
52
|
-
[tool.pdm.dev-dependencies]
|
|
53
|
-
lint = [
|
|
54
|
-
"pre-commit>=3.3.1",
|
|
55
|
-
"ruff>=0.4.2",
|
|
56
|
-
"mypy>=1.10.0",
|
|
57
|
-
"types-paho-mqtt>=1.6.0.20240106",
|
|
58
|
-
]
|
|
59
|
-
test = [
|
|
60
|
-
"pytest>=7.3.2",
|
|
61
|
-
"pytest-cov>=4.1.0",
|
|
62
|
-
"httpretty>=1.1.4",
|
|
63
|
-
]
|
|
64
|
-
|
|
65
|
-
[tool.pdm.scripts]
|
|
66
|
-
test-all = "pytest tests/ --cov=src/intersect_sdk/ --cov-fail-under=80 --cov-report=html:reports/htmlcov/ --cov-report=xml:reports/coverage_report.xml --junitxml=reports/junit.xml"
|
|
67
|
-
test-all-debug = "pytest tests/ --cov=src/intersect_sdk/ --cov-fail-under=80 --cov-report=html:reports/htmlcov/ --cov-report=xml:reports/coverage_report.xml --junitxml=reports/junit.xml -s"
|
|
68
|
-
test-unit = "pytest tests/unit --cov=src/intersect_sdk/"
|
|
69
|
-
test-e2e = "pytest tests/e2e --cov=src/intersect_sdk/"
|
|
70
|
-
lint-format = "ruff format"
|
|
71
|
-
lint-ruff = "ruff check --fix"
|
|
72
|
-
lint-mypy = "mypy src/intersect_sdk/"
|
|
73
|
-
|
|
74
|
-
[tool.pdm.scripts.lint]
|
|
75
|
-
composite = [
|
|
76
|
-
"lint-format",
|
|
77
|
-
"lint-ruff",
|
|
78
|
-
"lint-mypy",
|
|
79
|
-
]
|
|
80
|
-
|
|
81
|
-
[tool.pdm.build]
|
|
82
|
-
package-dir = "src"
|
|
83
|
-
|
|
84
|
-
[tool.pdm.version]
|
|
85
|
-
source = "file"
|
|
86
|
-
path = "src/intersect_sdk/version.py"
|
|
87
|
-
|
|
88
58
|
[tool.ruff]
|
|
89
59
|
line-length = 100
|
|
90
60
|
|
|
@@ -138,8 +108,6 @@ ignore = [
|
|
|
138
108
|
"COM812",
|
|
139
109
|
"ISC001",
|
|
140
110
|
"SIM105",
|
|
141
|
-
"ANN101",
|
|
142
|
-
"ANN102",
|
|
143
111
|
"ANN401",
|
|
144
112
|
"PLR2004",
|
|
145
113
|
]
|
|
@@ -214,13 +182,62 @@ addopts = "-ra"
|
|
|
214
182
|
[tool.coverage.report]
|
|
215
183
|
omit = [
|
|
216
184
|
"*__init__*",
|
|
185
|
+
"*/discovery_service.py",
|
|
217
186
|
]
|
|
218
187
|
exclude_also = [
|
|
219
188
|
"pragma: no-cover",
|
|
220
189
|
"if (typing\\\\.)?TYPE_CHECKING:",
|
|
221
190
|
"@(abc\\\\.)?abstractmethod",
|
|
191
|
+
"class .*\\bProtocol\\):",
|
|
192
|
+
"raise NotImplementedError",
|
|
193
|
+
"except.* ImportError",
|
|
222
194
|
]
|
|
223
195
|
|
|
196
|
+
[tool.pdm.dev-dependencies]
|
|
197
|
+
lint = [
|
|
198
|
+
"pre-commit>=3.3.1",
|
|
199
|
+
"ruff==0.9.4",
|
|
200
|
+
"mypy>=1.10.0",
|
|
201
|
+
"types-paho-mqtt>=1.6.0.20240106",
|
|
202
|
+
"codespell>=2.3.0",
|
|
203
|
+
]
|
|
204
|
+
test = [
|
|
205
|
+
"pytest>=7.3.2",
|
|
206
|
+
"pytest-cov>=4.1.0",
|
|
207
|
+
"httpretty>=1.1.4",
|
|
208
|
+
]
|
|
209
|
+
|
|
210
|
+
[tool.pdm.scripts]
|
|
211
|
+
test-all = "pytest tests/ --cov=src/intersect_sdk/ --cov-fail-under=80 --cov-report=html:reports/htmlcov/ --cov-report=xml:reports/coverage_report.xml --junitxml=reports/junit.xml"
|
|
212
|
+
test-all-debug = "pytest tests/ --cov=src/intersect_sdk/ --cov-fail-under=80 --cov-report=html:reports/htmlcov/ --cov-report=xml:reports/coverage_report.xml --junitxml=reports/junit.xml -s"
|
|
213
|
+
test-unit = "pytest tests/unit --cov=src/intersect_sdk/"
|
|
214
|
+
test-e2e = "pytest tests/e2e --cov=src/intersect_sdk/"
|
|
215
|
+
lint-docs = "sphinx-build -W --keep-going docs docs/_build"
|
|
216
|
+
lint-format = "ruff format"
|
|
217
|
+
lint-ruff = "ruff check --fix"
|
|
218
|
+
lint-mypy = "mypy src/intersect_sdk/"
|
|
219
|
+
lint-spelling = "codespell -w docs examples src tests *.md -S docs/_build"
|
|
220
|
+
|
|
221
|
+
[tool.pdm.scripts.lint]
|
|
222
|
+
composite = [
|
|
223
|
+
"lint-format",
|
|
224
|
+
"lint-ruff",
|
|
225
|
+
"lint-mypy",
|
|
226
|
+
"lint-spelling",
|
|
227
|
+
"lint-docs",
|
|
228
|
+
]
|
|
229
|
+
|
|
230
|
+
[tool.pdm.build]
|
|
231
|
+
package-dir = "src"
|
|
232
|
+
|
|
233
|
+
[tool.pdm.version]
|
|
234
|
+
source = "file"
|
|
235
|
+
path = "src/intersect_sdk/version.py"
|
|
236
|
+
|
|
237
|
+
[tool.codespell]
|
|
238
|
+
skip = ".git*,*.lock,.venv,.*cache/*,./docs/_build/*"
|
|
239
|
+
check-hidden = true
|
|
240
|
+
|
|
224
241
|
[build-system]
|
|
225
242
|
requires = [
|
|
226
243
|
"pdm-backend",
|
|
@@ -19,12 +19,13 @@ from .config.client import IntersectClientConfig
|
|
|
19
19
|
from .config.service import IntersectServiceConfig
|
|
20
20
|
from .config.shared import (
|
|
21
21
|
ControlPlaneConfig,
|
|
22
|
+
ControlProvider,
|
|
22
23
|
DataStoreConfig,
|
|
23
24
|
DataStoreConfigMap,
|
|
24
25
|
HierarchyConfig,
|
|
25
26
|
)
|
|
26
27
|
from .core_definitions import IntersectDataHandler, IntersectMimeType
|
|
27
|
-
from .schema import
|
|
28
|
+
from .schema import get_schema_from_capability_implementations
|
|
28
29
|
from .service import IntersectService
|
|
29
30
|
from .service_callback_definitions import (
|
|
30
31
|
INTERSECT_SERVICE_RESPONSE_CALLBACK_TYPE,
|
|
@@ -42,30 +43,31 @@ from .shared_callback_definitions import (
|
|
|
42
43
|
from .version import __version__, version_info, version_string
|
|
43
44
|
|
|
44
45
|
__all__ = [
|
|
45
|
-
'IntersectDataHandler',
|
|
46
|
-
'IntersectEventDefinition',
|
|
47
|
-
'IntersectMimeType',
|
|
48
|
-
'intersect_event',
|
|
49
|
-
'intersect_message',
|
|
50
|
-
'intersect_status',
|
|
51
|
-
'get_schema_from_capability_implementation',
|
|
52
|
-
'IntersectService',
|
|
53
|
-
'IntersectClient',
|
|
54
|
-
'IntersectClientCallback',
|
|
55
|
-
'IntersectDirectMessageParams',
|
|
56
|
-
'INTERSECT_CLIENT_RESPONSE_CALLBACK_TYPE',
|
|
57
46
|
'INTERSECT_CLIENT_EVENT_CALLBACK_TYPE',
|
|
47
|
+
'INTERSECT_CLIENT_RESPONSE_CALLBACK_TYPE',
|
|
58
48
|
'INTERSECT_JSON_VALUE',
|
|
59
49
|
'INTERSECT_SERVICE_RESPONSE_CALLBACK_TYPE',
|
|
60
|
-
'IntersectBaseCapabilityImplementation',
|
|
61
|
-
'default_intersect_lifecycle_loop',
|
|
62
|
-
'IntersectClientConfig',
|
|
63
|
-
'IntersectServiceConfig',
|
|
64
|
-
'HierarchyConfig',
|
|
65
50
|
'ControlPlaneConfig',
|
|
51
|
+
'ControlProvider',
|
|
66
52
|
'DataStoreConfig',
|
|
67
53
|
'DataStoreConfigMap',
|
|
54
|
+
'HierarchyConfig',
|
|
55
|
+
'IntersectBaseCapabilityImplementation',
|
|
56
|
+
'IntersectClient',
|
|
57
|
+
'IntersectClientCallback',
|
|
58
|
+
'IntersectClientConfig',
|
|
59
|
+
'IntersectDataHandler',
|
|
60
|
+
'IntersectDirectMessageParams',
|
|
61
|
+
'IntersectEventDefinition',
|
|
62
|
+
'IntersectMimeType',
|
|
63
|
+
'IntersectService',
|
|
64
|
+
'IntersectServiceConfig',
|
|
68
65
|
'__version__',
|
|
66
|
+
'default_intersect_lifecycle_loop',
|
|
67
|
+
'get_schema_from_capability_implementations',
|
|
68
|
+
'intersect_event',
|
|
69
|
+
'intersect_message',
|
|
70
|
+
'intersect_status',
|
|
69
71
|
'version_info',
|
|
70
72
|
'version_string',
|
|
71
73
|
]
|
|
@@ -254,7 +254,7 @@ class AMQPClient(BrokerClient):
|
|
|
254
254
|
if self._should_disconnect:
|
|
255
255
|
connection.ioloop.stop()
|
|
256
256
|
else:
|
|
257
|
-
logger.
|
|
257
|
+
logger.warning('Connection closed, reopening in 5 seconds: %s', reason)
|
|
258
258
|
connection.ioloop.call_later(5, connection.ioloop.stop)
|
|
259
259
|
self._channel_flags.unset_all()
|
|
260
260
|
self._channel_out = None
|
|
@@ -113,7 +113,7 @@ class MQTTClient(BrokerClient):
|
|
|
113
113
|
topic: The topic on which to publish the message as a string.
|
|
114
114
|
payload: The message to publish, as raw bytes.
|
|
115
115
|
persist: Determine if the message should live until queue consumers or available (True), or
|
|
116
|
-
if it should be removed
|
|
116
|
+
if it should be removed immediately (False)
|
|
117
117
|
"""
|
|
118
118
|
# NOTE: RabbitMQ only works with QOS of 1 and 0, and seems to convert QOS2 to QOS1
|
|
119
119
|
self._connection.publish(topic, payload, qos=2 if persist else 0)
|
|
@@ -66,7 +66,7 @@ class ControlPlaneManager:
|
|
|
66
66
|
"""
|
|
67
67
|
if control_configs == 'discovery':
|
|
68
68
|
msg = 'Discovery service not implemented yet'
|
|
69
|
-
raise
|
|
69
|
+
raise NotImplementedError(msg)
|
|
70
70
|
self._control_providers = [
|
|
71
71
|
create_control_provider(config, self.get_subscription_channels)
|
|
72
72
|
for config in control_configs
|
|
@@ -32,7 +32,7 @@ class DataPlaneManager:
|
|
|
32
32
|
|
|
33
33
|
# warn users about missing data plane
|
|
34
34
|
if not self._minio_providers:
|
|
35
|
-
logger.
|
|
35
|
+
logger.warning('WARNING: This service cannot support any MINIO instances')
|
|
36
36
|
|
|
37
37
|
def incoming_message_data_handler(self, message: UserspaceMessage | EventMessage) -> bytes:
|
|
38
38
|
"""Get data from the request data provider.
|
|
@@ -42,7 +42,7 @@ def definition_metadata_differences(
|
|
|
42
42
|
) -> list[tuple[str, str, str]]:
|
|
43
43
|
"""Return a list of differences between 'definition' and 'metadata'.
|
|
44
44
|
|
|
45
|
-
First tuple value =
|
|
45
|
+
First tuple value = definition key
|
|
46
46
|
Second tuple value = second value
|
|
47
47
|
Third tuple value = already cached value
|
|
48
48
|
"""
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from
|
|
4
|
-
from typing import TYPE_CHECKING, Any
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Protocol
|
|
5
4
|
|
|
6
5
|
if TYPE_CHECKING:
|
|
7
6
|
from uuid import UUID
|
|
8
7
|
|
|
8
|
+
from ..client_callback_definitions import INTERSECT_CLIENT_EVENT_CALLBACK_TYPE
|
|
9
|
+
from ..config.shared import HierarchyConfig
|
|
9
10
|
from ..service_callback_definitions import (
|
|
10
11
|
INTERSECT_SERVICE_RESPONSE_CALLBACK_TYPE,
|
|
11
12
|
)
|
|
@@ -14,13 +15,12 @@ if TYPE_CHECKING:
|
|
|
14
15
|
)
|
|
15
16
|
|
|
16
17
|
|
|
17
|
-
class IntersectEventObserver(
|
|
18
|
+
class IntersectEventObserver(Protocol):
|
|
18
19
|
"""Abstract definition of an entity which observes an INTERSECT event (i.e. IntersectService).
|
|
19
20
|
|
|
20
21
|
Used as the common interface for event emitters (i.e. CapabilityImplementations).
|
|
21
22
|
"""
|
|
22
23
|
|
|
23
|
-
@abstractmethod
|
|
24
24
|
def _on_observe_event(self, event_name: str, event_value: Any, operation: str) -> None:
|
|
25
25
|
"""How to react to an event being fired.
|
|
26
26
|
|
|
@@ -31,19 +31,35 @@ class IntersectEventObserver(ABC):
|
|
|
31
31
|
"""
|
|
32
32
|
...
|
|
33
33
|
|
|
34
|
-
@abstractmethod
|
|
35
34
|
def create_external_request(
|
|
36
35
|
self,
|
|
37
36
|
request: IntersectDirectMessageParams,
|
|
38
37
|
response_handler: INTERSECT_SERVICE_RESPONSE_CALLBACK_TYPE | None = None,
|
|
38
|
+
timeout: float = 300.0,
|
|
39
39
|
) -> UUID:
|
|
40
|
-
"""Observed entity (
|
|
40
|
+
"""Observed entity (capability) tells observer (i.e. service) to send an external request.
|
|
41
41
|
|
|
42
42
|
Params:
|
|
43
|
-
- request: the request we want to send out, encapsulated as an
|
|
43
|
+
- request: the request we want to send out, encapsulated as an IntersectDirectMessageParams object
|
|
44
44
|
- response_handler: optional callback for how we want to handle the response from this request.
|
|
45
|
+
- timeout: optional value for how long we should wait on the request, in seconds (default: 300 seconds)
|
|
45
46
|
|
|
46
47
|
Returns:
|
|
47
48
|
- generated RequestID associated with your request
|
|
48
49
|
"""
|
|
49
50
|
...
|
|
51
|
+
|
|
52
|
+
def register_event(
|
|
53
|
+
self,
|
|
54
|
+
service: HierarchyConfig,
|
|
55
|
+
event_name: str,
|
|
56
|
+
response_handler: INTERSECT_CLIENT_EVENT_CALLBACK_TYPE,
|
|
57
|
+
) -> None:
|
|
58
|
+
"""Observed entity (capability) tells observer (i.e. service) to subscribe to a specific event.
|
|
59
|
+
|
|
60
|
+
Params:
|
|
61
|
+
- service: HierarchyConfig of the service we want to talk to
|
|
62
|
+
- event_name: name of event to subscribe to
|
|
63
|
+
- response_handler: callback for how to handle the reception of an event
|
|
64
|
+
"""
|
|
65
|
+
...
|
{intersect_sdk-0.7.0 → intersect_sdk-0.8.1}/src/intersect_sdk/_internal/messages/userspace.py
RENAMED
|
@@ -25,13 +25,13 @@ from typing import Any, Union
|
|
|
25
25
|
from pydantic import AwareDatetime, Field, TypeAdapter
|
|
26
26
|
from typing_extensions import Annotated, TypedDict
|
|
27
27
|
|
|
28
|
-
from ...constants import SYSTEM_OF_SYSTEM_REGEX
|
|
29
|
-
from ...core_definitions import (
|
|
28
|
+
from ...constants import SYSTEM_OF_SYSTEM_REGEX
|
|
29
|
+
from ...core_definitions import (
|
|
30
30
|
IntersectDataHandler,
|
|
31
31
|
IntersectMimeType,
|
|
32
32
|
)
|
|
33
33
|
from ...version import version_string
|
|
34
|
-
from ..data_plane.minio_utils import MinioPayload # noqa:
|
|
34
|
+
from ..data_plane.minio_utils import MinioPayload # noqa: TC001 (this is runtime checked)
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
class UserspaceMessageHeader(TypedDict):
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import inspect
|
|
6
|
+
import re
|
|
6
7
|
from enum import Enum
|
|
7
8
|
from typing import (
|
|
8
9
|
TYPE_CHECKING,
|
|
@@ -55,6 +56,9 @@ For networking types, https://docs.pydantic.dev/latest/api/networks/
|
|
|
55
56
|
For a complete reference, https://docs.pydantic.dev/latest/concepts/conversion_table
|
|
56
57
|
"""
|
|
57
58
|
|
|
59
|
+
CAPABILITY_NAME_PATTERN = r'[\w-]+'
|
|
60
|
+
"""Regular expression we use to check valid capability names. Since capability namespacing only occurs in services, we can be more lax than for how we name services/systems/etc. """
|
|
61
|
+
|
|
58
62
|
|
|
59
63
|
class _FunctionAnalysisResult(NamedTuple):
|
|
60
64
|
"""private class generated from static analysis of function."""
|
|
@@ -302,7 +306,7 @@ def _add_events(
|
|
|
302
306
|
|
|
303
307
|
|
|
304
308
|
def _introspection_baseline(
|
|
305
|
-
capability: IntersectBaseCapabilityImplementation,
|
|
309
|
+
capability: type[IntersectBaseCapabilityImplementation],
|
|
306
310
|
excluded_data_handlers: set[IntersectDataHandler],
|
|
307
311
|
) -> tuple[
|
|
308
312
|
dict[Any, Any], # $defs for schemas (common)
|
|
@@ -332,8 +336,9 @@ def _introspection_baseline(
|
|
|
332
336
|
function_map = {}
|
|
333
337
|
event_metadatas: dict[str, EventMetadata] = {}
|
|
334
338
|
|
|
335
|
-
|
|
336
|
-
|
|
339
|
+
# capability_name should have already been checked before calling this function
|
|
340
|
+
cap_name = capability.intersect_sdk_capability_name
|
|
341
|
+
status_func, response_funcs, event_funcs = _get_functions(capability)
|
|
337
342
|
|
|
338
343
|
# parse functions
|
|
339
344
|
for class_name, name, method, min_params in response_funcs:
|
|
@@ -439,7 +444,7 @@ def _introspection_baseline(
|
|
|
439
444
|
|
|
440
445
|
# final function mapping
|
|
441
446
|
function_map[public_name] = FunctionMetadata(
|
|
442
|
-
|
|
447
|
+
capability,
|
|
443
448
|
method,
|
|
444
449
|
function_cache_request_adapter,
|
|
445
450
|
function_cache_response_adapter,
|
|
@@ -477,7 +482,7 @@ def _introspection_baseline(
|
|
|
477
482
|
if status_fn_type_adapter and status_fn and status_fn_name:
|
|
478
483
|
public_status_name = f'{cap_name}.{status_fn_name}'
|
|
479
484
|
function_map[public_status_name] = FunctionMetadata(
|
|
480
|
-
|
|
485
|
+
capability,
|
|
481
486
|
status_fn,
|
|
482
487
|
None,
|
|
483
488
|
status_fn_type_adapter,
|
|
@@ -494,52 +499,78 @@ def _introspection_baseline(
|
|
|
494
499
|
|
|
495
500
|
|
|
496
501
|
def get_schema_and_functions_from_capability_implementations(
|
|
497
|
-
capabilities: list[IntersectBaseCapabilityImplementation],
|
|
502
|
+
capabilities: list[type[IntersectBaseCapabilityImplementation]],
|
|
498
503
|
service_name: HierarchyConfig,
|
|
499
504
|
excluded_data_handlers: set[IntersectDataHandler],
|
|
500
505
|
) -> tuple[
|
|
501
506
|
dict[str, Any],
|
|
502
507
|
dict[str, FunctionMetadata],
|
|
503
508
|
dict[str, EventMetadata],
|
|
504
|
-
IntersectBaseCapabilityImplementation | None,
|
|
509
|
+
type[IntersectBaseCapabilityImplementation] | None,
|
|
505
510
|
str | None,
|
|
506
511
|
TypeAdapter[Any] | None,
|
|
507
512
|
]:
|
|
508
513
|
"""This function generates the core AsyncAPI schema, and the core mappings which are derived from the schema.
|
|
509
514
|
|
|
515
|
+
Importantly, this function needs to be able to work with static classes, and not instances. This is because users
|
|
516
|
+
should be free to define their constructor as they wish, with any arbitrary parameters. Users should also be allowed
|
|
517
|
+
to execute whatever code they'd like in their constructor, such as establishing remote connections. At the same time,
|
|
518
|
+
we want to allow users to quickly generate an INTERSECT schema, without having to worry about any dependencies from their constructor code.
|
|
519
|
+
|
|
510
520
|
In-depth introspection is handled later on.
|
|
511
521
|
"""
|
|
512
|
-
|
|
513
|
-
status_function_cap: IntersectBaseCapabilityImplementation | None = None
|
|
522
|
+
status_function_cap: type[IntersectBaseCapabilityImplementation] | None = None
|
|
514
523
|
status_function_name: str | None = None
|
|
515
524
|
status_function_schema: dict[str, Any] | None = None
|
|
516
525
|
status_function_adapter: TypeAdapter[Any] | None = None
|
|
517
|
-
|
|
518
|
-
|
|
526
|
+
shared_schemas: dict[Any, Any] = {} # "shared" schemas which get put in $defs
|
|
527
|
+
capability_schemas: dict[str, Any] = {} # endpoint schemas
|
|
519
528
|
function_map: dict[str, FunctionMetadata] = {} # endpoint functionality
|
|
520
|
-
events: dict[
|
|
529
|
+
events: dict[
|
|
530
|
+
str, Any
|
|
531
|
+
] = {} # event schemas - TODO event names are currently "global" across capabilities, may want to change this?
|
|
521
532
|
event_map: dict[str, EventMetadata] = {} # event functionality
|
|
522
|
-
for
|
|
523
|
-
|
|
524
|
-
if
|
|
525
|
-
|
|
533
|
+
for capability_type in capabilities:
|
|
534
|
+
cap_name = capability_type.intersect_sdk_capability_name
|
|
535
|
+
if (
|
|
536
|
+
not cap_name
|
|
537
|
+
or not isinstance(cap_name, str)
|
|
538
|
+
or not re.fullmatch(CAPABILITY_NAME_PATTERN, cap_name)
|
|
539
|
+
):
|
|
540
|
+
die(
|
|
541
|
+
f'Invalid intersect_sdk_capability_name on capability {capability_type.__name__} - must be a non-empty string with only alphanumeric characters and hyphens (you must explicitly set this, and do so on the class and not an instance).'
|
|
542
|
+
)
|
|
543
|
+
if cap_name in capability_schemas:
|
|
544
|
+
die(
|
|
545
|
+
f'Invalid intersect_sdk_capability_name on capability {capability_type.__name__} - value "{cap_name}" is a duplicate and has already appeared in another capability.'
|
|
546
|
+
)
|
|
547
|
+
|
|
526
548
|
(
|
|
527
|
-
|
|
549
|
+
subschemas,
|
|
528
550
|
(cap_status_fn_name, cap_status_schema, cap_status_type_adapter),
|
|
529
|
-
|
|
551
|
+
cap_functions,
|
|
530
552
|
cap_function_map,
|
|
531
553
|
cap_events,
|
|
532
554
|
cap_event_map,
|
|
533
|
-
) = _introspection_baseline(
|
|
555
|
+
) = _introspection_baseline(capability_type, excluded_data_handlers)
|
|
534
556
|
|
|
535
557
|
if cap_status_fn_name and cap_status_schema and cap_status_type_adapter:
|
|
536
|
-
|
|
558
|
+
if status_function_name is not None:
|
|
559
|
+
# TODO may want to change this later
|
|
560
|
+
die('Only one capability may have an @intersect_status function')
|
|
561
|
+
status_function_cap = capability_type
|
|
537
562
|
status_function_name = cap_status_fn_name
|
|
538
563
|
status_function_schema = cap_status_schema
|
|
539
564
|
status_function_adapter = cap_status_type_adapter
|
|
540
565
|
|
|
541
|
-
|
|
542
|
-
|
|
566
|
+
shared_schemas.update(subschemas)
|
|
567
|
+
# NOTE: we will still add the capability to the schema, even if there are no @intersect_message annotations
|
|
568
|
+
capability_schemas[cap_name] = {
|
|
569
|
+
'channels': cap_functions,
|
|
570
|
+
}
|
|
571
|
+
# add documentation for the capabilities
|
|
572
|
+
if capability_type.__doc__:
|
|
573
|
+
capability_schemas[cap_name]['description'] = inspect.cleandoc(capability_type.__doc__)
|
|
543
574
|
function_map.update(cap_function_map)
|
|
544
575
|
events.update(cap_events)
|
|
545
576
|
event_map.update(cap_event_map)
|
|
@@ -549,15 +580,17 @@ def get_schema_and_functions_from_capability_implementations(
|
|
|
549
580
|
'x-intersect-version': version_string,
|
|
550
581
|
'info': {
|
|
551
582
|
'title': service_name.hierarchy_string('.'),
|
|
583
|
+
'description': 'INTERSECT schema',
|
|
552
584
|
'version': '0.0.0', # NOTE: this will be modified by INTERSECT CORE, users do not manage their schema versions
|
|
553
585
|
},
|
|
554
586
|
# applies to how an incoming message payload will be parsed.
|
|
555
587
|
# can be changed per channel
|
|
556
588
|
'defaultContentType': 'application/json',
|
|
557
|
-
'
|
|
589
|
+
'capabilities': capability_schemas,
|
|
558
590
|
'events': events,
|
|
591
|
+
'status': status_function_schema if status_function_schema else {'type': 'null'},
|
|
559
592
|
'components': {
|
|
560
|
-
'schemas':
|
|
593
|
+
'schemas': shared_schemas,
|
|
561
594
|
'messageTraits': {
|
|
562
595
|
# this is where we can define our message headers
|
|
563
596
|
'commonHeaders': {
|
|
@@ -574,21 +607,6 @@ def get_schema_and_functions_from_capability_implementations(
|
|
|
574
607
|
},
|
|
575
608
|
}
|
|
576
609
|
|
|
577
|
-
if capability_type_docs != '':
|
|
578
|
-
asyncapi_spec['info']['description'] = capability_type_docs # type: ignore[index]
|
|
579
|
-
|
|
580
|
-
if status_function_schema:
|
|
581
|
-
asyncapi_spec['status'] = status_function_schema
|
|
582
|
-
|
|
583
|
-
"""
|
|
584
|
-
TODO - might want to include these fields
|
|
585
|
-
"securitySchemes": {},
|
|
586
|
-
"operationTraits": {},
|
|
587
|
-
"externalDocumentation": {
|
|
588
|
-
"url": "https://example.com", # REQUIRED
|
|
589
|
-
},
|
|
590
|
-
"""
|
|
591
|
-
|
|
592
610
|
return (
|
|
593
611
|
asyncapi_spec,
|
|
594
612
|
function_map,
|
|
@@ -82,7 +82,7 @@ class SignalHandler:
|
|
|
82
82
|
----------
|
|
83
83
|
signal (int): signal code.
|
|
84
84
|
"""
|
|
85
|
-
logger.warning('shutting down and handling signal %
|
|
85
|
+
logger.warning('shutting down and handling signal %s', signal)
|
|
86
86
|
if self._cleanup_callback:
|
|
87
87
|
self._cleanup_callback(signal)
|
|
88
88
|
self._exit.set()
|