GeneralManager 0.42.2__tar.gz → 0.43.0__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 (196) hide show
  1. {generalmanager-0.42.2/src/GeneralManager.egg-info → generalmanager-0.43.0}/PKG-INFO +1 -1
  2. {generalmanager-0.42.2 → generalmanager-0.43.0}/pyproject.toml +1 -1
  3. {generalmanager-0.42.2 → generalmanager-0.43.0/src/GeneralManager.egg-info}/PKG-INFO +1 -1
  4. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/bucket/database_bucket.py +6 -4
  5. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/cache/cache_decorator.py +69 -9
  6. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/cache/run_context.py +44 -0
  7. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/calculation/lifecycle.py +14 -4
  8. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/orm/support.py +22 -3
  9. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/orm_utils/field_descriptors.py +14 -0
  10. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/manager/input.py +9 -1
  11. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/permission/base_permission.py +5 -2
  12. {generalmanager-0.42.2 → generalmanager-0.43.0}/LICENSE +0 -0
  13. {generalmanager-0.42.2 → generalmanager-0.43.0}/README.md +0 -0
  14. {generalmanager-0.42.2 → generalmanager-0.43.0}/setup.cfg +0 -0
  15. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/GeneralManager.egg-info/SOURCES.txt +0 -0
  16. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/GeneralManager.egg-info/dependency_links.txt +0 -0
  17. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/GeneralManager.egg-info/requires.txt +0 -0
  18. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/GeneralManager.egg-info/top_level.txt +0 -0
  19. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/__init__.py +0 -0
  20. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/_types/__init__.py +0 -0
  21. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/_types/api.py +0 -0
  22. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/_types/bucket.py +0 -0
  23. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/_types/cache.py +0 -0
  24. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/_types/factory.py +0 -0
  25. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/_types/general_manager.py +0 -0
  26. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/_types/interface.py +0 -0
  27. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/_types/manager.py +0 -0
  28. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/_types/measurement.py +0 -0
  29. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/_types/permission.py +0 -0
  30. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/_types/rule.py +0 -0
  31. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/_types/search.py +0 -0
  32. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/_types/utils.py +0 -0
  33. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/api/__init__.py +0 -0
  34. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/api/graphql.py +0 -0
  35. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/api/graphql_errors.py +0 -0
  36. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/api/graphql_mutations.py +0 -0
  37. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/api/graphql_resolvers.py +0 -0
  38. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/api/graphql_search.py +0 -0
  39. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/api/graphql_subscription_consumer.py +0 -0
  40. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/api/graphql_subscriptions.py +0 -0
  41. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/api/graphql_view.py +0 -0
  42. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/api/mutation.py +0 -0
  43. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/api/property.py +0 -0
  44. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/api/registry.py +0 -0
  45. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/api/remote_api.py +0 -0
  46. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/api/remote_invalidation.py +0 -0
  47. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/api/remote_invalidation_client.py +0 -0
  48. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/apps.py +0 -0
  49. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/bootstrap.py +0 -0
  50. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/bucket/__init__.py +0 -0
  51. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/bucket/base_bucket.py +0 -0
  52. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/bucket/calculation_bucket.py +0 -0
  53. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/bucket/group_bucket.py +0 -0
  54. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/bucket/request_bucket.py +0 -0
  55. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/cache/__init__.py +0 -0
  56. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/cache/cache_tracker.py +0 -0
  57. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/cache/dependency_index.py +0 -0
  58. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/cache/model_dependency_collector.py +0 -0
  59. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/cache/signals.py +0 -0
  60. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/conf.py +0 -0
  61. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/factory/__init__.py +0 -0
  62. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/factory/auto_factory.py +0 -0
  63. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/factory/factories.py +0 -0
  64. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/factory/factory_methods.py +0 -0
  65. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/__init__.py +0 -0
  66. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/base_interface.py +0 -0
  67. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/bundles/__init__.py +0 -0
  68. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/bundles/calculation.py +0 -0
  69. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/bundles/database.py +0 -0
  70. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/bundles/remote_manager.py +0 -0
  71. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/bundles/request.py +0 -0
  72. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/__init__.py +0 -0
  73. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/base.py +0 -0
  74. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/builtin.py +0 -0
  75. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/calculation/__init__.py +0 -0
  76. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/calculation/_compat.py +0 -0
  77. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/configuration.py +0 -0
  78. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/core/observability.py +0 -0
  79. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/core/utils.py +0 -0
  80. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/exceptions.py +0 -0
  81. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/existing_model/__init__.py +0 -0
  82. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/existing_model/_compat.py +0 -0
  83. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/existing_model/resolution.py +0 -0
  84. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/factory.py +0 -0
  85. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/orm/__init__.py +0 -0
  86. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/orm/_compat.py +0 -0
  87. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/orm/history.py +0 -0
  88. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/orm/lifecycle.py +0 -0
  89. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/orm/mutations.py +0 -0
  90. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/orm_utils/__init__.py +0 -0
  91. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/orm_utils/django_manager_utils.py +0 -0
  92. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/orm_utils/payload_normalizer.py +0 -0
  93. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/read_only/__init__.py +0 -0
  94. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/read_only/_compat.py +0 -0
  95. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/read_only/lifecycle.py +0 -0
  96. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/read_only/management.py +0 -0
  97. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/registry.py +0 -0
  98. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/remote_manager.py +0 -0
  99. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/capabilities/request/__init__.py +0 -0
  100. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/infrastructure/__init__.py +0 -0
  101. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/infrastructure/startup_hooks.py +0 -0
  102. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/infrastructure/system_checks.py +0 -0
  103. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/interfaces/__init__.py +0 -0
  104. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/interfaces/calculation.py +0 -0
  105. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/interfaces/database.py +0 -0
  106. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/interfaces/existing_model.py +0 -0
  107. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/interfaces/read_only.py +0 -0
  108. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/interfaces/remote_manager.py +0 -0
  109. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/interfaces/request.py +0 -0
  110. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/manifests/__init__.py +0 -0
  111. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/manifests/capability_builder.py +0 -0
  112. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/manifests/capability_manifest.py +0 -0
  113. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/manifests/capability_models.py +0 -0
  114. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/orm_interface.py +0 -0
  115. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/requests.py +0 -0
  116. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/utils/__init__.py +0 -0
  117. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/utils/database_interface_protocols.py +0 -0
  118. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/utils/errors.py +0 -0
  119. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/interface/utils/models.py +0 -0
  120. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/logging.py +0 -0
  121. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/management/commands/search_index.py +0 -0
  122. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/management/commands/seed_manager_landscape.py +0 -0
  123. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/management/commands/shell.py +0 -0
  124. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/management/commands/workflow_drain_outbox.py +0 -0
  125. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/management/commands/workflow_replay_dead_letters.py +0 -0
  126. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/manager/__init__.py +0 -0
  127. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/manager/general_manager.py +0 -0
  128. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/manager/group_manager.py +0 -0
  129. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/manager/meta.py +0 -0
  130. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/measurement/__init__.py +0 -0
  131. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/measurement/measurement.py +0 -0
  132. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/measurement/measurement_field.py +0 -0
  133. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/metrics/__init__.py +0 -0
  134. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/metrics/graphql.py +0 -0
  135. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/migrations/0001_initial.py +0 -0
  136. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/migrations/0002_workflow_outbox_scaling_indexes.py +0 -0
  137. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/migrations/0003_workflow_execution_correlation_constraint.py +0 -0
  138. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/migrations/__init__.py +0 -0
  139. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/models.py +0 -0
  140. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/permission/__init__.py +0 -0
  141. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/permission/audit.py +0 -0
  142. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/permission/graphql_capabilities.py +0 -0
  143. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/permission/manager_based_permission.py +0 -0
  144. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/permission/mutation_permission.py +0 -0
  145. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/permission/permission_checks.py +0 -0
  146. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/permission/permission_data_manager.py +0 -0
  147. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/permission/utils.py +0 -0
  148. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/public_api_registry.py +0 -0
  149. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/py.typed +0 -0
  150. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/rule/__init__.py +0 -0
  151. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/rule/handler.py +0 -0
  152. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/rule/rule.py +0 -0
  153. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/search/__init__.py +0 -0
  154. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/search/async_tasks.py +0 -0
  155. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/search/backend.py +0 -0
  156. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/search/backend_registry.py +0 -0
  157. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/search/backends/__init__.py +0 -0
  158. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/search/backends/dev.py +0 -0
  159. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/search/backends/meilisearch.py +0 -0
  160. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/search/backends/opensearch.py +0 -0
  161. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/search/backends/typesense.py +0 -0
  162. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/search/config.py +0 -0
  163. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/search/indexer.py +0 -0
  164. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/search/registry.py +0 -0
  165. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/search/utils.py +0 -0
  166. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/seeding/__init__.py +0 -0
  167. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/seeding/manager_landscape.py +0 -0
  168. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/utils/__init__.py +0 -0
  169. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/utils/args_to_kwargs.py +0 -0
  170. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/utils/filter_parser.py +0 -0
  171. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/utils/format_string.py +0 -0
  172. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/utils/json_encoder.py +0 -0
  173. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/utils/make_cache_key.py +0 -0
  174. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/utils/none_to_zero.py +0 -0
  175. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/utils/path_mapping.py +0 -0
  176. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/utils/public_api.py +0 -0
  177. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/utils/testing.py +0 -0
  178. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/utils/type_checks.py +0 -0
  179. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/workflow/__init__.py +0 -0
  180. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/workflow/actions.py +0 -0
  181. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/workflow/backend_registry.py +0 -0
  182. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/workflow/backends/__init__.py +0 -0
  183. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/workflow/backends/celery.py +0 -0
  184. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/workflow/backends/local.py +0 -0
  185. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/workflow/backends/n8n.py +0 -0
  186. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/workflow/config.py +0 -0
  187. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/workflow/engine.py +0 -0
  188. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/workflow/event_registry.py +0 -0
  189. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/workflow/events.py +0 -0
  190. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/workflow/models.py +0 -0
  191. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/workflow/signal_bridge.py +0 -0
  192. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/workflow/tasks.py +0 -0
  193. {generalmanager-0.42.2 → generalmanager-0.43.0}/src/general_manager/workflow/telemetry.py +0 -0
  194. {generalmanager-0.42.2 → generalmanager-0.43.0}/tests/test_settings.py +0 -0
  195. {generalmanager-0.42.2 → generalmanager-0.43.0}/tests/test_urls.py +0 -0
  196. {generalmanager-0.42.2 → generalmanager-0.43.0}/tests/testing_asgi.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GeneralManager
