deriva-cli 0.8.0__tar.gz → 0.8.2__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 (199) hide show
  1. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/PKG-INFO +6 -13
  2. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/archimate/models.py +28 -14
  3. deriva_cli-0.8.2/deriva/adapters/archimate/views.py +121 -0
  4. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/archimate/xml_export.py +78 -5
  5. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/database/__init__.py +5 -0
  6. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/database/data/derivation_config.json +126 -86
  7. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/database/data/extraction_config.json +106 -4
  8. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/database/data/file_types.json +8 -0
  9. deriva_cli-0.8.2/deriva/adapters/database/data/function_models/pcf-8.0-cross-industry.csv +90 -0
  10. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/graph/__init__.py +20 -0
  11. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/graph/manager.py +56 -2
  12. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/graph/models.py +301 -5
  13. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/llm/__init__.py +0 -4
  14. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/llm/manager.py +38 -17
  15. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/llm/model_registry.py +11 -5
  16. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/llm/models.py +20 -1
  17. deriva_cli-0.8.2/deriva/adapters/llm/retry.py +147 -0
  18. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/llm/schemas.py +34 -0
  19. deriva_cli-0.8.2/deriva/adapters/treesitter/cdk.py +312 -0
  20. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/treesitter/languages/__init__.py +1 -0
  21. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/treesitter/languages/javascript.py +21 -15
  22. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/treesitter/languages/python.py +16 -15
  23. deriva_cli-0.8.2/deriva/adapters/treesitter/languages/sql.py +98 -0
  24. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/treesitter/manager.py +4 -1
  25. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/cli/cli.py +13 -0
  26. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/cli/commands/config.py +44 -16
  27. deriva_cli-0.8.2/deriva/cli/commands/graph.py +27 -0
  28. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/cli/commands/run.py +10 -0
  29. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/common/cache_utils.py +201 -36
  30. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/common/logging.py +6 -63
  31. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/common/settings.py +19 -3
  32. deriva_cli-0.8.2/deriva/modules/analysis/conventions.py +302 -0
  33. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/analysis/semantic_matching.py +17 -0
  34. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/application_service.py +3 -21
  35. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/base.py +304 -38
  36. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/business_actor.py +3 -21
  37. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/business_object.py +3 -23
  38. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/business_process.py +3 -22
  39. deriva_cli-0.8.2/deriva/modules/derivation/component_services.py +835 -0
  40. deriva_cli-0.8.2/deriva/modules/derivation/detail_level.py +83 -0
  41. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/element_base.py +224 -20
  42. deriva_cli-0.8.2/deriva/modules/derivation/function_model.py +415 -0
  43. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/refine/__init__.py +4 -8
  44. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/refine/base.py +2 -0
  45. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/refine/duplicate_elements.py +27 -107
  46. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/refine/duplicate_relationships.py +18 -38
  47. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/refine/joint.py +111 -45
  48. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/refine/joint_consistency.py +27 -52
  49. deriva_cli-0.8.2/deriva/modules/extraction/cooperation.py +242 -0
  50. deriva_cli-0.8.2/deriva/modules/extraction/data_domains.py +359 -0
  51. deriva_cli-0.8.2/deriva/modules/extraction/data_entities.py +261 -0
  52. deriva_cli-0.8.2/deriva/modules/extraction/deployable_units.py +502 -0
  53. deriva_cli-0.8.2/deriva/modules/extraction/deployments.py +657 -0
  54. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/extraction/edges.py +137 -45
  55. deriva_cli-0.8.2/deriva/modules/extraction/lifecycles.py +395 -0
  56. deriva_cli-0.8.2/deriva/modules/extraction/roles.py +91 -0
  57. deriva_cli-0.8.2/deriva/modules/extraction/step_tags.py +135 -0
  58. deriva_cli-0.8.2/deriva/modules/extraction/technologies.py +63 -0
  59. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/extraction/type_definition.py +2 -0
  60. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/services/about.py +16 -1
  61. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/services/config.py +29 -1
  62. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/services/config_models.py +2 -2
  63. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/services/derivation.py +513 -63
  64. deriva_cli-0.8.2/deriva/services/export_levels.py +71 -0
  65. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/services/extraction.py +935 -18
  66. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/services/llm_log.py +2 -0
  67. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/services/model_configs.py +12 -1
  68. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/services/session.py +55 -9
  69. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/pyproject.toml +61 -14
  70. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/pyproject.toml.orig +39 -18
  71. deriva_cli-0.8.0/deriva/adapters/llm/retry.py +0 -421
  72. deriva_cli-0.8.0/deriva/modules/derivation/component_services.py +0 -265
  73. deriva_cli-0.8.0/deriva/modules/derivation/refine/circular_relationships.py +0 -251
  74. deriva_cli-0.8.0/deriva/modules/derivation/refine/relationship_consolidation.py +0 -299
  75. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/LICENSE +0 -0
  76. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/archimate/README.md +0 -0
  77. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/archimate/__init__.py +0 -0
  78. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/archimate/archimate_xsd/documentation/Diagram.html +0 -0
  79. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/archimate/archimate_xsd/documentation/View.html +0 -0
  80. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/archimate/archimate_xsd/documentation/model.html +0 -0
  81. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/archimate/archimate_xsd/examples/archimate3_Diagram.xsd +0 -0
  82. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/archimate/archimate_xsd/examples/archimate3_Model.xsd +0 -0
  83. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/archimate/archimate_xsd/examples/archimate3_View.xsd +0 -0
  84. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/archimate/archimate_xsd/schemas/archimate3_Diagram.xsd +0 -0
  85. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/archimate/archimate_xsd/schemas/archimate3_Model.xsd +0 -0
  86. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/archimate/archimate_xsd/schemas/archimate3_View.xsd +0 -0
  87. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/archimate/archimate_xsd/snippets/Interoperability testing snippet-1.xml +0 -0
  88. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/archimate/archimate_xsd/snippets/Interoperability testing snippet-10.xml +0 -0
  89. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/archimate/archimate_xsd/snippets/Interoperability testing snippet-2.xml +0 -0
  90. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/archimate/archimate_xsd/snippets/Interoperability testing snippet-3.xml +0 -0
  91. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/archimate/archimate_xsd/snippets/Interoperability testing snippet-4.xml +0 -0
  92. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/archimate/archimate_xsd/snippets/Interoperability testing snippet-5.xml +0 -0
  93. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/archimate/archimate_xsd/snippets/Interoperability testing snippet-7.xml +0 -0
  94. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/archimate/archimate_xsd/snippets/Interoperability testing snippet-8.xml +0 -0
  95. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/archimate/archimate_xsd/snippets/Interoperability testing snippet-9.xml +0 -0
  96. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/archimate/manager.py +0 -0
  97. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/archimate/validation.py +0 -0
  98. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/database/README.md +0 -0
  99. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/database/data/derivation_patterns.json +0 -0
  100. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/database/data/system_settings.json +0 -0
  101. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/database/db_tool.py +0 -0
  102. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/database/manager.py +0 -0
  103. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/database/scripts/7_extraction_params.sql +0 -0
  104. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/database/scripts/schema.sql +0 -0
  105. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/grafeo/__init__.py +0 -0
  106. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/grafeo/manager.py +0 -0
  107. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/graph/README.md +0 -0
  108. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/graph/cache.py +0 -0
  109. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/graph/metamodel.py +0 -0
  110. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/llm/README.md +0 -0
  111. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/llm/cache.py +0 -0
  112. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/llm/rate_limiter.py +0 -0
  113. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/nlp/__init__.py +0 -0
  114. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/nlp/extract.py +0 -0
  115. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/nlp/language.py +0 -0
  116. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/nlp/manager.py +0 -0
  117. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/nlp/models.py +0 -0
  118. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/nlp/phrases.py +0 -0
  119. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/nlp/settings.py +0 -0
  120. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/nlp/text.py +0 -0
  121. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/nlp/translate.py +0 -0
  122. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/repository/README.md +0 -0
  123. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/repository/__init__.py +0 -0
  124. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/repository/manager.py +0 -0
  125. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/repository/models.py +0 -0
  126. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/treesitter/__init__.py +0 -0
  127. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/treesitter/languages/base.py +0 -0
  128. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/treesitter/languages/bms.py +0 -0
  129. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/treesitter/languages/cobol.py +0 -0
  130. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/treesitter/languages/csharp.py +0 -0
  131. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/treesitter/languages/java.py +0 -0
  132. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/treesitter/languages/jcl.py +0 -0
  133. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/treesitter/languages/structural.py +0 -0
  134. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/adapters/treesitter/models.py +0 -0
  135. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/cli/README.md +0 -0
  136. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/cli/__init__.py +0 -0
  137. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/cli/commands/__init__.py +0 -0
  138. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/cli/commands/repo.py +0 -0
  139. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/cli/progress.py +0 -0
  140. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/common/__init__.py +0 -0
  141. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/common/chunking.py +0 -0
  142. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/common/document_reader.py +0 -0
  143. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/common/exceptions.py +0 -0
  144. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/common/file_utils.py +0 -0
  145. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/common/json_utils.py +0 -0
  146. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/common/llm_utils.py +0 -0
  147. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/common/naming.py +0 -0
  148. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/common/ocel.py +0 -0
  149. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/common/paths.py +0 -0
  150. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/common/schema_utils.py +0 -0
  151. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/common/time_utils.py +0 -0
  152. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/common/timing.py +0 -0
  153. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/common/types.py +0 -0
  154. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/__init__.py +0 -0
  155. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/analysis/__init__.py +0 -0
  156. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/analysis/consistency.py +0 -0
  157. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/analysis/cross_repo_analysis.py +0 -0
  158. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/analysis/deviation.py +0 -0
  159. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/analysis/fit_analysis.py +0 -0
  160. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/analysis/model_quality.py +0 -0
  161. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/analysis/run_consistency.py +0 -0
  162. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/analysis/stability_analysis.py +0 -0
  163. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/analysis/types.py +0 -0
  164. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/__init__.py +0 -0
  165. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/application_component.py +0 -0
  166. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/application_interface.py +0 -0
  167. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/business_event.py +0 -0
  168. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/business_function.py +0 -0
  169. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/data_object.py +0 -0
  170. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/device.py +0 -0
  171. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/node.py +0 -0
  172. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/prep.py +0 -0
  173. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/refine/cross_layer.py +0 -0
  174. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/refine/graph_relationships.py +0 -0
  175. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/refine/normalization.py +0 -0
  176. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/refine/orphan_elements.py +0 -0
  177. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/refine/structural_consistency.py +0 -0
  178. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/system_software.py +0 -0
  179. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/derivation/technology_service.py +0 -0
  180. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/extraction/__init__.py +0 -0
  181. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/extraction/base.py +0 -0
  182. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/extraction/business_concept.py +0 -0
  183. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/extraction/classification.py +0 -0
  184. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/extraction/concept_candidates.py +0 -0
  185. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/extraction/directory.py +0 -0
  186. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/extraction/directory_classification.py +0 -0
  187. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/extraction/external_dependency.py +0 -0
  188. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/extraction/file.py +0 -0
  189. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/extraction/method.py +0 -0
  190. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/extraction/repository.py +0 -0
  191. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/extraction/technology_candidates.py +0 -0
  192. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/modules/extraction/test.py +0 -0
  193. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/services/__init__.py +0 -0
  194. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/services/export_bundle.py +0 -0
  195. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/services/ontology.py +0 -0
  196. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/services/overfit.py +0 -0
  197. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/services/pipeline.py +0 -0
  198. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/deriva/services/trace.py +0 -0
  199. {deriva_cli-0.8.0 → deriva_cli-0.8.2}/packages/README-deriva-cli.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deriva-cli
