Skip to content

Commit 2c6692f

Browse files
authored
Merge pull request #41 from INTERSECT-SDK/candidate-0.9.0
0.9.0
2 parents 2a51780 + cc17420 commit 2c6692f

113 files changed

Lines changed: 5077 additions & 3273 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ on:
44
push:
55
branches:
66
- main
7+
- candidate-*
78
pull_request:
89
types: [opened, synchronize, reopened]
910
branches:
1011
- main
12+
- candidate-*
1113
workflow_dispatch:
1214

1315
permissions:
@@ -22,7 +24,7 @@ jobs:
2224
- name: Setup PDM
2325
uses: pdm-project/setup-pdm@v4
2426
with:
25-
python-version: "3.8"
27+
python-version: "3.12"
2628
cache: true
2729
- name: Install dependencies
2830
run: |
@@ -38,7 +40,7 @@ jobs:
3840
name: Windows/MacOS unit tests
3941
strategy:
4042
matrix:
41-
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
43+
python-version: ["3.10", "3.11", "3.12", "3.13"]
4244
os:
4345
- macos-latest
4446
- windows-latest
@@ -61,13 +63,13 @@ jobs:
6163
name: Test with coverage
6264
strategy:
6365
matrix:
64-
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
66+
python-version: ["3.10", "3.11", "3.12", "3.13"]
6567
os:
6668
- ubuntu-latest
6769
runs-on: ${{ matrix.os }}
6870
services:
6971
rabbitmq:
70-
image: "bitnamilegacy/rabbitmq:3.13.3"
72+
image: "bitnamilegacy/rabbitmq:4.1"
7173
env:
7274
# space-delimited list of plugins
7375
RABBITMQ_PLUGINS: "rabbitmq_mqtt"

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ repos:
88
- id: end-of-file-fixer
99
- id: trailing-whitespace
1010
- repo: https://github.com/astral-sh/ruff-pre-commit
11-
rev: v0.9.4
11+
rev: v0.12.7
1212
hooks:
1313
- id: ruff
1414
args: [ --fix ]

CHANGELOG.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,30 @@
22

