intersect-sdk 0.9.0__tar.gz → 0.9.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.9.0 → intersect_sdk-0.9.1}/PKG-INFO +11 -13
- intersect_sdk-0.9.1/pyproject.toml +198 -0
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/__init__.py +74 -42
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/interfaces.py +2 -1
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/schema.py +11 -8
- intersect_sdk-0.9.1/src/intersect_sdk/_internal/service_queue_name.py +14 -0
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/capability/universal_capability/status.py +0 -2
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/client.py +21 -23
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/config/client.py +3 -3
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/config/service.py +7 -4
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/exceptions.py +2 -2
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/schema.py +1 -1
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/service.py +92 -40
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/service_definitions.py +1 -1
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/shared_callback_definitions.py +5 -3
- intersect_sdk-0.9.1/src/intersect_sdk/version.py +9 -0
- intersect_sdk-0.9.0/LICENSE +0 -29
- intersect_sdk-0.9.0/pyproject.toml +0 -253
- intersect_sdk-0.9.0/src/intersect_sdk/_internal/control_plane/__init__.py +0 -0
- intersect_sdk-0.9.0/src/intersect_sdk/_internal/control_plane/brokers/__init__.py +0 -0
- intersect_sdk-0.9.0/src/intersect_sdk/_internal/control_plane/brokers/amqp_client.py +0 -627
- intersect_sdk-0.9.0/src/intersect_sdk/_internal/control_plane/brokers/broker_client.py +0 -76
- intersect_sdk-0.9.0/src/intersect_sdk/_internal/control_plane/brokers/mqtt_client.py +0 -288
- intersect_sdk-0.9.0/src/intersect_sdk/_internal/control_plane/control_plane_manager.py +0 -182
- intersect_sdk-0.9.0/src/intersect_sdk/_internal/control_plane/definitions.py +0 -10
- intersect_sdk-0.9.0/src/intersect_sdk/_internal/control_plane/topic_handler.py +0 -17
- intersect_sdk-0.9.0/src/intersect_sdk/_internal/data_plane/__init__.py +0 -0
- intersect_sdk-0.9.0/src/intersect_sdk/_internal/data_plane/data_plane_manager.py +0 -113
- intersect_sdk-0.9.0/src/intersect_sdk/_internal/data_plane/minio_utils.py +0 -154
- intersect_sdk-0.9.0/src/intersect_sdk/_internal/exceptions.py +0 -17
- intersect_sdk-0.9.0/src/intersect_sdk/_internal/messages/__init__.py +0 -0
- intersect_sdk-0.9.0/src/intersect_sdk/_internal/messages/event.py +0 -145
- intersect_sdk-0.9.0/src/intersect_sdk/_internal/messages/lifecycle.py +0 -107
- intersect_sdk-0.9.0/src/intersect_sdk/_internal/messages/userspace.py +0 -183
- intersect_sdk-0.9.0/src/intersect_sdk/_internal/multi_flag_thread_event.py +0 -77
- intersect_sdk-0.9.0/src/intersect_sdk/_internal/version.py +0 -18
- intersect_sdk-0.9.0/src/intersect_sdk/_internal/version_resolver.py +0 -59
- intersect_sdk-0.9.0/src/intersect_sdk/config/shared.py +0 -168
- intersect_sdk-0.9.0/src/intersect_sdk/constants.py +0 -28
- intersect_sdk-0.9.0/src/intersect_sdk/core_definitions.py +0 -47
- intersect_sdk-0.9.0/src/intersect_sdk/version.py +0 -19
- intersect_sdk-0.9.0/tests/__init__.py +0 -0
- intersect_sdk-0.9.0/tests/conftest.py +0 -0
- intersect_sdk-0.9.0/tests/e2e/__init__.py +0 -0
- intersect_sdk-0.9.0/tests/e2e/test_examples.py +0 -152
- intersect_sdk-0.9.0/tests/fixtures/__init__.py +0 -0
- intersect_sdk-0.9.0/tests/fixtures/example_schema.json +0 -1275
- intersect_sdk-0.9.0/tests/fixtures/example_schema.py +0 -622
- intersect_sdk-0.9.0/tests/fixtures/return_type_mismatch.py +0 -7
- intersect_sdk-0.9.0/tests/integration/__init__.py +0 -0
- intersect_sdk-0.9.0/tests/integration/test_return_type_mismatch.py +0 -126
- intersect_sdk-0.9.0/tests/integration/test_service.py +0 -510
- intersect_sdk-0.9.0/tests/unit/__init__.py +0 -0
- intersect_sdk-0.9.0/tests/unit/test_annotations.py +0 -103
- intersect_sdk-0.9.0/tests/unit/test_base_capability_implementation.py +0 -169
- intersect_sdk-0.9.0/tests/unit/test_config.py +0 -194
- intersect_sdk-0.9.0/tests/unit/test_event_message_headers.py +0 -119
- intersect_sdk-0.9.0/tests/unit/test_imports.py +0 -7
- intersect_sdk-0.9.0/tests/unit/test_invalid_schema_runtime.py +0 -48
- intersect_sdk-0.9.0/tests/unit/test_lifecycle_message_headers.py +0 -101
- intersect_sdk-0.9.0/tests/unit/test_schema_invalids.py +0 -929
- intersect_sdk-0.9.0/tests/unit/test_schema_ref_resolution.py +0 -55
- intersect_sdk-0.9.0/tests/unit/test_schema_valid.py +0 -157
- intersect_sdk-0.9.0/tests/unit/test_userspace_message_headers.py +0 -139
- intersect_sdk-0.9.0/tests/unit/test_version_resolver.py +0 -123
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/README.md +0 -0
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/__init__.py +0 -0
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/constants.py +0 -0
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/event_metadata.py +0 -0
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/function_metadata.py +0 -0
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/generic_serializer.py +0 -0
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/logger.py +0 -0
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/pydantic_schema_generator.py +0 -0
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/status_metadata.py +0 -0
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/stoppable_thread.py +0 -0
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/utils.py +0 -0
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/app_lifecycle.py +0 -0
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/capability/__init__.py +0 -0
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/capability/base.py +0 -0
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/capability/universal_capability/__init__.py +0 -0
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/capability/universal_capability/universal_capability.py +0 -0
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/client_callback_definitions.py +0 -0
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/config/__init__.py +0 -0
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/py.typed +0 -0
- {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/service_callback_definitions.py +0 -0
|
@@ -1,30 +1,28 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: intersect-sdk
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.1
|
|
4
4
|
Summary: Python SDK to interact with INTERSECT
|
|
5
5
|
Keywords: intersect
|
|
6
|
-
Author
|
|
6
|
+
Author: Lance Drane, Marshall McDonnell, Seth Hitefield, Andrew Ayres, Gregory Cage, Jesse McGaha, Robert Smith, Gavin Wiggins, Michael Brim, Rick Archibald, Addi Malviya Thakur
|
|
7
|
+
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>
|
|
7
8
|
License: BSD-3-Clause
|
|
8
9
|
Classifier: Programming Language :: Python :: 3
|
|
9
10
|
Classifier: Programming Language :: Python :: 3.10
|
|
10
11
|
Classifier: Programming Language :: Python :: 3.11
|
|
11
12
|
Classifier: Programming Language :: Python :: 3.12
|
|
12
13
|
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Requires-Dist: pydantic>=2.7.0
|
|
15
|
+
Requires-Dist: intersect-sdk-common>=0.9.6,<0.10.0
|
|
16
|
+
Requires-Dist: jsonschema[format-nongpl]>=4.21.1
|
|
17
|
+
Requires-Dist: psutil>=7.0.0
|
|
18
|
+
Requires-Dist: sphinx>=5.3.0 ; extra == 'docs'
|
|
19
|
+
Requires-Dist: furo>=2023.3.27 ; extra == 'docs'
|
|
20
|
+
Requires-Python: >=3.10, <4.0
|
|
13
21
|
Project-URL: Homepage, https://github.com/INTERSECT-SDK/python-sdk/
|
|
14
22
|
Project-URL: Changelog, https://github.com/INTERSECT-SDK/python-sdk/blob/main/CHANGELOG.md
|
|
15
23
|
Project-URL: Documentation, https://intersect-python-sdk.readthedocs.io/en/latest/
|
|
16
24
|
Project-URL: Issues, https://github.com/INTERSECT-SDK/python-sdk/issues
|
|
17
|
-
Requires-Python: <4.0,>=3.10
|
|
18
|
-
Requires-Dist: pydantic>=2.7.0
|
|
19
|
-
Requires-Dist: retrying<2.0.0,>=1.3.4
|
|
20
|
-
Requires-Dist: paho-mqtt<3.0.0,>=2.1.0
|
|
21
|
-
Requires-Dist: pika<2.0.0,>=1.3.2
|
|
22
|
-
Requires-Dist: minio>=7.2.3
|
|
23
|
-
Requires-Dist: jsonschema[format-nongpl]>=4.21.1
|
|
24
|
-
Requires-Dist: psutil>=7.0.0
|
|
25
25
|
Provides-Extra: docs
|
|
26
|
-
Requires-Dist: sphinx>=5.3.0; extra == "docs"
|
|
27
|
-
Requires-Dist: furo>=2023.3.27; extra == "docs"
|
|
28
26
|
Description-Content-Type: text/markdown
|
|
29
27
|
|
|
30
28
|
[](https://doi.org/10.11578/dc.20240927.1)
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "intersect-sdk"
|
|
3
|
+
description = "Python SDK to interact with INTERSECT"
|
|
4
|
+
authors = [
|
|
5
|
+
{ name = "Lance Drane", email = "dranelt@ornl.gov" },
|
|
6
|
+
{ name = "Marshall McDonnell", email = "mcdonnellmt@ornl.gov" },
|
|
7
|
+
{ name = "Seth Hitefield", email = "hitefieldsd@ornl.gov" },
|
|
8
|
+
{ name = "Andrew Ayres", email = "ayresaf@ornl.gov" },
|
|
9
|
+
{ name = "Gregory Cage", email = "cagege@ornl.gov" },
|
|
10
|
+
{ name = "Jesse McGaha", email = "mcgahajr@ornl.gov" },
|
|
11
|
+
{ name = "Robert Smith", email = "smithrw@ornl.gov" },
|
|
12
|
+
{ name = "Gavin Wiggins", email = "wigginsg@ornl.gov" },
|
|
13
|
+
{ name = "Michael Brim", email = "brimmj@ornl.gov" },
|
|
14
|
+
{ name = "Rick Archibald", email = "archibaldrk@ornl.gov" },
|
|
15
|
+
{ name = "Addi Malviya Thakur", email = "malviyaa@ornl.gov" },
|
|
16
|
+
]
|
|
17
|
+
version = "0.9.1"
|
|
18
|
+
readme = "README.md"
|
|
19
|
+
license = { text = "BSD-3-Clause" }
|
|
20
|
+
requires-python = ">=3.10,<4.0"
|
|
21
|
+
keywords = ["intersect"]
|
|
22
|
+
classifiers = [
|
|
23
|
+
"Programming Language :: Python :: 3",
|
|
24
|
+
"Programming Language :: Python :: 3.10",
|
|
25
|
+
"Programming Language :: Python :: 3.11",
|
|
26
|
+
"Programming Language :: Python :: 3.12",
|
|
27
|
+
"Programming Language :: Python :: 3.13",
|
|
28
|
+
]
|
|
29
|
+
dependencies = [
|
|
30
|
+
"pydantic>=2.7.0",
|
|
31
|
+
"intersect-sdk-common>=0.9.6,<0.10.0",
|
|
32
|
+
"jsonschema[format-nongpl]>=4.21.1", # extras necessary for enforcing formats
|
|
33
|
+
#"brotli>=1.1.0", # TODO - add this dependency when we add compression
|
|
34
|
+
"psutil>=7.0.0",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
[project.urls]
|
|
38
|
+
Homepage = "https://github.com/INTERSECT-SDK/python-sdk/"
|
|
39
|
+
Changelog = "https://github.com/INTERSECT-SDK/python-sdk/blob/main/CHANGELOG.md"
|
|
40
|
+
Documentation = "https://intersect-python-sdk.readthedocs.io/en/latest/"
|
|
41
|
+
Issues = "https://github.com/INTERSECT-SDK/python-sdk/issues"
|
|
42
|
+
|
|
43
|
+
[project.optional-dependencies]
|
|
44
|
+
docs = ["sphinx>=5.3.0", "furo>=2023.3.27"]
|
|
45
|
+
|
|
46
|
+
[dependency-groups]
|
|
47
|
+
dev = [
|
|
48
|
+
"pre-commit>=3.3.1",
|
|
49
|
+
"ruff==0.12.7",
|
|
50
|
+
"mypy>=1.10.0",
|
|
51
|
+
"codespell>=2.3.0",
|
|
52
|
+
"pytest>=7.3.2",
|
|
53
|
+
"pytest-cov>=4.1.0",
|
|
54
|
+
"httpretty>=1.1.4",
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
[build-system]
|
|
58
|
+
requires = ["uv_build>=0.10.2,<0.11.0"]
|
|
59
|
+
build-backend = "uv_build"
|
|
60
|
+
|
|
61
|
+
[tool.ruff]
|
|
62
|
+
line-length = 100
|
|
63
|
+
format = { quote-style = 'single' }
|
|
64
|
+
|
|
65
|
+
[tool.ruff.lint]
|
|
66
|
+
isort = { known-first-party = ['src'] }
|
|
67
|
+
pydocstyle = { convention = 'google' }
|
|
68
|
+
flake8-quotes = { inline-quotes = 'single', multiline-quotes = 'double' }
|
|
69
|
+
mccabe = { max-complexity = 20 }
|
|
70
|
+
pylint = { max-args = 10, max-branches = 20, max-returns = 15, max-statements = 75 }
|
|
71
|
+
# pyflakes and the relevant pycodestyle rules are already configured
|
|
72
|
+
extend-select = [
|
|
73
|
+
'C90', # mccabe complexity
|
|
74
|
+
'I', # isort
|
|
75
|
+
'N', # pep8-naming
|
|
76
|
+
'D', # pydocstyle
|
|
77
|
+
'UP', # pyupgrade
|
|
78
|
+
'YTT', # flake8-2020
|
|
79
|
+
'ANN', # flake8-annotations
|
|
80
|
+
'ASYNC', # flake8-async
|
|
81
|
+
'S', # flake8-bandit
|
|
82
|
+
'BLE', # flake8-blind-except
|
|
83
|
+
'B', # flake8-bugbear
|
|
84
|
+
'A', # flake8-builtins
|
|
85
|
+
'COM', # flake8-commas
|
|
86
|
+
'C4', # flake8-comprehensions
|
|
87
|
+
'DTZ', # flake8-datetimez
|
|
88
|
+
'T10', # flake8-debugger
|
|
89
|
+
'EM', # flake8-error-message
|
|
90
|
+
'FA', # flake8-future-annotations
|
|
91
|
+
'ISC', # flake8-implicit-string-concat
|
|
92
|
+
'ICN', # flake8-import-conventions
|
|
93
|
+
'G', # flake8-logging-format
|
|
94
|
+
'INP', # flake8-no-pep420
|
|
95
|
+
'PIE', # flake8-PIE
|
|
96
|
+
'T20', # flake8-T20
|
|
97
|
+
'PYI', # flake8-pyi
|
|
98
|
+
'PT', # flake8-pytest-style
|
|
99
|
+
'Q', # flake8-quotes
|
|
100
|
+
'RSE', # flake8-raise
|
|
101
|
+
'RET', # flake8-return
|
|
102
|
+
'SLF', # flake8-self
|
|
103
|
+
'SLOT', # flake8-slots
|
|
104
|
+
'SIM', # flake8-simplify
|
|
105
|
+
'TC', # flake8-type-checking
|
|
106
|
+
'ARG', # flake8-unused-arguments
|
|
107
|
+
'PTH', # flake8-use-pathlib
|
|
108
|
+
'PGH', # pygrep-hooks
|
|
109
|
+
'PL', # pylint
|
|
110
|
+
'TRY', # tryceratops
|
|
111
|
+
'FLY', # flynt
|
|
112
|
+
'RUF', # RUFF additional rules
|
|
113
|
+
'INT', # flake8-gettext
|
|
114
|
+
]
|
|
115
|
+
# If you're seeking to disable a rule, first consider whether the rule is overbearing, or if it should only be turned off for your usecase.
|
|
116
|
+
ignore = [
|
|
117
|
+
'COM812', # formatter, handled by Ruff format
|
|
118
|
+
'ISC001', # formatter, handled by Ruff format
|
|
119
|
+
'SIM105', # "with contextlib.suppress():" is slower than try-except-pass
|
|
120
|
+
'ANN401', # allow explicit "Any" typing, use with care
|
|
121
|
+
'PLR2004', # allow "magic numbers"
|
|
122
|
+
]
|
|
123
|
+
|
|
124
|
+
[tool.ruff.lint.flake8-type-checking]
|
|
125
|
+
runtime-evaluated-base-classes = [
|
|
126
|
+
"pydantic.BaseModel",
|
|
127
|
+
"intersect_sdk.IntersectBaseCapabilityImplementation",
|
|
128
|
+
]
|
|
129
|
+
runtime-evaluated-decorators = [
|
|
130
|
+
"pydantic.dataclasses.dataclass",
|
|
131
|
+
"pydantic.validate_call",
|
|
132
|
+
]
|
|
133
|
+
|
|
134
|
+
[tool.ruff.lint.extend-per-file-ignores]
|
|
135
|
+
'__init__.py' = [
|
|
136
|
+
'F401', # __init__.py commonly has unused imports
|
|
137
|
+
'TC004', # do lazy imports when importing from the base module
|
|
138
|
+
]
|
|
139
|
+
'docs/*' = [
|
|
140
|
+
'D', # the documentation folder does not need documentation
|
|
141
|
+
'INP001', # docs are not a namespace package
|
|
142
|
+
]
|
|
143
|
+
'examples/*' = [
|
|
144
|
+
'N999', # module names for examples are not standard
|
|
145
|
+
'T20', # allow print/pprint statements in examples
|
|
146
|
+
'S106', # don't care about credentials in examples
|
|
147
|
+
'D100', # documenting modules in examples is unhelpful
|
|
148
|
+
'D104', # documenting packages in examples is unhelpful
|
|
149
|
+
'TRY002', # examples can raise their own exception
|
|
150
|
+
]
|
|
151
|
+
'tests/*' = [
|
|
152
|
+
'S101', # allow assert statements in tests
|
|
153
|
+
'S106', # don't care about credentials in tests
|
|
154
|
+
'S311', # don't care about cryptographic security in tests
|
|
155
|
+
'SLF001', # allow private member access in tests
|
|
156
|
+
'ANN', # tests in general don't need types, unless they are runtime types.
|
|
157
|
+
'ARG', # allow unused parameters in tests
|
|
158
|
+
'D', # ignore documentation in tests
|
|
159
|
+
'RUF012', # permit "mutable" class attributes to not be annotated with typing.ClassVar (these shouldn't be mutated anyways...)
|
|
160
|
+
]
|
|
161
|
+
|
|
162
|
+
# see https://mypy.readthedocs.io/en/stable/config_file.html for a complete reference
|
|
163
|
+
[tool.mypy]
|
|
164
|
+
strict = true
|
|
165
|
+
ignore_missing_imports = true # don't require typing for library stubs if they don't exist
|
|
166
|
+
disallow_untyped_decorators = false # this is needed for library decorator compatibility, i.e. "retrying"
|
|
167
|
+
plugins = ["pydantic.mypy"]
|
|
168
|
+
|
|
169
|
+
[tool.pydantic-mypy]
|
|
170
|
+
init_forbid_extra = true
|
|
171
|
+
init_typed = true
|
|
172
|
+
warn_required_dynamic_aliases = true
|
|
173
|
+
warn_untyped_fields = true
|
|
174
|
+
|
|
175
|
+
[tool.pytest.ini_options]
|
|
176
|
+
log_cli = true
|
|
177
|
+
addopts = "-ra"
|
|
178
|
+
|
|
179
|
+
[tool.coverage.report]
|
|
180
|
+
omit = [
|
|
181
|
+
'*__init__*', # __init__ files should just re-export other classes and functions
|
|
182
|
+
'*/discovery_service.py', # currently unused
|
|
183
|
+
]
|
|
184
|
+
exclude_also = [
|
|
185
|
+
'pragma: no-cover', # standard
|
|
186
|
+
'if (typing\\.)?TYPE_CHECKING:', # type checking blocks are not executed in coverage, but we don't care
|
|
187
|
+
'@(abc\\.)?abstractmethod', # don't try to cover abstract methods
|
|
188
|
+
"class .*\\bProtocol\\):", # don't cover protocol classes (similar to abstract classes)
|
|
189
|
+
'raise NotImplementedError', # it's not implemented so shouldn't be covered
|
|
190
|
+
'except.* ImportError', # these are usually used to throw a "friendlier" error and are not really worth testing
|
|
191
|
+
]
|
|
192
|
+
|
|
193
|
+
[tool.codespell]
|
|
194
|
+
# Ref: https://github.com/codespell-project/codespell#using-a-config-file
|
|
195
|
+
skip = '.git*,*.lock,.venv,.*cache/*,./docs/_build/*'
|
|
196
|
+
check-hidden = true
|
|
197
|
+
# ignore-regex = ''
|
|
198
|
+
# ignore-words-list = ''
|
|
@@ -12,6 +12,18 @@ from typing import TYPE_CHECKING
|
|
|
12
12
|
|
|
13
13
|
# import everything eagerly for IDEs/LSPs
|
|
14
14
|
if TYPE_CHECKING:
|
|
15
|
+
from intersect_sdk_common import (
|
|
16
|
+
ControlPlaneConfig,
|
|
17
|
+
ControlProvider,
|
|
18
|
+
DataStoreConfig,
|
|
19
|
+
DataStoreConfigMap,
|
|
20
|
+
HierarchyConfig,
|
|
21
|
+
IntersectDataHandler,
|
|
22
|
+
IntersectMimeType,
|
|
23
|
+
intersect_sdk_version_info,
|
|
24
|
+
intersect_sdk_version_string,
|
|
25
|
+
)
|
|
26
|
+
|
|
15
27
|
from .app_lifecycle import default_intersect_lifecycle_loop
|
|
16
28
|
from .capability.base import IntersectBaseCapabilityImplementation
|
|
17
29
|
from .client import IntersectClient
|
|
@@ -22,14 +34,6 @@ if TYPE_CHECKING:
|
|
|
22
34
|
)
|
|
23
35
|
from .config.client import IntersectClientConfig
|
|
24
36
|
from .config.service import IntersectServiceConfig
|
|
25
|
-
from .config.shared import (
|
|
26
|
-
ControlPlaneConfig,
|
|
27
|
-
ControlProvider,
|
|
28
|
-
DataStoreConfig,
|
|
29
|
-
DataStoreConfigMap,
|
|
30
|
-
HierarchyConfig,
|
|
31
|
-
)
|
|
32
|
-
from .core_definitions import IntersectDataHandler, IntersectMimeType
|
|
33
37
|
from .exceptions import IntersectCapabilityError
|
|
34
38
|
from .schema import get_schema_from_capability_implementations
|
|
35
39
|
from .service import IntersectService
|
|
@@ -47,7 +51,7 @@ if TYPE_CHECKING:
|
|
|
47
51
|
IntersectDirectMessageParams,
|
|
48
52
|
IntersectEventMessageParams,
|
|
49
53
|
)
|
|
50
|
-
from .version import __version__
|
|
54
|
+
from .version import __version__
|
|
51
55
|
|
|
52
56
|
__all__ = (
|
|
53
57
|
'INTERSECT_CLIENT_EVENT_CALLBACK_TYPE',
|
|
@@ -76,50 +80,78 @@ __all__ = (
|
|
|
76
80
|
'default_intersect_lifecycle_loop',
|
|
77
81
|
'get_schema_from_capability_implementations',
|
|
78
82
|
'intersect_message',
|
|
83
|
+
'intersect_sdk_version_info',
|
|
84
|
+
'intersect_sdk_version_string',
|
|
79
85
|
'intersect_status',
|
|
80
|
-
'version_info',
|
|
81
|
-
'version_string',
|
|
82
86
|
)
|
|
83
87
|
|
|
84
88
|
# PEP 562 stuff: do lazy imports for people who just want to import from the top-level module
|
|
85
|
-
|
|
89
|
+
# [0] = package, [1] = path to module within package
|
|
86
90
|
__lazy_imports = {
|
|
87
|
-
|
|
88
|
-
'
|
|
89
|
-
'
|
|
90
|
-
|
|
91
|
-
'
|
|
92
|
-
'
|
|
93
|
-
'
|
|
94
|
-
'
|
|
95
|
-
'
|
|
96
|
-
|
|
97
|
-
'
|
|
98
|
-
'
|
|
99
|
-
|
|
100
|
-
'
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
'
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
'
|
|
109
|
-
'
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
'
|
|
114
|
-
|
|
115
|
-
|
|
91
|
+
# COMMON: core types
|
|
92
|
+
'IntersectDataHandler': ('intersect_sdk_common', '.'),
|
|
93
|
+
'IntersectMimeType': ('intersect_sdk_common', '.'),
|
|
94
|
+
# COMMON: config types
|
|
95
|
+
'ControlPlaneConfig': ('intersect_sdk_common', '.'),
|
|
96
|
+
'ControlProvider': ('intersect_sdk_common', '.'),
|
|
97
|
+
'DataStoreConfig': ('intersect_sdk_common', '.'),
|
|
98
|
+
'DataStoreConfigMap': ('intersect_sdk_common', '.'),
|
|
99
|
+
'HierarchyConfig': ('intersect_sdk_common', '.'),
|
|
100
|
+
# COMMON: version
|
|
101
|
+
'intersect_sdk_version_info': ('intersect_sdk_common', '.'),
|
|
102
|
+
'intersect_sdk_version_string': ('intersect_sdk_common', '.'),
|
|
103
|
+
# imports not in common
|
|
104
|
+
'INTERSECT_CLIENT_EVENT_CALLBACK_TYPE': (
|
|
105
|
+
__spec__.parent,
|
|
106
|
+
'.client_callback_definitions',
|
|
107
|
+
),
|
|
108
|
+
'INTERSECT_CLIENT_RESPONSE_CALLBACK_TYPE': (
|
|
109
|
+
__spec__.parent,
|
|
110
|
+
'.client_callback_definitions',
|
|
111
|
+
),
|
|
112
|
+
'INTERSECT_JSON_VALUE': (__spec__.parent, '.shared_callback_definitions'),
|
|
113
|
+
'INTERSECT_RESPONSE_VALUE': (
|
|
114
|
+
__spec__.parent,
|
|
115
|
+
'.shared_callback_definitions',
|
|
116
|
+
),
|
|
117
|
+
'INTERSECT_SERVICE_RESPONSE_CALLBACK_TYPE': (
|
|
118
|
+
__spec__.parent,
|
|
119
|
+
'.service_callback_definitions',
|
|
120
|
+
),
|
|
121
|
+
'IntersectBaseCapabilityImplementation': (
|
|
122
|
+
__spec__.parent,
|
|
123
|
+
'.capability.base',
|
|
124
|
+
),
|
|
125
|
+
'IntersectCapabilityError': (__spec__.parent, '.exceptions'),
|
|
126
|
+
'IntersectClient': (__spec__.parent, '.client'),
|
|
127
|
+
'IntersectClientCallback': (
|
|
128
|
+
__spec__.parent,
|
|
129
|
+
'.client_callback_definitions',
|
|
130
|
+
),
|
|
131
|
+
'IntersectClientConfig': (__spec__.parent, '.config.client'),
|
|
132
|
+
'IntersectDirectMessageParams': (
|
|
133
|
+
__spec__.parent,
|
|
134
|
+
'.shared_callback_definitions',
|
|
135
|
+
),
|
|
136
|
+
'IntersectEventDefinition': (__spec__.parent, '.service_definitions'),
|
|
137
|
+
'IntersectEventMessageParams': (
|
|
138
|
+
__spec__.parent,
|
|
139
|
+
'.shared_callback_definitions',
|
|
140
|
+
),
|
|
141
|
+
'IntersectService': (__spec__.parent, '.service'),
|
|
142
|
+
'IntersectServiceConfig': (__spec__.parent, '.config.service'),
|
|
143
|
+
'__version__': (__spec__.parent, '.version'),
|
|
144
|
+
'default_intersect_lifecycle_loop': (__spec__.parent, '.app_lifecycle'),
|
|
145
|
+
'get_schema_from_capability_implementations': (__spec__.parent, '.schema'),
|
|
146
|
+
'intersect_message': (__spec__.parent, '.service_definitions'),
|
|
147
|
+
'intersect_status': (__spec__.parent, '.service_definitions'),
|
|
116
148
|
}
|
|
117
149
|
|
|
118
150
|
|
|
119
151
|
def __getattr__(attr_name: str) -> object:
|
|
120
152
|
attr_module = __lazy_imports.get(attr_name)
|
|
121
153
|
if attr_module:
|
|
122
|
-
module = import_module(attr_module, package=
|
|
154
|
+
module = import_module(attr_module[1], package=attr_module[0])
|
|
123
155
|
return getattr(module, attr_name)
|
|
124
156
|
|
|
125
157
|
msg = f'module {__name__!r} has no attribute {attr_name!r}'
|
|
@@ -5,8 +5,9 @@ from typing import TYPE_CHECKING, Any, Protocol
|
|
|
5
5
|
if TYPE_CHECKING:
|
|
6
6
|
from uuid import UUID
|
|
7
7
|
|
|
8
|
+
from intersect_sdk_common import HierarchyConfig
|
|
9
|
+
|
|
8
10
|
from ..client_callback_definitions import INTERSECT_CLIENT_EVENT_CALLBACK_TYPE
|
|
9
|
-
from ..config.shared import HierarchyConfig
|
|
10
11
|
from ..service_callback_definitions import (
|
|
11
12
|
INTERSECT_SERVICE_RESPONSE_CALLBACK_TYPE,
|
|
12
13
|
)
|
|
@@ -14,12 +14,18 @@ from typing import (
|
|
|
14
14
|
get_origin,
|
|
15
15
|
)
|
|
16
16
|
|
|
17
|
+
from intersect_sdk_common import intersect_sdk_version_string
|
|
18
|
+
from intersect_sdk_common.constants import CAPABILITY_REGEX
|
|
19
|
+
from intersect_sdk_common.control_plane.messages.event import (
|
|
20
|
+
EventMessageHeaders,
|
|
21
|
+
)
|
|
22
|
+
from intersect_sdk_common.control_plane.messages.userspace import (
|
|
23
|
+
UserspaceMessageHeaders,
|
|
24
|
+
)
|
|
17
25
|
from pydantic import Field, PydanticUserError, TypeAdapter
|
|
18
26
|
from typing_extensions import TypeAliasType
|
|
19
27
|
|
|
20
|
-
from ..constants import CAPABILITY_REGEX
|
|
21
28
|
from ..service_definitions import IntersectEventDefinition
|
|
22
|
-
from ..version import version_string
|
|
23
29
|
from .constants import (
|
|
24
30
|
BASE_RESPONSE_ATTR,
|
|
25
31
|
BASE_STATUS_ATTR,
|
|
@@ -32,18 +38,15 @@ from .constants import (
|
|
|
32
38
|
from .event_metadata import EventMetadata, definition_metadata_differences
|
|
33
39
|
from .function_metadata import FunctionMetadata
|
|
34
40
|
from .logger import logger
|
|
35
|
-
from .messages.event import EventMessageHeaders
|
|
36
|
-
from .messages.userspace import UserspaceMessageHeaders
|
|
37
41
|
from .pydantic_schema_generator import GenerateTypedJsonSchema
|
|
38
42
|
from .status_metadata import StatusMetadata
|
|
39
43
|
from .utils import die
|
|
40
44
|
|
|
41
45
|
if TYPE_CHECKING:
|
|
46
|
+
from intersect_sdk_common import HierarchyConfig, IntersectDataHandler
|
|
42
47
|
from pydantic.json_schema import JsonSchemaMode
|
|
43
48
|
|
|
44
49
|
from ..capability.base import IntersectBaseCapabilityImplementation
|
|
45
|
-
from ..config.shared import HierarchyConfig
|
|
46
|
-
from ..core_definitions import IntersectDataHandler
|
|
47
50
|
|
|
48
51
|
ASYNCAPI_VERSION = '2.6.0'
|
|
49
52
|
|
|
@@ -619,7 +622,7 @@ def get_schema_and_functions_from_capability_implementations(
|
|
|
619
622
|
or not re.fullmatch(CAPABILITY_REGEX, cap_name)
|
|
620
623
|
):
|
|
621
624
|
die(
|
|
622
|
-
f'Invalid intersect_sdk_capability_name on capability {capability_type.__name__} - must be a non-empty string with only alphanumeric characters and
|
|
625
|
+
f'Invalid intersect_sdk_capability_name on capability {capability_type.__name__} - must be a non-empty string with only alphanumeric characters and underscores (you must explicitly set this, and do so on the class and not an instance).'
|
|
623
626
|
)
|
|
624
627
|
if cap_name in capability_schemas:
|
|
625
628
|
die(
|
|
@@ -659,7 +662,7 @@ def get_schema_and_functions_from_capability_implementations(
|
|
|
659
662
|
|
|
660
663
|
asyncapi_spec = {
|
|
661
664
|
'asyncapi': ASYNCAPI_VERSION,
|
|
662
|
-
'x-intersect-version':
|
|
665
|
+
'x-intersect-version': intersect_sdk_version_string,
|
|
663
666
|
'info': {
|
|
664
667
|
'title': service_name.hierarchy_string('.'),
|
|
665
668
|
'description': 'INTERSECT schema',
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from hashlib import sha384
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def get_service_queue_name(routing_key: str) -> str:
|
|
5
|
+
"""Generate a valid queue name from the routing key.
|
|
6
|
+
|
|
7
|
+
We want to always be able to generate the same queue name from the routing key every time,
|
|
8
|
+
so we don't use UUIDs or want the broker to generate a key name.
|
|
9
|
+
|
|
10
|
+
We must also keep the length under 128 characters.
|
|
11
|
+
|
|
12
|
+
See https://www.rabbitmq.com/docs/queues#names for a complete reference.
|
|
13
|
+
"""
|
|
14
|
+
return sha384(routing_key.encode()).hexdigest()
|
|
@@ -10,44 +10,39 @@ Users do not need to interact with the client other than through its constructor
|
|
|
10
10
|
Most useful definitions and typings will be found in the client_callback_definitions module.
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
|
-
from __future__ import annotations
|
|
14
|
-
|
|
15
13
|
import time
|
|
16
|
-
from typing import TYPE_CHECKING
|
|
17
14
|
from uuid import uuid4
|
|
18
15
|
|
|
19
|
-
from
|
|
20
|
-
from typing_extensions import Self, final
|
|
21
|
-
|
|
22
|
-
from intersect_sdk._internal.generic_serializer import GENERIC_MESSAGE_SERIALIZER
|
|
23
|
-
|
|
24
|
-
from ._internal.control_plane.control_plane_manager import (
|
|
16
|
+
from intersect_sdk_common import (
|
|
25
17
|
ControlPlaneManager,
|
|
18
|
+
DataPlaneManager,
|
|
19
|
+
HierarchyConfig,
|
|
20
|
+
IntersectError,
|
|
21
|
+
resolve_user_version,
|
|
26
22
|
)
|
|
27
|
-
from .
|
|
28
|
-
from ._internal.exceptions import IntersectError
|
|
29
|
-
from ._internal.logger import logger
|
|
30
|
-
from ._internal.messages.event import (
|
|
23
|
+
from intersect_sdk_common.control_plane.messages.event import (
|
|
31
24
|
validate_event_message_headers,
|
|
32
25
|
)
|
|
33
|
-
from .
|
|
26
|
+
from intersect_sdk_common.control_plane.messages.userspace import (
|
|
34
27
|
create_userspace_message_headers,
|
|
35
28
|
validate_userspace_message_headers,
|
|
36
29
|
)
|
|
30
|
+
from pydantic import ValidationError
|
|
31
|
+
from typing_extensions import Self, final
|
|
32
|
+
|
|
33
|
+
from intersect_sdk._internal.generic_serializer import (
|
|
34
|
+
GENERIC_MESSAGE_SERIALIZER,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
from ._internal.logger import logger
|
|
37
38
|
from ._internal.utils import die, send_os_signal
|
|
38
|
-
from ._internal.version_resolver import resolve_user_version
|
|
39
39
|
from .client_callback_definitions import (
|
|
40
|
+
INTERSECT_CLIENT_EVENT_CALLBACK_TYPE,
|
|
41
|
+
INTERSECT_CLIENT_RESPONSE_CALLBACK_TYPE,
|
|
40
42
|
IntersectClientCallback,
|
|
41
43
|
)
|
|
42
44
|
from .config.client import IntersectClientConfig
|
|
43
|
-
from .
|
|
44
|
-
|
|
45
|
-
if TYPE_CHECKING:
|
|
46
|
-
from .client_callback_definitions import (
|
|
47
|
-
INTERSECT_CLIENT_EVENT_CALLBACK_TYPE,
|
|
48
|
-
INTERSECT_CLIENT_RESPONSE_CALLBACK_TYPE,
|
|
49
|
-
)
|
|
50
|
-
from .shared_callback_definitions import IntersectDirectMessageParams
|
|
45
|
+
from .shared_callback_definitions import IntersectDirectMessageParams
|
|
51
46
|
|
|
52
47
|
|
|
53
48
|
@final
|
|
@@ -131,6 +126,7 @@ class IntersectClient:
|
|
|
131
126
|
f'{self._hierarchy.hierarchy_string("/")}/response',
|
|
132
127
|
{self._handle_userspace_message},
|
|
133
128
|
persist=False,
|
|
129
|
+
queue_name=self._hierarchy.service,
|
|
134
130
|
)
|
|
135
131
|
if event_callback:
|
|
136
132
|
# Do not persist, as event messages are meant to be short-lived.
|
|
@@ -142,6 +138,7 @@ class IntersectClient:
|
|
|
142
138
|
f'{service.hierarchy.replace(".", "/")}/events/{service.capability_name}/{service.event_name}',
|
|
143
139
|
{self._handle_event_message},
|
|
144
140
|
persist=False,
|
|
141
|
+
queue_name=self._hierarchy.service,
|
|
145
142
|
)
|
|
146
143
|
self._user_callback = user_callback
|
|
147
144
|
self._event_callback = event_callback
|
|
@@ -393,6 +390,7 @@ class IntersectClient:
|
|
|
393
390
|
self._control_plane_manager.add_subscription_channel(
|
|
394
391
|
f'{add_event.hierarchy.replace(".", "/")}/events/{add_event.capability_name}/{add_event.event_name}',
|
|
395
392
|
{self._handle_event_message},
|
|
393
|
+
queue_name=self._hierarchy.service,
|
|
396
394
|
persist=False,
|
|
397
395
|
)
|
|
398
396
|
for remove_event in validated_result.services_to_stop_listening_for_events:
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
"""Client specific configuration types."""
|
|
2
2
|
|
|
3
|
-
from typing import Annotated
|
|
3
|
+
from typing import Annotated
|
|
4
4
|
|
|
5
|
+
from intersect_sdk_common import ControlPlaneConfig, DataStoreConfigMap
|
|
5
6
|
from pydantic import BaseModel, ConfigDict, Field
|
|
6
7
|
from typing_extensions import final
|
|
7
8
|
|
|
8
9
|
from ..client_callback_definitions import IntersectClientCallback
|
|
9
|
-
from .shared import ControlPlaneConfig, DataStoreConfigMap
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
@final
|
|
13
13
|
class IntersectClientConfig(BaseModel):
|
|
14
14
|
"""The user-provided configuration needed to integrate with INTERSECT as a client."""
|
|
15
15
|
|
|
16
|
-
brokers: Annotated[list[ControlPlaneConfig], Field(min_length=1)]
|
|
16
|
+
brokers: Annotated[list[ControlPlaneConfig], Field(min_length=1)]
|
|
17
17
|
"""
|
|
18
18
|
Configurations for any message brokers the application should attach to
|
|
19
19
|
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
"""Service specific configuration types."""
|
|
2
2
|
|
|
3
|
-
from typing import Annotated
|
|
3
|
+
from typing import Annotated
|
|
4
4
|
|
|
5
|
+
from intersect_sdk_common import (
|
|
6
|
+
ControlPlaneConfig,
|
|
7
|
+
DataStoreConfigMap,
|
|
8
|
+
HierarchyConfig,
|
|
9
|
+
)
|
|
5
10
|
from pydantic import BaseModel, ConfigDict, Field, PositiveFloat
|
|
6
11
|
|
|
7
|
-
from .shared import ControlPlaneConfig, DataStoreConfigMap, HierarchyConfig
|
|
8
|
-
|
|
9
12
|
|
|
10
13
|
class IntersectServiceConfig(BaseModel):
|
|
11
14
|
"""The user-provided configuration needed to integrate with INTERSECT."""
|
|
@@ -15,7 +18,7 @@ class IntersectServiceConfig(BaseModel):
|
|
|
15
18
|
Configuration of the System-of-System representation
|
|
16
19
|
"""
|
|
17
20
|
|
|
18
|
-
brokers: Annotated[list[ControlPlaneConfig], Field(min_length=1)]
|
|
21
|
+
brokers: Annotated[list[ControlPlaneConfig], Field(min_length=1)]
|
|
19
22
|
"""
|
|
20
23
|
Configurations for any message brokers the application should attach to
|
|
21
24
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"""Public exceptions API."""
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from intersect_sdk_common import IntersectApplicationError
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
class IntersectCapabilityError(
|
|
6
|
+
class IntersectCapabilityError(IntersectApplicationError):
|
|
7
7
|
"""This is a marker for a special kind of Capability Exception. WARNING: USE THIS WITH CARE.
|
|
8
8
|
|
|
9
9
|
When the SDK catches an Exception from Capability code, it has to decide whether to send information about the Exception in the message, or a generic "Application raised Exception" message.
|
|
@@ -38,7 +38,7 @@ from .capability.base import IntersectBaseCapabilityImplementation
|
|
|
38
38
|
from .capability.universal_capability.universal_capability import IntersectSdkCoreCapability
|
|
39
39
|
|
|
40
40
|
if TYPE_CHECKING:
|
|
41
|
-
from
|
|
41
|
+
from intersect_sdk_common import HierarchyConfig
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
def get_schema_from_capability_implementations(
|