3
- Version: 0.8.0
3
+ Version: 0.8.2
4
4
  Summary: Deriva is a research project aimed at enabling digital architects by automating the derivation of enterprise architecture models. Deriva uses dual knowledge graphs, heuristics and LLM's.
5
5
  Keywords: archimate,enterprise-architecture,code-analysis,llm,grafeo,fastapi
6
6
  Author: S. T. Grond
@@ -27,7 +27,6 @@ Requires-Dist: rich>=15
27
27
  Requires-Dist: lxml>=6
28
28
  Requires-Dist: duckdb>=1.5
29
29
  Requires-Dist: grafeo>=0.6.0b1
30
- Requires-Dist: sqlglot>=30
31
30
  Requires-Dist: tree-sitter>=0.26
32
31
  Requires-Dist: tree-sitter-python>=0.23.0
33
32
  Requires-Dist: tree-sitter-javascript>=0.23.0
@@ -36,20 +35,14 @@ Requires-Dist: tree-sitter-c-sharp>=0.23
36
35
  Requires-Dist: pypdf>=6
37
36
  Requires-Dist: python-docx>=1.2
38
37
  Requires-Dist: spacy==3.8.16
39
- Requires-Dist: ctranslate2==4.8.2
38
+ Requires-Dist: ctranslate2==4.8.3
40
39
  Requires-Dist: sentencepiece==0.2.2