33
We follow [Common Changelog](https://common-changelog.org/) formatting for this document.
44

5+
## Unreleased
6+
7+
### Fixed
8+
9+
- namespace events and statuses to capabilities instead of services ([commit 1](https://github.com/INTERSECT-SDK/python-sdk/commit/e05e27471f05bf50e0bc5a0123f7e0133a3d969e) [commit 2](https://github.com/INTERSECT-SDK/python-sdk/commit/1460e989f70efaf9713eb77bbb4508698db3e655)) (Lance-Drane)
10+
11+
### Changed
12+
13+
- Allow user to specify whatever message Content-Type they would like in messages, and provide handling for non-JSON data types ([commit](https://github.com/INTERSECT-SDK/python-sdk/commit/dcd536ebb03973e8939e2715e51dfc3da0d8bd16)) (Lance Drane)
14+
- change events API; instead of using `@intersect_event` or `@intersect_message(events=...)`, declare all events in capability variable `intersect_sdk_events` ([commit](https://github.com/INTERSECT-SDK/python-sdk/commit/1460e989f70efaf9713eb77bbb4508698db3e655)) (Lance Drane)
15+
- move Pika (AMQP) to be a required dependency instead of an optional dependency ([commit](https://github.com/INTERSECT-SDK/python-sdk/commit/5ed5be6a51917b5598043115fb9cb176a6627a2a)) (Lance Drane)
16+
- bump required Paho MQTT version from v1 to v2 ([commit](https://github.com/INTERSECT-SDK/python-sdk/commit/d0bcb9550aa92c7ef327e313a2ad5b34d914a3b3)) (Lance Drane)
17+
- change internal message structure representation; metadata is sent through as headers, while the direct payload is always the data. This decreases the number of JSON serializations/deserializations from 2 to at most 1 (if the data is actually JSON). This does NOT modify any APIs already in use, with the exception of core services ([initial commit](https://github.com/INTERSECT-SDK/python-sdk/commit/e09f13f9b244b92b6bcecc814df49c81340dcc02#diff-725ea87422115a87ba1869854601d413f1fcac6bea0c965ce5a14e2fcb0461b1) [commit which adds campaign IDs](https://github.com/INTERSECT-SDK/python-sdk/commit/ef8db5415c97af80df267277f8ddca6347440b5e)) (Lance Drane)
18+
19+
### Added
20+
21+
- Added MQTT 5.0 support ([commit](https://github.com/INTERSECT-SDK/python-sdk/commit/e09f13f9b244b92b6bcecc814df49c81340dcc02)) (Lance Drane)
22+
- Added a default `intersect_sdk` capability meant to encompass common system querying information ([commit](https://github.com/INTERSECT-SDK/python-sdk/commit/e05e27471f05bf50e0bc5a0123f7e0133a3d969e)) (Lance Drane)
23+
24+
### Removed
25+
26+
- Dropped MQTT 3.1.1 support ([commit](https://github.com/INTERSECT-SDK/python-sdk/commit/e09f13f9b244b92b6bcecc814df49c81340dcc02)) (Lance Drane)
27+
- Dropped support for Python versions <= 3.9
28+
529
## [0.8.4] - 2026-02-05
630

731
### Fixed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ For a high-level overview, please see [the architecture website.](https://inters
1919

2020
- Event-driven architecture
2121
- 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 3.1.1 and AMQP 0.9.1, but other protocols will be supported as well.
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.
2324
- 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.
2425

2526
## Authors

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
services:
55
broker:
6-
image: "bitnamilegacy/rabbitmq:3.13.3"
6+
image: "bitnamilegacy/rabbitmq:4.1"
77
ports:
88
- "1883:1883" # MQTT port
99
- "5672:5672" # AMQP port

docs/core_concepts.rst

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,27 @@ Arguments to the ``@intersect_message()`` decorator can be used to specify speci
3838
CapabilityImplementation - Events
3939
---------------------------------
4040

41-
You can emit events globally as part of an ``@intersect_message()`` annotated function by configuring the ``events`` argument to the decorator as a dictionary/mapping of event names (as strings) to IntersectEventDefinitions.
42-
An IntersectEventDefinition consists of an event_type, which is the typing of the event you'll emit.
41+
You can emit events globally, with or without input from other INTERSECT messages.
4342

44-
You can also emit events without having to react to an external request by annotating a function with ``@intersect_event()`` and providing the ``events`` argument to the decorator.
43+
To do this, you must create a mapping of keys to ``IntersectEventDefinition`` as your BaseCapability's ``intersect_sdk_events`` class variable.
44+
An IntersectEventDefinition consists of an ``event_type``, which is the typing of the event you'll emit.
4545

46-
You can emit an event by calling ``self.intersect_sdk_emit_event(event_name, event)`` . The typing of ``event`` must match the typing in the decorator configuration.
47-
Calling this function will only be effective if called from either an ``@intersect_message`` or ``@intersect_event`` decorated function, or an inner function called from a decorated function.
46+
You can emit an event by calling ``self.intersect_sdk_emit_event(event_name, event)`` . The typing of ``event`` must match the typing of ``IntersectEventDefinition(event_type)``.
4847

49-
You can specify the same event name on multiple functions, but it must always contain the same IntersectEventDefinition configuration.
48+
A simple example of how to configure this:
49+
50+
.. code-block:: python
51+
52+
class YourCapability(IntersectBaseCapabilityImplementation):
53+
# You should configure it on the class itself. Do NOT configure it on the instance.
54+
intersect_sdk_events: ClassVar[dict[str, IntersectEventDefinition]] = {
55+
'my_integer_event': IntersectEventDefinition(event_type=int),
56+
'my_str_event': IntersectEventDefinition(event_type=str),
57+
'my_float_event': IntersectEventDefinition(event_type=float),
58+
}
59+
60+
61+
Now this capability can call ``self.intersect_sdk_emit_event('my_integer_event', value)`` as long as "value" is actually an integer.
5062

5163
Client
5264
------

docs/pydantic.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Usage
1818
External users would benefit most by understanding the `Models <https://docs.pydantic.dev/latest/concepts/models/>`_, `Fields <https://docs.pydantic.dev/latest/concepts/fields/>`_,
1919
and `Types <https://docs.pydantic.dev/latest/concepts/types/>`_ documentation pages on Pydantic's own documentation website.
2020

21-
INTERSECT-SDK will handle the schema generation logic, but users are able to customize fields themselves. For example, users can combine ``typing_extensions.Annotated``
21+
INTERSECT-SDK will handle the schema generation logic, but users are able to customize fields themselves. For example, users can combine ``typing.Annotated``
2222
with ``pydantic.Field`` to specify regular expression patterns for string, minimum lengths for arrays/lists, and many other validation concepts.
2323

2424
For handling complex objects, your class should either extend ``pydantic.BaseModel`` or be a `Python Dataclass <https://docs.python.org/3/library/dataclasses.html>`_.

examples/1_hello_world/hello_client.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import logging
22

33
from intersect_sdk import (
4-
INTERSECT_JSON_VALUE,
4+
INTERSECT_RESPONSE_VALUE,
55
IntersectClient,
66
IntersectClientCallback,
77
IntersectClientConfig,
@@ -13,7 +13,7 @@
1313

1414

1515
def simple_client_callback(
16-
_source: str, _operation: str, _has_error: bool, payload: INTERSECT_JSON_VALUE
16+
_source: str, _operation: str, _has_error: bool, payload: INTERSECT_RESPONSE_VALUE
1717
) -> None:
1818
"""This simply prints the response from the service to your console.
1919
@@ -48,7 +48,7 @@ def simple_client_callback(
4848
'username': 'intersect_username',
4949
'password': 'intersect_password',
5050
'port': 1883,
51-
'protocol': 'mqtt3.1.1',
51+
'protocol': 'mqtt5.0',
5252
},
5353
],
5454
}

examples/1_hello_world/hello_service.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class HelloServiceCapabilityImplementation(IntersectBaseCapabilityImplementation
2121
but we do not use it here.
2222
2323
The operation we are calling is `say_hello_to_name` , so the message being sent will need to have
24-
an operationId of `say_hello_to_name`. The operation expects a string sent to it in the payload,
24+
an operation_id of `say_hello_to_name`. The operation expects a string sent to it in the payload,
2525
and will send a string back in its own payload.
2626
"""
2727

@@ -50,7 +50,7 @@ def say_hello_to_name(self, name: str) -> str:
5050
'username': 'intersect_username',
5151
'password': 'intersect_password',
5252
'port': 1883,
53-
'protocol': 'mqtt3.1.1',
53+
'protocol': 'mqtt5.0',
5454
},
5555
],
5656
}

0 commit comments

Comments
 (0)