Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
dcd536e
#8 - add schema-level and service-level handling of multiple content …
Lance-Drane Jul 30, 2024
aaec825
do not include destination in lifecycle messages
Lance-Drane Mar 19, 2025
42345a2
Merge remote-tracking branch 'origin/diverse-content-types' into cand…
Lance-Drane May 20, 2025
f664bdf
add tests to ensure binary content-type annotation is always 'bytes'
Lance-Drane May 20, 2025
664e1f9
#26 - always include a base value for the schema title
Lance-Drane Jul 23, 2025
cf8d928
Merge remote-tracking branch 'origin/main' into candidate-0.9.0
Lance-Drane Jul 23, 2025
c9e06f7
fix documentation for intersect_status
Lance-Drane Jul 23, 2025
92c3894
#24 - allow INTERSECT error propagation with IntersectCapabilityError
Lance-Drane Jul 23, 2025
b645ae2
fix docstring
Lance-Drane Jul 24, 2025
e05e274
#29 - add universal capability, #23 - namespace statuses
Lance-Drane Jul 25, 2025
5a400a0
make sure IntersectSdkCoreCapability registers the Service as an obse…
Lance-Drane Jul 25, 2025
1460e98
#23 and #33 - change event API, namespace events with capabilities
Lance-Drane Aug 4, 2025
acd3218
add ability to include event documentation in events schema
Lance-Drane Aug 5, 2025
2a7cb75
provide more metadata for events in schemas
Lance-Drane Aug 6, 2025
5ed5be6
make pika a required dependency
Lance-Drane Aug 6, 2025
d0bcb95
update paho-mqtt from v1 to v2
Lance-Drane Aug 6, 2025
5a0a752
add support for mqtt v5, upgrade RabbitMQ and paho-mqtt versions
Lance-Drane Aug 13, 2025
e09f13f
#8 - refine protocol-level handling, drop MQTT 3.x support
Lance-Drane Aug 18, 2025
0f54101
Merge remote-tracking branch 'origin/main' into candidate-0.9.0
Lance-Drane Feb 5, 2026
ef8db54
#40 - include campaign ID, request ID, message ID in userspace messages
Lance-Drane Feb 6, 2026
c9a3ebf
update changelog in preparation for 0.9.0 release
Lance-Drane Feb 6, 2026
9009e59
update changelog in preparation for 0.9.0 release
Lance-Drane Feb 6, 2026
fe99083
Add candidate-* branches to CI workflow
marshallmcdonnell Feb 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ on:
push:
branches:
- main
- candidate-*
pull_request:
types: [opened, synchronize, reopened]
branches:
- main
- candidate-*
workflow_dispatch:

permissions:
Expand All @@ -22,7 +24,7 @@ jobs:
- name: Setup PDM
uses: pdm-project/setup-pdm@v4
with:
python-version: "3.8"
python-version: "3.12"
cache: true
- name: Install dependencies
run: |
Expand All @@ -38,7 +40,7 @@ jobs:
name: Windows/MacOS unit tests
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
python-version: ["3.10", "3.11", "3.12", "3.13"]
os:
- macos-latest
- windows-latest
Expand All @@ -61,7 +63,7 @@ jobs:
name: Test with coverage
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
python-version: ["3.10", "3.11", "3.12", "3.13"]
os:
- ubuntu-latest
runs-on: ${{ matrix.os }}
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ repos:
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.4
rev: v0.12.7
hooks:
- id: ruff
args: [ --fix ]
Expand Down
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,29 @@

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

## Unreleased

### Fixed

- 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)

### Changed

