Skip to content

Commit d2f2ada

Browse files
committed
feat: enhance target setting handling and validation across components, update documentation, and add related tests
1 parent 1ca9c22 commit d2f2ada

21 files changed

Lines changed: 297 additions & 72 deletions

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
## [4.0.1] - unreleased
99
### Added
1010
- Add default target support to `target(...)`, allowing `target("OperationName")` to populate the generated setting initial expression, production Host setting, and graph edge once the named target item exists.
11+
- Allow `ComponentRef.connect(...)` to accept class-declared `target()` descriptors, supporting static-friendly calls such as `rest.connect(Rest.Output, operation)`.
12+
- Add package typing metadata with `py.typed` and explicit `ComponentRef` return annotations for production factory methods.
1113

1214
### Fixed
1315
- Expose declared and manual target settings through `dir(ComponentRef)` so `rest.my_target` style graph handles are discoverable by runtime autocomplete.
16+
- Validate target setting values that reference missing production items.
17+
- Render generated instance-style Python routes with `component.connect(...)`.
1418
- Refactor business process and operation message dispatch around normalized message keys for `@handler`, typed methods, legacy `DISPATCH`, and native IRIS requests.
1519

1620
## [4.0.0] - 2026-06-21

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class HelloOperation(BusinessOperation):
4444
prod = Production("HelloWorld.Production", testing_enabled=True)
4545
service = prod.service("HelloService", HelloService)
4646
operation = prod.operation("HelloOperation", HelloOperation)
47-
prod.connect(service.Output, operation)
47+
service.connect(HelloService.Output, operation)
4848

4949
PRODUCTIONS = [prod]
5050
```

docs/cookbooks/add-business-operation.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ If another component sends to the operation, declare a `target()` setting on the
9393
sender and connect it:
9494

9595
```python
96-
prod.connect(process.Orders, operation)
96+
process = prod.process("OrderProcess", OrderProcess)
97+
process.connect(OrderProcess.Orders, operation)
9798
```
9899

99100
## Migration Command

docs/cookbooks/add-business-process.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ process = prod.process("OrderProcess", OrderProcess)
8585
accepted = prod.operation("AcceptedOperation", AcceptedOperation)
8686
rejected = prod.operation("RejectedOperation", RejectedOperation)
8787

88-
prod.connect(process.Accepted, accepted)
89-
prod.connect(process.Rejected, rejected)
88+
process.connect(OrderProcess.Accepted, accepted)
89+
process.connect(OrderProcess.Rejected, rejected)
9090
```
9191

9292
## Migration Command
@@ -113,4 +113,3 @@ iop --migrate settings.py
113113
intended precedence explicit.
114114
- Calling a downstream component directly instead of sending a production
115115
message through a target.
116-

docs/cookbooks/add-polling-service.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ In `settings.py`:
5555
```python
5656
service = prod.service("FilePollService", FilePollService)
5757
operation = prod.operation("TargetOperation", TargetOperation)
58-
prod.connect(service.Output, operation)
58+
service.connect(FilePollService.Output, operation)
5959
```
6060

6161
## Migration Command

docs/cookbooks/hello-world-production.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ prod = Production("HelloWorld.Production", testing_enabled=True)
7474

7575
service = prod.service("HelloService", HelloService)
7676
operation = prod.operation("HelloOperation", HelloOperation)
77-
prod.connect(service.Output, operation)
77+
service.connect(HelloService.Output, operation)
7878

7979
PRODUCTIONS = [prod]
8080
```

docs/cookbooks/production-settings-and-targets.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Implementation requirements:
2424
- Add services with prod.service(...), processes with prod.process(...), and
2525
operations with prod.operation(...).
2626
- Use target() attributes on component classes for outbound routing.
27-
- Use prod.connect(source.TargetName, destination) for graph edges.
27+
- Use component.connect(ComponentClass.TargetName, destination) for graph edges.
2828
- Keep PRODUCTIONS = [prod] as the migration entrypoint.
2929
- Do not add raw CLASSES entries for components already declared in the
3030
Production graph.
@@ -51,8 +51,8 @@ process = prod.process("RouteProcess", RouteProcess)
5151
accepted = prod.operation("AcceptedOperation", AcceptedOperation)
5252
rejected = prod.operation("RejectedOperation", RejectedOperation)
5353

54-
prod.connect(process.Accepted, accepted)
55-
prod.connect(process.Rejected, rejected)
54+
process.connect(RouteProcess.Accepted, accepted)
55+
process.connect(RouteProcess.Rejected, rejected)
5656
```
5757

5858
When a route should have a conventional default, pass the target item name to

docs/getting-started/first-steps.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ prod = Production("HelloWorld.Production", testing_enabled=True)
126126

127127
service = prod.service("HelloService", HelloService)
128128
operation = prod.operation("HelloOperation", HelloOperation)
129-
prod.connect(service.Output, operation)
129+
service.connect(HelloService.Output, operation)
130130

