intersect-sdk 0.8.4__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.8.4 → intersect_sdk-0.9.1}/PKG-INFO +15 -17
- {intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/README.md +2 -1
- intersect_sdk-0.9.1/pyproject.toml +198 -0
- intersect_sdk-0.9.1/src/intersect_sdk/__init__.py +162 -0
- {intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/constants.py +0 -2
- {intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/event_metadata.py +2 -6
- intersect_sdk-0.9.1/src/intersect_sdk/_internal/function_metadata.py +52 -0
- intersect_sdk-0.9.1/src/intersect_sdk/_internal/generic_serializer.py +5 -0
- {intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/interfaces.py +6 -3
- {intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/pydantic_schema_generator.py +1 -7
- {intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/schema.py +241 -160
- intersect_sdk-0.9.1/src/intersect_sdk/_internal/service_queue_name.py +14 -0
- intersect_sdk-0.9.1/src/intersect_sdk/_internal/status_metadata.py +14 -0
- {intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/src/intersect_sdk/app_lifecycle.py +3 -1
- {intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/src/intersect_sdk/capability/__init__.py +0 -6
- {intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/src/intersect_sdk/capability/base.py +36 -49
- intersect_sdk-0.9.1/src/intersect_sdk/capability/universal_capability/__init__.py +4 -0
- intersect_sdk-0.9.1/src/intersect_sdk/capability/universal_capability/status.py +23 -0
- intersect_sdk-0.9.1/src/intersect_sdk/capability/universal_capability/universal_capability.py +60 -0
- {intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/src/intersect_sdk/client.py +78 -70
- {intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/src/intersect_sdk/client_callback_definitions.py +26 -19
- {intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/src/intersect_sdk/config/__init__.py +0 -11
- {intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/src/intersect_sdk/config/client.py +4 -4
- {intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/src/intersect_sdk/config/service.py +7 -5
- intersect_sdk-0.9.1/src/intersect_sdk/exceptions.py +40 -0
- {intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/src/intersect_sdk/schema.py +8 -7
- {intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/src/intersect_sdk/service.py +434 -261
- {intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/src/intersect_sdk/service_callback_definitions.py +7 -4
- {intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/src/intersect_sdk/service_definitions.py +26 -81
- {intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/src/intersect_sdk/shared_callback_definitions.py +39 -17
- intersect_sdk-0.9.1/src/intersect_sdk/version.py +9 -0
- intersect_sdk-0.8.4/LICENSE +0 -29
- intersect_sdk-0.8.4/pyproject.toml +0 -245
- intersect_sdk-0.8.4/src/intersect_sdk/__init__.py +0 -73
- intersect_sdk-0.8.4/src/intersect_sdk/_internal/control_plane/__init__.py +0 -0
- intersect_sdk-0.8.4/src/intersect_sdk/_internal/control_plane/brokers/__init__.py +0 -0
- intersect_sdk-0.8.4/src/intersect_sdk/_internal/control_plane/brokers/amqp_client.py +0 -598
- intersect_sdk-0.8.4/src/intersect_sdk/_internal/control_plane/brokers/broker_client.py +0 -72
- intersect_sdk-0.8.4/src/intersect_sdk/_internal/control_plane/brokers/mqtt_client.py +0 -204
- intersect_sdk-0.8.4/src/intersect_sdk/_internal/control_plane/control_plane_manager.py +0 -180
- intersect_sdk-0.8.4/src/intersect_sdk/_internal/control_plane/discovery_service.py +0 -40
- intersect_sdk-0.8.4/src/intersect_sdk/_internal/control_plane/topic_handler.py +0 -19
- intersect_sdk-0.8.4/src/intersect_sdk/_internal/data_plane/__init__.py +0 -0
- intersect_sdk-0.8.4/src/intersect_sdk/_internal/data_plane/data_plane_manager.py +0 -102
- intersect_sdk-0.8.4/src/intersect_sdk/_internal/data_plane/minio_utils.py +0 -149
- intersect_sdk-0.8.4/src/intersect_sdk/_internal/exceptions.py +0 -17
- intersect_sdk-0.8.4/src/intersect_sdk/_internal/function_metadata.py +0 -31
- intersect_sdk-0.8.4/src/intersect_sdk/_internal/messages/__init__.py +0 -0
- intersect_sdk-0.8.4/src/intersect_sdk/_internal/messages/event.py +0 -157
- intersect_sdk-0.8.4/src/intersect_sdk/_internal/messages/lifecycle.py +0 -174
- intersect_sdk-0.8.4/src/intersect_sdk/_internal/messages/userspace.py +0 -185
- intersect_sdk-0.8.4/src/intersect_sdk/_internal/multi_flag_thread_event.py +0 -77
- intersect_sdk-0.8.4/src/intersect_sdk/_internal/version.py +0 -18
- intersect_sdk-0.8.4/src/intersect_sdk/_internal/version_resolver.py +0 -58
- intersect_sdk-0.8.4/src/intersect_sdk/config/shared.py +0 -169
- intersect_sdk-0.8.4/src/intersect_sdk/constants.py +0 -9
- intersect_sdk-0.8.4/src/intersect_sdk/core_definitions.py +0 -37
- intersect_sdk-0.8.4/src/intersect_sdk/version.py +0 -21
- intersect_sdk-0.8.4/tests/__init__.py +0 -0
- intersect_sdk-0.8.4/tests/conftest.py +0 -0
- intersect_sdk-0.8.4/tests/e2e/__init__.py +0 -0
- intersect_sdk-0.8.4/tests/e2e/test_examples.py +0 -152
- intersect_sdk-0.8.4/tests/fixtures/__init__.py +0 -0
- intersect_sdk-0.8.4/tests/fixtures/example_schema.json +0 -1059
- intersect_sdk-0.8.4/tests/fixtures/example_schema.py +0 -593
- intersect_sdk-0.8.4/tests/fixtures/return_type_mismatch.py +0 -7
- intersect_sdk-0.8.4/tests/integration/__init__.py +0 -0
- intersect_sdk-0.8.4/tests/integration/test_return_type_mismatch.py +0 -125
- intersect_sdk-0.8.4/tests/integration/test_service.py +0 -386
- intersect_sdk-0.8.4/tests/unit/__init__.py +0 -0
- intersect_sdk-0.8.4/tests/unit/test_annotations.py +0 -164
- intersect_sdk-0.8.4/tests/unit/test_base_capability_implementation.py +0 -205
- intersect_sdk-0.8.4/tests/unit/test_config.py +0 -194
- intersect_sdk-0.8.4/tests/unit/test_invalid_schema_runtime.py +0 -45
- intersect_sdk-0.8.4/tests/unit/test_lifecycle_message.py +0 -101
- intersect_sdk-0.8.4/tests/unit/test_schema_invalids.py +0 -979
- intersect_sdk-0.8.4/tests/unit/test_schema_ref_resolution.py +0 -55
- intersect_sdk-0.8.4/tests/unit/test_schema_valid.py +0 -134
- intersect_sdk-0.8.4/tests/unit/test_userspace_message.py +0 -106
- intersect_sdk-0.8.4/tests/unit/test_version_resolver.py +0 -135
- {intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/__init__.py +0 -0
- {intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/logger.py +0 -0
- {intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/stoppable_thread.py +0 -0
- {intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/utils.py +0 -0
- {intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/src/intersect_sdk/py.typed +0 -0
|
@@ -1,31 +1,28 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: intersect-sdk
|
|
3
|
-
Version: 0.
|
|
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
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
10
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
11
10
|
Classifier: Programming Language :: Python :: 3.10
|
|
12
11
|
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.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.8.10
|
|
18
|
-
Requires-Dist: pydantic>=2.7.0
|
|
19
|
-
Requires-Dist: retrying<2.0.0,>=1.3.4
|
|
20
|
-
Requires-Dist: paho-mqtt<2.0.0,>=1.6.1
|
|
21
|
-
Requires-Dist: minio>=7.2.3
|
|
22
|
-
Requires-Dist: jsonschema[format-nongpl]>=4.21.1
|
|
23
|
-
Requires-Dist: eval-type-backport>=0.1.3; python_version < "3.10"
|
|
24
|
-
Provides-Extra: amqp
|
|
25
|
-
Requires-Dist: pika<2.0.0,>=1.3.2; extra == "amqp"
|
|
26
25
|
Provides-Extra: docs
|
|
27
|
-
Requires-Dist: sphinx>=5.3.0; extra == "docs"
|
|
28
|
-
Requires-Dist: furo>=2023.3.27; extra == "docs"
|
|
29
26
|
Description-Content-Type: text/markdown
|
|
30
27
|
|
|
31
28
|
[](https://doi.org/10.11578/dc.20240927.1)
|
|
@@ -49,7 +46,8 @@ For a high-level overview, please see [the architecture website.](https://inters
|
|
|
49
46
|
|
|
50
47
|
- Event-driven architecture
|
|
51
48
|
- Support core interaction types: request/response, events, commands, statuses
|
|
52
|
-
- Borrows several concepts from [AsyncAPI](https://www.asyncapi.com/docs/reference/specification/latest), and intends to support multiple different protocols. Currently, we support MQTT
|
|
49
|
+
- Borrows several concepts from [AsyncAPI](https://www.asyncapi.com/docs/reference/specification/latest), and intends to support multiple different protocols. Currently, we support MQTT 5.0 and AMQP 0.9.1, but other protocols will be supported as well.
|
|
50
|
+
- As a general rule, we will not support any protocols which do not support headers, do not allow for asynchronous messaging, or require the microservice itself to "keep alive" multiple connections.
|
|
53
51
|
- Users automatically generate schema from code; schemas are part of the core contract of an INTERSECT microservice, and both external inputs and microservice outputs are required to uphold this contract.
|
|
54
52
|
|
|
55
53
|
## Authors
|
|
@@ -19,7 +19,8 @@ For a high-level overview, please see [the architecture website.](https://inters
|
|
|
19
19
|
|
|
20
20
|
- Event-driven architecture
|
|
21
21
|
- Support core interaction types: request/response, events, commands, statuses
|
|
22
|
-
- Borrows several concepts from [AsyncAPI](https://www.asyncapi.com/docs/reference/specification/latest), and intends to support multiple different protocols. Currently, we support MQTT
|
|
22
|
+
- Borrows several concepts from [AsyncAPI](https://www.asyncapi.com/docs/reference/specification/latest), and intends to support multiple different protocols. Currently, we support MQTT 5.0 and AMQP 0.9.1, but other protocols will be supported as well.
|
|
23
|
+
- As a general rule, we will not support any protocols which do not support headers, do not allow for asynchronous messaging, or require the microservice itself to "keep alive" multiple connections.
|
|
23
24
|
- Users automatically generate schema from code; schemas are part of the core contract of an INTERSECT microservice, and both external inputs and microservice outputs are required to uphold this contract.
|
|
24
25
|
|
|
25
26
|
## Authors
|
|
@@ -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 = ''
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"""The root module contains the intended public API for users of the INTERSECT-SDK.
|
|
2
|
+
|
|
3
|
+
Users should not need to import anything outside of the root.
|
|
4
|
+
|
|
5
|
+
In general, most breaking changes on version updates will relate to:
|
|
6
|
+
- Configuration classes (both adding and removing new config models). These configuration classes are relevant to the next point.
|
|
7
|
+
- When a new data service is integrated into INTERSECT, ALL adapters will need to update to support this data service, which will include new dependencies.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from importlib import import_module
|
|
11
|
+
from typing import TYPE_CHECKING
|
|
12
|
+
|
|
13
|
+
# import everything eagerly for IDEs/LSPs
|
|
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
|
+
|
|
27
|
+
from .app_lifecycle import default_intersect_lifecycle_loop
|
|
28
|
+
from .capability.base import IntersectBaseCapabilityImplementation
|
|
29
|
+
from .client import IntersectClient
|
|
30
|
+
from .client_callback_definitions import (
|
|
31
|
+
INTERSECT_CLIENT_EVENT_CALLBACK_TYPE,
|
|
32
|
+
INTERSECT_CLIENT_RESPONSE_CALLBACK_TYPE,
|
|
33
|
+
IntersectClientCallback,
|
|
34
|
+
)
|
|
35
|
+
from .config.client import IntersectClientConfig
|
|
36
|
+
from .config.service import IntersectServiceConfig
|
|
37
|
+
from .exceptions import IntersectCapabilityError
|
|
38
|
+
from .schema import get_schema_from_capability_implementations
|
|
39
|
+
from .service import IntersectService
|
|
40
|
+
from .service_callback_definitions import (
|
|
41
|
+
INTERSECT_SERVICE_RESPONSE_CALLBACK_TYPE,
|
|
42
|
+
)
|
|
43
|
+
from .service_definitions import (
|
|
44
|
+
IntersectEventDefinition,
|
|
45
|
+
intersect_message,
|
|
46
|
+
intersect_status,
|
|
47
|
+
)
|
|
48
|
+
from .shared_callback_definitions import (
|
|
49
|
+
INTERSECT_JSON_VALUE,
|
|
50
|
+
INTERSECT_RESPONSE_VALUE,
|
|
51
|
+
IntersectDirectMessageParams,
|
|
52
|
+
IntersectEventMessageParams,
|
|
53
|
+
)
|
|
54
|
+
from .version import __version__
|
|
55
|
+
|
|
56
|
+
__all__ = (
|
|
57
|
+
'INTERSECT_CLIENT_EVENT_CALLBACK_TYPE',
|
|
58
|
+
'INTERSECT_CLIENT_RESPONSE_CALLBACK_TYPE',
|
|
59
|
+
'INTERSECT_JSON_VALUE',
|
|
60
|
+
'INTERSECT_RESPONSE_VALUE',
|
|
61
|
+
'INTERSECT_SERVICE_RESPONSE_CALLBACK_TYPE',
|
|
62
|
+
'ControlPlaneConfig',
|
|
63
|
+
'ControlProvider',
|
|
64
|
+
'DataStoreConfig',
|
|
65
|
+
'DataStoreConfigMap',
|
|
66
|
+
'HierarchyConfig',
|
|
67
|
+
'IntersectBaseCapabilityImplementation',
|
|
68
|
+
'IntersectCapabilityError',
|
|
69
|
+
'IntersectClient',
|
|
70
|
+
'IntersectClientCallback',
|
|
71
|
+
'IntersectClientConfig',
|
|
72
|
+
'IntersectDataHandler',
|
|
73
|
+
'IntersectDirectMessageParams',
|
|
74
|
+
'IntersectEventDefinition',
|
|
75
|
+
'IntersectEventMessageParams',
|
|
76
|
+
'IntersectMimeType',
|
|
77
|
+
'IntersectService',
|
|
78
|
+
'IntersectServiceConfig',
|
|
79
|
+
'__version__',
|
|
80
|
+
'default_intersect_lifecycle_loop',
|
|
81
|
+
'get_schema_from_capability_implementations',
|
|
82
|
+
'intersect_message',
|
|
83
|
+
'intersect_sdk_version_info',
|
|
84
|
+
'intersect_sdk_version_string',
|
|
85
|
+
'intersect_status',
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
# PEP 562 stuff: do lazy imports for people who just want to import from the top-level module
|
|
89
|
+
# [0] = package, [1] = path to module within package
|
|
90
|
+
__lazy_imports = {
|
|
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'),
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def __getattr__(attr_name: str) -> object:
|
|
152
|
+
attr_module = __lazy_imports.get(attr_name)
|
|
153
|
+
if attr_module:
|
|
154
|
+
module = import_module(attr_module[1], package=attr_module[0])
|
|
155
|
+
return getattr(module, attr_name)
|
|
156
|
+
|
|
157
|
+
msg = f'module {__name__!r} has no attribute {attr_name!r}'
|
|
158
|
+
raise AttributeError(msg)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def __dir__() -> list[str]:
|
|
162
|
+
return list(__all__)
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
BASE_RESPONSE_ATTR = '__is_intersect_response__'
|
|
2
2
|
BASE_STATUS_ATTR = '__is_intersect_status__'
|
|
3
|
-
BASE_EVENT_ATTR = '__is_intersect_event__'
|
|
4
3
|
# in theory, as long as the next attributes are unique, they can be any string
|
|
5
4
|
REQUEST_CONTENT = '__request_content_type__'
|
|
6
5
|
RESPONSE_CONTENT = '__response_content_type__'
|
|
7
6
|
RESPONSE_DATA = '__response_data_transfer_handler__'
|
|
8
7
|
STRICT_VALIDATION = '__strict_validation__'
|
|
9
8
|
SHUTDOWN_KEYS = '__ignore_message__'
|
|
10
|
-
EVENT_ATTR_KEY = '__intersect_sdk_events__'
|
|
@@ -15,10 +15,6 @@ class EventMetadata(NamedTuple):
|
|
|
15
15
|
NOTE: both this class and all properties in it should remain immutable after creation
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
|
-
operations: set[str]
|
|
19
|
-
"""
|
|
20
|
-
A hash set of operations which advertise this event
|
|
21
|
-
"""
|
|
22
18
|
type: type
|
|
23
19
|
"""
|
|
24
20
|
The actual type of the event
|
|
@@ -53,8 +49,8 @@ def definition_metadata_differences(
|
|
|
53
49
|
differences.append(
|
|
54
50
|
(
|
|
55
51
|
'content_type',
|
|
56
|
-
f'{definition.content_type
|
|
57
|
-
f'{metadata.content_type
|
|
52
|
+
f'{definition.content_type}',
|
|
53
|
+
f'{metadata.content_type}',
|
|
58
54
|
)
|
|
59
55
|
)
|
|
60
56
|
if definition.data_handler != metadata.data_transfer_handler:
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Literal, NamedTuple
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from pydantic import TypeAdapter
|
|
7
|
+
|
|
8
|
+
from ..core_definitions import IntersectDataHandler, IntersectMimeType
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class FunctionMetadata(NamedTuple):
|
|
12
|
+
"""Internal cache of public function metadata.
|
|
13
|
+
|
|
14
|
+
NOTE: both this class and all properties in it should remain immutable after creation
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
capability: type
|
|
18
|
+
"""
|
|
19
|
+
The type of the class that implements the target method.
|
|
20
|
+
"""
|
|
21
|
+
request_adapter: TypeAdapter[Any] | Literal[0] | None
|
|
22
|
+
"""
|
|
23
|
+
Type adapter for serializing and validating requests.
|
|
24
|
+
|
|
25
|
+
Null if user did not specify a request parameter.
|
|
26
|
+
0 if user did specify a request parameter, but Content-Type does not require a TypeAdapter.
|
|
27
|
+
"""
|
|
28
|
+
response_adapter: TypeAdapter[Any] | Literal[0]
|
|
29
|
+
"""
|
|
30
|
+
Type adapter for serializing and validating responses.
|
|
31
|
+
0 if Content-Type does not require a TypeAdapter.
|
|
32
|
+
"""
|
|
33
|
+
request_content_type: IntersectMimeType
|
|
34
|
+
"""
|
|
35
|
+
Content-Type of the request value
|
|
36
|
+
"""
|
|
37
|
+
response_content_type: IntersectMimeType
|
|
38
|
+
"""
|
|
39
|
+
Content-Type of the response value
|
|
40
|
+
"""
|
|
41
|
+
response_data_transfer_handler: IntersectDataHandler
|
|
42
|
+
"""
|
|
43
|
+
How we intend on handling the response value
|
|
44
|
+
"""
|
|
45
|
+
strict_validation: bool
|
|
46
|
+
"""
|
|
47
|
+
Whether or not we're using lenient Pydantic validation (default, False) or strict
|
|
48
|
+
"""
|
|
49
|
+
shutdown_keys: set[str]
|
|
50
|
+
"""
|
|
51
|
+
keys which should cause the function to be skipped if set
|
|
52
|
+
"""
|
|
@@ -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
|
)
|
|
@@ -21,13 +22,13 @@ class IntersectEventObserver(Protocol):
|
|
|
21
22
|
Used as the common interface for event emitters (i.e. CapabilityImplementations).
|
|
22
23
|
"""
|
|
23
24
|
|
|
24
|
-
def _on_observe_event(self, event_name: str, event_value: Any,
|
|
25
|
+
def _on_observe_event(self, event_name: str, event_value: Any, capability_name: str) -> None:
|
|
25
26
|
"""How to react to an event being fired.
|
|
26
27
|
|
|
27
28
|
Args:
|
|
28
29
|
event_name: The key of the event which is fired.
|
|
29
30
|
event_value: The value of the event which is fired.
|
|
30
|
-
|
|
31
|
+
capability_name: The name of the capability which fired the event.
|
|
31
32
|
"""
|
|
32
33
|
...
|
|
33
34
|
|
|
@@ -52,6 +53,7 @@ class IntersectEventObserver(Protocol):
|
|
|
52
53
|
def register_event(
|
|
53
54
|
self,
|
|
54
55
|
service: HierarchyConfig,
|
|
56
|
+
capability_name: str,
|
|
55
57
|
event_name: str,
|
|
56
58
|
response_handler: INTERSECT_CLIENT_EVENT_CALLBACK_TYPE,
|
|
57
59
|
) -> None:
|
|
@@ -59,6 +61,7 @@ class IntersectEventObserver(Protocol):
|
|
|
59
61
|
|
|
60
62
|
Params:
|
|
61
63
|
- service: HierarchyConfig of the service we want to talk to
|
|
64
|
+
- capability_name: name of capability which will fire off the event
|
|
62
65
|
- event_name: name of event to subscribe to
|
|
63
66
|
- response_handler: callback for how to handle the reception of an event
|
|
64
67
|
"""
|
{intersect_sdk-0.8.4 → intersect_sdk-0.9.1}/src/intersect_sdk/_internal/pydantic_schema_generator.py
RENAMED
|
@@ -3,10 +3,7 @@
|
|
|
3
3
|
See: https://docs.pydantic.dev/latest/api/json_schema/#pydantic.json_schema.GenerateJsonSchema
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
-
from __future__ import annotations
|
|
7
|
-
|
|
8
6
|
from typing import (
|
|
9
|
-
TYPE_CHECKING,
|
|
10
7
|
Any,
|
|
11
8
|
)
|
|
12
9
|
|
|
@@ -20,10 +17,7 @@ from pydantic.json_schema import (
|
|
|
20
17
|
JsonSchemaValue,
|
|
21
18
|
)
|
|
22
19
|
from pydantic.type_adapter import _type_has_config
|
|
23
|
-
from pydantic_core import PydanticSerializationError, to_jsonable_python
|
|
24
|
-
|
|
25
|
-
if TYPE_CHECKING:
|
|
26
|
-
from pydantic_core import CoreSchema, core_schema
|
|
20
|
+
from pydantic_core import CoreSchema, PydanticSerializationError, core_schema, to_jsonable_python
|
|
27
21
|
|
|
28
22
|
|
|
29
23
|
# build nested dictionary from list of keys. i.e. if keys = ['one', 'two', 'three']
|