GeneralManager 0.64.4__tar.gz → 0.65.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.64.4/src/GeneralManager.egg-info → generalmanager-0.65.1}/PKG-INFO +6 -9
- {generalmanager-0.64.4 → generalmanager-0.65.1}/README.md +6 -9
- {generalmanager-0.64.4 → generalmanager-0.65.1}/pyproject.toml +1 -1
- {generalmanager-0.64.4 → generalmanager-0.65.1/src/GeneralManager.egg-info}/PKG-INFO +6 -9
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/GeneralManager.egg-info/SOURCES.txt +5 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/_types/general_manager.py +4 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/_types/search.py +4 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/api/graphql_search.py +47 -6
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/apps.py +9 -2
- generalmanager-0.65.1/src/general_manager/cache/data_change_context.py +93 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/cache/signals.py +110 -52
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/orm/mutations.py +27 -30
- generalmanager-0.65.1/src/general_manager/migrations/0011_search_index_state_dirty_generation.py +20 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/public_api_registry.py +10 -0
- generalmanager-0.65.1/src/general_manager/search/async_tasks.py +507 -0
- generalmanager-0.65.1/src/general_manager/search/checks.py +259 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/search/config.py +41 -7
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/search/indexer.py +164 -119
- generalmanager-0.65.1/src/general_manager/search/invalidation.py +1231 -0
- generalmanager-0.65.1/src/general_manager/search/m2m_invalidation.py +372 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/search/models.py +55 -37
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/search/reconciliation.py +221 -53
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/uploads/finalization.py +51 -2
- generalmanager-0.64.4/src/general_manager/search/async_tasks.py +0 -217
- {generalmanager-0.64.4 → generalmanager-0.65.1}/LICENSE +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/setup.cfg +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/GeneralManager.egg-info/dependency_links.txt +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/GeneralManager.egg-info/requires.txt +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/GeneralManager.egg-info/top_level.txt +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/_types/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/_types/api.py +3 -3
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/_types/bucket.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/_types/cache.py +2 -2
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/_types/dataframes.py +2 -2
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/_types/factory.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/_types/interface.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/_types/manager.py +2 -2
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/_types/measurement.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/_types/permission.py +2 -2
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/_types/rule.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/_types/utils.py +2 -2
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/api/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/api/graphql.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/api/graphql_errors.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/api/graphql_mutations.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/api/graphql_prefetch.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/api/graphql_relations.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/api/graphql_resolvers.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/api/graphql_subscription_consumer.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/api/graphql_subscriptions.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/api/graphql_view.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/api/graphql_warmup.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/api/graphql_warmup_registry.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/api/graphql_warmup_tasks.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/api/mutation.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/api/notification_batching.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/api/property.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/api/registry.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/api/remote_api.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/api/remote_invalidation.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/api/remote_invalidation_client.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/bootstrap.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/bucket/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/bucket/base_bucket.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/bucket/calculation_bucket.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/bucket/database_bucket.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/bucket/group_bucket.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/bucket/indexing.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/bucket/request_bucket.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/cache/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/cache/cache_decorator.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/cache/cache_tracker.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/cache/dependency_cache.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/cache/dependency_index.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/cache/dependency_matching.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/cache/dependency_publish.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/cache/dependency_shards.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/cache/model_dependency_collector.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/cache/run_context.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/audit.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/bootstrap.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/checks.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/consumer.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/errors.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/evals/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/evals/__main__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/evals/baseline.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/evals/datasets/basic_queries.yaml +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/evals/datasets/demo_readiness.yaml +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/evals/datasets/edge_cases.yaml +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/evals/datasets/follow_ups.yaml +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/evals/datasets/large_schema.yaml +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/evals/datasets/multi_hop.yaml +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/evals/diagnostics.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/evals/fingerprints.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/evals/fixtures.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/evals/judges/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/evals/judges/answer_quality.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/evals/judges/contract.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/evals/judges/result_accuracy.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/evals/judges/tool_sequence.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/evals/readiness.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/evals/runner.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/evals/traces.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/grounding.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/models.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/providers/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/providers/_shared.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/providers/anthropic.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/providers/base.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/providers/google.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/providers/ollama.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/providers/openai.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/rate_limits.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/routing.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/schema_index.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/settings.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/signals.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/system_prompt.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/tool_metadata.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/tools.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/chat/views.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/conf.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/dataframes/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/dataframes/measurements.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/factory/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/factory/auto_factory.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/factory/factories.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/factory/factory_methods.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/base_interface.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/bundles/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/bundles/calculation.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/bundles/database.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/bundles/remote_manager.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/bundles/request.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/base.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/builtin.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/calculation/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/calculation/_compat.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/calculation/lifecycle.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/configuration.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/core/observability.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/core/utils.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/exceptions.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/existing_model/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/existing_model/_compat.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/existing_model/resolution.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/factory.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/orm/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/orm/_compat.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/orm/history.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/orm/lifecycle.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/orm/support.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/orm_utils/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/orm_utils/django_manager_utils.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/orm_utils/field_descriptors.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/orm_utils/payload_normalizer.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/read_only/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/read_only/_compat.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/read_only/_types.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/read_only/lifecycle.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/read_only/management.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/registry.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/remote_manager.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/capabilities/request/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/infrastructure/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/infrastructure/startup_hooks.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/infrastructure/system_checks.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/interfaces/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/interfaces/calculation.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/interfaces/database.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/interfaces/existing_model.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/interfaces/read_only.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/interfaces/remote_manager.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/interfaces/request.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/manifests/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/manifests/capability_builder.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/manifests/capability_manifest.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/manifests/capability_models.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/orm_interface.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/requests.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/utils/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/utils/database_interface_protocols.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/utils/errors.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/utils/history.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/interface/utils/models.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/logging.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/management/commands/chat_cleanup.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/management/commands/cleanup_upload_intents.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/management/commands/graphql_warmup.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/management/commands/graphql_warmup_refresh_due.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/management/commands/search_index.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/management/commands/search_reconcile.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/management/commands/seed_manager_landscape.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/management/commands/shell.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/management/commands/workflow_drain_outbox.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/management/commands/workflow_replay_dead_letters.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/manager/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/manager/general_manager.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/manager/group_manager.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/manager/input.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/manager/meta.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/measurement/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/measurement/measurement.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/measurement/measurement_field.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/metrics/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/metrics/graphql.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/migrations/0001_initial.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/migrations/0002_workflow_outbox_scaling_indexes.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/migrations/0003_workflow_execution_correlation_constraint.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/migrations/0004_chat_persistence_models.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/migrations/0004_search_index_state.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/migrations/0005_merge_chat_search.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/migrations/0006_chat_pending_confirmation_scoped_ids.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/migrations/0007_upload_intent.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/migrations/0008_upload_finalization_versions.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/migrations/0009_upload_cleanup_state.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/migrations/0010_chat_pending_confirmation_portable_uniqueness.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/migrations/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/models.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/permission/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/permission/audit.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/permission/base_permission.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/permission/graphql_capabilities.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/permission/manager_based_permission.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/permission/mutation_permission.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/permission/permission_checks.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/permission/permission_data_manager.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/permission/utils.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/py.typed +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/rule/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/rule/handler.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/rule/rule.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/search/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/search/backend.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/search/backend_registry.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/search/backends/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/search/backends/dev.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/search/backends/meilisearch.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/search/backends/opensearch.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/search/backends/typesense.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/search/registry.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/search/tasks.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/search/utils.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/seeding/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/seeding/manager_landscape.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/uploads/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/uploads/adapters.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/uploads/checks.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/uploads/config.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/uploads/errors.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/uploads/graphql.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/uploads/graphql_types.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/uploads/metrics.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/uploads/models.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/uploads/public.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/uploads/s3.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/uploads/services.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/uploads/tokens.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/uploads/types.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/uploads/urls.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/uploads/views.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/utils/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/utils/args_to_kwargs.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/utils/filter_parser.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/utils/format_string.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/utils/json_encoder.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/utils/make_cache_key.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/utils/none_to_zero.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/utils/path_mapping.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/utils/public_api.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/utils/testing.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/utils/type_checks.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/workflow/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/workflow/actions.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/workflow/backend_registry.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/workflow/backends/__init__.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/workflow/backends/celery.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/workflow/backends/local.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/workflow/backends/n8n.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/workflow/config.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/workflow/engine.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/workflow/event_registry.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/workflow/events.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/workflow/models.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/workflow/signal_bridge.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/workflow/tasks.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/workflow/telemetry.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/tests/test_settings.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.1}/tests/test_urls.py +0 -0
- {generalmanager-0.64.4 → generalmanager-0.65.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.65.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
|
|
@@ -144,15 +144,12 @@ and [interface concepts](https://timkleindick.github.io/general_manager/concepts
|
|
|
144
144
|
|
|
145
145
|
## Compatibility
|
|
146
146
|
|
|
147
|
-
- Python 3.12 or
|
|
148
|
-
- Django 5.2.15 or
|
|
149
|
-
- CI exercises Python 3.12, 3.13, and 3.14 on SQLite
|
|
147
|
+
- Python 3.12 or later
|
|
148
|
+
- Django 5.2.15 or later
|
|
150
149
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
Django-supported backends may work, but are not currently claimed as supported
|
|
155
|
-
by GeneralManager.
|
|
150
|
+
CI tests Python 3.12, 3.13, and 3.14 against SQLite, PostgreSQL and MariaDB.
|
|
151
|
+
|
|
152
|
+
Other database backends supported by Django may also work, but are not officially supported unless covered by GeneralManager’s test suite or maintained examples.
|
|
156
153
|
|
|
157
154
|
## Five-minute setup
|
|
158
155
|
|
|
@@ -55,15 +55,12 @@ and [interface concepts](https://timkleindick.github.io/general_manager/concepts
|
|
|
55
55
|
|
|
56
56
|
## Compatibility
|
|
57
57
|
|
|
58
|
-
- Python 3.12 or
|
|
59
|
-
- Django 5.2.15 or
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
PostgreSQL, and MariaDB are exercised by CI and are fully supported. Other
|
|
65
|
-
Django-supported backends may work, but are not currently claimed as supported
|
|
66
|
-
by GeneralManager.
|
|
58
|
+
- Python 3.12 or later
|
|
59
|
+
- Django 5.2.15 or later
|
|
60
|
+
|
|
61
|
+
CI tests Python 3.12, 3.13, and 3.14 against SQLite, PostgreSQL and MariaDB.
|
|
62
|
+
|
|
63
|
+
Other database backends supported by Django may also work, but are not officially supported unless covered by GeneralManager’s test suite or maintained examples.
|
|
67
64
|
|
|
68
65
|
## Five-minute setup
|
|
69
66
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "GeneralManager"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.65.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.65.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
|
|
@@ -144,15 +144,12 @@ and [interface concepts](https://timkleindick.github.io/general_manager/concepts
|
|
|
144
144
|
|
|
145
145
|
## Compatibility
|
|
146
146
|
|
|
147
|
-
- Python 3.12 or
|
|
148
|
-
- Django 5.2.15 or
|
|
149
|
-
- CI exercises Python 3.12, 3.13, and 3.14 on SQLite
|
|
147
|
+
- Python 3.12 or later
|
|
148
|
+
- Django 5.2.15 or later
|
|
150
149
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
Django-supported backends may work, but are not currently claimed as supported
|
|
155
|
-
by GeneralManager.
|
|
150
|
+
CI tests Python 3.12, 3.13, and 3.14 against SQLite, PostgreSQL and MariaDB.
|
|
151
|
+
|
|
152
|
+
Other database backends supported by Django may also work, but are not officially supported unless covered by GeneralManager’s test suite or maintained examples.
|
|
156
153
|
|
|
157
154
|
## Five-minute setup
|
|
158
155
|
|
|
@@ -59,6 +59,7 @@ src/general_manager/bucket/request_bucket.py
|
|
|
59
59
|
src/general_manager/cache/__init__.py
|
|
60
60
|
src/general_manager/cache/cache_decorator.py
|
|
61
61
|
src/general_manager/cache/cache_tracker.py
|
|
62
|
+
src/general_manager/cache/data_change_context.py
|
|
62
63
|
src/general_manager/cache/dependency_cache.py
|
|
63
64
|
src/general_manager/cache/dependency_index.py
|
|
64
65
|
src/general_manager/cache/dependency_matching.py
|
|
@@ -208,6 +209,7 @@ src/general_manager/migrations/0007_upload_intent.py
|
|
|
208
209
|
src/general_manager/migrations/0008_upload_finalization_versions.py
|
|
209
210
|
src/general_manager/migrations/0009_upload_cleanup_state.py
|
|
210
211
|
src/general_manager/migrations/0010_chat_pending_confirmation_portable_uniqueness.py
|
|
212
|
+
src/general_manager/migrations/0011_search_index_state_dirty_generation.py
|
|
211
213
|
src/general_manager/migrations/__init__.py
|
|
212
214
|
src/general_manager/permission/__init__.py
|
|
213
215
|
src/general_manager/permission/audit.py
|
|
@@ -225,8 +227,11 @@ src/general_manager/search/__init__.py
|
|
|
225
227
|
src/general_manager/search/async_tasks.py
|
|
226
228
|
src/general_manager/search/backend.py
|
|
227
229
|
src/general_manager/search/backend_registry.py
|
|
230
|
+
src/general_manager/search/checks.py
|
|
228
231
|
src/general_manager/search/config.py
|
|
229
232
|
src/general_manager/search/indexer.py
|
|
233
|
+
src/general_manager/search/invalidation.py
|
|
234
|
+
src/general_manager/search/m2m_invalidation.py
|
|
230
235
|
src/general_manager/search/models.py
|
|
231
236
|
src/general_manager/search/reconciliation.py
|
|
232
237
|
src/general_manager/search/registry.py
|
{generalmanager-0.64.4 → generalmanager-0.65.1}/src/general_manager/_types/general_manager.py
RENAMED
|
@@ -19,9 +19,11 @@ __all__ = [
|
|
|
19
19
|
"RequestInterface",
|
|
20
20
|
"Rule",
|
|
21
21
|
"SearchBackend",
|
|
22
|
+
"SearchChange",
|
|
22
23
|
"SearchConfigProtocol",
|
|
23
24
|
"SearchConfigSpec",
|
|
24
25
|
"SearchIndexer",
|
|
26
|
+
"SearchInvalidationRule",
|
|
25
27
|
"configure_search_backend",
|
|
26
28
|
"configure_search_backend_from_settings",
|
|
27
29
|
"get_logger",
|
|
@@ -54,9 +56,11 @@ from general_manager.interface.interfaces.remote_manager import RemoteManagerInt
|
|
|
54
56
|
from general_manager.interface.interfaces.request import RequestInterface
|
|
55
57
|
from general_manager.rule.rule import Rule
|
|
56
58
|
from general_manager.search.backend import SearchBackend
|
|
59
|
+
from general_manager.search.config import SearchChange
|
|
57
60
|
from general_manager.search.config import SearchConfigProtocol
|
|
58
61
|
from general_manager.search.config import SearchConfigSpec
|
|
59
62
|
from general_manager.search.indexer import SearchIndexer
|
|
63
|
+
from general_manager.search.config import SearchInvalidationRule
|
|
60
64
|
from general_manager.search.backend_registry import configure_search_backend
|
|
61
65
|
from general_manager.search.backend_registry import (
|
|
62
66
|
configure_search_backend_from_settings,
|
|
@@ -13,11 +13,13 @@ __all__ = [
|
|
|
13
13
|
"SearchBackendError",
|
|
14
14
|
"SearchBackendNotConfiguredError",
|
|
15
15
|
"SearchBackendNotImplementedError",
|
|
16
|
+
"SearchChange",
|
|
16
17
|
"SearchConfigProtocol",
|
|
17
18
|
"SearchConfigSpec",
|
|
18
19
|
"SearchDocument",
|
|
19
20
|
"SearchHit",
|
|
20
21
|
"SearchIndexer",
|
|
22
|
+
"SearchInvalidationRule",
|
|
21
23
|
"SearchResult",
|
|
22
24
|
"TypesenseBackend",
|
|
23
25
|
"configure_search_backend",
|
|
@@ -37,11 +39,13 @@ from general_manager.search.backend import SearchBackendClientMissingError
|
|
|
37
39
|
from general_manager.search.backend import SearchBackendError
|
|
38
40
|
from general_manager.search.backend import SearchBackendNotConfiguredError
|
|
39
41
|
from general_manager.search.backend import SearchBackendNotImplementedError
|
|
42
|
+
from general_manager.search.config import SearchChange
|
|
40
43
|
from general_manager.search.config import SearchConfigProtocol
|
|
41
44
|
from general_manager.search.config import SearchConfigSpec
|
|
42
45
|
from general_manager.search.backend import SearchDocument
|
|
43
46
|
from general_manager.search.backend import SearchHit
|
|
44
47
|
from general_manager.search.indexer import SearchIndexer
|
|
48
|
+
from general_manager.search.config import SearchInvalidationRule
|
|
45
49
|
from general_manager.search.backend import SearchResult
|
|
46
50
|
from general_manager.search.backends.typesense import TypesenseBackend
|
|
47
51
|
from general_manager.search.backend_registry import configure_search_backend
|
|
@@ -600,6 +600,38 @@ def get_filter_options(
|
|
|
600
600
|
)
|
|
601
601
|
|
|
602
602
|
|
|
603
|
+
def _get_filter_relation_info(
|
|
604
|
+
field_type: type[GeneralManager],
|
|
605
|
+
attribute_name: str,
|
|
606
|
+
attr_info: Mapping[str, object],
|
|
607
|
+
) -> Mapping[str, object]:
|
|
608
|
+
"""Return explicit relation metadata or infer it for manager inputs."""
|
|
609
|
+
if attr_info.get("relation_kind") is not None:
|
|
610
|
+
return attr_info
|
|
611
|
+
|
|
612
|
+
interface = getattr(field_type, "Interface", None)
|
|
613
|
+
input_fields = getattr(interface, "input_fields", {})
|
|
614
|
+
input_field = (
|
|
615
|
+
input_fields.get(attribute_name) if isinstance(input_fields, dict) else None
|
|
616
|
+
)
|
|
617
|
+
input_type = getattr(input_field, "type", None)
|
|
618
|
+
if (
|
|
619
|
+
input_field is None
|
|
620
|
+
or resolve_general_manager_type(
|
|
621
|
+
input_type,
|
|
622
|
+
get_graphql_manager_registry(),
|
|
623
|
+
)
|
|
624
|
+
is None
|
|
625
|
+
):
|
|
626
|
+
return attr_info
|
|
627
|
+
|
|
628
|
+
return {
|
|
629
|
+
**attr_info,
|
|
630
|
+
"relation_kind": "direct",
|
|
631
|
+
"filter_lookup": attr_info.get("filter_lookup", attribute_name),
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
|
|
603
635
|
def get_relation_filter_option(
|
|
604
636
|
attribute_type: object,
|
|
605
637
|
attribute_name: str,
|
|
@@ -713,7 +745,12 @@ def create_filter_options(
|
|
|
713
745
|
|
|
714
746
|
filter_fields: dict[str, GrapheneFieldType] = {}
|
|
715
747
|
for attr_name, attr_info in field_type.Interface.get_attribute_types().items():
|
|
716
|
-
|
|
748
|
+
effective_attr_info = _get_filter_relation_info(
|
|
749
|
+
field_type,
|
|
750
|
+
attr_name,
|
|
751
|
+
attr_info,
|
|
752
|
+
)
|
|
753
|
+
attr_type = effective_attr_info["type"]
|
|
717
754
|
manager_type = resolve_general_manager_type(
|
|
718
755
|
attr_type,
|
|
719
756
|
get_graphql_manager_registry(),
|
|
@@ -722,7 +759,7 @@ def create_filter_options(
|
|
|
722
759
|
relation_option = get_relation_filter_option(
|
|
723
760
|
manager_type,
|
|
724
761
|
attr_name,
|
|
725
|
-
|
|
762
|
+
effective_attr_info,
|
|
726
763
|
graphql_filter_type_registry,
|
|
727
764
|
map_field_to_graphene_read,
|
|
728
765
|
remaining_depth,
|
|
@@ -736,7 +773,10 @@ def create_filter_options(
|
|
|
736
773
|
**{
|
|
737
774
|
k: v
|
|
738
775
|
for k, v in get_filter_options(
|
|
739
|
-
|
|
776
|
+
cast(type, attr_type),
|
|
777
|
+
attr_name,
|
|
778
|
+
map_field_to_graphene_read,
|
|
779
|
+
effective_attr_info,
|
|
740
780
|
)
|
|
741
781
|
if v is not None
|
|
742
782
|
},
|
|
@@ -841,9 +881,10 @@ def normalize_filter_input(
|
|
|
841
881
|
filters[key] = normalize_id_filter_value(field_type, key, value)
|
|
842
882
|
continue
|
|
843
883
|
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
884
|
+
effective_attr_info = _get_filter_relation_info(field_type, key, attr_info)
|
|
885
|
+
attr_type = effective_attr_info.get("type")
|
|
886
|
+
relation_kind = effective_attr_info.get("relation_kind")
|
|
887
|
+
lookup = effective_attr_info.get("filter_lookup", key)
|
|
847
888
|
manager_type = resolve_general_manager_type(
|
|
848
889
|
attr_type,
|
|
849
890
|
get_graphql_manager_registry(),
|
|
@@ -168,8 +168,10 @@ class GeneralmanagerConfig(AppConfig):
|
|
|
168
168
|
self.install_startup_hook_runner()
|
|
169
169
|
self.register_system_checks()
|
|
170
170
|
from general_manager.uploads.checks import register_upload_checks
|
|
171
|
+
from general_manager.search.checks import register_search_checks
|
|
171
172
|
|
|
172
173
|
register_upload_checks()
|
|
174
|
+
register_search_checks()
|
|
173
175
|
_autoload_app_managers_modules()
|
|
174
176
|
self.initialize_general_manager_classes(
|
|
175
177
|
GeneralManagerMeta.pending_attribute_initialization,
|
|
@@ -178,14 +180,19 @@ class GeneralmanagerConfig(AppConfig):
|
|
|
178
180
|
handle_remote_api(GeneralManagerMeta.all_classes)
|
|
179
181
|
configure_audit_logger_from_settings(settings)
|
|
180
182
|
configure_search_backend_from_settings(settings)
|
|
183
|
+
from general_manager.search.invalidation import configure_search_invalidation
|
|
184
|
+
from general_manager.search.m2m_invalidation import (
|
|
185
|
+
configure_search_m2m_invalidation,
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
configure_search_invalidation()
|
|
189
|
+
configure_search_m2m_invalidation()
|
|
181
190
|
configure_workflow_engine_from_settings(settings)
|
|
182
191
|
configure_event_registry_from_settings(settings)
|
|
183
192
|
configure_workflow_signal_bridge_from_settings(settings)
|
|
184
193
|
configure_workflow_beat_schedule_from_settings(settings)
|
|
185
194
|
configure_search_reconcile_beat_schedule_from_settings(settings)
|
|
186
195
|
configure_graphql_warmup_beat_schedule_from_settings(settings)
|
|
187
|
-
import general_manager.search.indexer as _search_indexer # noqa: F401
|
|
188
|
-
|
|
189
196
|
from general_manager.conf import get_setting
|
|
190
197
|
|
|
191
198
|
if get_setting("AUTOCREATE_GRAPHQL", False):
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""Context-local ownership metadata for ORM data-change transactions."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Iterator
|
|
6
|
+
from contextlib import contextmanager
|
|
7
|
+
from contextvars import ContextVar
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class _DataChangeTransaction:
|
|
13
|
+
"""Live marker for one framework-owned transaction envelope."""
|
|
14
|
+
|
|
15
|
+
database_alias: str
|
|
16
|
+
caller_in_atomic_block: bool
|
|
17
|
+
active: bool = True
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
_owned_transactions: ContextVar[tuple[_DataChangeTransaction, ...]] = ContextVar(
|
|
21
|
+
"owned_data_change_transactions",
|
|
22
|
+
default=(),
|
|
23
|
+
)
|
|
24
|
+
_authorized_operations: ContextVar[tuple[_DataChangeTransaction, ...]] = ContextVar(
|
|
25
|
+
"authorized_data_change_operations",
|
|
26
|
+
default=(),
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _current_owner(database_alias: str) -> _DataChangeTransaction | None:
|
|
31
|
+
for owner in reversed(_owned_transactions.get()):
|
|
32
|
+
if owner.active and owner.database_alias == database_alias:
|
|
33
|
+
return owner
|
|
34
|
+
return None
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@contextmanager
|
|
38
|
+
def own_data_change_transaction(
|
|
39
|
+
database_alias: str,
|
|
40
|
+
*,
|
|
41
|
+
caller_in_atomic_block: bool,
|
|
42
|
+
) -> Iterator[None]:
|
|
43
|
+
"""Record a live framework envelope without inspecting Django internals."""
|
|
44
|
+
owner = _DataChangeTransaction(
|
|
45
|
+
database_alias=database_alias,
|
|
46
|
+
caller_in_atomic_block=caller_in_atomic_block,
|
|
47
|
+
)
|
|
48
|
+
token = _owned_transactions.set((*_owned_transactions.get(), owner))
|
|
49
|
+
try:
|
|
50
|
+
yield
|
|
51
|
+
finally:
|
|
52
|
+
owner.active = False
|
|
53
|
+
_owned_transactions.reset(token)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@contextmanager
|
|
57
|
+
def authorize_data_change_operation(database_alias: str) -> Iterator[None]:
|
|
58
|
+
"""Authorize only the decorated manager method to reuse its envelope."""
|
|
59
|
+
owner = _current_owner(database_alias)
|
|
60
|
+
if owner is None:
|
|
61
|
+
yield
|
|
62
|
+
return
|
|
63
|
+
token = _authorized_operations.set((*_authorized_operations.get(), owner))
|
|
64
|
+
try:
|
|
65
|
+
yield
|
|
66
|
+
finally:
|
|
67
|
+
_authorized_operations.reset(token)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def owns_data_change_transaction(database_alias: str) -> bool:
|
|
71
|
+
"""Return whether this context has a live framework envelope for an alias."""
|
|
72
|
+
return _current_owner(database_alias) is not None
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def is_data_change_operation_authorized(database_alias: str) -> bool:
|
|
76
|
+
"""Return whether the current owner is running its decorated method body."""
|
|
77
|
+
owner = _current_owner(database_alias)
|
|
78
|
+
if owner is None:
|
|
79
|
+
return False
|
|
80
|
+
return any(
|
|
81
|
+
authorized is owner and authorized.active
|
|
82
|
+
for authorized in _authorized_operations.get()
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def may_reuse_data_change_transaction(database_alias: str) -> bool:
|
|
87
|
+
"""Conservatively authorize reuse when the manager opened the outer block."""
|
|
88
|
+
owner = _current_owner(database_alias)
|
|
89
|
+
return bool(
|
|
90
|
+
owner is not None
|
|
91
|
+
and not owner.caller_in_atomic_block
|
|
92
|
+
and is_data_change_operation_authorized(database_alias)
|
|
93
|
+
)
|
|
@@ -2,12 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
from contextlib import nullcontext
|
|
5
6
|
from copy import deepcopy
|
|
6
|
-
from django.dispatch import Signal
|
|
7
|
-
from typing import Callable, TypeVar, ParamSpec, cast, overload
|
|
8
|
-
|
|
9
7
|
from functools import wraps
|
|
8
|
+
from typing import Callable, ParamSpec, TypeVar, cast, overload
|
|
9
|
+
|
|
10
|
+
from django.db import DEFAULT_DB_ALIAS, connections, transaction
|
|
11
|
+
from django.dispatch import Signal
|
|
12
|
+
from django.utils.connection import ConnectionDoesNotExist
|
|
10
13
|
|
|
14
|
+
from general_manager.cache.data_change_context import (
|
|
15
|
+
authorize_data_change_operation,
|
|
16
|
+
own_data_change_transaction,
|
|
17
|
+
)
|
|
11
18
|
from general_manager.logging import get_logger
|
|
12
19
|
|
|
13
20
|
post_data_change = Signal()
|
|
@@ -20,6 +27,16 @@ R = TypeVar("R")
|
|
|
20
27
|
logger = get_logger("cache.signals")
|
|
21
28
|
|
|
22
29
|
|
|
30
|
+
def _caller_in_atomic_block(database_alias: str) -> bool:
|
|
31
|
+
"""Read public transaction state when the configured alias is available."""
|
|
32
|
+
try:
|
|
33
|
+
return bool(connections[database_alias].in_atomic_block)
|
|
34
|
+
except ConnectionDoesNotExist:
|
|
35
|
+
# Preserve lightweight callers that replace ``transaction.atomic`` in
|
|
36
|
+
# isolation. A real atomic call will still reject an unknown alias.
|
|
37
|
+
return False
|
|
38
|
+
|
|
39
|
+
|
|
23
40
|
@overload
|
|
24
41
|
def data_change(func: Callable[P, R]) -> Callable[P, R]: ...
|
|
25
42
|
|
|
@@ -39,9 +56,12 @@ def data_change(
|
|
|
39
56
|
clears run-scoped ORM bucket/index caches, emits `pre_data_change`, invokes
|
|
40
57
|
the wrapped callable, then emits `post_data_change` with the changed
|
|
41
58
|
instance, previous instance, action name, identification, and copied
|
|
42
|
-
`_old_values` payload.
|
|
43
|
-
|
|
44
|
-
|
|
59
|
+
`_old_values` payload. Both signals receive a per-call `change_context` and
|
|
60
|
+
the manager interface's database alias. ORM-backed signal dispatch and the
|
|
61
|
+
mutation share one transaction. GraphQL warm-up requeue keys collected
|
|
62
|
+
during signal handling are drained only after the outermost active
|
|
63
|
+
data-change barrier has closed; failed mutations drain pending keys but do
|
|
64
|
+
not enqueue rewarm work.
|
|
45
65
|
|
|
46
66
|
Parameters:
|
|
47
67
|
func: Function that performs a data mutation. Methods named `create`
|
|
@@ -85,6 +105,29 @@ def data_change(
|
|
|
85
105
|
is_dependency_data_change_active,
|
|
86
106
|
)
|
|
87
107
|
from general_manager.cache.run_context import current_calculation_run_context
|
|
108
|
+
from general_manager.interface.orm_interface import OrmInterfaceBase
|
|
109
|
+
|
|
110
|
+
action = decorator_source.__name__
|
|
111
|
+
if action == "create":
|
|
112
|
+
sender = args[0]
|
|
113
|
+
instance_before = None
|
|
114
|
+
else:
|
|
115
|
+
instance_before = args[0]
|
|
116
|
+
sender = instance_before.__class__
|
|
117
|
+
|
|
118
|
+
interface = getattr(sender, "Interface", None)
|
|
119
|
+
is_orm_backed = isinstance(interface, type) and issubclass(
|
|
120
|
+
interface, OrmInterfaceBase
|
|
121
|
+
)
|
|
122
|
+
database_alias = DEFAULT_DB_ALIAS
|
|
123
|
+
if is_orm_backed:
|
|
124
|
+
database_alias = getattr(interface, "database", None) or DEFAULT_DB_ALIAS
|
|
125
|
+
change_context: dict[str, object] = {}
|
|
126
|
+
signal_kwargs = {
|
|
127
|
+
**kwargs,
|
|
128
|
+
"change_context": change_context,
|
|
129
|
+
"database_alias": database_alias,
|
|
130
|
+
}
|
|
88
131
|
|
|
89
132
|
primary_exc: BaseException | None = None
|
|
90
133
|
completed = False
|
|
@@ -95,55 +138,70 @@ def data_change(
|
|
|
95
138
|
context.clear_bucket_indexes()
|
|
96
139
|
context.clear_trusted_orm_managers()
|
|
97
140
|
try:
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
else:
|
|
103
|
-
instance = args[0]
|
|
104
|
-
sender = instance.__class__
|
|
105
|
-
instance_before = instance
|
|
106
|
-
pre_data_change.send(
|
|
107
|
-
sender=sender,
|
|
108
|
-
instance=instance_before,
|
|
109
|
-
action=action,
|
|
110
|
-
**kwargs,
|
|
141
|
+
transaction_context = (
|
|
142
|
+
transaction.atomic(using=database_alias)
|
|
143
|
+
if is_orm_backed
|
|
144
|
+
else nullcontext()
|
|
111
145
|
)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
getattr(instance_before, "identification", None)
|
|
146
|
+
caller_in_atomic_block = (
|
|
147
|
+
_caller_in_atomic_block(database_alias) if is_orm_backed else False
|
|
115
148
|
)
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if context is not None:
|
|
124
|
-
context.clear_orm_bucket_results()
|
|
125
|
-
context.clear_bucket_indexes()
|
|
126
|
-
context.clear_trusted_orm_managers()
|
|
127
|
-
|
|
128
|
-
instance = result
|
|
129
|
-
identification = getattr(instance, "identification", None)
|
|
130
|
-
if identification is None:
|
|
131
|
-
identification = pre_identification
|
|
132
|
-
|
|
133
|
-
post_data_change.send(
|
|
134
|
-
sender=sender,
|
|
135
|
-
instance=instance,
|
|
136
|
-
previous_instance=instance_before,
|
|
137
|
-
identification=identification,
|
|
138
|
-
action=action,
|
|
139
|
-
old_relevant_values=old_relevant_values,
|
|
140
|
-
**kwargs,
|
|
149
|
+
ownership_context = (
|
|
150
|
+
own_data_change_transaction(
|
|
151
|
+
database_alias,
|
|
152
|
+
caller_in_atomic_block=caller_in_atomic_block,
|
|
153
|
+
)
|
|
154
|
+
if is_orm_backed
|
|
155
|
+
else nullcontext()
|
|
141
156
|
)
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
157
|
+
with transaction_context, ownership_context:
|
|
158
|
+
pre_data_change.send(
|
|
159
|
+
sender=sender,
|
|
160
|
+
instance=instance_before,
|
|
161
|
+
action=action,
|
|
162
|
+
**signal_kwargs,
|
|
163
|
+
)
|
|
164
|
+
old_relevant_values = getattr(instance_before, "_old_values", {})
|
|
165
|
+
pre_identification = deepcopy(
|
|
166
|
+
getattr(instance_before, "identification", None)
|
|
167
|
+
)
|
|
168
|
+
operation_context = (
|
|
169
|
+
authorize_data_change_operation(database_alias)
|
|
170
|
+
if is_orm_backed
|
|
171
|
+
else nullcontext()
|
|
172
|
+
)
|
|
173
|
+
with operation_context:
|
|
174
|
+
if isinstance(func, classmethod):
|
|
175
|
+
inner = cast(Callable[P, R], func.__func__)
|
|
176
|
+
result = inner(*args, **kwargs)
|
|
177
|
+
else:
|
|
178
|
+
result = func(*args, **kwargs)
|
|
179
|
+
|
|
180
|
+
context = current_calculation_run_context()
|
|
181
|
+
if context is not None:
|
|
182
|
+
context.clear_orm_bucket_results()
|
|
183
|
+
context.clear_bucket_indexes()
|
|
184
|
+
context.clear_trusted_orm_managers()
|
|
185
|
+
|
|
186
|
+
instance = result
|
|
187
|
+
identification = getattr(instance, "identification", None)
|
|
188
|
+
if identification is None:
|
|
189
|
+
identification = pre_identification
|
|
190
|
+
|
|
191
|
+
post_data_change.send(
|
|
192
|
+
sender=sender,
|
|
193
|
+
instance=instance,
|
|
194
|
+
previous_instance=instance_before,
|
|
195
|
+
identification=identification,
|
|
196
|
+
action=action,
|
|
197
|
+
old_relevant_values=old_relevant_values,
|
|
198
|
+
**signal_kwargs,
|
|
199
|
+
)
|
|
200
|
+
if instance_before is not None:
|
|
201
|
+
try:
|
|
202
|
+
delattr(instance_before, "_old_values")
|
|
203
|
+
except AttributeError:
|
|
204
|
+
pass
|
|
147
205
|
completed = True
|
|
148
206
|
except BaseException as error:
|
|
149
207
|
primary_exc = error
|