131131
PRODUCTIONS = [prod]
132132
```
@@ -136,7 +136,7 @@ In this production:
136136
- `Production("HelloWorld.Production")` declares the IRIS production class.
137137
- `prod.service("HelloService", HelloService)` adds one service item.
138138
- `prod.operation("HelloOperation", HelloOperation)` adds one operation item.
139-
- `prod.connect(service.Output, operation)` sets the service `Output` target to `HelloOperation` and records the production graph edge.
139+
- `service.connect(HelloService.Output, operation)` sets the service `Output` target to `HelloOperation` and records the production graph edge.
140140
- `PRODUCTIONS = [prod]` tells IoP what to migrate.
141141

142142
You do not need a separate `CLASSES` dictionary for these production components. IoP registers Python component classes from the `Production` graph during migration.

docs/getting-started/register-component.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class OrderOperation(BusinessOperation):
4040
prod = Production("Demo.Production", testing_enabled=True)
4141
file = prod.service("FileInput", FileService)
4242
orders = prod.operation("OrderOperation", OrderOperation)
43-
prod.connect(file.Output, orders)
43+
file.connect(FileService.Output, orders)
4444

4545
PRODUCTIONS = [prod]
4646
```
@@ -55,7 +55,7 @@ Migration registers the generated IRIS proxy classes for `FileService` and
5555
`OrderOperation`, then saves `Demo.Production`.
5656

5757
`target()` declares a configurable outbound target setting on the component
58-
class. `prod.connect(file.Output, orders)` sets that setting to the destination
58+
class. `file.connect(FileService.Output, orders)` sets that setting to the destination
5959
component and records the production graph edge.
6060

6161
When you need to test `FileService` at runtime, do not use `iop --test`.

docs/index.md

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,51 +8,61 @@
88

99
Welcome to the **Interoperability On Python (IoP)** proof of concept! This project demonstrates how the **IRIS Interoperability Framework** can be utilized with a **Python-first approach**.
1010

11+
Documentation can be found [here](https://grongierisc.github.io/interoperability-embedded-python/).
12+
For prompt-driven workflows, see [AI-assisted coding with IoP](https://grongierisc.github.io/interoperability-embedded-python/ai-coding/).
13+
For task-oriented examples, see the [IoP cookbooks](https://grongierisc.github.io/interoperability-embedded-python/cookbooks/).
14+
For application repositories, start from the [reusable AGENTS.md template](https://grongierisc.github.io/interoperability-embedded-python/agents-template/).
15+
1116
## Example
1217

13-
Here's a simple example of how a Business Operation can be implemented in Python:
18+
Here's a tiny Python-authored production:
1419

1520
```python
16-
from iop import BusinessOperation
21+
from dataclasses import dataclass
1722

18-
class MyBo(BusinessOperation):
19-
def on_message(self, request):
20-
self.log_info("Hello World")
21-
```
23+
from iop import BusinessOperation, Message, PollingBusinessService, Production, target
2224

23-
## Installation
2425

25-
To start using this proof of concept, install it using pip:
26+
@dataclass
27+
class HelloRequest(Message):
28+
text: str = "Hello World"
2629

27-
```bash
28-
pip install iris-pex-embedded-python
29-
```
3030

31-
with zpm/ipm:
31+
class HelloService(PollingBusinessService):
32+
Output = target()
3233

33-
install zpm :
34+
def on_poll(self):
35+
self.send_request_async(self.Output, HelloRequest())
3436

35-
```objectscript
36-
set r = ##class(%Net.HttpRequest).%New(),r.Server="pm.community.intersystems.com",r.SSLConfiguration="ISC.FeatureTracker.SSL.Config" d r.Get("/packages/zpm/0.9.0/installer"),$system.OBJ.LoadStream(r.HttpResponse.Data,"c")
37-
```
3837

39-
Then install the package:
38+
class HelloOperation(BusinessOperation):
39+
def on_message(self, request: HelloRequest):
40+
self.log_info(request.text)
41+
return request
42+
4043

41-
```objectscript
42-
zpm "install pex-embbeded-python"
44+
prod = Production("HelloWorld.Production", testing_enabled=True)
45+
service = prod.service("HelloService", HelloService)
46+
operation = prod.operation("HelloOperation", HelloOperation)
47+
service.connect(HelloService.Output, operation)
48+
49+
PRODUCTIONS = [prod]
4350
```
4451

52+
## Installation
4553

46-
## Getting Started
54+
To start using this proof of concept, install it using pip:
4755

48-
If you're new to this proof of concept, begin by reading the [installation guide](getting-started/installation.md). Then, follow the [first steps](getting-started/first-steps.md) to create your first Python-authored production.
56+
```bash
57+
pip install iris-pex-embedded-python
58+
```
59+
60+
## Getting Started
4961

50-
If you are using an AI coding assistant, start with [AI-assisted coding with IoP](ai-coding.md).
51-
For concrete workflows, use the [IoP cookbooks](cookbooks/index.md).
52-
For application repositories, copy the [reusable AGENTS.md template](agents-template.md).
53-
For healthcare productions, also see [Healthcare AI-assisted coding](healthcare-ai-coding.md).
62+
If you're new to this project, begin by reading the [installation guide](https://grongierisc.github.io/interoperability-embedded-python/getting-started/installation). Then, follow the [first steps](https://grongierisc.github.io/interoperability-embedded-python/getting-started/first-steps) to create your first Python-authored production.
5463

55-
For the Pythonic production graph model, see [Production Graph](production-graph.md).
56-
For safe changes to existing IRIS productions, see the [production change workflow](production-change-workflow.md).
64+
If you are using an AI coding assistant, start with [AI-assisted coding with IoP](https://grongierisc.github.io/interoperability-embedded-python/ai-coding/).
65+
For concrete workflows, use the [IoP cookbooks](https://grongierisc.github.io/interoperability-embedded-python/cookbooks/).
66+
For healthcare productions, also see [Healthcare AI-assisted coding](https://grongierisc.github.io/interoperability-embedded-python/healthcare-ai-coding/).
5767

5868
Happy coding!

0 commit comments

Comments
 (0)