lsst-daf-butler 30.2026.100__tar.gz → 30.2026.300__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.
- {lsst_daf_butler-30.2026.100/python/lsst_daf_butler.egg-info → lsst_daf_butler-30.2026.300}/PKG-INFO +1 -1
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_butler.py +8 -5
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_butler_metrics.py +49 -2
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_labeled_butler_factory.py +28 -8
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/configs/datastores/formatters.yaml +1 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/configs/storageClasses.yaml +15 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/dimensions/_coordinate.py +5 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/direct_butler/_direct_butler.py +45 -28
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/logging.py +9 -3
- lsst_daf_butler-30.2026.300/python/lsst/daf/butler/registry/expand_data_ids.py +93 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/sql_registry.py +2 -24
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/_remote_butler.py +5 -1
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/hybrid_butler.py +4 -1
- lsst_daf_butler-30.2026.300/python/lsst/daf/butler/tests/registry_data/lsstcam-subset.yaml +191 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/transfers/_context.py +7 -6
- lsst_daf_butler-30.2026.300/python/lsst/daf/butler/version.py +2 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300/python/lsst_daf_butler.egg-info}/PKG-INFO +1 -1
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst_daf_butler.egg-info/SOURCES.txt +2 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_butler.py +98 -1
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_butler_factory.py +11 -7
- lsst_daf_butler-30.2026.100/python/lsst/daf/butler/version.py +0 -2
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/COPYRIGHT +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/LICENSE +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/MANIFEST.in +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/README.md +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/bsd_license.txt +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/doc/lsst.daf.butler/CHANGES.rst +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/doc/lsst.daf.butler/concreteStorageClasses.rst +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/doc/lsst.daf.butler/configuring.rst +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/doc/lsst.daf.butler/datastores.rst +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/doc/lsst.daf.butler/dimensions.rst +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/doc/lsst.daf.butler/formatters.rst +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/doc/lsst.daf.butler/index.rst +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/doc/lsst.daf.butler/organizing.rst +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/doc/lsst.daf.butler/queries.rst +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/doc/lsst.daf.butler/use-in-tests.rst +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/doc/lsst.daf.butler/writing-subcommands.rst +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/gpl-v3.0.txt +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/pyproject.toml +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_butler_collections.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_butler_config.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_butler_instance_options.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_butler_repo_index.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_collection_type.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_config.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_config_support.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_dataset_association.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_dataset_existence.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_dataset_provenance.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_dataset_ref.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_dataset_type.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_deferredDatasetHandle.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_exceptions.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_exceptions_legacy.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_file_dataset.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_file_descriptor.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_formatter.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_limited_butler.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_location.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_named.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_quantum.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_quantum_backed.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_query_all_datasets.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_registry_shim.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_rubin/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_rubin/file_datasets.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_rubin/temporary_for_ingest.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_standalone_datastore.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_storage_class.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_storage_class_delegate.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_timespan.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_topology.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_utilities/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_utilities/locked_object.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_utilities/named_locks.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_utilities/thread_safe_cache.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_uuid.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/arrow_utils.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/cli/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/cli/butler.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/cli/cliLog.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/cli/cmd/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/cli/cmd/_remove_collections.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/cli/cmd/_remove_runs.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/cli/cmd/commands.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/cli/opt/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/cli/opt/arguments.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/cli/opt/optionGroups.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/cli/opt/options.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/cli/progress.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/cli/utils.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/column_spec.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/configs/datastore.yaml +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/configs/datastores/composites.yaml +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/configs/datastores/fileDatastore.yaml +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/configs/datastores/writeRecipes.yaml +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/configs/dimensions.yaml +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe0.yaml +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe1.yaml +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe2.yaml +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe3.yaml +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe4.yaml +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe5.yaml +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe6.yaml +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe7.yaml +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/configs/registry.yaml +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/configs/repo_transfer_formats.yaml +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/datastore/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/datastore/_datastore.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/datastore/_transfer.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/datastore/cache_manager.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/datastore/composites.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/datastore/constraints.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/datastore/file_templates.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/datastore/generic_base.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/datastore/record_data.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/datastore/stored_file_info.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/datastores/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/datastores/chainedDatastore.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/datastores/fileDatastore.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/datastores/file_datastore/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/datastores/file_datastore/get.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/datastores/file_datastore/retrieve_artifacts.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/datastores/file_datastore/transfer.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/datastores/inMemoryDatastore.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/ddl.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/delegates/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/delegates/arrowtable.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/dimensions/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/dimensions/_config.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/dimensions/_data_coordinate_iterable.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/dimensions/_database.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/dimensions/_elements.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/dimensions/_governor.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/dimensions/_group.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/dimensions/_packer.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/dimensions/_record_set.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/dimensions/_record_table.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/dimensions/_records.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/dimensions/_schema.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/dimensions/_skypix.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/dimensions/_universe.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/dimensions/construction.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/dimensions/record_cache.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/direct_butler/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/direct_butler/_direct_butler_collections.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/direct_query_driver/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/direct_query_driver/_driver.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/direct_query_driver/_postprocessing.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/direct_query_driver/_query_analysis.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/direct_query_driver/_query_builder.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/direct_query_driver/_result_page_converter.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/direct_query_driver/_sql_builders.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/direct_query_driver/_sql_column_visitor.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/formatters/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/formatters/astropyTable.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/formatters/file.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/formatters/json.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/formatters/logs.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/formatters/matplotlib.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/formatters/packages.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/formatters/parquet.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/formatters/pickle.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/formatters/typeless.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/formatters/yaml.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/json.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/mapping_factory.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/name_shrinker.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/nonempty_mapping.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/persistence_context.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/progress.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/py.typed +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/pydantic_utils.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/_base.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/_data_coordinate_query_results.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/_dataset_query_results.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/_dimension_record_query_results.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/_expression_strings.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/_general_query_results.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/_identifiers.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/_query.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/convert_args.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/driver.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/expression_factory.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/expressions/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/expressions/categorize.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/expressions/parser/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/expressions/parser/exprTree.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/expressions/parser/parser.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/expressions/parser/parserLex.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/expressions/parser/parserYacc.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/expressions/parser/ply/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/expressions/parser/ply/lex.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/expressions/parser/ply/yacc.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/expressions/parser/treeVisitor.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/overlaps.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/predicate_constraints_summary.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/result_specs.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/tree/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/tree/_base.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/tree/_column_expression.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/tree/_column_literal.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/tree/_column_reference.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/tree/_column_set.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/tree/_predicate.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/tree/_query_tree.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/queries/visitors.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/_caching_context.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/_collection_record_cache.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/_collection_summary.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/_collection_summary_cache.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/_config.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/_defaults.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/_exceptions.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/_registry.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/_registry_base.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/_registry_factory.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/attributes.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/bridge/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/bridge/ephemeral.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/bridge/monolithic.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/collections/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/collections/_base.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/collections/nameKey.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/collections/synthIntKey.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/connectionString.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/databases/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/databases/postgresql.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/databases/sqlite.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/datasets/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/datasets/byDimensions/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/datasets/byDimensions/_dataset_type_cache.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/datasets/byDimensions/_manager.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/datasets/byDimensions/summaries.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/datasets/byDimensions/tables.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/dimensions/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/dimensions/static.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/interfaces/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/interfaces/_attributes.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/interfaces/_bridge.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/interfaces/_collections.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/interfaces/_database.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/interfaces/_database_explain.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/interfaces/_datasets.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/interfaces/_dimensions.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/interfaces/_obscore.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/interfaces/_opaque.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/interfaces/_versioning.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/managers.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/nameShrinker.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/obscore/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/obscore/_config.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/obscore/_manager.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/obscore/_records.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/obscore/_schema.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/obscore/_spatial.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/obscore/default_spatial.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/obscore/pgsphere.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/opaque.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/queries/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/queries/_query_common.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/queries/_query_data_coordinates.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/queries/_query_datasets.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/queries/_query_dimension_records.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/queries/_results.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/tests/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/tests/_database.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/tests/_registry.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/versions.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/registry/wildcards.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/_collection_args.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/_config.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/_defaults.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/_errors.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/_factory.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/_get.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/_http_connection.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/_query_driver.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/_query_results.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/_ref_utils.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/_registry.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/_remote_butler_collections.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/_remote_file_transfer_source.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/authentication/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/authentication/cadc.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/authentication/interface.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/authentication/rubin.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/registry/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/server/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/server/_config.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/server/_dependencies.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/server/_factory.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/server/_gafaelfawr.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/server/_server.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/server/_telemetry.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/server/handlers/_external.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/server/handlers/_external_query.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/server/handlers/_file_info.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/server/handlers/_internal.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/server/handlers/_query_limits.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/server/handlers/_query_serialization.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/server/handlers/_query_streaming.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/server/handlers/_utils.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/remote_butler/server_models.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/repo_relocation.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/script/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/script/_associate.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/script/_pruneDatasets.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/script/butlerImport.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/script/certifyCalibrations.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/script/collectionChain.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/script/configDump.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/script/configValidate.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/script/createRepo.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/script/exportCalibs.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/script/ingest_files.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/script/ingest_zip.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/script/queryCollections.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/script/queryDataIds.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/script/queryDatasetTypes.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/script/queryDatasets.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/script/queryDimensionRecords.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/script/register_dataset_type.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/script/removeCollections.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/script/removeDatasetType.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/script/removeRuns.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/script/retrieveArtifacts.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/script/transferDatasets.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/_datasetsHelper.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/_dummyRegistry.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/_examplePythonTypes.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/_testRepo.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/butler_queries.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/cliCmdTestBase.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/cliLogTestBase.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/deferredFormatter.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/dict_convertible_model.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/hybrid_butler_collections.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/hybrid_butler_registry.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/postgresql.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/registry_data/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/registry_data/base.yaml +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/registry_data/ci_hsc-subset-skymap.yaml +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/registry_data/ci_hsc-subset.yaml +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/registry_data/datasets.yaml +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/registry_data/hsc-rc2-subset-v0.yaml +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/registry_data/spatial.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/registry_data/spatial.yaml +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/server.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/server_available.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/server_utils.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/testFormatters.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/tests/utils.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/time_utils.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/timespan_database_representation.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/transfers/__init__.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/transfers/_interfaces.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/transfers/_yaml.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/utils.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst_daf_butler.egg-info/dependency_links.txt +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst_daf_butler.egg-info/entry_points.txt +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst_daf_butler.egg-info/requires.txt +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst_daf_butler.egg-info/top_level.txt +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst_daf_butler.egg-info/zip-safe +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/setup.cfg +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_astropyTableFormatter.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_authentication.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_cliCmdAssociate.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_cliCmdConfigDump.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_cliCmdConfigValidate.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_cliCmdCreate.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_cliCmdImport.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_cliCmdIngestFiles.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_cliCmdPruneDatasets.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_cliCmdQueryCollections.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_cliCmdQueryDataIds.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_cliCmdQueryDatasetTypes.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_cliCmdQueryDatasets.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_cliCmdQueryDimensionRecords.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_cliCmdRemoveCollections.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_cliCmdRemoveRuns.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_cliCmdRetrieveArtifacts.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_cliLog.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_cliPluginLoader.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_cliUtilSplitCommas.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_cliUtilSplitKv.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_cliUtilToUpper.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_cliUtils.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_column_spec.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_composites.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_config.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_connectionString.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_constraints.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_datasets.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_datastore.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_ddl.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_dimension_record_containers.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_dimensions.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_exprParserLex.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_exprParserYacc.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_formatter.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_gafaelfawr.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_location.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_logFormatter.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_logging.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_matplotlibFormatter.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_nonempty_mapping.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_obscore.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_packages.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_parquet.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_postgresql.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_progress.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_pydantic_utils.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_quantum.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_quantumBackedButler.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_query_direct_postgresql.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_query_direct_sqlite.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_query_interface.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_query_remote.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_query_utilities.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_remote_butler.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_server.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_simpleButler.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_sqlite.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_storageClass.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_templates.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_testRepo.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_thread_utils.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_time_utils.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_timespan.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_utils.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_uuid.py +0 -0
- {lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/tests/test_versioning.py +0 -0
{lsst_daf_butler-30.2026.100/python/lsst_daf_butler.egg-info → lsst_daf_butler-30.2026.300}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lsst-daf-butler
|
|
3
|
-
Version: 30.2026.
|
|
3
|
+
Version: 30.2026.300
|
|
4
4
|
Summary: An abstraction layer for reading and writing astronomical data to datastores.
|
|
5
5
|
Author-email: Rubin Observatory Data Management <dm-admin@lists.lsst.org>
|
|
6
6
|
License-Expression: BSD-3-Clause OR GPL-3.0-or-later
|
{lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/_butler.py
RENAMED
|
@@ -1566,7 +1566,7 @@ class Butler(LimitedButler): # numpydoc ignore=PR02
|
|
|
1566
1566
|
|
|
1567
1567
|
@abstractmethod
|
|
1568
1568
|
def transfer_dimension_records_from(
|
|
1569
|
-
self, source_butler: LimitedButler | Butler, source_refs: Iterable[DatasetRef]
|
|
1569
|
+
self, source_butler: LimitedButler | Butler, source_refs: Iterable[DatasetRef | DataCoordinate]
|
|
1570
1570
|
) -> None:
|
|
1571
1571
|
"""Transfer dimension records to this Butler from another Butler.
|
|
1572
1572
|
|
|
@@ -1578,10 +1578,9 @@ class Butler(LimitedButler): # numpydoc ignore=PR02
|
|
|
1578
1578
|
`Butler` whose registry will be used to expand data IDs. If the
|
|
1579
1579
|
source refs contain coordinates that are used to populate other
|
|
1580
1580
|
records then this will also need to be a full `Butler`.
|
|
1581
|
-
source_refs : iterable of `DatasetRef`
|
|
1582
|
-
Datasets defined in the source butler whose dimension
|
|
1583
|
-
should be transferred to this butler.
|
|
1584
|
-
transfer is faster if the dataset refs are expanded.
|
|
1581
|
+
source_refs : iterable of `DatasetRef` or `DataCoordinate`
|
|
1582
|
+
Datasets or data IDs defined in the source butler whose dimension
|
|
1583
|
+
records should be transferred to this butler.
|
|
1585
1584
|
"""
|
|
1586
1585
|
raise NotImplementedError()
|
|
1587
1586
|
|
|
@@ -2227,3 +2226,7 @@ class Butler(LimitedButler): # numpydoc ignore=PR02
|
|
|
2227
2226
|
@abstractmethod
|
|
2228
2227
|
def close(self) -> None:
|
|
2229
2228
|
raise NotImplementedError()
|
|
2229
|
+
|
|
2230
|
+
@abstractmethod
|
|
2231
|
+
def _expand_data_ids(self, data_ids: Iterable[DataCoordinate]) -> list[DataCoordinate]:
|
|
2232
|
+
raise NotImplementedError()
|
|
@@ -29,12 +29,15 @@ from __future__ import annotations
|
|
|
29
29
|
|
|
30
30
|
from collections.abc import Callable, Iterator
|
|
31
31
|
from contextlib import contextmanager
|
|
32
|
+
from typing import Concatenate, ParamSpec
|
|
32
33
|
|
|
33
34
|
from pydantic import BaseModel
|
|
34
35
|
|
|
35
36
|
from lsst.utils.logging import LsstLoggers
|
|
36
37
|
from lsst.utils.timer import time_this
|
|
37
38
|
|
|
39
|
+
P = ParamSpec("P")
|
|
40
|
+
|
|
38
41
|
|
|
39
42
|
class ButlerMetrics(BaseModel):
|
|
40
43
|
"""Metrics collected during Butler operations."""
|
|
@@ -45,18 +48,26 @@ class ButlerMetrics(BaseModel):
|
|
|
45
48
|
time_in_get: float = 0.0
|
|
46
49
|
"""Wall-clock time, in seconds, spent in get()."""
|
|
47
50
|
|
|
51
|
+
time_in_ingest: float = 0.0
|
|
52
|
+
"""Wall-clock time, in seconds, spent in ingest()."""
|
|
53
|
+
|
|
48
54
|
n_get: int = 0
|
|
49
55
|
"""Number of datasets retrieved with get()."""
|
|
50
56
|
|
|
51
57
|
n_put: int = 0
|
|
52
58
|
"""Number of datasets stored with put()."""
|
|
53
59
|
|
|
60
|
+
n_ingest: int = 0
|
|
61
|
+
"""Number of datasets ingested."""
|
|
62
|
+
|
|
54
63
|
def reset(self) -> None:
|
|
55
64
|
"""Reset all metrics."""
|
|
56
65
|
self.time_in_put = 0.0
|
|
57
66
|
self.time_in_get = 0.0
|
|
67
|
+
self.time_in_ingest = 0.0
|
|
58
68
|
self.n_get = 0
|
|
59
69
|
self.n_put = 0
|
|
70
|
+
self.n_ingest = 0
|
|
60
71
|
|
|
61
72
|
def increment_get(self, duration: float) -> None:
|
|
62
73
|
"""Increment time for get().
|
|
@@ -80,13 +91,31 @@ class ButlerMetrics(BaseModel):
|
|
|
80
91
|
self.time_in_put += duration
|
|
81
92
|
self.n_put += 1
|
|
82
93
|
|
|
94
|
+
def increment_ingest(self, duration: float, n_datasets: int) -> None:
|
|
95
|
+
"""Increment time and datasets for ingest().
|
|
96
|
+
|
|
97
|
+
Parameters
|
|
98
|
+
----------
|
|
99
|
+
duration : `float`
|
|
100
|
+
Duration to add to the ingest() statistics.
|
|
101
|
+
n_datasets : `int`
|
|
102
|
+
Number of datasets to be ingested for this call.
|
|
103
|
+
"""
|
|
104
|
+
self.time_in_ingest += duration
|
|
105
|
+
self.n_ingest += n_datasets
|
|
106
|
+
|
|
83
107
|
@contextmanager
|
|
84
108
|
def _timer(
|
|
85
|
-
self,
|
|
109
|
+
self,
|
|
110
|
+
handler: Callable[Concatenate[float, P], None],
|
|
111
|
+
log: LsstLoggers | None = None,
|
|
112
|
+
msg: str | None = None,
|
|
113
|
+
*args: P.args,
|
|
114
|
+
**kwargs: P.kwargs,
|
|
86
115
|
) -> Iterator[None]:
|
|
87
116
|
with time_this(log=log, msg=msg) as timer:
|
|
88
117
|
yield
|
|
89
|
-
handler(timer.duration)
|
|
118
|
+
handler(timer.duration, *args, **kwargs)
|
|
90
119
|
|
|
91
120
|
@contextmanager
|
|
92
121
|
def instrument_get(self, log: LsstLoggers | None = None, msg: str | None = None) -> Iterator[None]:
|
|
@@ -115,3 +144,21 @@ class ButlerMetrics(BaseModel):
|
|
|
115
144
|
"""
|
|
116
145
|
with self._timer(self.increment_put, log=log, msg=msg):
|
|
117
146
|
yield
|
|
147
|
+
|
|
148
|
+
@contextmanager
|
|
149
|
+
def instrument_ingest(
|
|
150
|
+
self, n_datasets: int, log: LsstLoggers | None = None, msg: str | None = None
|
|
151
|
+
) -> Iterator[None]:
|
|
152
|
+
"""Run code and increment ingest statistics.
|
|
153
|
+
|
|
154
|
+
Parameters
|
|
155
|
+
----------
|
|
156
|
+
n_datasets : `int`
|
|
157
|
+
Number of datasets being ingested.
|
|
158
|
+
log : `logging.Logger` or `None`
|
|
159
|
+
Logger to use for any timing information.
|
|
160
|
+
msg : `str` or `None`
|
|
161
|
+
Any message to be included in log output.
|
|
162
|
+
"""
|
|
163
|
+
with self._timer(self.increment_ingest, n_datasets=n_datasets, log=log, msg=msg):
|
|
164
|
+
yield
|
|
@@ -30,7 +30,9 @@ from __future__ import annotations
|
|
|
30
30
|
__all__ = ("LabeledButlerFactory", "LabeledButlerFactoryProtocol")
|
|
31
31
|
|
|
32
32
|
from collections.abc import Mapping
|
|
33
|
-
from
|
|
33
|
+
from contextlib import AbstractContextManager
|
|
34
|
+
from logging import getLogger
|
|
35
|
+
from typing import Any, Literal, Protocol, Self
|
|
34
36
|
|
|
35
37
|
from lsst.resources import ResourcePathExpression
|
|
36
38
|
|
|
@@ -40,6 +42,8 @@ from ._butler_repo_index import ButlerRepoIndex
|
|
|
40
42
|
from ._utilities.named_locks import NamedLocks
|
|
41
43
|
from ._utilities.thread_safe_cache import ThreadSafeCache
|
|
42
44
|
|
|
45
|
+
_LOG = getLogger(__name__)
|
|
46
|
+
|
|
43
47
|
|
|
44
48
|
class LabeledButlerFactoryProtocol(Protocol):
|
|
45
49
|
"""Callable to retrieve a butler from a label."""
|
|
@@ -47,7 +51,7 @@ class LabeledButlerFactoryProtocol(Protocol):
|
|
|
47
51
|
def __call__(self, label: str) -> Butler: ...
|
|
48
52
|
|
|
49
53
|
|
|
50
|
-
class LabeledButlerFactory:
|
|
54
|
+
class LabeledButlerFactory(AbstractContextManager):
|
|
51
55
|
"""Factory for efficiently instantiating Butler instances from the
|
|
52
56
|
repository index file. This is intended for use from long-lived services
|
|
53
57
|
that want to instantiate a separate Butler instance for each end user
|
|
@@ -60,6 +64,9 @@ class LabeledButlerFactory:
|
|
|
60
64
|
files. If not provided, defaults to the global repository index
|
|
61
65
|
configured by the ``DAF_BUTLER_REPOSITORY_INDEX`` environment variable
|
|
62
66
|
-- see `ButlerRepoIndex`.
|
|
67
|
+
writeable : `bool`, optional
|
|
68
|
+
If `True`, Butler instances created by this factory will be writeable.
|
|
69
|
+
If `False` (the default), instances will be read-only.
|
|
63
70
|
|
|
64
71
|
Notes
|
|
65
72
|
-----
|
|
@@ -76,11 +83,12 @@ class LabeledButlerFactory:
|
|
|
76
83
|
safely be used by separate threads.
|
|
77
84
|
"""
|
|
78
85
|
|
|
79
|
-
def __init__(self, repositories: Mapping[str, str] | None = None) -> None:
|
|
86
|
+
def __init__(self, repositories: Mapping[str, str] | None = None, writeable: bool = False) -> None:
|
|
80
87
|
if repositories is None:
|
|
81
88
|
self._repositories = None
|
|
82
89
|
else:
|
|
83
90
|
self._repositories = dict(repositories)
|
|
91
|
+
self._writeable = writeable
|
|
84
92
|
|
|
85
93
|
self._factories = ThreadSafeCache[str, _ButlerFactory]()
|
|
86
94
|
self._initialization_locks = NamedLocks()
|
|
@@ -88,6 +96,16 @@ class LabeledButlerFactory:
|
|
|
88
96
|
# This may be overridden by unit tests.
|
|
89
97
|
self._preload_unsafe_direct_butler_caches = True
|
|
90
98
|
|
|
99
|
+
def __enter__(self) -> Self:
|
|
100
|
+
return self
|
|
101
|
+
|
|
102
|
+
def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> Literal[False]:
|
|
103
|
+
try:
|
|
104
|
+
self.close()
|
|
105
|
+
except Exception:
|
|
106
|
+
_LOG.exception("An exception occurred during LabeledButlerFactory.close()")
|
|
107
|
+
return False
|
|
108
|
+
|
|
91
109
|
def bind(self, access_token: str | None) -> LabeledButlerFactoryProtocol:
|
|
92
110
|
"""Create a callable factory function for generating Butler instances
|
|
93
111
|
with out needing to specify access tokans again.
|
|
@@ -109,7 +127,7 @@ class LabeledButlerFactory:
|
|
|
109
127
|
|
|
110
128
|
return create
|
|
111
129
|
|
|
112
|
-
def create_butler(self,
|
|
130
|
+
def create_butler(self, label: str, *, access_token: str | None = None) -> Butler:
|
|
113
131
|
"""Create a Butler instance.
|
|
114
132
|
|
|
115
133
|
Parameters
|
|
@@ -118,7 +136,7 @@ class LabeledButlerFactory:
|
|
|
118
136
|
Label of the repository to instantiate, from the ``repositories``
|
|
119
137
|
parameter to the `LabeledButlerFactory` constructor or the global
|
|
120
138
|
repository index file.
|
|
121
|
-
access_token : `str` | `None
|
|
139
|
+
access_token : `str` | `None`, optional
|
|
122
140
|
Gafaelfawr access token used to authenticate to a Butler server.
|
|
123
141
|
This is required for any repositories configured to use
|
|
124
142
|
`RemoteButler`. If you only use `DirectButler`, this may be
|
|
@@ -167,7 +185,9 @@ class LabeledButlerFactory:
|
|
|
167
185
|
|
|
168
186
|
match butler_type:
|
|
169
187
|
case ButlerType.DIRECT:
|
|
170
|
-
return _DirectButlerFactory(
|
|
188
|
+
return _DirectButlerFactory(
|
|
189
|
+
config, self._preload_unsafe_direct_butler_caches, self._writeable
|
|
190
|
+
)
|
|
171
191
|
case ButlerType.REMOTE:
|
|
172
192
|
return _RemoteButlerFactory(config)
|
|
173
193
|
case _:
|
|
@@ -189,12 +209,12 @@ class _ButlerFactory(Protocol):
|
|
|
189
209
|
|
|
190
210
|
|
|
191
211
|
class _DirectButlerFactory(_ButlerFactory):
|
|
192
|
-
def __init__(self, config: ButlerConfig, preload_unsafe_caches: bool) -> None:
|
|
212
|
+
def __init__(self, config: ButlerConfig, preload_unsafe_caches: bool, writeable: bool) -> None:
|
|
193
213
|
import lsst.daf.butler.direct_butler
|
|
194
214
|
|
|
195
215
|
# Create a 'template' Butler that will be cloned when callers request
|
|
196
216
|
# an instance.
|
|
197
|
-
self._butler = Butler.from_config(config)
|
|
217
|
+
self._butler = Butler.from_config(config, writeable=writeable)
|
|
198
218
|
assert isinstance(self._butler, lsst.daf.butler.direct_butler.DirectButler)
|
|
199
219
|
|
|
200
220
|
# Load caches so that data is available in cloned instances without
|
|
@@ -100,3 +100,4 @@ VisitBackgroundModel: lsst.daf.butler.formatters.json.JsonFormatter
|
|
|
100
100
|
VignettingCorrection: lsst.ts.observatory.control.utils.extras.vignetting_storage.VignettingCorrectionFormatter
|
|
101
101
|
SSPAuxiliaryFile: lsst.pipe.tasks.sspAuxiliaryFile.SSPAuxiliaryFileFormatter
|
|
102
102
|
VisitGeometry: lsst.daf.butler.formatters.json.JsonFormatter
|
|
103
|
+
ProvenanceQuantumGraph: lsst.pipe.base.quantum_graph.formatter.ProvenanceFormatter
|
|
@@ -443,3 +443,18 @@ storageClasses:
|
|
|
443
443
|
pytype: lsst.pipe.tasks.sspAuxiliaryFile.SSPAuxiliaryFile
|
|
444
444
|
VisitGeometry:
|
|
445
445
|
pytype: lsst.obs.base.visit_geometry.VisitGeometry
|
|
446
|
+
ProvenanceQuantumGraph:
|
|
447
|
+
pytype: lsst.pipe.base.quantum_graph.ProvenanceQuantumGraph
|
|
448
|
+
parameters:
|
|
449
|
+
- import_mode # lsst.pipe.base.pipeline_graph.TaskImportMode
|
|
450
|
+
- quanta # iterable of uuid.UUID; quanta to read
|
|
451
|
+
- datasets # iterable of uuid.UUID; datasets to read
|
|
452
|
+
- read_init_quanta # bool, defaults to True; whether to read pre-exec-init info
|
|
453
|
+
derivedComponents:
|
|
454
|
+
packages: Packages # ignores node parameters
|
|
455
|
+
|
|
456
|
+
# UUID keys can be quantum or data IDs (whichever is passed in via
|
|
457
|
+
# parameters). Nested lists are attempts to run the quantum (last is
|
|
458
|
+
# most recent).
|
|
459
|
+
logs: StructuredDataDict # dict[uuid.UUID, list[ButlerLogRecords]]
|
|
460
|
+
metadata: StructuredDataDict # dict[uuid.UUID, list[TaskMetadata]]
|
|
@@ -755,6 +755,11 @@ class DataCoordinate:
|
|
|
755
755
|
to_json = to_json_pydantic
|
|
756
756
|
from_json: ClassVar[Callable[..., Self]] = cast(Callable[..., Self], classmethod(from_json_pydantic))
|
|
757
757
|
|
|
758
|
+
@property
|
|
759
|
+
def dataId(self) -> Self:
|
|
760
|
+
"""Return this `DataCoordinate` instance, unmodified."""
|
|
761
|
+
return self
|
|
762
|
+
|
|
758
763
|
|
|
759
764
|
DataId = DataCoordinate | Mapping[str, Any]
|
|
760
765
|
"""A type-annotation alias for signatures that accept both informal data ID
|
|
@@ -1822,12 +1822,25 @@ class DirectButler(Butler): # numpydoc ignore=PR02
|
|
|
1822
1822
|
f" Example: {existing_datasets[0]}"
|
|
1823
1823
|
)
|
|
1824
1824
|
|
|
1825
|
+
# Calculate some statistics based on the given list of datasets.
|
|
1826
|
+
n_files = len(datasets)
|
|
1827
|
+
n_datasets = 0
|
|
1828
|
+
for d in datasets:
|
|
1829
|
+
n_datasets += len(d.refs)
|
|
1830
|
+
sfiles = "s" if n_files != 1 else ""
|
|
1831
|
+
srefs = "s" if n_datasets != 1 else ""
|
|
1832
|
+
|
|
1825
1833
|
# We use `datasets` rather `new_datasets` for the Registry
|
|
1826
1834
|
# portion of this, to let it confirm that everything matches the
|
|
1827
1835
|
# existing datasets.
|
|
1828
1836
|
import_info = self._prepare_ingest_file_datasets(datasets, progress)
|
|
1829
1837
|
|
|
1830
|
-
with
|
|
1838
|
+
with (
|
|
1839
|
+
self._metrics.instrument_ingest(
|
|
1840
|
+
n_datasets, _LOG, msg=f"Ingesting {n_files} file{sfiles} with {n_datasets} dataset{srefs}"
|
|
1841
|
+
),
|
|
1842
|
+
self.transaction(),
|
|
1843
|
+
):
|
|
1831
1844
|
self._ingest_file_datasets(datasets, import_info, progress)
|
|
1832
1845
|
|
|
1833
1846
|
# Bulk-insert everything into Datastore.
|
|
@@ -1982,7 +1995,7 @@ class DirectButler(Butler): # numpydoc ignore=PR02
|
|
|
1982
1995
|
doImport(filename) # type: ignore
|
|
1983
1996
|
|
|
1984
1997
|
def transfer_dimension_records_from(
|
|
1985
|
-
self, source_butler: LimitedButler | Butler, source_refs: Iterable[DatasetRef]
|
|
1998
|
+
self, source_butler: LimitedButler | Butler, source_refs: Iterable[DatasetRef | DataCoordinate]
|
|
1986
1999
|
) -> None:
|
|
1987
2000
|
# Allowed dimensions in the target butler.
|
|
1988
2001
|
elements = frozenset(element for element in self.dimensions.elements if element.has_own_table)
|
|
@@ -2012,16 +2025,13 @@ class DirectButler(Butler): # numpydoc ignore=PR02
|
|
|
2012
2025
|
source_butler, data_ids, allowed_elements
|
|
2013
2026
|
)
|
|
2014
2027
|
|
|
2015
|
-
can_query = True if isinstance(source_butler, Butler) else False
|
|
2016
|
-
|
|
2017
2028
|
additional_records: dict[DimensionElement, dict[DataCoordinate, DimensionRecord]] = defaultdict(dict)
|
|
2018
2029
|
for original_element, record_mapping in primary_records.items():
|
|
2019
2030
|
# Get dimensions that depend on this dimension.
|
|
2020
2031
|
populated_by = self.dimensions.get_elements_populated_by(
|
|
2021
2032
|
self.dimensions[original_element.name] # type: ignore
|
|
2022
2033
|
)
|
|
2023
|
-
|
|
2024
|
-
for data_id in record_mapping.keys():
|
|
2034
|
+
if populated_by:
|
|
2025
2035
|
for element in populated_by:
|
|
2026
2036
|
if element not in allowed_elements:
|
|
2027
2037
|
continue
|
|
@@ -2040,28 +2050,32 @@ class DirectButler(Butler): # numpydoc ignore=PR02
|
|
|
2040
2050
|
# have to be scanned.
|
|
2041
2051
|
continue
|
|
2042
2052
|
|
|
2043
|
-
if
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2053
|
+
if record_mapping:
|
|
2054
|
+
if not isinstance(source_butler, Butler):
|
|
2055
|
+
raise RuntimeError(
|
|
2056
|
+
f"Transferring populated_by records like {element.name}"
|
|
2057
|
+
" requires a full Butler."
|
|
2058
|
+
)
|
|
2047
2059
|
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
additional_records[record.definition].setdefault(record.dataId, record)
|
|
2060
|
+
with source_butler.query() as query:
|
|
2061
|
+
records = query.join_data_coordinates(record_mapping.keys()).dimension_records(
|
|
2062
|
+
element.name
|
|
2063
|
+
)
|
|
2064
|
+
for record in records:
|
|
2065
|
+
additional_records[record.definition].setdefault(record.dataId, record)
|
|
2055
2066
|
|
|
2056
2067
|
# The next step is to walk back through the additional records to
|
|
2057
2068
|
# pick up any missing content (such as visit_definition needing to
|
|
2058
2069
|
# know the exposure). Want to ensure we do not request records we
|
|
2059
2070
|
# already have.
|
|
2060
2071
|
missing_data_ids = set()
|
|
2061
|
-
for
|
|
2072
|
+
for record_mapping in additional_records.values():
|
|
2062
2073
|
for data_id in record_mapping.keys():
|
|
2063
|
-
|
|
2064
|
-
|
|
2074
|
+
for dimension in data_id.dimensions.required:
|
|
2075
|
+
element = source_butler.dimensions[dimension]
|
|
2076
|
+
dimension_key = data_id.subset(dimension)
|
|
2077
|
+
if dimension_key not in primary_records[element]:
|
|
2078
|
+
missing_data_ids.add(dimension_key)
|
|
2065
2079
|
|
|
2066
2080
|
# Fill out the new records. Assume that these new records do not
|
|
2067
2081
|
# also need to carry over additional populated_by records.
|
|
@@ -2078,19 +2092,19 @@ class DirectButler(Butler): # numpydoc ignore=PR02
|
|
|
2078
2092
|
def _extract_dimension_records_from_data_ids(
|
|
2079
2093
|
self,
|
|
2080
2094
|
source_butler: LimitedButler | Butler,
|
|
2081
|
-
data_ids:
|
|
2095
|
+
data_ids: Iterable[DataCoordinate],
|
|
2082
2096
|
allowed_elements: frozenset[DimensionElement],
|
|
2083
2097
|
) -> dict[DimensionElement, dict[DataCoordinate, DimensionRecord]]:
|
|
2084
2098
|
dimension_records: dict[DimensionElement, dict[DataCoordinate, DimensionRecord]] = defaultdict(dict)
|
|
2085
2099
|
|
|
2100
|
+
data_ids = set(data_ids)
|
|
2101
|
+
if not all(data_id.hasRecords() for data_id in data_ids):
|
|
2102
|
+
if isinstance(source_butler, Butler):
|
|
2103
|
+
data_ids = source_butler._expand_data_ids(data_ids)
|
|
2104
|
+
else:
|
|
2105
|
+
raise TypeError("Input butler needs to be a full butler to expand DataId.")
|
|
2106
|
+
|
|
2086
2107
|
for data_id in data_ids:
|
|
2087
|
-
# Need an expanded record, if not expanded that we need a full
|
|
2088
|
-
# butler with registry (allow mocks with registry too).
|
|
2089
|
-
if not data_id.hasRecords():
|
|
2090
|
-
if registry := getattr(source_butler, "registry", None):
|
|
2091
|
-
data_id = registry.expandDataId(data_id)
|
|
2092
|
-
else:
|
|
2093
|
-
raise TypeError("Input butler needs to be a full butler to expand DataId.")
|
|
2094
2108
|
# If this butler doesn't know about a dimension in the source
|
|
2095
2109
|
# butler things will break later.
|
|
2096
2110
|
for element_name in data_id.dimensions.elements:
|
|
@@ -2569,6 +2583,9 @@ class DirectButler(Butler): # numpydoc ignore=PR02
|
|
|
2569
2583
|
"""Immediately load caches that are used for common operations."""
|
|
2570
2584
|
self._registry.preload_cache(load_dimension_record_cache=load_dimension_record_cache)
|
|
2571
2585
|
|
|
2586
|
+
def _expand_data_ids(self, data_ids: Iterable[DataCoordinate]) -> list[DataCoordinate]:
|
|
2587
|
+
return self._registry.expand_data_ids(data_ids)
|
|
2588
|
+
|
|
2572
2589
|
_config: ButlerConfig
|
|
2573
2590
|
"""Configuration for this Butler instance."""
|
|
2574
2591
|
|
{lsst_daf_butler-30.2026.100 → lsst_daf_butler-30.2026.300}/python/lsst/daf/butler/logging.py
RENAMED
|
@@ -764,11 +764,17 @@ class ButlerLogRecords(MutableSequence[ButlerLogRecord]):
|
|
|
764
764
|
|
|
765
765
|
|
|
766
766
|
class ButlerLogRecordHandler(StreamHandler):
|
|
767
|
-
"""Python log handler that accumulates records.
|
|
767
|
+
"""Python log handler that accumulates records.
|
|
768
768
|
|
|
769
|
-
|
|
769
|
+
Parameters
|
|
770
|
+
----------
|
|
771
|
+
records : `ButlerLogRecords`, optional
|
|
772
|
+
Container to store logs in.
|
|
773
|
+
"""
|
|
774
|
+
|
|
775
|
+
def __init__(self, records: ButlerLogRecords | None = None) -> None:
|
|
770
776
|
super().__init__()
|
|
771
|
-
self.records = ButlerLogRecords([])
|
|
777
|
+
self.records = ButlerLogRecords([]) if records is None else records
|
|
772
778
|
|
|
773
779
|
def emit(self, record: LogRecord) -> None:
|
|
774
780
|
self.records.append(record)
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# This file is part of daf_butler.
|
|
2
|
+
#
|
|
3
|
+
# Developed for the LSST Data Management System.
|
|
4
|
+
# This product includes software developed by the LSST Project
|
|
5
|
+
# (http://www.lsst.org).
|
|
6
|
+
# See the COPYRIGHT file at the top-level directory of this distribution
|
|
7
|
+
# for details of code ownership.
|
|
8
|
+
#
|
|
9
|
+
# This software is dual licensed under the GNU General Public License and also
|
|
10
|
+
# under a 3-clause BSD license. Recipients may choose which of these licenses
|
|
11
|
+
# to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
|
|
12
|
+
# respectively. If you choose the GPL option then the following text applies
|
|
13
|
+
# (but note that there is still no warranty even if you opt for BSD instead):
|
|
14
|
+
#
|
|
15
|
+
# This program is free software: you can redistribute it and/or modify
|
|
16
|
+
# it under the terms of the GNU General Public License as published by
|
|
17
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
18
|
+
# (at your option) any later version.
|
|
19
|
+
#
|
|
20
|
+
# This program is distributed in the hope that it will be useful,
|
|
21
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
22
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
23
|
+
# GNU General Public License for more details.
|
|
24
|
+
#
|
|
25
|
+
# You should have received a copy of the GNU General Public License
|
|
26
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
27
|
+
|
|
28
|
+
from __future__ import annotations
|
|
29
|
+
|
|
30
|
+
from collections import defaultdict
|
|
31
|
+
from collections.abc import Iterable
|
|
32
|
+
|
|
33
|
+
from ..dimensions import (
|
|
34
|
+
DataCoordinate,
|
|
35
|
+
DimensionDataAttacher,
|
|
36
|
+
DimensionGroup,
|
|
37
|
+
DimensionUniverse,
|
|
38
|
+
)
|
|
39
|
+
from ..dimensions.record_cache import DimensionRecordCache
|
|
40
|
+
from ..queries import QueryFactoryFunction
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def expand_data_ids(
|
|
44
|
+
data_ids: Iterable[DataCoordinate],
|
|
45
|
+
universe: DimensionUniverse,
|
|
46
|
+
query_func: QueryFactoryFunction,
|
|
47
|
+
cache: DimensionRecordCache | None,
|
|
48
|
+
) -> list[DataCoordinate]:
|
|
49
|
+
"""Expand the given data IDs to look up implied dimension values and attach
|
|
50
|
+
dimension records.
|
|
51
|
+
|
|
52
|
+
Parameters
|
|
53
|
+
----------
|
|
54
|
+
data_ids : `~collections.abc.Iterable` [ `DataCoordinate` ]
|
|
55
|
+
Data coordinates to be expanded.
|
|
56
|
+
universe : `DimensionUniverse`
|
|
57
|
+
Dimension universe associated with the given ``data_ids`` values.
|
|
58
|
+
query_func : QueryFactoryFunction
|
|
59
|
+
Function used to set up a Butler query context for looking up required
|
|
60
|
+
information from the database.
|
|
61
|
+
cache : `DimensionRecordCache` | None
|
|
62
|
+
Cache containing already-known dimension records. May be `None` if a
|
|
63
|
+
cache is not available.
|
|
64
|
+
|
|
65
|
+
Returns
|
|
66
|
+
-------
|
|
67
|
+
expanded : `list` [ `DataCoordinate` ]
|
|
68
|
+
List of `DataCoordinate` instances in the same order as the input
|
|
69
|
+
values. It is guaranteed that each `DataCoordinate` has
|
|
70
|
+
``hasRecords()=True`` and ``hasFull()=True``.
|
|
71
|
+
"""
|
|
72
|
+
output = list(data_ids)
|
|
73
|
+
|
|
74
|
+
grouped_by_dimensions: defaultdict[DimensionGroup, list[int]] = defaultdict(list)
|
|
75
|
+
for i, data_id in enumerate(data_ids):
|
|
76
|
+
if not data_id.hasRecords():
|
|
77
|
+
grouped_by_dimensions[data_id.dimensions].append(i)
|
|
78
|
+
|
|
79
|
+
if not grouped_by_dimensions:
|
|
80
|
+
# All given DataCoordinate values are already expanded.
|
|
81
|
+
return output
|
|
82
|
+
|
|
83
|
+
attacher = DimensionDataAttacher(
|
|
84
|
+
cache=cache,
|
|
85
|
+
dimensions=DimensionGroup.union(*grouped_by_dimensions.keys(), universe=universe),
|
|
86
|
+
)
|
|
87
|
+
for dimensions, indexes in grouped_by_dimensions.items():
|
|
88
|
+
with query_func() as query:
|
|
89
|
+
expanded = attacher.attach(dimensions, (output[index] for index in indexes), query)
|
|
90
|
+
for index, data_id in zip(indexes, expanded):
|
|
91
|
+
output[index] = data_id
|
|
92
|
+
|
|
93
|
+
return output
|
|
@@ -34,7 +34,6 @@ __all__ = ("SqlRegistry",)
|
|
|
34
34
|
import contextlib
|
|
35
35
|
import logging
|
|
36
36
|
import warnings
|
|
37
|
-
from collections import defaultdict
|
|
38
37
|
from collections.abc import Iterable, Iterator, Mapping, Sequence
|
|
39
38
|
from typing import TYPE_CHECKING, Any
|
|
40
39
|
|
|
@@ -54,7 +53,6 @@ from ..dimensions import (
|
|
|
54
53
|
DataCoordinate,
|
|
55
54
|
DataId,
|
|
56
55
|
DimensionConfig,
|
|
57
|
-
DimensionDataAttacher,
|
|
58
56
|
DimensionElement,
|
|
59
57
|
DimensionGroup,
|
|
60
58
|
DimensionRecord,
|
|
@@ -78,6 +76,7 @@ from ..registry.interfaces import ChainedCollectionRecord, ReadOnlyDatabaseError
|
|
|
78
76
|
from ..registry.managers import RegistryManagerInstances, RegistryManagerTypes
|
|
79
77
|
from ..registry.wildcards import CollectionWildcard, DatasetTypeWildcard
|
|
80
78
|
from ..utils import transactional
|
|
79
|
+
from .expand_data_ids import expand_data_ids
|
|
81
80
|
|
|
82
81
|
if TYPE_CHECKING:
|
|
83
82
|
from .._butler_config import ButlerConfig
|
|
@@ -1415,28 +1414,7 @@ class SqlRegistry:
|
|
|
1415
1414
|
return DataCoordinate.standardize(keys, dimensions=standardized.dimensions).expanded(records=records)
|
|
1416
1415
|
|
|
1417
1416
|
def expand_data_ids(self, data_ids: Iterable[DataCoordinate]) -> list[DataCoordinate]:
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
grouped_by_dimensions: defaultdict[DimensionGroup, list[int]] = defaultdict(list)
|
|
1421
|
-
for i, data_id in enumerate(data_ids):
|
|
1422
|
-
if not data_id.hasRecords():
|
|
1423
|
-
grouped_by_dimensions[data_id.dimensions].append(i)
|
|
1424
|
-
|
|
1425
|
-
if not grouped_by_dimensions:
|
|
1426
|
-
# All given DataCoordinate values are already expanded.
|
|
1427
|
-
return output
|
|
1428
|
-
|
|
1429
|
-
attacher = DimensionDataAttacher(
|
|
1430
|
-
cache=self.dimension_record_cache,
|
|
1431
|
-
dimensions=DimensionGroup.union(*grouped_by_dimensions.keys(), universe=self.dimensions),
|
|
1432
|
-
)
|
|
1433
|
-
with self._query() as query:
|
|
1434
|
-
for dimensions, indexes in grouped_by_dimensions.items():
|
|
1435
|
-
expanded = attacher.attach(dimensions, (output[index] for index in indexes), query)
|
|
1436
|
-
for index, data_id in zip(indexes, expanded):
|
|
1437
|
-
output[index] = data_id
|
|
1438
|
-
|
|
1439
|
-
return output
|
|
1417
|
+
return expand_data_ids(data_ids, self.dimensions, self._query, self.dimension_record_cache)
|
|
1440
1418
|
|
|
1441
1419
|
def expand_refs(self, dataset_refs: list[DatasetRef]) -> list[DatasetRef]:
|
|
1442
1420
|
expanded_ids = self.expand_data_ids([ref.dataId for ref in dataset_refs])
|
|
@@ -65,6 +65,7 @@ from ..dimensions import DataCoordinate, DataIdValue, DimensionConfig, Dimension
|
|
|
65
65
|
from ..queries import Query
|
|
66
66
|
from ..queries.tree import make_column_literal
|
|
67
67
|
from ..registry import CollectionArgType, NoDefaultCollectionError, Registry, RegistryDefaults
|
|
68
|
+
from ..registry.expand_data_ids import expand_data_ids
|
|
68
69
|
from ._collection_args import convert_collection_arg_to_glob_string_list
|
|
69
70
|
from ._defaults import DefaultsHolder
|
|
70
71
|
from ._get import convert_http_url_to_resource_path, get_dataset_as_python_object
|
|
@@ -633,7 +634,7 @@ class RemoteButler(Butler): # numpydoc ignore=PR02
|
|
|
633
634
|
raise NotImplementedError()
|
|
634
635
|
|
|
635
636
|
def transfer_dimension_records_from(
|
|
636
|
-
self, source_butler: LimitedButler | Butler, source_refs: Iterable[DatasetRef]
|
|
637
|
+
self, source_butler: LimitedButler | Butler, source_refs: Iterable[DatasetRef | DataCoordinate]
|
|
637
638
|
) -> None:
|
|
638
639
|
# Docstring inherited.
|
|
639
640
|
raise NotImplementedError()
|
|
@@ -738,6 +739,9 @@ class RemoteButler(Butler): # numpydoc ignore=PR02
|
|
|
738
739
|
def close(self) -> None:
|
|
739
740
|
pass
|
|
740
741
|
|
|
742
|
+
def _expand_data_ids(self, data_ids: Iterable[DataCoordinate]) -> list[DataCoordinate]:
|
|
743
|
+
return expand_data_ids(data_ids, self.dimensions, self.query, None)
|
|
744
|
+
|
|
741
745
|
@property
|
|
742
746
|
def _file_transfer_source(self) -> RemoteFileTransferSource:
|
|
743
747
|
return RemoteFileTransferSource(self._connection)
|
|
@@ -338,7 +338,7 @@ class HybridButler(Butler):
|
|
|
338
338
|
)
|
|
339
339
|
|
|
340
340
|
def transfer_dimension_records_from(
|
|
341
|
-
self, source_butler: LimitedButler | Butler, source_refs: Iterable[DatasetRef]
|
|
341
|
+
self, source_butler: LimitedButler | Butler, source_refs: Iterable[DatasetRef | DataCoordinate]
|
|
342
342
|
) -> None:
|
|
343
343
|
return self._direct_butler.transfer_dimension_records_from(source_butler, source_refs)
|
|
344
344
|
|
|
@@ -425,6 +425,9 @@ class HybridButler(Butler):
|
|
|
425
425
|
source_butler, data_ids, allowed_elements
|
|
426
426
|
)
|
|
427
427
|
|
|
428
|
+
def _expand_data_ids(self, data_ids: Iterable[DataCoordinate]) -> list[DataCoordinate]:
|
|
429
|
+
return self._remote_butler._expand_data_ids(data_ids)
|
|
430
|
+
|
|
428
431
|
@property
|
|
429
432
|
def collection_chains(self) -> ButlerCollections:
|
|
430
433
|
return HybridButlerCollections(self)
|