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.
Files changed (85) hide show
  1. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/PKG-INFO +11 -13
  2. intersect_sdk-0.9.1/pyproject.toml +198 -0
  3. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/__init__.py +74 -42
  4. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/interfaces.py +2 -1
  5. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/schema.py +11 -8
  6. intersect_sdk-0.9.1/src/intersect_sdk/_internal/service_queue_name.py +14 -0
  7. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/capability/universal_capability/status.py +0 -2
  8. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/client.py +21 -23
  9. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/config/client.py +3 -3
  10. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/config/service.py +7 -4
  11. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/exceptions.py +2 -2
  12. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/schema.py +1 -1
  13. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/service.py +92 -40
  14. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/service_definitions.py +1 -1
  15. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/shared_callback_definitions.py +5 -3
  16. intersect_sdk-0.9.1/src/intersect_sdk/version.py +9 -0
  17. intersect_sdk-0.9.0/LICENSE +0 -29
  18. intersect_sdk-0.9.0/pyproject.toml +0 -253
  19. intersect_sdk-0.9.0/src/intersect_sdk/_internal/control_plane/__init__.py +0 -0
  20. intersect_sdk-0.9.0/src/intersect_sdk/_internal/control_plane/brokers/__init__.py +0 -0
  21. intersect_sdk-0.9.0/src/intersect_sdk/_internal/control_plane/brokers/amqp_client.py +0 -627
  22. intersect_sdk-0.9.0/src/intersect_sdk/_internal/control_plane/brokers/broker_client.py +0 -76
  23. intersect_sdk-0.9.0/src/intersect_sdk/_internal/control_plane/brokers/mqtt_client.py +0 -288
  24. intersect_sdk-0.9.0/src/intersect_sdk/_internal/control_plane/control_plane_manager.py +0 -182
  25. intersect_sdk-0.9.0/src/intersect_sdk/_internal/control_plane/definitions.py +0 -10
  26. intersect_sdk-0.9.0/src/intersect_sdk/_internal/control_plane/topic_handler.py +0 -17
  27. intersect_sdk-0.9.0/src/intersect_sdk/_internal/data_plane/__init__.py +0 -0
  28. intersect_sdk-0.9.0/src/intersect_sdk/_internal/data_plane/data_plane_manager.py +0 -113
  29. intersect_sdk-0.9.0/src/intersect_sdk/_internal/data_plane/minio_utils.py +0 -154
  30. intersect_sdk-0.9.0/src/intersect_sdk/_internal/exceptions.py +0 -17
  31. intersect_sdk-0.9.0/src/intersect_sdk/_internal/messages/__init__.py +0 -0
  32. intersect_sdk-0.9.0/src/intersect_sdk/_internal/messages/event.py +0 -145
  33. intersect_sdk-0.9.0/src/intersect_sdk/_internal/messages/lifecycle.py +0 -107
  34. intersect_sdk-0.9.0/src/intersect_sdk/_internal/messages/userspace.py +0 -183
  35. intersect_sdk-0.9.0/src/intersect_sdk/_internal/multi_flag_thread_event.py +0 -77
  36. intersect_sdk-0.9.0/src/intersect_sdk/_internal/version.py +0 -18
  37. intersect_sdk-0.9.0/src/intersect_sdk/_internal/version_resolver.py +0 -59
  38. intersect_sdk-0.9.0/src/intersect_sdk/config/shared.py +0 -168
  39. intersect_sdk-0.9.0/src/intersect_sdk/constants.py +0 -28
  40. intersect_sdk-0.9.0/src/intersect_sdk/core_definitions.py +0 -47
  41. intersect_sdk-0.9.0/src/intersect_sdk/version.py +0 -19
  42. intersect_sdk-0.9.0/tests/__init__.py +0 -0
  43. intersect_sdk-0.9.0/tests/conftest.py +0 -0
  44. intersect_sdk-0.9.0/tests/e2e/__init__.py +0 -0
  45. intersect_sdk-0.9.0/tests/e2e/test_examples.py +0 -152
  46. intersect_sdk-0.9.0/tests/fixtures/__init__.py +0 -0
  47. intersect_sdk-0.9.0/tests/fixtures/example_schema.json +0 -1275
  48. intersect_sdk-0.9.0/tests/fixtures/example_schema.py +0 -622
  49. intersect_sdk-0.9.0/tests/fixtures/return_type_mismatch.py +0 -7
  50. intersect_sdk-0.9.0/tests/integration/__init__.py +0 -0
  51. intersect_sdk-0.9.0/tests/integration/test_return_type_mismatch.py +0 -126
  52. intersect_sdk-0.9.0/tests/integration/test_service.py +0 -510
  53. intersect_sdk-0.9.0/tests/unit/__init__.py +0 -0
  54. intersect_sdk-0.9.0/tests/unit/test_annotations.py +0 -103
  55. intersect_sdk-0.9.0/tests/unit/test_base_capability_implementation.py +0 -169
  56. intersect_sdk-0.9.0/tests/unit/test_config.py +0 -194
  57. intersect_sdk-0.9.0/tests/unit/test_event_message_headers.py +0 -119
  58. intersect_sdk-0.9.0/tests/unit/test_imports.py +0 -7
  59. intersect_sdk-0.9.0/tests/unit/test_invalid_schema_runtime.py +0 -48
  60. intersect_sdk-0.9.0/tests/unit/test_lifecycle_message_headers.py +0 -101
  61. intersect_sdk-0.9.0/tests/unit/test_schema_invalids.py +0 -929
  62. intersect_sdk-0.9.0/tests/unit/test_schema_ref_resolution.py +0 -55
  63. intersect_sdk-0.9.0/tests/unit/test_schema_valid.py +0 -157
  64. intersect_sdk-0.9.0/tests/unit/test_userspace_message_headers.py +0 -139
  65. intersect_sdk-0.9.0/tests/unit/test_version_resolver.py +0 -123
  66. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/README.md +0 -0
  67. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/__init__.py +0 -0
  68. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/constants.py +0 -0
  69. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/event_metadata.py +0 -0
  70. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/function_metadata.py +0 -0
  71. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/generic_serializer.py +0 -0
  72. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/logger.py +0 -0
  73. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/pydantic_schema_generator.py +0 -0
  74. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/status_metadata.py +0 -0
  75. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/stoppable_thread.py +0 -0
  76. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/utils.py +0 -0
  77. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/app_lifecycle.py +0 -0
  78. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/capability/__init__.py +0 -0
  79. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/capability/base.py +0 -0
  80. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/capability/universal_capability/__init__.py +0 -0
  81. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/capability/universal_capability/universal_capability.py +0 -0
  82. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/client_callback_definitions.py +0 -0
  83. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/config/__init__.py +0 -0
  84. {intersect_sdk-0.9.0 → intersect_sdk-0.9.1}/src/intersect_sdk/py.typed +0 -0
  85. {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
1
+ Metadata-Version: 2.3
2
2
  Name: intersect-sdk
3
- Version: 0.9.0
3
+ Version: 0.9.1
4
4
  Summary: Python SDK to interact with INTERSECT
5
5
  Keywords: intersect
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>
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
  [![Static Badge](https://img.shields.io/badge/DOI-10.11578%2Fdc.20240927.1-blue)](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__, version_info, version_string
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
- 'INTERSECT_CLIENT_EVENT_CALLBACK_TYPE': '.client_callback_definitions',
88
- 'INTERSECT_CLIENT_RESPONSE_CALLBACK_TYPE': '.client_callback_definitions',
89
- 'INTERSECT_JSON_VALUE': '.shared_callback_definitions',
90
- 'INTERSECT_RESPONSE_VALUE': '.shared_callback_definitions',
91
- 'INTERSECT_SERVICE_RESPONSE_CALLBACK_TYPE': '.service_callback_definitions',
92
- 'ControlPlaneConfig': '.config.shared',
93
- 'ControlProvider': '.config.shared',
94
- 'DataStoreConfig': '.config.shared',
95
- 'DataStoreConfigMap': '.config.shared',
96
- 'HierarchyConfig': '.config.shared',
97
- 'IntersectBaseCapabilityImplementation': '.capability.base',
98
- 'IntersectCapabilityError': '.exceptions',
99
- 'IntersectClient': '.client',
100
- 'IntersectClientCallback': '.client_callback_definitions',
101
- 'IntersectClientConfig': '.config.client',
102
- 'IntersectDataHandler': '.core_definitions',
103
- 'IntersectDirectMessageParams': '.shared_callback_definitions',
104
- 'IntersectEventDefinition': '.service_definitions',
105
- 'IntersectEventMessageParams': '.shared_callback_definitions',
106
- 'IntersectMimeType': '.core_definitions',
107
- 'IntersectService': '.service',
108
- 'IntersectServiceConfig': '.config.service',
109
- '__version__': '.version',
110
- 'default_intersect_lifecycle_loop': '.app_lifecycle',
111
- 'get_schema_from_capability_implementations': '.schema',
112
- 'intersect_message': '.service_definitions',
113
- 'intersect_status': '.service_definitions',
114
- 'version_info': '.version',
115
- 'version_string': '.version',
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=__spec__.parent)
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 hyphens (you must explicitly set this, and do so on the class and not an instance).'
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': version_string,
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()
@@ -1,7 +1,5 @@
1
1
  """Definitions supporting the 'core status' functionality of the core capability."""
2
2
 
3
- from __future__ import annotations
4
-
5
3
  import datetime
6
4
  from typing import Annotated
7
5
 
@@ -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 pydantic import ValidationError
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 ._internal.data_plane.data_plane_manager import DataPlaneManager
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 ._internal.messages.userspace import (
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 .config.shared import HierarchyConfig
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, Literal
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)] | Literal['discovery']
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, Literal
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)] | Literal['discovery']
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 ._internal.exceptions import IntersectError
3
+ from intersect_sdk_common import IntersectApplicationError
4
4
 
5
5
 
6
- class IntersectCapabilityError(IntersectError):
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 .config.shared import HierarchyConfig
41
+ from intersect_sdk_common import HierarchyConfig
42
42
 
43
43
 
44
44
  def get_schema_from_capability_implementations(