GeneralManager 0.52.2__tar.gz → 0.53.1__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.
- {generalmanager-0.52.2/src/GeneralManager.egg-info → generalmanager-0.53.1}/PKG-INFO +1 -1
- {generalmanager-0.52.2 → generalmanager-0.53.1}/pyproject.toml +1 -1
- {generalmanager-0.52.2 → generalmanager-0.53.1/src/GeneralManager.egg-info}/PKG-INFO +1 -1
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/bucket/calculation_bucket.py +17 -17
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/bucket/database_bucket.py +128 -19
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/run_context.py +10 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/orm_interface.py +29 -1
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/manager/general_manager.py +51 -1
- {generalmanager-0.52.2 → generalmanager-0.53.1}/LICENSE +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/README.md +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/setup.cfg +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/GeneralManager.egg-info/SOURCES.txt +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/GeneralManager.egg-info/dependency_links.txt +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/GeneralManager.egg-info/requires.txt +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/GeneralManager.egg-info/top_level.txt +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/api.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/bucket.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/cache.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/factory.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/general_manager.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/interface.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/manager.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/measurement.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/permission.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/rule.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/search.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/utils.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/graphql.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/graphql_errors.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/graphql_mutations.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/graphql_prefetch.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/graphql_resolvers.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/graphql_search.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/graphql_subscription_consumer.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/graphql_subscriptions.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/graphql_view.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/mutation.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/property.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/registry.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/remote_api.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/remote_invalidation.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/remote_invalidation_client.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/apps.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/bootstrap.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/bucket/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/bucket/base_bucket.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/bucket/group_bucket.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/bucket/indexing.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/bucket/request_bucket.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/cache_decorator.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/cache_tracker.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/dependency_cache.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/dependency_index.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/dependency_matching.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/dependency_publish.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/dependency_shards.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/model_dependency_collector.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/signals.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/conf.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/factory/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/factory/auto_factory.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/factory/factories.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/factory/factory_methods.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/base_interface.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/bundles/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/bundles/calculation.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/bundles/database.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/bundles/remote_manager.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/bundles/request.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/base.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/builtin.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/calculation/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/calculation/_compat.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/calculation/lifecycle.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/configuration.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/core/observability.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/core/utils.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/exceptions.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/existing_model/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/existing_model/_compat.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/existing_model/resolution.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/factory.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/orm/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/orm/_compat.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/orm/history.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/orm/lifecycle.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/orm/mutations.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/orm/support.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/orm_utils/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/orm_utils/django_manager_utils.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/orm_utils/field_descriptors.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/orm_utils/payload_normalizer.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/read_only/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/read_only/_compat.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/read_only/lifecycle.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/read_only/management.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/registry.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/remote_manager.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/capabilities/request/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/infrastructure/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/infrastructure/startup_hooks.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/infrastructure/system_checks.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/interfaces/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/interfaces/calculation.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/interfaces/database.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/interfaces/existing_model.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/interfaces/read_only.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/interfaces/remote_manager.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/interfaces/request.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/manifests/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/manifests/capability_builder.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/manifests/capability_manifest.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/manifests/capability_models.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/requests.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/utils/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/utils/database_interface_protocols.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/utils/errors.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/utils/models.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/logging.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/management/commands/search_index.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/management/commands/seed_manager_landscape.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/management/commands/shell.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/management/commands/workflow_drain_outbox.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/management/commands/workflow_replay_dead_letters.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/manager/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/manager/group_manager.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/manager/input.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/manager/meta.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/measurement/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/measurement/measurement.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/measurement/measurement_field.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/metrics/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/metrics/graphql.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/migrations/0001_initial.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/migrations/0002_workflow_outbox_scaling_indexes.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/migrations/0003_workflow_execution_correlation_constraint.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/migrations/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/models.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/permission/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/permission/audit.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/permission/base_permission.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/permission/graphql_capabilities.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/permission/manager_based_permission.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/permission/mutation_permission.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/permission/permission_checks.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/permission/permission_data_manager.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/permission/utils.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/public_api_registry.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/py.typed +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/rule/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/rule/handler.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/rule/rule.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/async_tasks.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/backend.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/backend_registry.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/backends/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/backends/dev.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/backends/meilisearch.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/backends/opensearch.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/backends/typesense.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/config.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/indexer.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/registry.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/search/utils.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/seeding/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/seeding/manager_landscape.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/utils/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/utils/args_to_kwargs.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/utils/filter_parser.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/utils/format_string.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/utils/json_encoder.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/utils/make_cache_key.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/utils/none_to_zero.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/utils/path_mapping.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/utils/public_api.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/utils/testing.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/utils/type_checks.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/actions.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/backend_registry.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/backends/__init__.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/backends/celery.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/backends/local.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/backends/n8n.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/config.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/engine.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/event_registry.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/events.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/models.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/signal_bridge.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/tasks.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/workflow/telemetry.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/tests/test_settings.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/tests/test_urls.py +0 -0
- {generalmanager-0.52.2 → generalmanager-0.53.1}/tests/testing_asgi.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: GeneralManager
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.53.1
|
|
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.
|
|
7
|
+
version = "0.53.1"
|
|
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.
|
|
3
|
+
Version: 0.53.1
|
|
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
|
{generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/bucket/calculation_bucket.py
RENAMED
|
@@ -521,21 +521,21 @@ class CalculationBucket(Bucket[GeneralManagerType]):
|
|
|
521
521
|
if self._data is None:
|
|
522
522
|
from general_manager.cache.run_context import ensure_calculation_run_context
|
|
523
523
|
|
|
524
|
-
sorted_inputs = self.topological_sort_inputs()
|
|
525
|
-
sorted_filters = self._sort_filters(sorted_inputs)
|
|
526
|
-
current_combinations = self._generate_input_combinations(
|
|
527
|
-
sorted_inputs,
|
|
528
|
-
sorted_filters["input_filters"],
|
|
529
|
-
sorted_filters["input_excludes"],
|
|
530
|
-
)
|
|
531
|
-
sort_key = self._normalized_sort_key()
|
|
532
|
-
needs_manager_access = (
|
|
533
|
-
bool(sorted_filters["prop_filters"])
|
|
534
|
-
or bool(sorted_filters["prop_excludes"])
|
|
535
|
-
or not self._sort_uses_only_inputs(sort_key)
|
|
536
|
-
)
|
|
537
|
-
|
|
538
524
|
with ensure_calculation_run_context():
|
|
525
|
+
sorted_inputs = self.topological_sort_inputs()
|
|
526
|
+
sorted_filters = self._sort_filters(sorted_inputs)
|
|
527
|
+
current_combinations = self._generate_input_combinations(
|
|
528
|
+
sorted_inputs,
|
|
529
|
+
sorted_filters["input_filters"],
|
|
530
|
+
sorted_filters["input_excludes"],
|
|
531
|
+
)
|
|
532
|
+
sort_key = self._normalized_sort_key()
|
|
533
|
+
needs_manager_access = (
|
|
534
|
+
bool(sorted_filters["prop_filters"])
|
|
535
|
+
or bool(sorted_filters["prop_excludes"])
|
|
536
|
+
or not self._sort_uses_only_inputs(sort_key)
|
|
537
|
+
)
|
|
538
|
+
|
|
539
539
|
if needs_manager_access:
|
|
540
540
|
manager_combinations = self._manager_combinations(
|
|
541
541
|
current_combinations
|
|
@@ -564,9 +564,9 @@ class CalculationBucket(Bucket[GeneralManagerType]):
|
|
|
564
564
|
sort_key,
|
|
565
565
|
)
|
|
566
566
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
567
|
+
if self.reverse:
|
|
568
|
+
identifications.reverse()
|
|
569
|
+
self._data = identifications
|
|
570
570
|
|
|
571
571
|
return self._data
|
|
572
572
|
|
{generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/bucket/database_bucket.py
RENAMED
|
@@ -257,11 +257,44 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
257
257
|
),
|
|
258
258
|
)
|
|
259
259
|
|
|
260
|
-
def
|
|
260
|
+
def _build_manager_from_primary_key(self, pk: Any) -> GeneralManagerType:
|
|
261
261
|
if self._search_date is None:
|
|
262
262
|
return self._manager_class(pk)
|
|
263
263
|
return self._manager_class(pk, search_date=self._search_date)
|
|
264
264
|
|
|
265
|
+
def _can_trust_orm_instance(self, instance: models.Model) -> bool:
|
|
266
|
+
interface_model = getattr(self._manager_class.Interface, "_model", None)
|
|
267
|
+
if isinstance(interface_model, type) and issubclass(
|
|
268
|
+
interface_model, models.Model
|
|
269
|
+
):
|
|
270
|
+
if not isinstance(instance, interface_model):
|
|
271
|
+
return False
|
|
272
|
+
get_deferred_fields = getattr(instance, "get_deferred_fields", None)
|
|
273
|
+
if callable(get_deferred_fields) and get_deferred_fields():
|
|
274
|
+
return False
|
|
275
|
+
if self._search_date is not None and not (
|
|
276
|
+
hasattr(instance, "_history") or hasattr(instance, "history_date")
|
|
277
|
+
):
|
|
278
|
+
return False
|
|
279
|
+
return True
|
|
280
|
+
|
|
281
|
+
def _build_manager_from_instance(
|
|
282
|
+
self,
|
|
283
|
+
instance: models.Model,
|
|
284
|
+
) -> GeneralManagerType:
|
|
285
|
+
interface_hydrate = getattr(
|
|
286
|
+
self._manager_class.Interface, "_from_trusted_orm_instance", None
|
|
287
|
+
)
|
|
288
|
+
manager_hydrate = self._manager_class._from_trusted_orm_instance
|
|
289
|
+
if callable(interface_hydrate) and self._can_trust_orm_instance(instance):
|
|
290
|
+
return manager_hydrate(instance, search_date=self._search_date)
|
|
291
|
+
return self._build_manager_from_primary_key(instance.pk)
|
|
292
|
+
|
|
293
|
+
def _build_manager(self, value: Any) -> GeneralManagerType:
|
|
294
|
+
if isinstance(value, models.Model):
|
|
295
|
+
return self._build_manager_from_instance(value)
|
|
296
|
+
return self._build_manager_from_primary_key(value)
|
|
297
|
+
|
|
265
298
|
@staticmethod
|
|
266
299
|
def _copy_filter_definitions(
|
|
267
300
|
definitions: dict[str, Any] | None,
|
|
@@ -314,6 +347,11 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
314
347
|
return None
|
|
315
348
|
if query.distinct:
|
|
316
349
|
return None
|
|
350
|
+
if getattr(self._data, "_prefetch_related_lookups", ()):
|
|
351
|
+
return None
|
|
352
|
+
deferred_loading = getattr(query, "deferred_loading", None)
|
|
353
|
+
if isinstance(deferred_loading, tuple) and deferred_loading[0]:
|
|
354
|
+
return None
|
|
317
355
|
try:
|
|
318
356
|
sql, params = self._data.query.sql_with_params()
|
|
319
357
|
except (EmptyResultSet, FieldError, TypeError, ValueError):
|
|
@@ -360,16 +398,44 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
360
398
|
if cached is not None:
|
|
361
399
|
return cached # type: ignore[return-value]
|
|
362
400
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
401
|
+
if self._data.ordered:
|
|
402
|
+
primary_keys = tuple(
|
|
403
|
+
self._data.values_list("pk", flat=True)[
|
|
404
|
+
: MAX_RUN_SCOPED_BUCKET_RESULT_ROWS + 1
|
|
405
|
+
]
|
|
406
|
+
)
|
|
407
|
+
else:
|
|
408
|
+
# Preserve the order normal queryset iteration would expose.
|
|
409
|
+
primary_keys = tuple(
|
|
410
|
+
row.pk for row in self._data[: MAX_RUN_SCOPED_BUCKET_RESULT_ROWS + 1]
|
|
411
|
+
)
|
|
368
412
|
if len(primary_keys) > MAX_RUN_SCOPED_BUCKET_RESULT_ROWS:
|
|
369
413
|
return None
|
|
370
414
|
context.set_orm_bucket_result(signature, primary_keys)
|
|
371
415
|
return primary_keys
|
|
372
416
|
|
|
417
|
+
def _get_run_scoped_rows(self) -> tuple[models.Model, ...] | None:
|
|
418
|
+
"""
|
|
419
|
+
Load or reuse a bounded model-row snapshot for trusted hydration.
|
|
420
|
+
"""
|
|
421
|
+
context = current_calculation_run_context()
|
|
422
|
+
if context is None:
|
|
423
|
+
return None
|
|
424
|
+
signature = self._query_signature()
|
|
425
|
+
if signature is None:
|
|
426
|
+
return None
|
|
427
|
+
cached = context.get_orm_bucket_rows(signature)
|
|
428
|
+
if cached is not None:
|
|
429
|
+
return cached # type: ignore[return-value]
|
|
430
|
+
|
|
431
|
+
rows = tuple(self._data[: MAX_RUN_SCOPED_BUCKET_RESULT_ROWS + 1])
|
|
432
|
+
if len(rows) > MAX_RUN_SCOPED_BUCKET_RESULT_ROWS:
|
|
433
|
+
return None
|
|
434
|
+
primary_keys = tuple(row.pk for row in rows)
|
|
435
|
+
context.set_orm_bucket_rows(signature, rows)
|
|
436
|
+
context.set_orm_bucket_result(signature, primary_keys)
|
|
437
|
+
return rows
|
|
438
|
+
|
|
373
439
|
def _peek_run_scoped_primary_keys(self) -> tuple[Any, ...] | None:
|
|
374
440
|
"""
|
|
375
441
|
Return an already cached primary-key snapshot without evaluating the ORM.
|
|
@@ -393,6 +459,19 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
393
459
|
return None
|
|
394
460
|
return cached # type: ignore[return-value]
|
|
395
461
|
|
|
462
|
+
def _peek_run_scoped_rows(self) -> tuple[models.Model, ...] | None:
|
|
463
|
+
"""Return cached model rows without evaluating the ORM."""
|
|
464
|
+
context = current_calculation_run_context()
|
|
465
|
+
if context is None:
|
|
466
|
+
return None
|
|
467
|
+
signature = self._query_signature()
|
|
468
|
+
if signature is None:
|
|
469
|
+
return None
|
|
470
|
+
cached = context.get_orm_bucket_rows(signature)
|
|
471
|
+
if cached is None:
|
|
472
|
+
return None
|
|
473
|
+
return cached # type: ignore[return-value]
|
|
474
|
+
|
|
396
475
|
@staticmethod
|
|
397
476
|
def _snapshot_get_primary_key(kwargs: dict[str, Any]) -> Any | None:
|
|
398
477
|
"""
|
|
@@ -458,13 +537,18 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
458
537
|
GeneralManagerType: Manager instance for each primary key in the queryset.
|
|
459
538
|
"""
|
|
460
539
|
self._track_effective_dependencies()
|
|
461
|
-
|
|
540
|
+
rows = self._get_run_scoped_rows()
|
|
541
|
+
if rows is not None:
|
|
542
|
+
for row in rows:
|
|
543
|
+
yield self._build_manager_from_instance(row)
|
|
544
|
+
return
|
|
545
|
+
primary_keys = self._peek_run_scoped_primary_keys()
|
|
462
546
|
if primary_keys is not None:
|
|
463
547
|
for primary_key in primary_keys:
|
|
464
|
-
yield self.
|
|
548
|
+
yield self._build_manager_from_primary_key(primary_key)
|
|
465
549
|
return
|
|
466
550
|
for item in self._data:
|
|
467
|
-
yield self.
|
|
551
|
+
yield self._build_manager_from_instance(item)
|
|
468
552
|
|
|
469
553
|
def __or__(
|
|
470
554
|
self,
|
|
@@ -585,7 +669,7 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
585
669
|
"""
|
|
586
670
|
ids: list[int] = []
|
|
587
671
|
for obj in query_set:
|
|
588
|
-
inst = self.
|
|
672
|
+
inst = self._build_manager_from_instance(obj)
|
|
589
673
|
keep = True
|
|
590
674
|
for k, val, root in python_filters:
|
|
591
675
|
lookup = k.split("__", 1)[1] if "__" in k else ""
|
|
@@ -704,15 +788,20 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
704
788
|
GeneralManagerType | None: First manager instance if available.
|
|
705
789
|
"""
|
|
706
790
|
self._track_effective_dependencies()
|
|
791
|
+
rows = self._peek_run_scoped_rows()
|
|
792
|
+
if rows is not None:
|
|
793
|
+
if not rows:
|
|
794
|
+
return None
|
|
795
|
+
return self._build_manager_from_instance(rows[0])
|
|
707
796
|
primary_keys = self._peek_run_scoped_primary_keys()
|
|
708
797
|
if primary_keys is not None:
|
|
709
798
|
if not primary_keys:
|
|
710
799
|
return None
|
|
711
|
-
return self.
|
|
800
|
+
return self._build_manager_from_primary_key(primary_keys[0])
|
|
712
801
|
first_element = self._data.first()
|
|
713
802
|
if first_element is None:
|
|
714
803
|
return None
|
|
715
|
-
return self.
|
|
804
|
+
return self._build_manager_from_instance(first_element)
|
|
716
805
|
|
|
717
806
|
def last(self) -> GeneralManagerType | None:
|
|
718
807
|
"""
|
|
@@ -722,15 +811,20 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
722
811
|
GeneralManagerType | None: Last manager instance if available.
|
|
723
812
|
"""
|
|
724
813
|
self._track_effective_dependencies()
|
|
814
|
+
rows = self._peek_run_scoped_rows()
|
|
815
|
+
if rows is not None:
|
|
816
|
+
if not rows:
|
|
817
|
+
return None
|
|
818
|
+
return self._build_manager_from_instance(rows[-1])
|
|
725
819
|
primary_keys = self._peek_run_scoped_primary_keys()
|
|
726
820
|
if primary_keys is not None:
|
|
727
821
|
if not primary_keys:
|
|
728
822
|
return None
|
|
729
|
-
return self.
|
|
823
|
+
return self._build_manager_from_primary_key(primary_keys[-1])
|
|
730
824
|
first_element = self._data.last()
|
|
731
825
|
if first_element is None:
|
|
732
826
|
return None
|
|
733
|
-
return self.
|
|
827
|
+
return self._build_manager_from_instance(first_element)
|
|
734
828
|
|
|
735
829
|
def count(self) -> int:
|
|
736
830
|
"""
|
|
@@ -778,18 +872,28 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
778
872
|
models.MultipleObjectsReturned: Propagated when multiple rows satisfy the lookup.
|
|
779
873
|
"""
|
|
780
874
|
self._track_effective_dependencies()
|
|
875
|
+
rows = self._peek_run_scoped_rows()
|
|
876
|
+
if rows is not None:
|
|
877
|
+
requested_primary_key = self._snapshot_get_primary_key(kwargs)
|
|
878
|
+
if requested_primary_key is not None:
|
|
879
|
+
matches = [row for row in rows if row.pk == requested_primary_key]
|
|
880
|
+
if len(matches) == 1:
|
|
881
|
+
return self._build_manager_from_instance(matches[0])
|
|
882
|
+
if len(matches) > 1:
|
|
883
|
+
raise self._data.model.MultipleObjectsReturned
|
|
884
|
+
raise self._data.model.DoesNotExist
|
|
781
885
|
primary_keys = self._peek_run_scoped_primary_keys()
|
|
782
886
|
if primary_keys is not None:
|
|
783
887
|
requested_primary_key = self._snapshot_get_primary_key(kwargs)
|
|
784
888
|
if requested_primary_key is not None:
|
|
785
889
|
match_count = primary_keys.count(requested_primary_key)
|
|
786
890
|
if match_count == 1:
|
|
787
|
-
return self.
|
|
891
|
+
return self._build_manager_from_primary_key(requested_primary_key)
|
|
788
892
|
if match_count > 1:
|
|
789
893
|
raise self._data.model.MultipleObjectsReturned
|
|
790
894
|
raise self._data.model.DoesNotExist
|
|
791
895
|
element = self._data.get(**kwargs)
|
|
792
|
-
return self.
|
|
896
|
+
return self._build_manager_from_instance(element)
|
|
793
897
|
|
|
794
898
|
def __getitem__(
|
|
795
899
|
self, item: int | slice
|
|
@@ -815,12 +919,17 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
815
919
|
run_scoped_cacheable=self._run_scoped_cacheable,
|
|
816
920
|
)
|
|
817
921
|
self._track_effective_dependencies()
|
|
922
|
+
rows = self._peek_run_scoped_rows()
|
|
923
|
+
if rows is not None:
|
|
924
|
+
if item < 0:
|
|
925
|
+
raise ValueError
|
|
926
|
+
return self._build_manager_from_instance(rows[item])
|
|
818
927
|
primary_keys = self._peek_run_scoped_primary_keys()
|
|
819
928
|
if primary_keys is not None:
|
|
820
929
|
if item < 0:
|
|
821
930
|
raise ValueError
|
|
822
|
-
return self.
|
|
823
|
-
return self.
|
|
931
|
+
return self._build_manager_from_primary_key(primary_keys[item])
|
|
932
|
+
return self._build_manager_from_instance(self._data[item])
|
|
824
933
|
|
|
825
934
|
def __len__(self) -> int:
|
|
826
935
|
"""
|
|
@@ -926,7 +1035,7 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
926
1035
|
objs = list(qs)
|
|
927
1036
|
|
|
928
1037
|
def key_func(obj: models.Model) -> tuple[object, ...]:
|
|
929
|
-
inst = self.
|
|
1038
|
+
inst = self._build_manager_from_instance(obj)
|
|
930
1039
|
values = []
|
|
931
1040
|
for k in key:
|
|
932
1041
|
if k in properties:
|
|
@@ -26,6 +26,7 @@ _active_context: ContextVar["CalculationRunContext | None"] = ContextVar(
|
|
|
26
26
|
default=None,
|
|
27
27
|
)
|
|
28
28
|
ORM_BUCKET_RESULT_PREFIX = "orm_bucket_result"
|
|
29
|
+
ORM_BUCKET_ROW_RESULT_PREFIX = "orm_bucket_row_result"
|
|
29
30
|
BUCKET_INDEX_PREFIX = "bucket_index"
|
|
30
31
|
DEFAULT_DEPENDENCY_CACHE_PUBLISH_BATCH_SIZE = 1000
|
|
31
32
|
logger = get_logger("cache.run_context")
|
|
@@ -191,9 +192,18 @@ class CalculationRunContext:
|
|
|
191
192
|
"""Store an ORM bucket result for the active run."""
|
|
192
193
|
self.set((ORM_BUCKET_RESULT_PREFIX, key), value)
|
|
193
194
|
|
|
195
|
+
def get_orm_bucket_rows(self, key: Hashable) -> object:
|
|
196
|
+
"""Return cached ORM bucket rows for key, or None when absent."""
|
|
197
|
+
return self.get((ORM_BUCKET_ROW_RESULT_PREFIX, key))
|
|
198
|
+
|
|
199
|
+
def set_orm_bucket_rows(self, key: Hashable, value: object) -> None:
|
|
200
|
+
"""Store ORM bucket rows for the active run."""
|
|
201
|
+
self.set((ORM_BUCKET_ROW_RESULT_PREFIX, key), value)
|
|
202
|
+
|
|
194
203
|
def clear_orm_bucket_results(self) -> None:
|
|
195
204
|
"""Discard all run-scoped ORM bucket result entries."""
|
|
196
205
|
self.discard_prefix((ORM_BUCKET_RESULT_PREFIX,))
|
|
206
|
+
self.discard_prefix((ORM_BUCKET_ROW_RESULT_PREFIX,))
|
|
197
207
|
|
|
198
208
|
def _bucket_index_cache_key(
|
|
199
209
|
self,
|
{generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/orm_interface.py
RENAMED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
from datetime import datetime
|
|
6
|
-
from typing import ClassVar, Generic, Type, TypeVar, cast
|
|
6
|
+
from typing import Any, ClassVar, Generic, Type, TypeVar, cast
|
|
7
7
|
|
|
8
8
|
from django.db import models
|
|
9
9
|
from django.utils import timezone
|
|
@@ -60,6 +60,34 @@ class OrmInterfaceBase(InterfaceBase, Generic[HistoryModelT]):
|
|
|
60
60
|
self._search_date = self.normalize_search_date(search_date)
|
|
61
61
|
self._instance: HistoryModelT = self.get_data()
|
|
62
62
|
|
|
63
|
+
@classmethod
|
|
64
|
+
def _from_trusted_orm_instance(
|
|
65
|
+
cls,
|
|
66
|
+
instance: HistoryModelT,
|
|
67
|
+
*,
|
|
68
|
+
search_date: datetime | None = None,
|
|
69
|
+
) -> "OrmInterfaceBase[HistoryModelT]":
|
|
70
|
+
"""
|
|
71
|
+
Build an interface from an ORM-loaded row without public input validation.
|
|
72
|
+
|
|
73
|
+
This is an internal trusted path. Callers must only pass model or
|
|
74
|
+
historical rows that came from Django ORM querysets owned by this
|
|
75
|
+
interface. External/API/user payloads must continue through __init__.
|
|
76
|
+
"""
|
|
77
|
+
pk = cast(Any, instance).pk
|
|
78
|
+
if cls.__init__ is not OrmInterfaceBase.__init__:
|
|
79
|
+
if search_date is None:
|
|
80
|
+
return cls(pk)
|
|
81
|
+
return cls(pk, search_date=search_date)
|
|
82
|
+
|
|
83
|
+
interface = cls.__new__(cls)
|
|
84
|
+
identification = {"id": pk}
|
|
85
|
+
interface.identification = identification
|
|
86
|
+
interface.pk = pk
|
|
87
|
+
interface._search_date = cls.normalize_search_date(search_date)
|
|
88
|
+
interface._instance = instance
|
|
89
|
+
return interface
|
|
90
|
+
|
|
63
91
|
@staticmethod
|
|
64
92
|
def normalize_search_date(search_date: datetime | None) -> datetime | None:
|
|
65
93
|
"""
|
{generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/manager/general_manager.py
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
from collections.abc import Mapping
|
|
3
|
-
from typing import TYPE_CHECKING, Any, Iterator, Self, Type
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Iterator, Self, Type, cast
|
|
4
4
|
|
|
5
5
|
from general_manager.api.property import GraphQLProperty
|
|
6
6
|
from general_manager.bucket.base_bucket import Bucket
|
|
@@ -24,6 +24,13 @@ class UnsupportedUnionOperandError(TypeError):
|
|
|
24
24
|
super().__init__(f"Unsupported type for union: {operand_type}.")
|
|
25
25
|
|
|
26
26
|
|
|
27
|
+
class TrustedOrmHydrationNotSupportedError(TypeError):
|
|
28
|
+
"""Raised when trusted ORM hydration is requested for a non-ORM interface."""
|
|
29
|
+
|
|
30
|
+
def __init__(self, interface_name: str) -> None:
|
|
31
|
+
super().__init__(f"{interface_name} does not support trusted ORM hydration.")
|
|
32
|
+
|
|
33
|
+
|
|
27
34
|
if TYPE_CHECKING:
|
|
28
35
|
from general_manager.permission.base_permission import BasePermission
|
|
29
36
|
from general_manager.interface.base_interface import InterfaceBase
|
|
@@ -65,6 +72,49 @@ class GeneralManager(metaclass=GeneralManagerMeta):
|
|
|
65
72
|
},
|
|
66
73
|
)
|
|
67
74
|
|
|
75
|
+
@classmethod
|
|
76
|
+
def _from_trusted_orm_instance(
|
|
77
|
+
cls,
|
|
78
|
+
instance: Any,
|
|
79
|
+
*,
|
|
80
|
+
search_date: Any = None,
|
|
81
|
+
) -> Self:
|
|
82
|
+
"""
|
|
83
|
+
Build a manager around an ORM-loaded row without public input validation.
|
|
84
|
+
|
|
85
|
+
This private path is only for framework-owned Django ORM rows. It must
|
|
86
|
+
not be used for GraphQL, mutation, import, factory, or other external
|
|
87
|
+
payloads because it bypasses Interface input validation.
|
|
88
|
+
"""
|
|
89
|
+
hydrate = getattr(cls.Interface, "_from_trusted_orm_instance", None)
|
|
90
|
+
if not callable(hydrate):
|
|
91
|
+
raise TrustedOrmHydrationNotSupportedError(cls.Interface.__name__)
|
|
92
|
+
|
|
93
|
+
if cls.__init__ is not GeneralManager.__init__:
|
|
94
|
+
pk = instance.pk
|
|
95
|
+
if search_date is None:
|
|
96
|
+
return cls(pk)
|
|
97
|
+
return cls(pk, search_date=search_date)
|
|
98
|
+
|
|
99
|
+
manager = cls.__new__(cls)
|
|
100
|
+
manager._interface = hydrate(instance, search_date=search_date)
|
|
101
|
+
manager.__id = manager._interface.identification
|
|
102
|
+
manager._manager_state_valid = True
|
|
103
|
+
manager._manager_state_reason = None
|
|
104
|
+
DependencyTracker.track(
|
|
105
|
+
cls.__name__,
|
|
106
|
+
"identification",
|
|
107
|
+
serialize_dependency_identifier(manager.__id),
|
|
108
|
+
)
|
|
109
|
+
logger.debug(
|
|
110
|
+
"trusted orm manager hydrated",
|
|
111
|
+
context={
|
|
112
|
+
"manager": cls.__name__,
|
|
113
|
+
"identification": manager.__id,
|
|
114
|
+
},
|
|
115
|
+
)
|
|
116
|
+
return cast(Self, manager)
|
|
117
|
+
|
|
68
118
|
def __str__(self) -> str:
|
|
69
119
|
"""Return a user-friendly representation showing the identification."""
|
|
70
120
|
return f"{self.__class__.__name__}(**{self.__id})"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.52.2 → generalmanager-0.53.1}/src/GeneralManager.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/_types/general_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/graphql_mutations.py
RENAMED
|
File without changes
|
|
File without changes
|
{generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/graphql_resolvers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/graphql_subscriptions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/api/remote_invalidation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/bucket/request_bucket.py
RENAMED
|
File without changes
|
|
File without changes
|
{generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/cache_decorator.py
RENAMED
|
File without changes
|
|
File without changes
|
{generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/dependency_cache.py
RENAMED
|
File without changes
|
{generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/dependency_index.py
RENAMED
|
File without changes
|
{generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/dependency_matching.py
RENAMED
|
File without changes
|
{generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/dependency_publish.py
RENAMED
|
File without changes
|
{generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/cache/dependency_shards.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/factory/factory_methods.py
RENAMED
|
File without changes
|
|
File without changes
|
{generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/base_interface.py
RENAMED
|
File without changes
|
{generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/bundles/__init__.py
RENAMED
|
File without changes
|
{generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/bundles/calculation.py
RENAMED
|
File without changes
|
{generalmanager-0.52.2 → generalmanager-0.53.1}/src/general_manager/interface/bundles/database.py
RENAMED
|
File without changes
|