iris-pex-embedded-python 4.0.1b1__tar.gz → 4.0.1b3__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 (145) hide show
  1. {iris_pex_embedded_python-4.0.1b1/src/iris_pex_embedded_python.egg-info → iris_pex_embedded_python-4.0.1b3}/PKG-INFO +30 -6
  2. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/README.md +29 -5
  3. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/agents-template.md +4 -2
  4. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/ai-coding.md +1 -0
  5. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/command-line.md +4 -0
  6. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/component-interaction.md +44 -27
  7. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/cookbooks/code-index.md +6 -0
  8. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/example.md +32 -17
  9. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/getting-started/register-component.md +6 -3
  10. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/python-api.md +34 -23
  11. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/settings.md +25 -8
  12. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/pyproject.toml +1 -1
  13. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/__init__.py +2 -2
  14. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/components/business_service.py +12 -16
  15. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/messages/dispatch.py +38 -1
  16. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/migration/utils.py +16 -16
  17. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3/src/iris_pex_embedded_python.egg-info}/PKG-INFO +30 -6
  18. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/AGENTS.md +0 -0
  19. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/LICENSE +0 -0
  20. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/MANIFEST.in +0 -0
  21. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/benchmarks.md +0 -0
  22. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/changelog.md +0 -0
  23. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/code-of-conduct.md +0 -0
  24. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/contributing.md +0 -0
  25. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/cookbooks/add-business-operation.md +0 -0
  26. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/cookbooks/add-business-process.md +0 -0
  27. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/cookbooks/add-polling-service.md +0 -0
  28. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/cookbooks/fhir-submission-python-client.md +0 -0
  29. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/cookbooks/hello-world-production.md +0 -0
  30. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/cookbooks/hl7v2-native-input.md +0 -0
  31. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/cookbooks/hl7v2-to-fhir-with-fhir-converter.md +0 -0
  32. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/cookbooks/index.md +0 -0
  33. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/cookbooks/production-settings-and-targets.md +0 -0
  34. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/cookbooks/remote-migration.md +0 -0
  35. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/credits.md +0 -0
  36. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/debug.md +0 -0
  37. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/dtl.md +0 -0
  38. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/getting-started/first-steps.md +0 -0
  39. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/getting-started/installation.md +0 -0
  40. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/healthcare-ai-coding.md +0 -0
  41. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/index.md +0 -0
  42. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/logging.md +0 -0
  43. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/prod-settings.md +0 -0
  44. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/production-change-workflow.md +0 -0
  45. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/production-graph.md +0 -0
  46. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/rest-api.md +0 -0
  47. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/useful-links.md +0 -0
  48. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/venv.md +0 -0
  49. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/docs/wrapper.md +0 -0
  50. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/mkdocs.yml +0 -0
  51. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/setup.cfg +0 -0
  52. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/__main__.py +0 -0
  53. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cli/__init__.py +0 -0
  54. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cli/formatting.py +0 -0
  55. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cli/main.py +0 -0
  56. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cli/parser.py +0 -0
  57. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cli/types.py +0 -0
  58. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/BusinessOperation.cls +0 -0
  59. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/BusinessProcess.cls +0 -0
  60. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/BusinessService.cls +0 -0
  61. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/Common.cls +0 -0
  62. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/Director.cls +0 -0
  63. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/Duplex/Operation.cls +0 -0
  64. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/Duplex/Process.cls +0 -0
  65. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/Duplex/Service.cls +0 -0
  66. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/Generator/Message/Ack.cls +0 -0
  67. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/Generator/Message/Poll.cls +0 -0
  68. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/Generator/Message/Start.cls +0 -0
  69. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/Generator/Message/StartPickle.cls +0 -0
  70. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/Generator/Message/Stop.cls +0 -0
  71. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/InboundAdapter.cls +0 -0
  72. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/Message/JSONSchema.cls +0 -0
  73. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/Message.cls +0 -0
  74. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/OutboundAdapter.cls +0 -0
  75. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/PickleMessage.cls +0 -0
  76. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/PrivateSession/Duplex.cls +0 -0
  77. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/PrivateSession/Message/Ack.cls +0 -0
  78. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/PrivateSession/Message/Poll.cls +0 -0
  79. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/PrivateSession/Message/Start.cls +0 -0
  80. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/PrivateSession/Message/Stop.cls +0 -0
  81. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/Projection.cls +0 -0
  82. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/Service/Remote/Handler.cls +0 -0
  83. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/Service/Remote/Rest/v1.cls +0 -0
  84. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/Test.cls +0 -0
  85. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/Utils.cls +0 -0
  86. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/cls/IOP/Wrapper.cls +0 -0
  87. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/components/__init__.py +0 -0
  88. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/components/async_request.py +0 -0
  89. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/components/business_host.py +0 -0
  90. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/components/business_operation.py +0 -0
  91. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/components/business_process.py +0 -0
  92. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/components/common.py +0 -0
  93. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/components/debugpy.py +0 -0
  94. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/components/generator_request.py +0 -0
  95. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/components/inbound_adapter.py +0 -0
  96. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/components/log_manager.py +0 -0
  97. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/components/outbound_adapter.py +0 -0
  98. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/components/polling_business_service.py +0 -0
  99. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/components/private_session_duplex.py +0 -0
  100. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/components/private_session_process.py +0 -0
  101. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/components/settings.py +0 -0
  102. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/messages/__init__.py +0 -0
  103. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/messages/base.py +0 -0
  104. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/messages/decorators.py +0 -0
  105. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/messages/persistent.py +0 -0
  106. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/messages/serialization.py +0 -0
  107. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/messages/validation.py +0 -0
  108. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/migration/__init__.py +0 -0
  109. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/migration/io.py +0 -0
  110. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/migration/manifest.py +0 -0
  111. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/migration/plans.py +0 -0
  112. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/production/__init__.py +0 -0
  113. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/production/actions.py +0 -0
  114. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/production/common.py +0 -0
  115. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/production/component.py +0 -0
  116. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/production/declarations.py +0 -0
  117. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/production/declarative.py +0 -0
  118. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/production/diff.py +0 -0
  119. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/production/import_.py +0 -0
  120. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/production/inspection.py +0 -0
  121. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/production/model.py +0 -0
  122. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/production/planning.py +0 -0
  123. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/production/reconstruction.py +0 -0
  124. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/production/rendering.py +0 -0
  125. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/production/runtime.py +0 -0
  126. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/production/source_inference.py +0 -0
  127. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/production/types.py +0 -0
  128. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/production/validation.py +0 -0
  129. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/runtime/__init__.py +0 -0
  130. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/runtime/director.py +0 -0
  131. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/runtime/environment.py +0 -0
  132. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/runtime/iris.py +0 -0
  133. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/runtime/local.py +0 -0
  134. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/runtime/protocol.py +0 -0
  135. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/runtime/remote/__init__.py +0 -0
  136. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/runtime/remote/client.py +0 -0
  137. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/runtime/remote/director.py +0 -0
  138. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/runtime/remote/migration.py +0 -0
  139. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/runtime/remote/settings.py +0 -0
  140. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iop/runtime/remote/setup.py +0 -0
  141. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iris_pex_embedded_python.egg-info/SOURCES.txt +0 -0
  142. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iris_pex_embedded_python.egg-info/dependency_links.txt +0 -0
  143. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iris_pex_embedded_python.egg-info/entry_points.txt +0 -0
  144. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iris_pex_embedded_python.egg-info/requires.txt +0 -0
  145. {iris_pex_embedded_python-4.0.1b1 → iris_pex_embedded_python-4.0.1b3}/src/iris_pex_embedded_python.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iris_pex_embedded_python