- 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)
- 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)
- 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)
- bump required Paho MQTT version from v1 to v2 ([commit](https://github.com/INTERSECT-SDK/python-sdk/commit/d0bcb9550aa92c7ef327e313a2ad5b34d914a3b3)) (Lance Drane)
- 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)

### Added

- Added MQTT 5.0 support ([commit](https://github.com/INTERSECT-SDK/python-sdk/commit/e09f13f9b244b92b6bcecc814df49c81340dcc02)) (Lance Drane)
- 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)

### Removed

- Dropped MQTT 3.1.1 support ([commit](https://github.com/INTERSECT-SDK/python-sdk/commit/e09f13f9b244b92b6bcecc814df49c81340dcc02)) (Lance Drane)

## [0.8.4] - 2026-02-05

### Fixed
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ For a high-level overview, please see [the architecture website.](https://inters

- Event-driven architecture
- Support core interaction types: request/response, events, commands, statuses
- 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.
- 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.
- 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.
- 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.

## Authors
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

services:
broker:
image: "bitnamilegacy/rabbitmq:3.13.3"
image: "bitnamilegacy/rabbitmq:4.1"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to change in ci.yml as well?

I am having issues with running the e2e tests locally, getting "FAILED".
(env) ntm@lap128806:python-sdk$ pdm run test-all -vvv
======================================================= test session starts =======================================================
platform linux -- Python 3.11.9, pytest-8.3.2, pluggy-1.5.0 -- /home/ntm/projects/intersect/github/python-sdk/env/bin/python
cachedir: .pytest_cache
rootdir: /home/ntm/projects/intersect/github/python-sdk
configfile: pyproject.toml
plugins: cov-5.0.0
collected 169 items

tests/e2e/test_examples.py::test_example_1_hello_world_amqp FAILED [ 0%]
tests/e2e/test_examples.py::test_example_1_hello_world_mqtt FAILED [ 1%]
tests/e2e/test_examples.py::test_example_1_hello_world_minio FAILED [ 1%]
tests/e2e/test_examples.py::test_example_1_hello_world_events ...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it does! I just forgot to fix the version on the candidate branch, as I had fixed the URI on the main branch.

ports:
- "1883:1883" # MQTT port
- "5672:5672" # AMQP port
Expand Down
24 changes: 18 additions & 6 deletions docs/core_concepts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,27 @@ Arguments to the ``@intersect_message()`` decorator can be used to specify speci
CapabilityImplementation - Events
---------------------------------

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.
An IntersectEventDefinition consists of an event_type, which is the typing of the event you'll emit.
You can emit events globally, with or without input from other INTERSECT messages.

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.
To do this, you must create a mapping of keys to ``IntersectEventDefinition`` as your BaseCapability's ``intersect_sdk_events`` class variable.
An IntersectEventDefinition consists of an ``event_type``, which is the typing of the event you'll emit.

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.
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.
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)``.

You can specify the same event name on multiple functions, but it must always contain the same IntersectEventDefinition configuration.
A simple example of how to configure this:

.. code-block:: python

class YourCapability(IntersectBaseCapabilityImplementation):
# You should configure it on the class itself. Do NOT configure it on the instance.
intersect_sdk_events: ClassVar[dict[str, IntersectEventDefinition]] = {
'my_integer_event': IntersectEventDefinition(event_type=int),
'my_str_event': IntersectEventDefinition(event_type=str),
'my_float_event': IntersectEventDefinition(event_type=float),
}


Now this capability can call ``self.intersect_sdk_emit_event('my_integer_event', value)`` as long as "value" is actually an integer.

Client
------
Expand Down
2 changes: 1 addition & 1 deletion docs/pydantic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Usage
External users would benefit most by understanding the `Models <https://docs.pydantic.dev/latest/concepts/models/>`_, `Fields <https://docs.pydantic.dev/latest/concepts/fields/>`_,
and `Types <https://docs.pydantic.dev/latest/concepts/types/>`_ documentation pages on Pydantic's own documentation website.

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

For handling complex objects, your class should either extend ``pydantic.BaseModel`` or be a `Python Dataclass <https://docs.python.org/3/library/dataclasses.html>`_.
Expand Down
6 changes: 3 additions & 3 deletions examples/1_hello_world/hello_client.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging

from intersect_sdk import (
INTERSECT_JSON_VALUE,
INTERSECT_RESPONSE_VALUE,
IntersectClient,
IntersectClientCallback,
IntersectClientConfig,
Expand All @@ -13,7 +13,7 @@


def simple_client_callback(
_source: str, _operation: str, _has_error: bool, payload: INTERSECT_JSON_VALUE
_source: str, _operation: str, _has_error: bool, payload: INTERSECT_RESPONSE_VALUE
) -> None:
"""This simply prints the response from the service to your console.

Expand Down Expand Up @@ -48,7 +48,7 @@ def simple_client_callback(
'username': 'intersect_username',
'password': 'intersect_password',
'port': 1883,
'protocol': 'mqtt3.1.1',
'protocol': 'mqtt5.0',
},
],
}
Expand Down
4 changes: 2 additions & 2 deletions examples/1_hello_world/hello_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class HelloServiceCapabilityImplementation(IntersectBaseCapabilityImplementation
but we do not use it here.

The operation we are calling is `say_hello_to_name` , so the message being sent will need to have
an operationId of `say_hello_to_name`. The operation expects a string sent to it in the payload,
an operation_id of `say_hello_to_name`. The operation expects a string sent to it in the payload,
and will send a string back in its own payload.
"""

Expand Down Expand Up @@ -50,7 +50,7 @@ def say_hello_to_name(self, name: str) -> str:
'username': 'intersect_username',
'password': 'intersect_password',
'port': 1883,
'protocol': 'mqtt3.1.1',
'protocol': 'mqtt5.0',
},
],
}
Expand Down
Loading
Loading