41
40
  Requires-Dist: solvor>=0.6.3
42
- Requires-Dist: backoff>=2.2.1
43
- Requires-Dist: pydantic-ai>=2.55
44
- Requires-Dist: authlib>=1.8.0
45
- Requires-Dist: pyasn1>=0.6.4
46
- Requires-Dist: pyjwt>=2.15
47
- Requires-Dist: diskcache>=5.6.3
48
- Requires-Dist: nest-asyncio>=1.6.0
49
- Requires-Dist: structlog>=26.1.0
41
+ Requires-Dist: pydantic-ai-slim[openai,anthropic]>=2.55
42
+ Requires-Dist: httpx2>=2.13
43
+ Requires-Dist: lmdb>=1.6
50
44
  Requires-Dist: typer>=0.27
51
- Requires-Dist: httpx>=0.28.1
52
- Requires-Dist: pydantic-ai-slim[mistral]>=2.55
45
+ Requires-Dist: tree-sitter-typescript==0.23.2
53
46
  Requires-Python: >=3.14
54
47
  Project-URL: Homepage, https://deriva.dev
55
48
  Project-URL: Documentation, https://docs.deriva.dev
@@ -122,6 +122,13 @@ ELEMENT_TYPES: dict[str, ElementType] = {
122
122
  aspect="Behavior",
123
123
  description="An explicitly defined exposed technology behavior",
124
124
  ),