3
- Version: 0.42.2
3
+ Version: 0.43.0
4
4
  Summary: Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching.
5
5
  Author-email: Tim Kleindick <tkleindick@yahoo.de>
6
6
  License: MIT License
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "GeneralManager"
7
- version = "0.42.2"
7
+ version = "0.43.0"
8
8
  description = "Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching."
9
9
  readme = "README.md"
10
10
  authors = [{ name = "Tim Kleindick", email = "tkleindick@yahoo.de" }]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GeneralManager
3
- Version: 0.42.2
3
+ Version: 0.43.0
4
4
  Summary: Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching.
5
5
  Author-email: Tim Kleindick <tkleindick@yahoo.de>
6
6
  License: MIT License
@@ -689,10 +689,12 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
689
689
 
690
690
  self._track_effective_dependencies()
691
691
  if isinstance(item, GeneralManager):
692
- return item.identification.get("id", None) in self._data.values_list(
693
- "pk", flat=True
694
- )
695
- return item.pk in self._data.values_list("pk", flat=True)
692
+ pk = item.identification.get("id", None)
693
+ else:
694
+ pk = item.pk
695
+ if pk is None:
696
+ return False
697
+ return self._data.filter(pk=pk).exists()
696
698
 
697
699
  def sort(
698
700
  self,
@@ -44,7 +44,7 @@ class CacheBackend(Protocol):
44
44
 
45
45
  RecordFn = Callable[[str, Set[Dependency]], None]
46
46
  FuncT = TypeVar("FuncT", bound=Callable[..., object])
47
- CacheScope = Literal["dependency", "run", "none"]
47
+ CacheScope = Literal["dependency", "run", "timeout", "none"]
48
48
 
49
49
  _SENTINEL = object()
50
50
  logger = get_logger("cache.decorator")
@@ -57,31 +57,67 @@ class UnsupportedCacheScopeError(ValueError):
57
57
  super().__init__(f"Unsupported cache scope: {scope}")
58
58
 
59
59
 
60
+ class CacheTimeoutConfigurationError(ValueError):
61
+ """Raised when timeout is used with an incompatible cache scope."""
62
+
63
+ @classmethod
64
+ def missing_timeout(cls) -> "CacheTimeoutConfigurationError":
65
+ return cls('scope="timeout" requires timeout')
66
+
67
+ @classmethod
68
+ def unexpected_timeout(cls) -> "CacheTimeoutConfigurationError":
69
+ return cls('timeout is only supported with scope="timeout"')
70
+
71
+
60
72
  def cached(
61
73
  timeout: Optional[int] = None,
62
74
  cache_backend: CacheBackend = django_cache,
63
75
  record_fn: RecordFn = record_dependencies,
64
76
  *,
65
- scope: CacheScope = "dependency",
77
+ scope: CacheScope = "run",
66
78
  ) -> Callable[[FuncT], FuncT]:
67
79
  """
68
- Cache a function call while registering its data dependencies.
80
+ Decorator factory for caching a function call.
81
+
82
+ By default, cached values are scoped to the active
83
+ :class:`~general_manager.cache.run_context.CalculationRunContext` and are
84
+ discarded when that run ends. Use ``scope="dependency"`` to persist values
85
+ in ``cache_backend`` and use ``record_fn`` to persist dependency metadata
86
+ for invalidation. Use ``scope="timeout"`` with ``timeout`` set for
87
+ cache-backend storage with time-based expiry; dependency recording is
88
+ ignored for timeout-scoped values.
69
89
 
70
90
  Parameters:
71
- timeout (int | None): Expiration in seconds for cached values; `None` stores results until invalidated.
91
+ timeout (int | None): Expiration in seconds for timeout-scoped cached values.
92
+ Required when ``scope`` is ``"timeout"`` and invalid with any other
93
+ ``CacheScope``.
72
94
  cache_backend (CacheBackend): Backend used to read and write cached results.
73
- record_fn (RecordFn): Callback invoked to persist dependency metadata when no timeout is
74
- defined. Defaults to :func:`~general_manager.cache.dependency_index.record_dependencies`.
95
+ record_fn (RecordFn): Callback invoked to persist dependency metadata when
96
+ ``scope`` is ``"dependency"``. Defaults to
97
+ :func:`~general_manager.cache.dependency_index.record_dependencies`.
98
+ scope (CacheScope): Cache storage strategy. ``"run"`` memoizes for the active run,
99
+ ``"dependency"`` stores in ``cache_backend`` with dependency tracking,
100
+ ``"timeout"`` stores in ``cache_backend`` with time-based expiry, and
101
+ ``"none"`` disables caching.
75
102
 
76
103
  Returns:
77
104
  Callable: Decorator that wraps the target function with caching behaviour.
78
105
 
79
106
  Raises:
107
+ ValueError: Raised for invalid ``scope``/``timeout`` combinations, including
108
+ unsupported ``CacheScope`` values, missing ``timeout`` for
109
+ ``scope="timeout"``, and ``timeout`` supplied for non-timeout scopes.
80
110
  DependencyLockTimeoutError: Propagated from ``record_fn`` (i.e.
81
111
  :func:`~general_manager.cache.dependency_index.record_dependencies`) when the
82
112
  dependency-index lock cannot be acquired within the configured timeout. The cached
83
113
  value has already been stored at that point; only the dependency metadata is lost.
84
114
  """
115
+ if scope not in {"dependency", "run", "timeout", "none"}:
116
+ raise UnsupportedCacheScopeError(scope)
117
+ if scope == "timeout" and timeout is None:
118
+ raise CacheTimeoutConfigurationError.missing_timeout()
119
+ if timeout is not None and scope != "timeout":
120
+ raise CacheTimeoutConfigurationError.unexpected_timeout()
85
121
 
86
122
  def decorator(func: FuncT) -> FuncT:
87
123
  @wraps(func)
@@ -94,10 +130,34 @@ def cached(
94
130
  with ensure_calculation_run_context() as context:
95
131
  return context.get_or_set(key, lambda: func(*args, **kwargs))
96
132
 
97
- if scope != "dependency":
98
- raise UnsupportedCacheScopeError(scope)
99
-
100
133
  key = make_cache_key(func, args, kwargs)
134
+
135
+ if scope == "timeout":
136
+ cached_result = cache_backend.get(key, _SENTINEL)
137
+ if cached_result is not _SENTINEL:
138
+ logger.debug(
139
+ "cache hit",
140
+ context={
141
+ "function": func.__qualname__,
142
+ "key": key,
143
+ "scope": scope,
144
+ },
145
+ )
146
+ return cached_result
147
+
148
+ result = func(*args, **kwargs)
149
+ cache_backend.set(key, result, timeout)
150
+ logger.debug(
151
+ "cache miss stored",
152
+ context={
153
+ "function": func.__qualname__,
154
+ "key": key,
155
+ "timeout": timeout,
156
+ "scope": scope,
157
+ },
158
+ )
159
+ return result
160
+
101
161
  deps_key = f"{key}:deps"
102
162
 
103
163
  cached_result = cache_backend.get(key, _SENTINEL)
@@ -2,6 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ from collections import defaultdict
5
6
  from collections.abc import Callable, Hashable, Iterable
6
7
  from contextvars import ContextVar, Token
7
8
  from types import TracebackType
@@ -44,6 +45,22 @@ class CalculationRunContext:
44
45
  self._values[key] = loader()
45
46
  return self._values[key] # type: ignore[return-value]
46
47
 
48
+ def get(self, key: Hashable, default: object = None) -> object:
49
+ """Return the stored value for key, or default when key is absent."""
50
+ return self._values.get(key, default)
51
+
52
+ def set(self, key: Hashable, value: object) -> None:
53
+ """Store a value for the active run."""
54
+ self._values[key] = value
55
+
56
+ def has(self, key: Hashable) -> bool:
57
+ """Return whether key has a value in the active run."""
58
+ return key in self._values
59
+
60
+ def __contains__(self, key: Hashable) -> bool:
61
+ """Return whether key has a value in the active run."""
62
+ return self.has(key)
63
+
47
64
  def index(
48
65
  self,
49
66
  *,
@@ -57,6 +74,33 @@ class CalculationRunContext:
57
74
  lambda: {index_by(row): row for row in loader()},
58
75
  )
59
76
 
77
+ def group_by(
78
+ self,
79
+ *,
80
+ key: Hashable,
81
+ loader: Callable[[], Iterable[T]],
82
+ group_by: Callable[[T], K],
83
+ ) -> dict[K, list[T]]:
84
+ """Load a working set once and group it by the supplied key function."""
85
+
86
+ def load_groups() -> dict[K, list[T]]:
87
+ grouped: defaultdict[K, list[T]] = defaultdict(list)
88
+ for row in loader():
89
+ grouped[group_by(row)].append(row)
90
+ return dict(grouped)
91
+
92
+ return self.get_or_set(("group_by", key), load_groups)
93
+
94
+ def index_many(
95
+ self,
96
+ *,
97
+ key: Hashable,
98
+ loader: Callable[[], Iterable[T]],
99
+ index_by: Callable[[T], K],
100
+ ) -> dict[K, list[T]]:
101
+ """Load a working set once and group rows sharing the same index key."""
102
+ return self.group_by(key=key, loader=loader, group_by=index_by)
103
+
60
104
 
61
105
  def current_calculation_run_context() -> CalculationRunContext | None:
62
106
  """Return the active calculation run context, if any."""
@@ -5,6 +5,8 @@ from __future__ import annotations
5
5
  from typing import Any, TYPE_CHECKING, ClassVar
6
6
 
7
7
  from general_manager.bucket.calculation_bucket import CalculationBucket
8
+ from general_manager.cache.cache_tracker import DependencyTracker
9
+ from general_manager.cache.dependency_index import serialize_dependency_identifier
8
10
  from general_manager.manager.general_manager import GeneralManager
9
11
  from general_manager.manager.input import Input
10
12
 
@@ -18,6 +20,15 @@ if TYPE_CHECKING: # pragma: no cover
18
20
  )
19
21
 
20
22
 
23
+ def _track_cached_manager(value: Any) -> None:
24
+ if isinstance(value, GeneralManager):
25
+ DependencyTracker.track(
26
+ value.__class__.__name__,
27
+ "identification",
28
+ serialize_dependency_identifier(value.identification),
29
+ )
30
+
31
+
21
32
  class CalculationReadCapability(BaseCapability):
22
33
  """Calculations expose inputs only and never persist data."""
23
34
 
@@ -88,8 +99,8 @@ class CalculationReadCapability(BaseCapability):
88
99
  input_field = interface_cls.input_fields[field_name]
89
100
  if field_name in resolved_values:
90
101
  cached_value = resolved_values[field_name]
91
- if not isinstance(cached_value, GeneralManager):
92
- return cached_value
102
+ _track_cached_manager(cached_value)
103
+ return cached_value
93
104
 
94
105
  input_field = interface_cls.input_fields[field_name]
95
106
  dependency_values = {
@@ -103,8 +114,7 @@ class CalculationReadCapability(BaseCapability):
103
114
  interface_instance.identification.get(field_name),
104
115
  dependency_values,
105
116
  )
106
- if not isinstance(value, GeneralManager):
107
- resolved_values[field_name] = value
117
+ resolved_values[field_name] = value
108
118
  return value
109
119
 
110
120
  return {
@@ -328,9 +328,28 @@ class OrmReadCapability(BaseCapability):
328
328
  field_name (str): Name of the field on the model.
329
329
 
330
330
  Returns:
331
- type: The class used to represent the field's values: the related model's `_general_manager_class` when the field is a relation to a model that exposes that attribute, otherwise the Python type of the field object.
332
- """
333
- field = interface_cls._model._meta.get_field(field_name)
331
+ type: The Django field class for stored model fields, the related
332
+ model's `_general_manager_class` for managed relations, or descriptor
333
+ metadata for synthetic interface fields.
334
+ """
335
+ try:
336
+ field = interface_cls._model._meta.get_field(field_name)
337
+ except FieldDoesNotExist:
338
+ descriptors = get_support_capability(interface_cls).get_field_descriptors(
339
+ interface_cls
340
+ )
341
+ descriptor = descriptors.get(field_name)
342
+ if descriptor is not None:
343
+ return descriptor.metadata["type"]
344
+ raise
345
+ if getattr(field, "name", field_name) != field_name:
346
+ descriptor = (
347
+ get_support_capability(interface_cls)
348
+ .get_field_descriptors(interface_cls)
349
+ .get(field_name)
350
+ )
351
+ if descriptor is not None:
352
+ return descriptor.metadata["type"]
334
353
  if (
335
354
  field.is_relation
336
355
  and field.related_model
@@ -227,6 +227,20 @@ class _FieldDescriptorBuilder:
227
227
  relation_kind="direct",
228
228
  filter_lookup=field.name,
229
229
  )
230
+ raw_id_name = getattr(field, "attname", f"{field.name}_id")
231
+ if raw_id_name not in self._descriptors:
232
+ target_field = getattr(field, "target_field", None)
233
+ raw_id_type = type(target_field) if target_field is not None else int
234
+ self._register(
235
+ attribute_name=raw_id_name,
236
+ raw_type=raw_id_type,
237
+ is_required=not field.null,
238
+ is_editable=False,
239
+ default=default,
240
+ is_derived=False,
241
+ accessor=_instance_attribute_accessor(raw_id_name),
242
+ filter_lookup=raw_id_name,
243
+ )
230
244
 
231
245
  def _add_reverse_one_to_one_relations(self) -> None:
232
246
  """Register snake_case aliases for reverse one-to-one relation accessors."""
@@ -661,10 +661,18 @@ class Input(Generic[INPUT_TYPE]):
661
661
 
662
662
  if value is None:
663
663
  return None
664
- possible_values = self.resolve_possible_values(identification)
664
+ possible_values = (
665
+ self.possible_values
666
+ if isinstance(self.possible_values, InputDomain)
667
+ else None
668
+ )
665
669
  if isinstance(possible_values, InputDomain):
666
670
  value = possible_values.normalize(value)
667
671
  if self.normalizer is not None:
672
+ if possible_values is None:
673
+ possible_values = self.resolve_possible_values(identification)
674
+ if isinstance(possible_values, InputDomain):
675
+ value = possible_values.normalize(value)
668
676
  dependency_values = self._build_dependency_values(identification)
669
677
  return _invoke_callable(
670
678
  self.normalizer,
@@ -437,7 +437,10 @@ class BasePermission(ABC):
437
437
  """
438
438
  Resolve a user identifier or user-like object to a Django User or AnonymousUser instance.
439
439
 
440
- If the input is already an AbstractBaseUser or AnonymousUser, it is returned unchanged. If the input is a primary key (or other value used to look up a User by id), the corresponding User is returned; if no such User exists, an AnonymousUser is returned.
440
+ If the input is already an AbstractBaseUser, AnonymousUser, or configured
441
+ user-model instance, it is returned unchanged. If the input is a primary
442
+ key (or other value used to look up a User by id), the corresponding User
443
+ is returned; if no such User exists, an AnonymousUser is returned.
441
444
 
442
445
  Parameters:
443
446
  user (Any | UserLike): A user object or a value to look up a User by primary key.
@@ -454,7 +457,7 @@ class BasePermission(ABC):
454
457
  user = lazy_user._wrapped
455
458
 
456
459
  User = get_user_model()
457
- if isinstance(user, (AbstractBaseUser, AnonymousUser)):
460
+ if isinstance(user, (AbstractBaseUser, AnonymousUser, User)):
458
461
  return user
459
462
  try:
460
463
  return User.objects.get(pk=user)
File without changes