3
- Version: 4.0.1b1
3
+ Version: 4.0.1b3
4
4
  Summary: Iris Interoperability based on Embedded Python
5
5
  Author-email: grongier <guillaume.rongier@intersystems.com>
6
6
  License: MIT License
@@ -69,14 +69,38 @@ For application repositories, start from the [reusable AGENTS.md template](https
69
69
 
70
70
  ## Example
71
71
 
72
- Here's a simple example of how a Business Operation can be implemented in Python:
72
+ Here's a tiny Python-authored production:
73
73
 
74
74
  ```python
75
- from iop import BusinessOperation
75
+ from dataclasses import dataclass
76
76
 
77
- class MyBo(BusinessOperation):
78
- def on_message(self, request):
79
- self.log_info("Hello World")
77
+ from iop import BusinessOperation, Message, PollingBusinessService, Production, target
78
+
79
+
80
+ @dataclass
81
+ class HelloRequest(Message):
82
+ text: str = "Hello World"
83
+
84
+
85
+ class HelloService(PollingBusinessService):
86
+ Output = target()
87
+
88
+ def on_poll(self):
89
+ self.send_request_async(self.Output, HelloRequest())
90
+
91
+
92
+ class HelloOperation(BusinessOperation):
93
+ def on_message(self, request: HelloRequest):
94
+ self.log_info(request.text)
95
+ return request
96
+
97
+
98
+ prod = Production("HelloWorld.Production", testing_enabled=True)
99
+ service = prod.service("HelloService", HelloService)
100
+ operation = prod.operation("HelloOperation", HelloOperation)
101
+ prod.connect(service.Output, operation)
102
+
103
+ PRODUCTIONS = [prod]
80
104
  ```
81
105
 
82
106
  ## Installation
@@ -15,14 +15,38 @@ For application repositories, start from the [reusable AGENTS.md template](https
15
15
 
16
16
  ## Example
17
17
 
18
- Here's a simple example of how a Business Operation can be implemented in Python:
18
+ Here's a tiny Python-authored production:
19
19
 
20
20
  ```python
21
- from iop import BusinessOperation
21
+ from dataclasses import dataclass
22
22
 
23
- class MyBo(BusinessOperation):
24
- def on_message(self, request):
25
- self.log_info("Hello World")
23
+ from iop import BusinessOperation, Message, PollingBusinessService, Production, target
24
+
25
+
26
+ @dataclass
27
+ class HelloRequest(Message):
28
+ text: str = "Hello World"
29
+
30
+
31
+ class HelloService(PollingBusinessService):
32
+ Output = target()
33
+
34
+ def on_poll(self):
35
+ self.send_request_async(self.Output, HelloRequest())
36
+
37
+
38
+ class HelloOperation(BusinessOperation):
39
+ def on_message(self, request: HelloRequest):
40
+ self.log_info(request.text)
41
+ return request
42
+
43
+
44
+ prod = Production("HelloWorld.Production", testing_enabled=True)
45
+ service = prod.service("HelloService", HelloService)
46
+ operation = prod.operation("HelloOperation", HelloOperation)
47
+ prod.connect(service.Output, operation)
48
+
49
+ PRODUCTIONS = [prod]
26
50
  ```
27
51
 
28
52
  ## Installation
@@ -79,8 +79,8 @@ Update this list for the local project:
79
79
  - Use `@dataclass` on regular `Message` classes. Do not decorate
80
80
  `PydanticMessage` classes with `@dataclass`.
81
81
  - Use `PersistentMessage` only when IRIS needs a native persistent message body.
82
- - Avoid raw `CLASSES` entries for components already declared in the production
83
- graph.
82
+ - Put new graph components in `PRODUCTIONS`; avoid raw `CLASSES` entries for
83
+ components already declared in the production graph.
84
84
  - Keep executable sample code behind `if __name__ == "__main__":` when it lives
85
85
  in a migration file.
86
86
 
@@ -91,6 +91,8 @@ Update this list for the local project:
91
91
  `submit_order(self, request: OrderRequest)`.
92
92
  - Use `@handler(MessageType)` when the handler should be explicit or the type
93
93
  annotation is not enough.
94
+ - Avoid explicit `DISPATCH` entries in new code; treat them as legacy or
95
+ advanced compatibility hooks.
94
96
  - Avoid duplicate handlers for the same message type unless the intended
95
97
  precedence is clear.
96
98
 
@@ -13,6 +13,7 @@ Read these files first:
13
13
  - local AGENTS.md, if this application repository has one
14
14
  - docs/ai-coding.md
15
15
  - docs/cookbooks/index.md
16
+ - docs/cookbooks/code-index.md, when starting from source code
16
17
  - docs/getting-started/first-steps.md
17
18
  - docs/getting-started/register-component.md
18
19
  - docs/production-graph.md
@@ -209,6 +209,10 @@ The plan uses the same sections as the migration file: `CLASSES`, `SCHEMAS`,
209
209
  components or `PersistentMessage` classes. Migration output includes the mode,
210
210
  namespace, and a final `Migration succeeded` line when the migration completes.
211
211
 
212
+ For new Python-authored production components, prefer `Production` objects in
213
+ `PRODUCTIONS`; use `CLASSES` for standalone bindings, native
214
+ `PersistentMessage` classes, and legacy migration files.
215
+
212
216
  Production validation warns by default. Pass `--strict-production-validation`
213
217
  to fail the dry-run or migration when validation reports an issue:
214
218
 
@@ -27,6 +27,11 @@ To exchange messages between components, you can use the following methods:
27
27
  - `send_multi_request_sync`: This method is used to send multiple requests synchronously. It will wait for all responses before continuing.
28
28
  - `send_generator_request`: This method is used to send a request synchronously and return a generator.
29
29
 
30
+ For new Python-authored productions, pass a `target()` attribute such as
31
+ `self.Output` to these methods and connect it in the `Production` graph with
32
+ `prod.connect(...)`. Hard-coded target component names are mainly for legacy or
33
+ manual code.
34
+
30
35
  ## send_request_sync
31
36
 
32
37
  This method is used to send a request synchronously. It will wait for a response before continuing.
@@ -34,12 +39,12 @@ This method is used to send a request synchronously. It will wait for a response
34
39
  ### Function signature
35
40
 
36
41
  ```python
37
- def send_request_sync(self, target: str, request: Union[Message, Any],
42
+ def send_request_sync(self, target: str | TargetSettingRef, request: Union[Message, Any],
38
43
  timeout: int = -1, description: Optional[str] = None) -> Any:
39
44
  """Send message synchronously to target component.
40
45
 
41
46
  Args:
42
- target: Name of target component
47
+ target: Target setting reference such as self.Output, or a target component name for legacy/manual code
43
48
  request: Message to send
44
49
  timeout: Timeout in seconds, -1 means wait forever
45
50
  description: Optional description for logging
@@ -56,15 +61,16 @@ def send_request_sync(self, target: str, request: Union[Message, Any],
56
61
  ### Example usage
57
62
 
58
63
  ```python
59
- from iop import BusinessProcess
64
+ from iop import BusinessProcess, target
60
65
  from msg import MyMessage
61
66
 
62
67
  class MyBP(BusinessProcess):
68
+ Output = target()
63
69
 
64
70
  def on_message(self, request):
65
71
  msg = MyMessage(message="Hello World")
66
72
  # Send a synchronous request to the target component
67
- response = self.send_request_sync("Python.MyBO", msg)
73
+ response = self.send_request_sync(self.Output, msg)
68
74
  self.log_info(f"Received response: {response}")
69
75
  ```
70
76
 
@@ -75,12 +81,12 @@ This method is used to send a request asynchronously. It will not wait for a res
75
81
  ### Function signature (for BusinessService and BusinessOperation)
76
82
 
77
83
  ```python
78
- def send_request_async(self, target: str, request: Union[Message, Any],
84
+ def send_request_async(self, target: str | TargetSettingRef, request: Union[Message, Any],
79
85
  description: Optional[str] = None) -> None:
80
86
  """Send message asynchronously to target component.
81
87
 
82
88
  Args:
83
- target: Name of target component
89
+ target: Target setting reference such as self.Output, or a target component name for legacy/manual code
84
90
  request: Message to send
85
91
  description: Optional description for logging
86
92
 
@@ -93,15 +99,16 @@ def send_request_async(self, target: str, request: Union[Message, Any],
93
99
  ### Example usage (for BusinessService and BusinessOperation)
94
100
 
95
101
  ```python
96
- from iop import BusinessService
102
+ from iop import BusinessService, target
97
103
  from msg import MyMessage
98
104
 
99
105
  class MyBS(BusinessService):
106
+ Output = target()
100
107
 
101
108
  def on_message(self, request):
102
109
  msg = MyMessage(message="Hello World")
103
110
  # Send an asynchronous request to the target component
104
- self.send_request_async("Python.MyBO", msg)
111
+ self.send_request_async(self.Output, msg)
105
112
  self.log_info("Request sent asynchronously")
106
113
  ```
107
114
 
@@ -111,11 +118,11 @@ directly. For regular message-driven services, prefer `on_message()`.
111
118
  ### Function signature (for BusinessProcess)
112
119
 
113
120
  ```python
114
- def send_request_async(self, target: str, request: Any, description: Optional[str]=None, completion_key: Optional[str]=None, response_required: bool=True) -> None:
121
+ def send_request_async(self, target: str | TargetSettingRef, request: Any, description: Optional[str]=None, completion_key: Optional[str]=None, response_required: bool=True) -> None:
115
122
  """Send the specified message to the target business process or business operation asynchronously.
116
123
 
117
124
  Args:
118
- target: The name of the business process or operation to receive the request
125
+ target: Target setting reference such as self.Output, or a target component name for legacy/manual code
119
126
  request: The message to send to the target
120
127
  description: An optional description property in the message header
121
128
  completion_key: A token to identify the completion of the request
@@ -130,17 +137,18 @@ def send_request_async(self, target: str, request: Any, description: Optional[st
130
137
  ### Example usage (for BusinessProcess)
131
138
 
132
139
  ```python
133
- from iop import BusinessProcess
140
+ from iop import BusinessProcess, target
134
141
  from msg import MyMessage
135
142
 
136
143
  class MyBP(BusinessProcess):
144
+ Output = target()
137
145
 
138
146
  def on_message(self, request):
139
147
  msg_one = MyMessage(message="Message1")
140
148
  msg_two = MyMessage(message="Message2")
141
149
 
142
- self.send_request_async("Python.MyBO", msg_one,completion_key="1")
143
- self.send_request_async("Python.MyBO", msg_two,completion_key="2")
150
+ self.send_request_async(self.Output, msg_one, completion_key="1")
151
+ self.send_request_async(self.Output, msg_two, completion_key="2")
144
152
 
145
153
  def on_response(self, request, response, call_request, call_response, completion_key):
146
154
  if completion_key == "1":
@@ -160,12 +168,12 @@ This method is used to send a request asynchronously using an asyncio implementa
160
168
  ### Function signature
161
169
 
162
170
  ```python
163
- async def send_request_async_ng(self, target: str, request: Union[Message, Any],
171
+ async def send_request_async_ng(self, target: str | TargetSettingRef, request: Union[Message, Any],
164
172
  timeout: int = -1, description: Optional[str] = None) -> Any:
165
173
  """Send message asynchronously to target component with asyncio.
166
174
 
167
175
  Args:
168
- target: Name of target component
176
+ target: Target setting reference such as self.Output, or a target component name for legacy/manual code
169
177
  request: Message to send
170
178
  timeout: Timeout in seconds, -1 means wait forever
171
179
  description: Optional description for logging
@@ -182,11 +190,12 @@ async def send_request_async_ng(self, target: str, request: Union[Message, Any],
182
190
  import asyncio
183
191
  import random
184
192
 
185
- from iop import BusinessProcess
193
+ from iop import BusinessProcess, target
186
194
  from msg import MyMessage
187
195
 
188
196
 
189
197
  class MyAsyncNGBP(BusinessProcess):
198
+ Output = target()
190
199
 
191
200
  def on_message(self, request):
192
201
 
@@ -201,8 +210,12 @@ class MyAsyncNGBP(BusinessProcess):
201
210
  # create 1 to 10 messages
202
211
  tasks = []
203
212
  for i in range(random.randint(1, 10)):
204
- tasks.append(self.send_request_async_ng("Python.MyAsyncNGBO",
205
- MyMessage(message=f"Message {i}")))
213
+ tasks.append(
214
+ self.send_request_async_ng(
215
+ self.Output,
216
+ MyMessage(message=f"Message {i}"),
217
+ )
218
+ )
206
219
 
207
220
  return await asyncio.gather(*tasks)
208
221
 
@@ -215,12 +228,12 @@ This method is used to send multiple requests synchronously. It will wait for al
215
228
  ### Function signature
216
229
 
217
230
  ```python
218
- def send_multi_request_sync(self, target_request: List[Tuple[str, Union[Message, Any]]],
231
+ def send_multi_request_sync(self, target_request: List[Tuple[str | TargetSettingRef, Union[Message, Any]]],
219
232
  timeout: int = -1, description: Optional[str] = None) -> List[Tuple[str, Union[Message, Any], Any, int]]:
220
233
  """Send multiple messages synchronously to target components.
221
234
 
222
235
  Args:
223
- target_request: List of tuples (target, request) to send
236
+ target_request: List of tuples (target setting reference or legacy target name, request) to send
224
237
  timeout: Timeout in seconds, -1 means wait forever
225
238
  description: Optional description for logging
226
239
 
@@ -237,18 +250,21 @@ def send_multi_request_sync(self, target_request: List[Tuple[str, Union[Message,
237
250
  ### Example usage
238
251
 
239
252
  ```python
240
- from iop import BusinessProcess
253
+ from iop import BusinessProcess, target
241
254
  from msg import MyMessage
242
255
 
243
256
 
244
257
  class MyMultiBP(BusinessProcess):
258
+ Output = target()
245
259
 
246
260
  def on_message(self, request):
247
261
  msg_one = MyMessage(message="Message1")
248
262
  msg_two = MyMessage(message="Message2")
249
263
 
250
- tuple_responses = self.send_multi_request_sync([("Python.MyMultiBO", msg_one),
251
- ("Python.MyMultiBO", msg_two)])
264
+ tuple_responses = self.send_multi_request_sync([
265
+ (self.Output, msg_one),
266
+ (self.Output, msg_two),
267
+ ])
252
268
 
253
269
  self.log_info("All requests have been processed")
254
270
  for target,request,response,status in tuple_responses:
@@ -262,11 +278,11 @@ This method is used to send a request synchronously and return a generator.
262
278
  ### Function signature
263
279
 
264
280
  ```python
265
- def send_generator_request(self, target: str, request: Union[Message, Any],
281
+ def send_generator_request(self, target: str | TargetSettingRef, request: Union[Message, Any],
266
282
  timeout: int = -1, description: Optional[str] = None) -> _GeneratorRequest:
267
283
  """Send message as a generator request to target component.
268
284
  Args:
269
- target: Name of target component
285
+ target: Target setting reference such as self.Output, or a target component name for legacy/manual code
270
286
  request: Message to send
271
287
  timeout: Timeout in seconds, -1 means wait forever
272
288
  description: Optional description for logging
@@ -282,15 +298,16 @@ This method is used to send a request synchronously and return a generator.
282
298
 
283
299
  ```python
284
300
  from typing import Any
285
- from iop import BusinessProcess,BusinessOperation
301
+ from iop import BusinessOperation, BusinessProcess, target
286
302
 
287
303
  from msg import MyGenerator,MyGeneratorResponse
288
304
 
289
305
  class MyGeneratorProcess(BusinessProcess):
306
+ Output = target()
290
307
 
291
308
  def on_request(self, request: Any) -> Any:
292
309
  gen = self.send_generator_request(
293
- target="User.MyGeneratorOperation",
310
+ target=self.Output,
294
311
  request=MyGenerator(my_string="Hello, World!"),
295
312
  timeout=10,
296
313
  description="My generator request")
@@ -31,6 +31,8 @@ the fuller cookbook workflows.
31
31
  | `src/iop/messages/base.py` | Python-only message contracts |
32
32
  | `src/iop/messages/persistent.py` | Native persistent IRIS message contracts |
33
33
  | `src/iop/messages/dispatch.py` | `@handler`, typed method dispatch, fallback `on_message()` |
34
+ | `src/iop/components/common.py` | component lifecycle hooks such as `on_init()` and `on_tear_down()` |
35
+ | `src/iop/components/business_host.py` | shared `send_request_sync(...)` and `send_request_async(...)` helpers |
34
36
  | `src/iop/components/business_process.py` | process runtime hooks and request helpers |
35
37
  | `src/iop/components/business_operation.py` | operation runtime dispatch |
36
38
  | `src/iop/components/business_service.py` | service `on_message()` and `on_process_input()` hooks |
@@ -48,6 +50,10 @@ to:
48
50
  Use `@handler(MessageType)` when the handler must be explicit. Use typed
49
51
  one-argument methods when annotations are enough.
50
52
 
53
+ Explicit `DISPATCH` entries are still supported for legacy and advanced code,
54
+ but new application code should prefer `@handler(MessageType)` or typed
55
+ one-argument methods.
56
+
51
57
  ## Message Quick Reference
52
58
 
53
59
  Use `@dataclass` with regular `Message` classes:
@@ -5,7 +5,9 @@ Python-authored production that registers them with IRIS.
5
5
 
6
6
  ## Business Operation
7
7
 
8
- Below is an example of a business operation in Python:
8
+ Below is a standalone business operation fragment. A normal application also
9
+ declares a `Production` graph and connects senders with `target()` and
10
+ `prod.connect(...)`.
9
11
 
10
12
  ```python
11
13
  from dataclasses import dataclass
@@ -80,7 +82,8 @@ iop --migrate /path/to/your/project/settings.py
80
82
  ```
81
83
 
82
84
  Use a standalone `CLASSES` entry only when you need to bind a Python component
83
- without adding it to a Python `Production` graph.
85
+ without adding it to a Python `Production` graph. New graph components belong in
86
+ `PRODUCTIONS`, where migration registers their Python classes automatically.
84
87
 
85
88
  ## Conservative Production Changes
86
89
 
@@ -113,15 +116,15 @@ Two kinds of business services can be created in Python:
113
116
  To create a business service, use the following code:
114
117
 
115
118
  ```python
116
- from iop import BusinessService
119
+ from iop import BusinessService, target
117
120
 
118
121
  class MyBusinessService(BusinessService):
122
+ Output = target()
119
123
 
120
124
  def on_message(self, message_input: 'MyRequest'):
121
125
  # This method is called when the service is called
122
126
  self.log_info("[Python] MyBusinessService:on_message() is called with message: " + message_input.request_string)
123
- response = MyResponse("MyBusinessService:on_message() echos")
124
- return response
127
+ self.send_request_async(self.Output, message_input)
125
128
  ```
126
129
 
127
130
  ### Polling Business Service
@@ -129,18 +132,21 @@ class MyBusinessService(BusinessService):
129
132
  To create a polling business service, use the following code:
130
133
 
131
134
  ```python
132
- from iop import PollingBusinessService
135
+ from iop import PollingBusinessService, target
133
136
 
134
137
  class MyBusinessService(PollingBusinessService):
138
+ Output = target()
135
139
 
136
140
  def on_poll(self):
137
141
  # This method is called by the scheduler
138
142
  self.log_info("[Python] MyBusinessService:on_poll() is called")
143
+ self.send_request_async(self.Output, MyRequest())
139
144
  ```
140
145
 
141
- ## Flask app sending a message to an Business Service
146
+ ## Flask app sending a message to a Business Service
142
147
 
143
- To send a message to a business service, use the following code:
148
+ To send a message to a deployed business service, use the runtime Director
149
+ rather than instantiating production components directly:
144
150
 
145
151
 
146
152
  ```python
@@ -191,11 +197,12 @@ To make an async call with asyncio, use the following code:
191
197
  import asyncio
192
198
  import random
193
199
 
194
- from iop import BusinessProcess
200
+ from iop import BusinessProcess, target
195
201
  from msg import MyMessage
196
202
 
197
203
 
198
204
  class MyAsyncNGBP(BusinessProcess):
205
+ Output = target()
199
206
 
200
207
  def on_message(self, request):
201
208
 
@@ -208,8 +215,12 @@ class MyAsyncNGBP(BusinessProcess):
208
215
  # create 1 to 10 messages
209
216
  tasks = []
210
217
  for i in range(random.randint(1, 10)):
211
- tasks.append(self.send_request_async_ng("Python.MyAsyncNGBO",
212
- MyMessage(message=f"Message {i}")))
218
+ tasks.append(
219
+ self.send_request_async_ng(
220
+ self.Output,
221
+ MyMessage(message=f"Message {i}"),
222
+ )
223
+ )
213
224
 
214
225
  return await asyncio.gather(*tasks)
215
226
  ```
@@ -219,18 +230,19 @@ class MyAsyncNGBP(BusinessProcess):
219
230
  To make an async call with the native `send_request_async` method, use the following code:
220
231
 
221
232
  ```python
222
- from iop import BusinessProcess
233
+ from iop import BusinessProcess, target
223
234
  from msg import MyMessage
224
235
 
225
236
 
226
237
  class MyBP(BusinessProcess):
238
+ Output = target()
227
239
 
228
240
  def on_message(self, request):
229
241
  msg_one = MyMessage(message="Message1")
230
242
  msg_two = MyMessage(message="Message2")
231
243
 
232
- self.send_request_async("Python.MyBO", msg_one,completion_key="1")
233
- self.send_request_async("Python.MyBO", msg_two,completion_key="2")
244
+ self.send_request_async(self.Output, msg_one, completion_key="1")
245
+ self.send_request_async(self.Output, msg_two, completion_key="2")
234
246
 
235
247
  def on_response(self, request, response, call_request, call_response, completion_key):
236
248
  if completion_key == "1":
@@ -248,18 +260,21 @@ class MyBP(BusinessProcess):
248
260
  To make an async call with the `send_multi_request_sync` method, use the following code:
249
261
 
250
262
  ```python
251
- from iop import BusinessProcess
263
+ from iop import BusinessProcess, target
252
264
  from msg import MyMessage
253
265
 
254
266
 
255
267
  class MyMultiBP(BusinessProcess):
268
+ Output = target()
256
269
 
257
270
  def on_message(self, request):
258
271
  msg_one = MyMessage(message="Message1")
259
272
  msg_two = MyMessage(message="Message2")
260
273
 
261
- tuple_responses = self.send_multi_request_sync([("Python.MyMultiBO", msg_one),
262
- ("Python.MyMultiBO", msg_two)])
274
+ tuple_responses = self.send_multi_request_sync([
275
+ (self.Output, msg_one),
276
+ (self.Output, msg_two),
277
+ ])
263
278
 
264
279
  self.log_info("All requests have been processed")
265
280
  for target,request,response,status in tuple_responses:
@@ -70,7 +70,7 @@ A migration file can define these sections:
70
70
  | Section | Purpose |
71
71
  |---------|---------|
72
72
  | `PRODUCTIONS` | Preferred way to register Python-authored production graphs |
73
- | `CLASSES` | Standalone bindings and native `PersistentMessage` registrations |
73
+ | `CLASSES` | Standalone or legacy component bindings and native `PersistentMessage` registrations |
74
74
  | `SCHEMAS` | JSON schemas for DTL support |
75
75
  | `REMOTE_SETTINGS` | Remote IRIS connection settings |
76
76
 
@@ -111,7 +111,8 @@ CLASSES = {
111
111
  ## Standalone Bindings
112
112
 
113
113
  Use `CLASSES` when you need to create an IRIS proxy class without putting the
114
- component in a Python `Production` graph:
114
+ component in a Python `Production` graph, usually for standalone bindings or
115
+ legacy migration files:
115
116
 
116
117
  ```python
117
118
  from bo import FileOperation
@@ -230,7 +231,9 @@ iop --bindings --unused
230
231
  ## Python Shell Utilities
231
232
 
232
233
  The Python utility functions remain available for scripting standalone
233
- bindings. The migration-file workflow is preferred for normal projects.
234
+ bindings and legacy/manual registration. The migration-file workflow with a
235
+ `Production` object in `PRODUCTIONS` is preferred for normal projects, and it
236
+ registers graph component classes automatically.
234
237
 
235
238
  ```python
236
239
  from iop import bind_component, register_component