125
+ # A detail-level element (the export's detail level): the deployed image or package of a component
126
+ "Artifact": ElementType(
127
+ name="Artifact",
128
+ layer="Technology",
129
+ aspect="Passive",
130
+ description="A piece of data that is used or produced in a software development process, or by deployment and operation of an IT system",
131
+ ),
125
132
  }
126
133
 
127
134
 
@@ -152,6 +159,7 @@ BEHAVIOR_ELEMENTS: set[str] = {
152
159
  PASSIVE_ELEMENTS: set[str] = {
153
160
  "DataObject",
154
161
  "BusinessObject",
162
+ "Artifact",
155
163
  }
156
164
 
157
165
  # All elements
@@ -178,6 +186,7 @@ TECHNOLOGY_LAYER: set[str] = {
178
186
  "Device",
179
187
  "SystemSoftware",
180
188
  "TechnologyService",
189
+ "Artifact",
181
190
  }
182
191
 
183
192
 
@@ -196,7 +205,7 @@ def layer_of(element_type: str) -> str:
196
205
  # ArchiMate 3.2 Relationship Table
197
206
  # =============================================================================
198
207
  # Source: ArchiMate 3.2 Specification, Appendix B.5 "Relationship Tables", restricted
199
- # to the 13 element types Deriva derives. The spec publishes the tables as images;
208
+ # to the 13 element types Deriva derives plus Artifact (the export's detail level). The spec publishes the tables as images;
200
209
  # letters were read from them and cross-checked (case-insensitively, all 169 cells)
201
210
  # against Archi's relationships.xml v3.2.
202
211
  #
@@ -233,24 +242,29 @@ _TABLE_COLUMNS = (
233
242
  "Device",
234
243
  "SystemSoftware",
235
244
  "TechnologyService",
245
+ "Artifact",
236
246
  )
237
247
 
248
+ # Artifact (row and column) from Archi's relationships.xml; uppercase where the spec's metamodel figures show the
249
+ # relationship: Node, Device and SystemSoftware are assigned to an artifact, an artifact realizes an application
250
+ # component, a data object or system software; artifacts compose, aggregate and specialize artifacts.
238
251
  # Row = source, columns in _TABLE_COLUMNS order = target.
239
252
  # fmt: off
240
253
  _TABLE_ROWS: dict[str, tuple[str, ...]] = {
241
- "BusinessActor": ("SCGvtfO", "IvtfO", "IvtfO", "IvtfO", "aO", "vtfO", "vtfO", "vtfO", "aO", "vtfO", "vtfO", "vtfO", "vtfO"),
242
- "BusinessProcess": ("vtfO", "SCGvTFO", "CGvTFO", "vTFO", "AO", "vtfO", "vtfO", "vtfO", "aO", "vtfO", "vtfO", "vtfO", "vtfO"),
243
- "BusinessFunction": ("vtfO", "CGvTFO", "SCGvTFO", "vTFO", "AO", "vtfO", "vtfO", "vtfO", "aO", "vtfO", "vtfO", "vtfO", "vtfO"),
244
- "BusinessEvent": ("vtfO", "vTFO", "vTFO", "SCGvTFO", "AO", "vtfO", "vtfO", "vtfO", "aO", "vtfO", "vtfO", "vtfO", "vtfO"),
245
- "BusinessObject": ("O", "O", "O", "O", "SCGO", "O", "O", "O", "O", "O", "O", "O", "O"),
246
- "ApplicationComponent": ("vtfO", "rvtfO", "rvtfO", "rvtfO", "aO", "SCGRvtfO", "CgrvtfO", "irvtfO", "aO", "vtfO", "vtfO", "vtfO", "vtfO"),
247
- "ApplicationInterface": ("VtfO", "vtfO", "vtfO", "vtfO", "aO", "VtfO", "SCGvtfO", "IvtfO", "aO", "VtfO", "VtfO", "VtfO", "vtfO"),
248
- "ApplicationService": ("VtfO", "VtfO", "VtfO", "vtfO", "aO", "VtfO", "vtfO", "SCGvTFO", "AO", "VtfO", "VtfO", "VtfO", "vtfO"),
249
- "DataObject": ("O", "O", "O", "O", "RO", "O", "O", "O", "SCGO", "O", "O", "O", "O"),
250
- "Node": ("ivtfO", "irvtfO", "irvtfO", "irvtfO", "aO", "rvtfO", "rvtfO", "rvtfO", "aO", "SCGivtfO", "CGirvtfO", "CGirvtfO", "irvtfO"),
251
- "Device": ("vtfO", "rvtfO", "rvtfO", "rvtfO", "aO", "rvtfO", "rvtfO", "rvtfO", "aO", "vtfO", "SCGvtfO", "CGIrvtfO", "irvtfO"),
252
- "SystemSoftware": ("vtfO", "rvtfO", "rvtfO", "rvtfO", "aO", "rvtfO", "rvtfO", "rvtfO", "aO", "vtfO", "vtfO", "SCGIrvtfO", "irvtfO"),
253
- "TechnologyService": ("VtfO", "VtfO", "VtfO", "vtfO", "aO", "VtfO", "vtfO", "RvtfO", "aO", "VtfO", "VtfO", "VtfO", "SCGvTFO"),
254
+ "BusinessActor": ("SCGvtfO", "IvtfO", "IvtfO", "IvtfO", "aO", "vtfO", "vtfO", "vtfO", "aO", "vtfO", "vtfO", "vtfO", "vtfO", "aO"),
255
+ "BusinessProcess": ("vtfO", "SCGvTFO", "CGvTFO", "vTFO", "AO", "vtfO", "vtfO", "vtfO", "aO", "vtfO", "vtfO", "vtfO", "vtfO", "aO"),
256
+ "BusinessFunction": ("vtfO", "CGvTFO", "SCGvTFO", "vTFO", "AO", "vtfO", "vtfO", "vtfO", "aO", "vtfO", "vtfO", "vtfO", "vtfO", "aO"),
257
+ "BusinessEvent": ("vtfO", "vTFO", "vTFO", "SCGvTFO", "AO", "vtfO", "vtfO", "vtfO", "aO", "vtfO", "vtfO", "vtfO", "vtfO", "aO"),
258
+ "BusinessObject": ("O", "O", "O", "O", "SCGO", "O", "O", "O", "O", "O", "O", "O", "O", "O"),
259
+ "ApplicationComponent": ("vtfO", "rvtfO", "rvtfO", "rvtfO", "aO", "SCGRvtfO", "CgrvtfO", "irvtfO", "aO", "vtfO", "vtfO", "vtfO", "vtfO", "aO"),
260
+ "ApplicationInterface": ("VtfO", "vtfO", "vtfO", "vtfO", "aO", "VtfO", "SCGvtfO", "IvtfO", "aO", "VtfO", "VtfO", "VtfO", "vtfO", "aO"),
261
+ "ApplicationService": ("VtfO", "VtfO", "VtfO", "vtfO", "aO", "VtfO", "vtfO", "SCGvTFO", "AO", "VtfO", "VtfO", "VtfO", "vtfO", "aO"),
262
+ "DataObject": ("O", "O", "O", "O", "RO", "O", "O", "O", "SCGO", "O", "O", "O", "O", "O"),
263
+ "Node": ("ivtfO", "irvtfO", "irvtfO", "irvtfO", "aO", "rvtfO", "rvtfO", "rvtfO", "aO", "SCGivtfO", "CGirvtfO", "CGirvtfO", "irvtfO", "aIO"),
264
+ "Device": ("vtfO", "rvtfO", "rvtfO", "rvtfO", "aO", "rvtfO", "rvtfO", "rvtfO", "aO", "vtfO", "SCGvtfO", "CGIrvtfO", "irvtfO", "aIO"),
265
+ "SystemSoftware": ("vtfO", "rvtfO", "rvtfO", "rvtfO", "aO", "rvtfO", "rvtfO", "rvtfO", "aO", "vtfO", "vtfO", "SCGIrvtfO", "irvtfO", "aIO"),
266
+ "TechnologyService": ("VtfO", "VtfO", "VtfO", "vtfO", "aO", "VtfO", "vtfO", "RvtfO", "aO", "VtfO", "VtfO", "VtfO", "SCGvTFO", "aO"),
267
+ "Artifact": ("O", "rO", "rO", "rO", "rO", "RO", "rO", "rO", "RO", "O", "O", "RO", "rO", "SCGrO"),
254
268
  }
255
269
  # fmt: on
256
270
 
@@ -0,0 +1,121 @@
1
+ """Generated views (pure): ArchiMate viewpoints per level with a deterministic band layout.
2
+
3
+ Each viewpoint (ArchiMate 3.2 Specification, chapter 13) shows the architect elements of its types; a detail
4
+ variant adds the detail elements (property ``level`` = detail) nested under those types. The layout puts the
5
+ layers in horizontal bands (business, application, technology) and the elements of a band in a grid, ordered by
6
+ type and name, each detail element right after its parent, so the same model gives the same view in every run.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from dataclasses import dataclass, field
12
+
13
+ from .models import Element, Relationship, layer_of
14
+
15
+ # (view name, viewpoint, element types, with detail elements)
16
+ VIEWPOINTS: tuple[tuple[str, str, frozenset[str] | None, bool], ...] = (
17
+ ("Layered", "Layered", None, False),
18
+ ("Application Cooperation", "Application Cooperation", frozenset({"ApplicationComponent", "ApplicationInterface", "ApplicationService"}), False),
19
+ ("Information Structure", "Information Structure", frozenset({"BusinessObject", "DataObject"}), False),
20
+ ("Information Structure (detail)", "Information Structure", frozenset({"BusinessObject", "DataObject"}), True),
21
+ ("Implementation and Deployment", "Implementation and Deployment", frozenset({"ApplicationComponent", "Node", "Device", "SystemSoftware", "TechnologyService"}), False),
22
+ (
23
+ "Implementation and Deployment (detail)",
24
+ "Implementation and Deployment",
25
+ frozenset({"ApplicationComponent", "Node", "Device", "SystemSoftware", "TechnologyService", "Artifact"}),
26
+ True,
27
+ ),
28
+ ("Business", "Business Process Cooperation", frozenset({"BusinessActor", "BusinessProcess", "BusinessFunction", "BusinessEvent", "ApplicationService"}), False),
29
+ )
30
+ # A view needs an element of its anchor types (the Business view: a business element, not application services alone)
31
+ ANCHORS = {"Business": frozenset({"BusinessActor", "BusinessProcess", "BusinessFunction", "BusinessEvent"})}
32
+ BANDS = ("Business", "Application", "Technology", "Other")
33
+ TYPE_ORDER = (
34
+ "BusinessActor", "BusinessFunction", "BusinessProcess", "BusinessEvent", "BusinessObject",
35
+ "ApplicationComponent", "ApplicationInterface", "ApplicationService", "DataObject",
36
+ "Node", "Device", "SystemSoftware", "TechnologyService", "Artifact",
37
+ ) # fmt: skip
38
+ COLUMNS, WIDTH, HEIGHT, GAP, BAND_GAP, MARGIN = 6, 160, 60, 20, 60, 20
39
+
40
+
41
+ @dataclass(frozen=True)
42
+ class ViewNode:
43
+ identifier: str
44
+ element: str
45
+ x: int
46
+ y: int
47
+ w: int = WIDTH
48
+ h: int = HEIGHT
49
+
50
+
51
+ @dataclass(frozen=True)
52
+ class ViewConnection:
53
+ identifier: str
54
+ relationship: str
55
+ source: str # node identifiers
56
+ target: str
57
+
58
+
59
+ @dataclass
60
+ class View:
61
+ identifier: str
62
+ name: str
63
+ viewpoint: str
64
+ level: str = "architect" # detail: the view shows the detail elements too
65
+ nodes: list[ViewNode] = field(default_factory=list)
66
+ connections: list[ViewConnection] = field(default_factory=list)
67
+
68
+
69
+ def _level(e: Element) -> str:
70
+ return str((e.properties or {}).get("level") or "architect")
71
+
72
+
73
+ def _order(e: Element) -> tuple[int, str, str]:
74
+ return (TYPE_ORDER.index(e.element_type) if e.element_type in TYPE_ORDER else len(TYPE_ORDER), e.name.casefold(), e.identifier)
75
+
76
+
77
+ def _layout(view: View, shown: list[Element]) -> None:
78
+ by_parent: dict[str, list[Element]] = {}
79
+ for e in shown:
80
+ if _level(e) == "detail":
81
+ by_parent.setdefault(str((e.properties or {}).get("parent") or ""), []).append(e)
82
+ shown_ids = {e.identifier for e in shown}
83
+ y = MARGIN
84
+ for band in BANDS:
85
+ # One group per element type (each starts a new row), every element followed by its detail members
86
+ groups: dict[str, list[Element]] = {}
87
+ for e in sorted((e for e in shown if _level(e) != "detail" and layer_of(e.element_type) == band), key=_order):
88
+ groups.setdefault(e.element_type, []).append(e)
89
+ groups[e.element_type] += sorted(by_parent.get(e.identifier, []), key=_order)
90
+ # Detail elements whose parent is not in the view still get a place, after the band's own
91
+ orphans = (e for e in shown if _level(e) == "detail" and layer_of(e.element_type) == band and str((e.properties or {}).get("parent")) not in shown_ids)
92
+ if rest := sorted(orphans, key=_order):
93
+ groups[""] = rest
94
+ if not groups:
95
+ continue
96
+ for group in groups.values():
97
+ for i, e in enumerate(group):
98
+ row, column = divmod(i, COLUMNS)
99
+ node_id = f"{view.identifier}-n-{e.identifier}"
100
+ view.nodes.append(ViewNode(identifier=node_id, element=e.identifier, x=MARGIN + column * (WIDTH + GAP), y=y + row * (HEIGHT + GAP)))
101
+ y += (len(group) + COLUMNS - 1) // COLUMNS * (HEIGHT + GAP)
102
+ y += BAND_GAP
103
+
104
+
105
+ def build_views(elements: list[Element], relationships: list[Relationship]) -> list[View]:
106
+ """The views of the model, one per viewpoint that has elements, in VIEWPOINTS order."""
107
+ views: list[View] = []
108
+ for number, (name, viewpoint, types, with_detail) in enumerate(VIEWPOINTS, 1):
109
+ shown = [e for e in elements if (types is None or e.element_type in types) and (with_detail or _level(e) != "detail")]
110
+ anchors = ANCHORS.get(name)
111
+ if not shown or (anchors and not any(e.element_type in anchors for e in shown)) or (with_detail and not any(_level(e) == "detail" for e in shown)):
112
+ continue
113
+ view = View(identifier=f"view-{number}", name=name, viewpoint=viewpoint, level="detail" if with_detail else "architect")
114
+ _layout(view, shown)
115
+ node_of = {n.element: n.identifier for n in view.nodes}
116
+ for r in sorted(relationships, key=lambda r: r.identifier):
117
+ if r.source in node_of and r.target in node_of:
118
+ connection = ViewConnection(identifier=f"{view.identifier}-c-{r.identifier}", relationship=r.identifier, source=node_of[r.source], target=node_of[r.target])
119
+ view.connections.append(connection)
120
+ views.append(view)
121
+ return views
@@ -8,12 +8,14 @@ Reference: https://www.opengroup.org/archimate-forum/archimate-exchange-format
8
8
 
9
9
  from __future__ import annotations
10
10
 
11
+ from collections.abc import Mapping, Sequence
11
12
  from datetime import datetime
12
13
  from pathlib import Path
13
14
 
14
15
  from lxml import etree
15
16
 
16
17
  from .models import Element, Relationship
18
+ from .views import View
17
19
 
18
20
 
19
21
  class ArchiMateXMLExporter:
@@ -47,6 +49,8 @@ class ArchiMateXMLExporter:
47
49
  output_path: str,
48
50
  model_name: str = "ArchiMate Model",
49
51
  model_id: str = "model-001",
52
+ properties: Mapping[str, Mapping[str, str]] | None = None,
53
+ views: Sequence[View] | None = None,
50
54
  ) -> None:
51
55
  """
52
56
  Export ArchiMate model to XML file.
@@ -57,6 +61,8 @@ class ArchiMateXMLExporter:
57
61
  output_path: Path to output XML file
58
62
  model_name: Name of the model
59
63
  model_id: Unique identifier for the model
64
+ properties: Exported properties per element id (e.g. ``level``), declared as propertyDefinitions
65
+ views: Diagrams to export (see ``views.build_views``)
60
66
  """
61
67
  # Create root model element
62
68
  root = etree.Element(
@@ -76,11 +82,15 @@ class ArchiMateXMLExporter:
76
82
  # Add metadata
77
83
  self._add_metadata(root)
78
84
 
85
+ properties = properties or {}
86
+ keys = sorted({key for values in properties.values() for key, value in values.items() if value})
87
+ definition_of = {key: f"propid-{key}" for key in keys}
88
+
79
89
  # Add elements section
80
90
  if elements:
81
91
  elements_section = etree.SubElement(root, "elements")
82
92
  for element in elements:
83
- self._add_element(elements_section, element)
93
+ self._add_element(elements_section, element, properties.get(element.identifier, {}), definition_of)
84
94
 
85
95
  # Add relationships section
86
96
  if relationships:
@@ -88,6 +98,15 @@ class ArchiMateXMLExporter:
88
98
  for relationship in relationships:
89
99
  self._add_relationship(rels_section, relationship)
90
100
 
101
+ # The exchange format's order: elements, relationships, organizations, propertyDefinitions, views
102
+ if keys:
103
+ definitions = etree.SubElement(root, "propertyDefinitions")
104
+ for key in keys:
105
+ definition = etree.SubElement(definitions, "propertyDefinition", attrib={"identifier": definition_of[key], "type": "string"})
106
+ etree.SubElement(definition, "name").text = key
107
+ if views:
108
+ self._add_views(root, views)
109
+
91
110
  # Write to file
92
111
  tree = etree.ElementTree(root)
93
112
  output_file = Path(output_path)
@@ -124,13 +143,21 @@ class ArchiMateXMLExporter:
124
143
  description = etree.SubElement(metadata, f"{{{self.DC_NS}}}description")
125
144
  description.text = "ArchiMate model generated by Deriva from source code analysis"
126
145
 
127
- def _add_element(self, parent: etree.Element, element: Element) -> None:
146
+ def _add_element(
147
+ self,
148
+ parent: etree.Element,
149
+ element: Element,
150
+ properties: Mapping[str, str] | None = None,
151
+ definition_of: Mapping[str, str] | None = None,
152
+ ) -> None:
128
153
  """
129
154
  Add an element to the XML tree.
130
155
 
131
156
  Args:
132
157
  parent: Parent XML element
133
158
  element: ArchiMate element to add
159
+ properties: The element's exported properties (key -> value)
160
+ definition_of: propertyDefinition identifier per key
134
161
  """
135
162
  elem = etree.SubElement(
136
163
  parent,
@@ -152,9 +179,55 @@ class ArchiMateXMLExporter:
152
179
  doc_elem.set(f"{{{self.XML_NS}}}lang", "en")
153
180
  doc_elem.text = element.documentation
154
181
 
155
- # Note: Properties are not exported as they require propertyDefinitions
156
- # at the model level per ArchiMate Exchange Format XSD.
157
- # Internal metadata (source, confidence, derived_at) is omitted.
182
+ # Only the properties passed in are exported (each needs a model-level propertyDefinition);
183
+ # internal metadata (source, derived_at) on the element is omitted.
184
+ shown = sorted((key, value) for key, value in (properties or {}).items() if value and key in (definition_of or {}))
185
+ if shown and definition_of:
186
+ props = etree.SubElement(elem, "properties")
187
+ for key, value in shown:
188
+ prop = etree.SubElement(props, "property", attrib={"propertyDefinitionRef": definition_of[key]})
189
+ value_elem = etree.SubElement(prop, "value")
190
+ value_elem.set(f"{{{self.XML_NS}}}lang", "en")
191
+ value_elem.text = value
192
+
193
+ def _add_views(self, root: etree.Element, views: Sequence[View]) -> None:
194
+ """Add the diagrams: element nodes with their bounds, relationship connections between them."""
195
+ diagrams = etree.SubElement(etree.SubElement(root, "views"), "diagrams")
196
+ for view in views:
197
+ diagram = etree.SubElement(
198
+ diagrams,
199
+ "view",
200
+ attrib={"identifier": view.identifier, f"{{{self.XSI_NS}}}type": "Diagram", "viewpoint": view.viewpoint},
201
+ )
202
+ name_elem = etree.SubElement(diagram, "name")
203
+ name_elem.set(f"{{{self.XML_NS}}}lang", "en")
204
+ name_elem.text = view.name
205
+ for node in view.nodes:
206
+ etree.SubElement(
207
+ diagram,
208
+ "node",
209
+ attrib={
210
+ "identifier": node.identifier,
211
+ "elementRef": node.element,
212
+ f"{{{self.XSI_NS}}}type": "Element",
213
+ "x": str(node.x),
214
+ "y": str(node.y),
215
+ "w": str(node.w),
216
+ "h": str(node.h),
217
+ },
218
+ )
219
+ for connection in view.connections:
220
+ etree.SubElement(
221
+ diagram,
222
+ "connection",
223
+ attrib={
224
+ "identifier": connection.identifier,
225
+ "relationshipRef": connection.relationship,
226
+ f"{{{self.XSI_NS}}}type": "Relationship",
227
+ "source": connection.source,
228
+ "target": connection.target,
229
+ },
230
+ )
158
231
 
159
232
  def _add_relationship(self, parent: etree.Element, relationship: Relationship) -> None:
160
233
  """
@@ -25,6 +25,7 @@ Usage:
25
25
 
26
26
  from __future__ import annotations
27
27
 
28
+ from .db_tool import DATA_DIR
28
29
  from .db_tool import export_all as export_database
29
30
  from .db_tool import import_all as import_database
30
31
  from .manager import (
@@ -37,7 +38,11 @@ from .manager import (
37
38
  seed_database,
38
39
  )
39
40
 
41
+ # Bundled business function models (a config path names one of them, or a user-supplied file)
42
+ FUNCTION_MODELS_DIR = DATA_DIR / "function_models"
43
+
40
44
  __all__ = [
45
+ "FUNCTION_MODELS_DIR",
41
46
  "ensure_database",
42
47
  "get_connection",
43
48
  "init_database",