GeneralManager 0.85.0__tar.gz → 0.86.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.85.0/src/GeneralManager.egg-info → generalmanager-0.86.1}/PKG-INFO +1 -1
- {generalmanager-0.85.0 → generalmanager-0.86.1}/pyproject.toml +1 -1
- {generalmanager-0.85.0 → generalmanager-0.86.1/src/GeneralManager.egg-info}/PKG-INFO +1 -1
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/graphql.py +120 -33
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/graphql_identifiers.py +22 -3
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/graphql_resolvers.py +13 -3
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/graphql_search.py +4 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/graphql_subscriptions.py +8 -3
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/mutation.py +5 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/bootstrap.py +5 -1
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/bucket/calculation_bucket.py +117 -16
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/base_interface.py +31 -1
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/calculation/input_resolution.py +11 -3
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/manager/general_manager.py +25 -2
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/manager/input.py +152 -2
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/manager/meta.py +10 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/utils/filter_parser.py +61 -7
- {generalmanager-0.85.0 → generalmanager-0.86.1}/LICENSE +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/README.md +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/setup.cfg +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/GeneralManager.egg-info/SOURCES.txt +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/GeneralManager.egg-info/dependency_links.txt +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/GeneralManager.egg-info/requires.txt +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/GeneralManager.egg-info/top_level.txt +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/_types/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/_types/api.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/_types/bucket.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/_types/cache.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/_types/dataframes.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/_types/factory.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/_types/general_manager.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/_types/interface.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/_types/manager.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/_types/measurement.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/_types/permission.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/_types/rule.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/_types/search.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/_types/utils.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/graphql_as_of.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/graphql_errors.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/graphql_groups.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/graphql_mutations.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/graphql_ordering.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/graphql_output.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/graphql_prefetch.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/graphql_relations.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/graphql_subscription_consumer.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/graphql_type.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/graphql_view.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/graphql_warmup.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/graphql_warmup_registry.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/graphql_warmup_tasks.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/notification_batching.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/property.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/registry.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/remote_api.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/remote_invalidation.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/remote_invalidation_client.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/apps.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/as_of.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/bucket/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/bucket/_materialized_bucket.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/bucket/_ordering.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/bucket/base_bucket.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/bucket/database_bucket.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/bucket/excel_bucket.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/bucket/group_bucket.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/bucket/indexing.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/bucket/projection.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/bucket/request_bucket.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/cache/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/cache/_dependency_graph.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/cache/batch_refresh.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/cache/cache_decorator.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/cache/cache_tracker.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/cache/data_change_context.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/cache/dependency_cache.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/cache/dependency_index.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/cache/dependency_matching.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/cache/dependency_publish.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/cache/dependency_shards.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/cache/model_dependency_collector.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/cache/run_context.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/cache/run_context_lru.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/cache/signals.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/cache/transaction_barrier.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/audit.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/bootstrap.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/checks.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/consumer.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/context.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/errors.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/evals/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/evals/__main__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/evals/baseline.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/evals/datasets/basic_queries.yaml +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/evals/datasets/demo_readiness.yaml +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/evals/datasets/edge_cases.yaml +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/evals/datasets/follow_ups.yaml +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/evals/datasets/large_schema.yaml +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/evals/datasets/multi_hop.yaml +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/evals/datasets/planned_orchestration.yaml +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/evals/diagnostics.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/evals/fingerprints.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/evals/fixtures.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/evals/judges/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/evals/judges/answer_quality.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/evals/judges/contract.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/evals/judges/result_accuracy.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/evals/judges/tool_sequence.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/evals/readiness.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/evals/runner.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/evals/traces.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/grounding.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/models.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/planned/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/planned/budget.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/planned/calculations.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/planned/catalog.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/planned/config.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/planned/events.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/planned/evidence.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/planned/models.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/planned/planner.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/planned/provider_calls.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/planned/resolver.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/planned/routing.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/planned/scheduler.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/planned/synthesis.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/planned/validation.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/providers/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/providers/_shared.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/providers/anthropic.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/providers/base.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/providers/google.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/providers/ollama.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/providers/openai.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/rate_limits.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/routing.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/schema_index.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/settings.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/signals.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/system_prompt.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/tool_metadata.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/tools.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/turns.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/chat/views.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/conf.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/dataframes/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/dataframes/measurements.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/factory/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/factory/auto_factory.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/factory/factories.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/factory/factory_methods.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/bundles/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/bundles/calculation.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/bundles/database.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/bundles/excel.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/bundles/remote_manager.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/bundles/request.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/base.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/builtin.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/calculation/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/calculation/_compat.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/calculation/lifecycle.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/configuration.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/core/observability.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/core/utils.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/excel/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/exceptions.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/existing_model/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/existing_model/_compat.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/existing_model/resolution.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/factory.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/orm/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/orm/_compat.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/orm/bulk.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/orm/create_many.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/orm/history.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/orm/lifecycle.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/orm/mutations.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/orm/support.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/orm_utils/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/orm_utils/django_manager_utils.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/orm_utils/field_descriptors.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/orm_utils/payload_normalizer.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/orm_utils/update_state.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/read_only/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/read_only/_compat.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/read_only/_types.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/read_only/lifecycle.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/read_only/management.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/registry.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/remote_manager.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/capabilities/request/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/excel.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/excel_store.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/excel_workbook.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/infrastructure/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/infrastructure/startup_hooks.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/infrastructure/system_checks.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/interfaces/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/interfaces/calculation.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/interfaces/database.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/interfaces/excel.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/interfaces/existing_model.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/interfaces/read_only.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/interfaces/remote_manager.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/interfaces/request.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/manifests/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/manifests/capability_builder.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/manifests/capability_manifest.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/manifests/capability_models.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/orm_interface.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/requests.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/utils/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/utils/database_interface_protocols.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/utils/errors.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/utils/history.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/interface/utils/models.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/logging.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/management/commands/chat_cleanup.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/management/commands/cleanup_upload_intents.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/management/commands/graphql_warmup.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/management/commands/graphql_warmup_refresh_due.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/management/commands/search_index.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/management/commands/search_reconcile.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/management/commands/seed_manager_landscape.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/management/commands/shell.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/management/commands/sync_read_only.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/management/commands/workflow_drain_outbox.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/management/commands/workflow_replay_dead_letters.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/manager/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/manager/bulk_create.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/manager/group_manager.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/measurement/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/measurement/measurement.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/measurement/measurement_field.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/metrics/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/metrics/graphql.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/migrations/0001_initial.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/migrations/0002_workflow_outbox_scaling_indexes.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/migrations/0003_workflow_execution_correlation_constraint.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/migrations/0004_chat_persistence_models.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/migrations/0004_search_index_state.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/migrations/0005_merge_chat_search.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/migrations/0006_chat_pending_confirmation_scoped_ids.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/migrations/0007_upload_intent.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/migrations/0008_upload_finalization_versions.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/migrations/0009_upload_cleanup_state.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/migrations/0010_chat_pending_confirmation_portable_uniqueness.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/migrations/0011_search_index_state_dirty_generation.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/migrations/0012_chat_context_watermarks.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/migrations/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/models.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/permission/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/permission/audit.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/permission/base_permission.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/permission/graphql_capabilities.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/permission/manager_based_permission.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/permission/mutation_permission.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/permission/permission_checks.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/permission/permission_data_manager.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/permission/utils.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/public_api_registry.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/py.typed +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/rule/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/rule/handler.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/rule/rule.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/search/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/search/async_tasks.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/search/backend.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/search/backend_registry.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/search/backends/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/search/backends/dev.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/search/backends/meilisearch.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/search/backends/opensearch.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/search/backends/typesense.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/search/checks.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/search/config.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/search/identity.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/search/indexer.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/search/invalidation.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/search/m2m_invalidation.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/search/models.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/search/reconciliation.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/search/registry.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/search/tasks.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/search/utils.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/seeding/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/seeding/manager_landscape.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/uploads/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/uploads/adapters.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/uploads/checks.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/uploads/config.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/uploads/errors.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/uploads/finalization.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/uploads/graphql.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/uploads/graphql_types.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/uploads/metrics.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/uploads/models.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/uploads/public.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/uploads/s3.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/uploads/services.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/uploads/tokens.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/uploads/types.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/uploads/urls.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/uploads/views.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/utils/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/utils/_args_to_kwargs.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/utils/_cache_key_encoder.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/utils/_make_cache_key.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/utils/_none_to_zero.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/utils/format_string.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/utils/json_encoder.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/utils/path_mapping.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/utils/public_api.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/utils/testing.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/utils/type_checks.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/workflow/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/workflow/actions.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/workflow/backend_registry.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/workflow/backends/__init__.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/workflow/backends/celery.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/workflow/backends/local.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/workflow/backends/n8n.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/workflow/config.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/workflow/engine.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/workflow/event_registry.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/workflow/events.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/workflow/models.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/workflow/signal_bridge.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/workflow/tasks.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/workflow/telemetry.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/tests/test_settings.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.1}/tests/test_urls.py +0 -0
- {generalmanager-0.85.0 → generalmanager-0.86.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.86.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.86.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.86.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
|
|
@@ -47,6 +47,7 @@ from general_manager.bucket._materialized_bucket import MaterializedBucket
|
|
|
47
47
|
from general_manager.bucket.group_bucket import GroupBucket
|
|
48
48
|
from general_manager.bucket.request_bucket import RequestBucket
|
|
49
49
|
from general_manager.bucket.indexing import freeze_bucket_index_value
|
|
50
|
+
from general_manager.cache.cache_tracker import DependencyTracker
|
|
50
51
|
from general_manager.cache.dependency_index import (
|
|
51
52
|
Dependency,
|
|
52
53
|
)
|
|
@@ -116,6 +117,7 @@ from general_manager.api.graphql_resolvers import (
|
|
|
116
117
|
apply_pagination as _apply_pagination_fn,
|
|
117
118
|
apply_grouping as _apply_grouping_fn,
|
|
118
119
|
check_read_permission as _check_read_permission_fn,
|
|
120
|
+
check_read_permission_for_user as _check_read_permission_for_user_fn,
|
|
119
121
|
can_read_instance_for_user as _can_read_instance_for_user_fn,
|
|
120
122
|
create_measurement_resolver as _create_measurement_resolver_fn,
|
|
121
123
|
create_normal_resolver as _create_normal_resolver_fn,
|
|
@@ -835,14 +837,25 @@ class GraphQL:
|
|
|
835
837
|
graphene_type_name = f"{generalManagerClass.__name__}Type"
|
|
836
838
|
fields: GraphQLFieldMap = {}
|
|
837
839
|
|
|
840
|
+
# Only declared typed-list inputs opt into native list output semantics.
|
|
841
|
+
input_fields = getattr(interface_cls, "input_fields", {})
|
|
838
842
|
# Map Attribute Types to Graphene Fields
|
|
839
|
-
for field_name,
|
|
843
|
+
for field_name, attribute_info in interface_cls.get_attribute_types().items():
|
|
844
|
+
field_info: Mapping[str, object] = attribute_info
|
|
845
|
+
input_field = input_fields.get(field_name)
|
|
846
|
+
is_collection_input = getattr(input_field, "is_collection", False) is True
|
|
847
|
+
if is_collection_input:
|
|
848
|
+
field_info = {**field_info, "is_collection_input": True}
|
|
840
849
|
field_type = field_info["type"]
|
|
841
850
|
resolved_manager_type = resolve_general_manager_type(
|
|
842
851
|
field_type,
|
|
843
852
|
cls.manager_registry,
|
|
844
853
|
)
|
|
845
|
-
resolved_field_type =
|
|
854
|
+
resolved_field_type = (
|
|
855
|
+
field_type
|
|
856
|
+
if is_collection_input
|
|
857
|
+
else resolved_manager_type or field_type
|
|
858
|
+
)
|
|
846
859
|
fields[field_name] = cls._map_field_to_graphene_read(
|
|
847
860
|
resolved_field_type,
|
|
848
861
|
field_name,
|
|
@@ -873,10 +886,22 @@ class GraphQL:
|
|
|
873
886
|
)
|
|
874
887
|
|
|
875
888
|
fields[resolver_name] = resolve_stored_file
|
|
889
|
+
elif is_collection_input:
|
|
890
|
+
fields[resolver_name] = (
|
|
891
|
+
cls._create_measurement_resolver(field_name)
|
|
892
|
+
if safe_issubclass(get_args(field_type)[0], Measurement)
|
|
893
|
+
else _create_normal_resolver_fn(
|
|
894
|
+
field_name,
|
|
895
|
+
authorize_manager_collection=resolve_general_manager_type(
|
|
896
|
+
get_args(field_type)[0], cls.manager_registry
|
|
897
|
+
)
|
|
898
|
+
is not None,
|
|
899
|
+
)
|
|
900
|
+
)
|
|
876
901
|
else:
|
|
877
902
|
fields[resolver_name] = cls._create_resolver(
|
|
878
903
|
field_name,
|
|
879
|
-
resolved_field_type,
|
|
904
|
+
cast(type, resolved_field_type),
|
|
880
905
|
)
|
|
881
906
|
if (
|
|
882
907
|
field_name.endswith("_list")
|
|
@@ -1396,6 +1421,24 @@ class GraphQL:
|
|
|
1396
1421
|
Returns:
|
|
1397
1422
|
object: Graphene field or type configured for the attribute.
|
|
1398
1423
|
"""
|
|
1424
|
+
if field_info and field_info.get("is_collection_input") is True:
|
|
1425
|
+
element = get_args(field_type)[0]
|
|
1426
|
+
manager_element = resolve_general_manager_type(
|
|
1427
|
+
element, GraphQL.manager_registry
|
|
1428
|
+
)
|
|
1429
|
+
if manager_element is not None:
|
|
1430
|
+
return graphene.List(
|
|
1431
|
+
graphene.NonNull(
|
|
1432
|
+
lambda: GraphQL.graphql_type_registry[manager_element.__name__]
|
|
1433
|
+
)
|
|
1434
|
+
)
|
|
1435
|
+
scalar = (
|
|
1436
|
+
MeasurementType
|
|
1437
|
+
if safe_issubclass(element, Measurement)
|
|
1438
|
+
else GraphQL._map_field_to_graphene_base_type(element)
|
|
1439
|
+
)
|
|
1440
|
+
return graphene.List(graphene.NonNull(scalar))
|
|
1441
|
+
|
|
1399
1442
|
manager_type = resolve_general_manager_type(
|
|
1400
1443
|
field_type,
|
|
1401
1444
|
GraphQL.manager_registry,
|
|
@@ -2350,6 +2393,36 @@ class GraphQL:
|
|
|
2350
2393
|
raise
|
|
2351
2394
|
return item if readable else None
|
|
2352
2395
|
|
|
2396
|
+
@classmethod
|
|
2397
|
+
def _prepare_detail_subscription(
|
|
2398
|
+
cls,
|
|
2399
|
+
manager_class: type[GeneralManager],
|
|
2400
|
+
identification: GraphQLIdentification,
|
|
2401
|
+
user: object,
|
|
2402
|
+
*,
|
|
2403
|
+
property_names: Iterable[str] = (),
|
|
2404
|
+
) -> tuple[GeneralManager, set[Dependency]] | None:
|
|
2405
|
+
"""Hydrate and authorize before priming selected readable properties.
|
|
2406
|
+
|
|
2407
|
+
Call in a worker thread: construction, native permissions and property
|
|
2408
|
+
reads may all access the ORM. Only hydration errors are suppressed;
|
|
2409
|
+
permission-backend and property failures must fail the stream closed.
|
|
2410
|
+
"""
|
|
2411
|
+
with DependencyTracker() as dependencies:
|
|
2412
|
+
try:
|
|
2413
|
+
instance, _ = cls._instantiate_manager(manager_class, identification)
|
|
2414
|
+
except SUBSCRIPTION_HYDRATION_ERRORS:
|
|
2415
|
+
return None
|
|
2416
|
+
if not _can_read_instance_for_user_fn(instance, user):
|
|
2417
|
+
return None
|
|
2418
|
+
readable_properties = [
|
|
2419
|
+
name
|
|
2420
|
+
for name in property_names
|
|
2421
|
+
if _check_read_permission_for_user_fn(instance, user, name)
|
|
2422
|
+
]
|
|
2423
|
+
cls._prime_graphql_properties(instance, readable_properties)
|
|
2424
|
+
return instance, dependencies
|
|
2425
|
+
|
|
2353
2426
|
@classmethod
|
|
2354
2427
|
def _add_subscription_field(
|
|
2355
2428
|
cls,
|
|
@@ -2370,7 +2443,7 @@ class GraphQL:
|
|
|
2370
2443
|
|
|
2371
2444
|
Notes:
|
|
2372
2445
|
- The subscribe function requires an available channel layer and subscribes the caller to channel groups derived from the instance identification and its resolved dependencies.
|
|
2373
|
-
-
|
|
2446
|
+
- Detail events contain an authorized current instance and an action; unavailable or unreadable targets terminate the detail stream.
|
|
2374
2447
|
- On termination the subscription cleans up listener tasks and unsubscribes from channel groups.
|
|
2375
2448
|
"""
|
|
2376
2449
|
manager_field_name = pascal_to_snake(generalManagerClass.__name__)
|
|
@@ -2410,27 +2483,30 @@ class GraphQL:
|
|
|
2410
2483
|
"""
|
|
2411
2484
|
Stream subscription events for a specific manager instance identified by the provided arguments.
|
|
2412
2485
|
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
Returns:
|
|
2419
|
-
AsyncIterator[SubscriptionEvent]: An asynchronous iterator that first yields a snapshot event and then yields update events; each event's `item` is the manager instance or `None` if it could not be instantiated.
|
|
2486
|
+
Authorize the request user before property priming and registration.
|
|
2487
|
+
Recheck access before each event; unavailable or unreadable targets
|
|
2488
|
+
end the iterator without forwarding the queued action. Closing the
|
|
2489
|
+
iterator removes its listeners and channel memberships.
|
|
2420
2490
|
"""
|
|
2421
2491
|
identification_copy = deepcopy(identification)
|
|
2422
2492
|
property_names = cls._subscription_property_names(info, generalManagerClass)
|
|
2493
|
+
subscription_user = info.context.user
|
|
2423
2494
|
try:
|
|
2424
|
-
|
|
2425
|
-
cls.
|
|
2495
|
+
prepared = await asyncio.to_thread(
|
|
2496
|
+
cls._prepare_detail_subscription,
|
|
2426
2497
|
generalManagerClass,
|
|
2427
2498
|
identification_copy,
|
|
2428
|
-
|
|
2499
|
+
subscription_user,
|
|
2429
2500
|
property_names=property_names,
|
|
2430
2501
|
)
|
|
2431
2502
|
except Exception as exc: # pragma: no cover - bubbled to GraphQL
|
|
2432
2503
|
raise GraphQLError(str(exc)) from exc
|
|
2433
2504
|
|
|
2505
|
+
if prepared is None:
|
|
2506
|
+
message = "Subscription target is unavailable or not readable."
|
|
2507
|
+
raise GraphQLError(message)
|
|
2508
|
+
instance, dependency_records = prepared
|
|
2509
|
+
|
|
2434
2510
|
try:
|
|
2435
2511
|
channel_layer = cast(
|
|
2436
2512
|
BaseChannelLayer, cls._get_channel_layer(strict=True)
|
|
@@ -2457,15 +2533,16 @@ class GraphQL:
|
|
|
2457
2533
|
group_names.add(cls._refresh_group_name(dependency_class))
|
|
2458
2534
|
|
|
2459
2535
|
async def event_stream() -> AsyncIterator[SubscriptionEvent]:
|
|
2460
|
-
"""
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2536
|
+
"""Deliver authorized events and clean up on every exit path."""
|
|
2537
|
+
# The iterator may be consumed long after subscribe() returns.
|
|
2538
|
+
prepared = await asyncio.to_thread(
|
|
2539
|
+
cls._prepare_detail_subscription,
|
|
2540
|
+
generalManagerClass,
|
|
2541
|
+
identification_copy,
|
|
2542
|
+
subscription_user,
|
|
2543
|
+
)
|
|
2544
|
+
if prepared is None:
|
|
2545
|
+
return
|
|
2469
2546
|
channel_name = cast(str, await channel_layer.new_channel())
|
|
2470
2547
|
queue: asyncio.Queue[str] = asyncio.Queue[str]()
|
|
2471
2548
|
joined_groups = await _join_subscription_groups(
|
|
@@ -2482,19 +2559,29 @@ class GraphQL:
|
|
|
2482
2559
|
joined_groups,
|
|
2483
2560
|
listener_task,
|
|
2484
2561
|
):
|
|
2562
|
+
# Group registration awaits I/O; access can change meanwhile.
|
|
2563
|
+
prepared = await asyncio.to_thread(
|
|
2564
|
+
cls._prepare_detail_subscription,
|
|
2565
|
+
generalManagerClass,
|
|
2566
|
+
identification_copy,
|
|
2567
|
+
subscription_user,
|
|
2568
|
+
)
|
|
2569
|
+
if prepared is None:
|
|
2570
|
+
return
|
|
2571
|
+
item, _ = prepared
|
|
2485
2572
|
clear_capability_context(info)
|
|
2486
|
-
yield SubscriptionEvent(item=
|
|
2573
|
+
yield SubscriptionEvent(item=item, action="snapshot")
|
|
2487
2574
|
while True:
|
|
2488
2575
|
action = await queue.get()
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2576
|
+
prepared = await asyncio.to_thread(
|
|
2577
|
+
cls._prepare_detail_subscription,
|
|
2578
|
+
generalManagerClass,
|
|
2579
|
+
identification_copy,
|
|
2580
|
+
subscription_user,
|
|
2581
|
+
)
|
|
2582
|
+
if prepared is None:
|
|
2583
|
+
return
|
|
2584
|
+
item, _ = prepared
|
|
2498
2585
|
clear_capability_context(info)
|
|
2499
2586
|
yield SubscriptionEvent(item=item, action=action)
|
|
2500
2587
|
|
{generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/graphql_identifiers.py
RENAMED
|
@@ -92,8 +92,13 @@ def build_identification_arguments(
|
|
|
92
92
|
# name is independent of the actual primary-key column name.
|
|
93
93
|
is_orm_id = is_orm_identifier_input(manager_class, name)
|
|
94
94
|
required = input_field.required or (for_mutation and is_orm_id)
|
|
95
|
+
is_collection = getattr(input_field, "is_collection", False) is True
|
|
96
|
+
element_type = (
|
|
97
|
+
input_field.collection_element_type if is_collection else input_field.type
|
|
98
|
+
)
|
|
99
|
+
assert element_type is not None
|
|
95
100
|
manager_type = resolve_general_manager_type(
|
|
96
|
-
|
|
101
|
+
element_type, get_graphql_manager_registry()
|
|
97
102
|
)
|
|
98
103
|
if manager_type is not None:
|
|
99
104
|
# Reuse custom mutation support for structured/composite manager
|
|
@@ -101,16 +106,30 @@ def build_identification_arguments(
|
|
|
101
106
|
from general_manager.api.mutation import (
|
|
102
107
|
_build_manager_argument_field,
|
|
103
108
|
_uses_single_id_input,
|
|
109
|
+
_get_or_create_manager_input_type,
|
|
104
110
|
)
|
|
105
111
|
|
|
112
|
+
if is_collection:
|
|
113
|
+
reference = (
|
|
114
|
+
graphene.ID
|
|
115
|
+
if _uses_single_id_input(manager_type)
|
|
116
|
+
else _get_or_create_manager_input_type(manager_type)
|
|
117
|
+
)
|
|
118
|
+
arguments[f"{name}_id"] = graphene.Argument(
|
|
119
|
+
graphene.List(graphene.NonNull(reference)), required=required
|
|
120
|
+
)
|
|
121
|
+
continue
|
|
106
122
|
arguments[f"{name}_id"] = (
|
|
107
123
|
graphene.Argument(graphene.ID, required=required)
|
|
108
124
|
if _uses_single_id_input(manager_type)
|
|
109
125
|
else _build_manager_argument_field(manager_type, required=required)
|
|
110
126
|
)
|
|
111
127
|
else:
|
|
112
|
-
scalar = map_identification_scalar(manager_class, name,
|
|
113
|
-
arguments[name] = graphene.Argument(
|
|
128
|
+
scalar = map_identification_scalar(manager_class, name, element_type)
|
|
129
|
+
arguments[name] = graphene.Argument(
|
|
130
|
+
graphene.List(graphene.NonNull(scalar)) if is_collection else scalar,
|
|
131
|
+
required=required,
|
|
132
|
+
)
|
|
114
133
|
return arguments
|
|
115
134
|
|
|
116
135
|
|
{generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/graphql_resolvers.py
RENAMED
|
@@ -1339,12 +1339,15 @@ def create_measurement_resolver(field_name: str) -> Resolver:
|
|
|
1339
1339
|
return resolver
|
|
1340
1340
|
|
|
1341
1341
|
|
|
1342
|
-
def create_normal_resolver(
|
|
1342
|
+
def create_normal_resolver(
|
|
1343
|
+
field_name: str, *, authorize_manager_collection: bool = False
|
|
1344
|
+
) -> Resolver:
|
|
1343
1345
|
"""
|
|
1344
1346
|
Return a resolver for a scalar (non-list, non-Measurement) field.
|
|
1345
1347
|
|
|
1346
1348
|
The generated resolver returns ``None`` when field read permission is denied;
|
|
1347
|
-
otherwise it returns ``getattr(self, field_name)``.
|
|
1349
|
+
otherwise it returns ``getattr(self, field_name)``. Typed manager collections
|
|
1350
|
+
additionally omit members denied by the manager-level read gate.
|
|
1348
1351
|
"""
|
|
1349
1352
|
|
|
1350
1353
|
def resolver(self: GeneralManager, info: GraphQLResolveInfo) -> object:
|
|
@@ -1356,11 +1359,18 @@ def create_normal_resolver(field_name: str) -> Resolver:
|
|
|
1356
1359
|
if relation_id is not _NO_GROUPED_RELATION_ID_ALIAS:
|
|
1357
1360
|
return relation_id
|
|
1358
1361
|
_validate_grouped_field_projection(self, field_name)
|
|
1359
|
-
|
|
1362
|
+
value = project_grouped_field_value(
|
|
1360
1363
|
self,
|
|
1361
1364
|
field_name,
|
|
1362
1365
|
read_grouped_field_value(self, field_name),
|
|
1363
1366
|
)
|
|
1367
|
+
if authorize_manager_collection and value is not None:
|
|
1368
|
+
return [
|
|
1369
|
+
member
|
|
1370
|
+
for member in cast(list[GeneralManager], value)
|
|
1371
|
+
if can_read_instance_for_user(member, info.context.user)
|
|
1372
|
+
]
|
|
1373
|
+
return value
|
|
1364
1374
|
|
|
1365
1375
|
return resolve_with_read_permission(
|
|
1366
1376
|
self,
|
|
@@ -805,6 +805,10 @@ def create_filter_options(
|
|
|
805
805
|
|
|
806
806
|
filter_fields: dict[str, GrapheneFieldType] = {}
|
|
807
807
|
for attr_name, attr_info in field_type.Interface.get_attribute_types().items():
|
|
808
|
+
# Native constructor selections do not add a new GraphQL filter language.
|
|
809
|
+
input_field = getattr(field_type.Interface, "input_fields", {}).get(attr_name)
|
|
810
|
+
if getattr(input_field, "is_collection", False) is True:
|
|
811
|
+
continue
|
|
808
812
|
effective_attr_info = _get_filter_relation_info(
|
|
809
813
|
field_type,
|
|
810
814
|
attr_name,
|
{generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/api/graphql_subscriptions.py
RENAMED
|
@@ -348,7 +348,14 @@ def resolve_subscription_dependencies(
|
|
|
348
348
|
interface_cls = manager_class.Interface
|
|
349
349
|
|
|
350
350
|
for input_name, input_field in interface_cls.input_fields.items():
|
|
351
|
-
|
|
351
|
+
manager_type = (
|
|
352
|
+
input_field.collection_element_type
|
|
353
|
+
if getattr(input_field, "is_collection", False) is True
|
|
354
|
+
else input_field.type
|
|
355
|
+
)
|
|
356
|
+
if not isinstance(manager_type, type) or not issubclass(
|
|
357
|
+
manager_type, GeneralManager
|
|
358
|
+
):
|
|
352
359
|
continue
|
|
353
360
|
|
|
354
361
|
raw_value = instance._interface.identification.get(input_name)
|
|
@@ -359,7 +366,6 @@ def resolve_subscription_dependencies(
|
|
|
359
366
|
for value in values:
|
|
360
367
|
if isinstance(value, GeneralManager):
|
|
361
368
|
identification = deepcopy(value.identification)
|
|
362
|
-
manager_type = input_field.type
|
|
363
369
|
if (
|
|
364
370
|
manager_type is manager_class
|
|
365
371
|
and identification == instance.identification
|
|
@@ -375,7 +381,6 @@ def resolve_subscription_dependencies(
|
|
|
375
381
|
dep_list.append((manager_type, identification))
|
|
376
382
|
elif isinstance(value, dict):
|
|
377
383
|
identification_dict = deepcopy(cast(Identification, value))
|
|
378
|
-
manager_type = input_field.type
|
|
379
384
|
if (
|
|
380
385
|
manager_type is manager_class
|
|
381
386
|
and identification_dict == instance.identification
|
|
@@ -180,6 +180,11 @@ def _get_or_create_manager_input_type(
|
|
|
180
180
|
for input_name, input_field in _manager_input_fields(manager_class).items():
|
|
181
181
|
field_type = input_field.type
|
|
182
182
|
required = input_field.required
|
|
183
|
+
if get_origin(field_type) is list:
|
|
184
|
+
fields[input_name] = graphene.InputField(
|
|
185
|
+
_mutation_input_type(field_type), required=required
|
|
186
|
+
)
|
|
187
|
+
continue
|
|
183
188
|
if _is_general_manager_type(field_type):
|
|
184
189
|
if _uses_single_id_input(field_type):
|
|
185
190
|
fields[input_name] = graphene.ID(required=required)
|
|
@@ -368,7 +368,11 @@ def initialize_general_manager_classes(
|
|
|
368
368
|
seen: set[str] = set()
|
|
369
369
|
input_fields = getattr(general_manager_class.Interface, "input_fields", {})
|
|
370
370
|
for attribute_name, attribute in input_fields.items():
|
|
371
|
-
if
|
|
371
|
+
if (
|
|
372
|
+
isinstance(attribute, Input)
|
|
373
|
+
and isinstance(attribute.type, type)
|
|
374
|
+
and issubclass(attribute.type, _GM)
|
|
375
|
+
):
|
|
372
376
|
seen.add(attribute_name)
|
|
373
377
|
yield attribute_name, attribute.type
|
|
374
378
|
|
{generalmanager-0.85.0 → generalmanager-0.86.1}/src/general_manager/bucket/calculation_bucket.py
RENAMED
|
@@ -36,10 +36,15 @@ from general_manager.bucket._ordering import (
|
|
|
36
36
|
validate_ordering_fields,
|
|
37
37
|
)
|
|
38
38
|
from general_manager.bucket.projection import ProjectionRows
|
|
39
|
-
from general_manager.manager.input import
|
|
39
|
+
from general_manager.manager.input import (
|
|
40
|
+
Input,
|
|
41
|
+
InputDomain,
|
|
42
|
+
_prepare_normalized_identification,
|
|
43
|
+
)
|
|
40
44
|
from general_manager.utils.filter_parser import (
|
|
41
45
|
FilterFunction,
|
|
42
46
|
ParsedFilters,
|
|
47
|
+
ParsedFilterCriteria,
|
|
43
48
|
create_filter_function,
|
|
44
49
|
parse_filters,
|
|
45
50
|
)
|
|
@@ -240,6 +245,7 @@ class CalculationBucket(Bucket[GeneralManagerType]):
|
|
|
240
245
|
parse_filters(group, possible_values) for group in self._exclude_call_groups
|
|
241
246
|
)
|
|
242
247
|
|
|
248
|
+
self._normalized_collections: dict[Hashable, object] = {}
|
|
243
249
|
self._data: list[Combination] | None = None
|
|
244
250
|
self._allowed_identifications: list[Combination] | None = None
|
|
245
251
|
self._sort_fields: tuple[str, ...] = ()
|
|
@@ -687,7 +693,7 @@ class CalculationBucket(Bucket[GeneralManagerType]):
|
|
|
687
693
|
self._ensure_as_of_compatible()
|
|
688
694
|
combinations = self.generate_combinations()
|
|
689
695
|
for combo in combinations:
|
|
690
|
-
yield self.
|
|
696
|
+
yield self._construct_manager(combo)
|
|
691
697
|
|
|
692
698
|
def _project_rows(self, fields: tuple[str, ...]) -> ProjectionRows:
|
|
693
699
|
"""Project normalized calculation inputs without manager instances."""
|
|
@@ -712,7 +718,7 @@ class CalculationBucket(Bucket[GeneralManagerType]):
|
|
|
712
718
|
tuple(
|
|
713
719
|
resolve_calculation_input_value(
|
|
714
720
|
interface_class,
|
|
715
|
-
identification,
|
|
721
|
+
self._normalized_constructor_values(identification),
|
|
716
722
|
field,
|
|
717
723
|
resolved_values,
|
|
718
724
|
)
|
|
@@ -803,8 +809,8 @@ class CalculationBucket(Bucket[GeneralManagerType]):
|
|
|
803
809
|
or any(len(group) > 1 for group in self._exclude_call_groups)
|
|
804
810
|
)
|
|
805
811
|
|
|
806
|
-
@staticmethod
|
|
807
812
|
def _matches_call_group(
|
|
813
|
+
self,
|
|
808
814
|
manager: GeneralManagerType,
|
|
809
815
|
group: ParsedFilters,
|
|
810
816
|
) -> bool:
|
|
@@ -814,9 +820,19 @@ class CalculationBucket(Bucket[GeneralManagerType]):
|
|
|
814
820
|
value = getattr(manager, field_name)
|
|
815
821
|
except AttributeError:
|
|
816
822
|
return False
|
|
817
|
-
|
|
818
|
-
|
|
823
|
+
if "collection_criteria" in definitions:
|
|
824
|
+
dependencies = {
|
|
825
|
+
name: getattr(manager, name)
|
|
826
|
+
for name in self.input_fields[field_name].depends_on
|
|
827
|
+
}
|
|
828
|
+
if not self._collection_matches(
|
|
829
|
+
field_name, value, definitions, dependencies
|
|
830
|
+
):
|
|
819
831
|
return False
|
|
832
|
+
else:
|
|
833
|
+
for filter_func in definitions.get("filter_funcs", []):
|
|
834
|
+
if not filter_func(value):
|
|
835
|
+
return False
|
|
820
836
|
for lookup, expected in definitions.get("filter_kwargs", {}).items():
|
|
821
837
|
identification = getattr(value, "identification", None)
|
|
822
838
|
lookup_parts = lookup.split("__") if lookup else []
|
|
@@ -904,13 +920,56 @@ class CalculationBucket(Bucket[GeneralManagerType]):
|
|
|
904
920
|
identity_for=lambda combo: combo,
|
|
905
921
|
)
|
|
906
922
|
|
|
923
|
+
def _normalize_collection(
|
|
924
|
+
self, name: str, value: object, context: Combination
|
|
925
|
+
) -> object:
|
|
926
|
+
"""Normalize a selection once for each dependency context in this plan."""
|
|
927
|
+
field = self.input_fields[name]
|
|
928
|
+
dependencies = {
|
|
929
|
+
dependency: context[dependency] for dependency in field.depends_on
|
|
930
|
+
}
|
|
931
|
+
key = (
|
|
932
|
+
name,
|
|
933
|
+
freeze_bucket_index_value(value),
|
|
934
|
+
freeze_bucket_index_value(dependencies),
|
|
935
|
+
)
|
|
936
|
+
if key not in self._normalized_collections:
|
|
937
|
+
self._normalized_collections[key] = field.cast(
|
|
938
|
+
value, dependencies, cache_context=(self._manager_class, name)
|
|
939
|
+
)
|
|
940
|
+
result = self._normalized_collections[key]
|
|
941
|
+
return list(result) if isinstance(result, list) else result
|
|
942
|
+
|
|
943
|
+
def _collection_matches(
|
|
944
|
+
self,
|
|
945
|
+
name: str,
|
|
946
|
+
value: object,
|
|
947
|
+
criteria: ParsedFilterCriteria,
|
|
948
|
+
context: Combination,
|
|
949
|
+
) -> bool:
|
|
950
|
+
"""Compare complete normalized selections with normalized alternatives."""
|
|
951
|
+
return all(
|
|
952
|
+
any(
|
|
953
|
+
value == self._normalize_collection(name, candidate, context)
|
|
954
|
+
for candidate in alternatives
|
|
955
|
+
)
|
|
956
|
+
for alternatives in criteria.get("collection_criteria", [])
|
|
957
|
+
)
|
|
958
|
+
|
|
959
|
+
def _normalized_constructor_values(self, combination: Combination) -> Combination:
|
|
960
|
+
"""Mark normalized lists when reconstructing bucket managers or projections."""
|
|
961
|
+
return _prepare_normalized_identification(self._manager_class, combination)
|
|
962
|
+
|
|
963
|
+
def _construct_manager(self, combination: Combination) -> GeneralManagerType:
|
|
964
|
+
return self._manager_class(**self._normalized_constructor_values(combination))
|
|
965
|
+
|
|
907
966
|
def _manager_combinations(
|
|
908
967
|
self,
|
|
909
968
|
combinations: list[Combination],
|
|
910
969
|
) -> list[GeneralManagerType]:
|
|
911
970
|
"""Instantiate managers for each raw input-combination dictionary."""
|
|
912
971
|
self._ensure_as_of_compatible()
|
|
913
|
-
return [self.
|
|
972
|
+
return [self._construct_manager(combo) for combo in combinations]
|
|
914
973
|
|
|
915
974
|
@staticmethod
|
|
916
975
|
def _manager_identifications(
|
|
@@ -1165,16 +1224,56 @@ class CalculationBucket(Bucket[GeneralManagerType]):
|
|
|
1165
1224
|
input_name: str = sorted_inputs[index]
|
|
1166
1225
|
input_field = self.input_fields[input_name]
|
|
1167
1226
|
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1227
|
+
field_filters = filters.get(input_name, {})
|
|
1228
|
+
field_excludes = excludes.get(input_name, {})
|
|
1229
|
+
possible_values: Iterable[object] | Bucket[GeneralManager] | None
|
|
1230
|
+
if input_field.is_collection and input_field.possible_values is None:
|
|
1231
|
+
if "candidate_values" in field_filters:
|
|
1232
|
+
possible_values = field_filters["candidate_values"]
|
|
1233
|
+
elif input_field.required:
|
|
1234
|
+
raise InvalidPossibleValuesError(input_name)
|
|
1235
|
+
else:
|
|
1236
|
+
possible_values = [None]
|
|
1237
|
+
else:
|
|
1238
|
+
possible_values = self.get_possible_values(
|
|
1239
|
+
input_name, input_field, current_combo
|
|
1240
|
+
)
|
|
1171
1241
|
if possible_values is None:
|
|
1172
1242
|
if input_passes_filters(input_name, current_combo):
|
|
1173
1243
|
yield from helper(index + 1, current_combo)
|
|
1174
1244
|
return
|
|
1175
1245
|
|
|
1176
|
-
|
|
1177
|
-
|
|
1246
|
+
if input_field.is_collection:
|
|
1247
|
+
from general_manager.interface.capabilities.calculation.input_resolution import (
|
|
1248
|
+
resolve_calculation_input_value,
|
|
1249
|
+
)
|
|
1250
|
+
|
|
1251
|
+
resolved_dependencies: Combination = {}
|
|
1252
|
+
for dependency in input_field.depends_on:
|
|
1253
|
+
resolve_calculation_input_value(
|
|
1254
|
+
cast(
|
|
1255
|
+
"type[CalculationInterface]", self._manager_class.Interface
|
|
1256
|
+
),
|
|
1257
|
+
self._normalized_constructor_values(current_combo),
|
|
1258
|
+
dependency,
|
|
1259
|
+
resolved_dependencies,
|
|
1260
|
+
)
|
|
1261
|
+
for raw_value in possible_values:
|
|
1262
|
+
value = self._normalize_collection(
|
|
1263
|
+
input_name, raw_value, resolved_dependencies
|
|
1264
|
+
)
|
|
1265
|
+
if not self._collection_matches(
|
|
1266
|
+
input_name, value, field_filters, resolved_dependencies
|
|
1267
|
+
):
|
|
1268
|
+
continue
|
|
1269
|
+
if field_excludes and self._collection_matches(
|
|
1270
|
+
input_name, value, field_excludes, resolved_dependencies
|
|
1271
|
+
):
|
|
1272
|
+
continue
|
|
1273
|
+
current_combo[input_name] = value
|
|
1274
|
+
yield from helper(index + 1, current_combo)
|
|
1275
|
+
del current_combo[input_name]
|
|
1276
|
+
return
|
|
1178
1277
|
|
|
1179
1278
|
# use filter_funcs and exclude_funcs to filter possible values
|
|
1180
1279
|
if isinstance(possible_values, Bucket):
|
|
@@ -1197,7 +1296,9 @@ class CalculationBucket(Bucket[GeneralManagerType]):
|
|
|
1197
1296
|
possible_values = list(possible_values)
|
|
1198
1297
|
|
|
1199
1298
|
for value in possible_values:
|
|
1200
|
-
if not isinstance(
|
|
1299
|
+
if not input_field.is_collection and not isinstance(
|
|
1300
|
+
value, input_field.type
|
|
1301
|
+
):
|
|
1201
1302
|
continue
|
|
1202
1303
|
current_combo[input_name] = value
|
|
1203
1304
|
yield from helper(index + 1, current_combo)
|
|
@@ -1247,7 +1348,7 @@ class CalculationBucket(Bucket[GeneralManagerType]):
|
|
|
1247
1348
|
matching combinations have been found.
|
|
1248
1349
|
"""
|
|
1249
1350
|
for combo in combinations:
|
|
1250
|
-
manager = self.
|
|
1351
|
+
manager = self._construct_manager(combo)
|
|
1251
1352
|
if (
|
|
1252
1353
|
allowed_identification_keys is not None
|
|
1253
1354
|
and freeze_bucket_index_value(manager.identification)
|
|
@@ -1371,10 +1472,10 @@ class CalculationBucket(Bucket[GeneralManagerType]):
|
|
|
1371
1472
|
|
|
1372
1473
|
return MaterializedBucket(
|
|
1373
1474
|
self._manager_class,
|
|
1374
|
-
tuple(self.
|
|
1475
|
+
tuple(self._construct_manager(combination) for combination in result),
|
|
1375
1476
|
snapshot=self._effective_search_date,
|
|
1376
1477
|
)
|
|
1377
|
-
return self.
|
|
1478
|
+
return self._construct_manager(result)
|
|
1378
1479
|
|
|
1379
1480
|
def __contains__(self, item: GeneralManagerType) -> bool:
|
|
1380
1481
|
"""
|