lsst-daf-butler 29.2025.3100__tar.gz → 29.2025.3300__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (449) hide show
  1. {lsst_daf_butler-29.2025.3100/python/lsst_daf_butler.egg-info → lsst_daf_butler-29.2025.3300}/PKG-INFO +1 -1
  2. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_limited_butler.py +1 -6
  3. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_storage_class.py +66 -174
  4. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/datastore/record_data.py +22 -0
  5. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/datastore/stored_file_info.py +2 -4
  6. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/dimensions/_record_set.py +49 -2
  7. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/server/_config.py +9 -1
  8. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/server/_dependencies.py +24 -3
  9. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/server/_server.py +4 -1
  10. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/server/handlers/_external_query.py +3 -4
  11. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/server/handlers/_query_limits.py +7 -5
  12. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/server/handlers/_query_streaming.py +3 -3
  13. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/_examplePythonTypes.py +1 -6
  14. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/server.py +2 -2
  15. lsst_daf_butler-29.2025.3300/python/lsst/daf/butler/version.py +2 -0
  16. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300/python/lsst_daf_butler.egg-info}/PKG-INFO +1 -1
  17. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_datasets.py +0 -13
  18. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_dimension_record_containers.py +19 -9
  19. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_quantumBackedButler.py +18 -0
  20. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_server.py +1 -0
  21. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_storageClass.py +4 -13
  22. lsst_daf_butler-29.2025.3100/python/lsst/daf/butler/version.py +0 -2
  23. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/COPYRIGHT +0 -0
  24. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/LICENSE +0 -0
  25. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/MANIFEST.in +0 -0
  26. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/README.md +0 -0
  27. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/bsd_license.txt +0 -0
  28. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/doc/lsst.daf.butler/CHANGES.rst +0 -0
  29. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/doc/lsst.daf.butler/concreteStorageClasses.rst +0 -0
  30. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/doc/lsst.daf.butler/configuring.rst +0 -0
  31. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/doc/lsst.daf.butler/datastores.rst +0 -0
  32. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/doc/lsst.daf.butler/dimensions.rst +0 -0
  33. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/doc/lsst.daf.butler/formatters.rst +0 -0
  34. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/doc/lsst.daf.butler/index.rst +0 -0
  35. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/doc/lsst.daf.butler/organizing.rst +0 -0
  36. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/doc/lsst.daf.butler/queries.rst +0 -0
  37. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/doc/lsst.daf.butler/use-in-tests.rst +0 -0
  38. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/doc/lsst.daf.butler/writing-subcommands.rst +0 -0
  39. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/gpl-v3.0.txt +0 -0
  40. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/pyproject.toml +0 -0
  41. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/__init__.py +0 -0
  42. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/__init__.py +0 -0
  43. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/__init__.py +0 -0
  44. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_butler.py +0 -0
  45. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_butler_collections.py +0 -0
  46. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_butler_config.py +0 -0
  47. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_butler_instance_options.py +0 -0
  48. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_butler_metrics.py +0 -0
  49. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_butler_repo_index.py +0 -0
  50. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_collection_type.py +0 -0
  51. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_column_categorization.py +0 -0
  52. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_column_tags.py +0 -0
  53. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_column_type_info.py +0 -0
  54. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_config.py +0 -0
  55. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_config_support.py +0 -0
  56. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_dataset_association.py +0 -0
  57. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_dataset_existence.py +0 -0
  58. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_dataset_provenance.py +0 -0
  59. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_dataset_ref.py +0 -0
  60. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_dataset_type.py +0 -0
  61. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_deferredDatasetHandle.py +0 -0
  62. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_exceptions.py +0 -0
  63. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_exceptions_legacy.py +0 -0
  64. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_file_dataset.py +0 -0
  65. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_file_descriptor.py +0 -0
  66. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_formatter.py +0 -0
  67. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_labeled_butler_factory.py +0 -0
  68. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_location.py +0 -0
  69. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_named.py +0 -0
  70. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_quantum.py +0 -0
  71. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_quantum_backed.py +0 -0
  72. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_query_all_datasets.py +0 -0
  73. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_registry_shim.py +0 -0
  74. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_storage_class_delegate.py +0 -0
  75. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_timespan.py +0 -0
  76. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_topology.py +0 -0
  77. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_utilities/__init__.py +0 -0
  78. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_utilities/locked_object.py +0 -0
  79. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_utilities/named_locks.py +0 -0
  80. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/_utilities/thread_safe_cache.py +0 -0
  81. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/arrow_utils.py +0 -0
  82. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/cli/__init__.py +0 -0
  83. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/cli/butler.py +0 -0
  84. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/cli/cliLog.py +0 -0
  85. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/cli/cmd/__init__.py +0 -0
  86. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/cli/cmd/_remove_collections.py +0 -0
  87. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/cli/cmd/_remove_runs.py +0 -0
  88. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/cli/cmd/commands.py +0 -0
  89. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/cli/opt/__init__.py +0 -0
  90. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/cli/opt/arguments.py +0 -0
  91. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/cli/opt/optionGroups.py +0 -0
  92. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/cli/opt/options.py +0 -0
  93. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/cli/progress.py +0 -0
  94. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/cli/utils.py +0 -0
  95. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/column_spec.py +0 -0
  96. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/configs/datastore.yaml +0 -0
  97. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/configs/datastores/composites.yaml +0 -0
  98. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/configs/datastores/fileDatastore.yaml +0 -0
  99. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/configs/datastores/formatters.yaml +0 -0
  100. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/configs/datastores/writeRecipes.yaml +0 -0
  101. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/configs/dimensions.yaml +0 -0
  102. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe0.yaml +0 -0
  103. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe1.yaml +0 -0
  104. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe2.yaml +0 -0
  105. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe3.yaml +0 -0
  106. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe4.yaml +0 -0
  107. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe5.yaml +0 -0
  108. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe6.yaml +0 -0
  109. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe7.yaml +0 -0
  110. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/configs/registry.yaml +0 -0
  111. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/configs/repo_transfer_formats.yaml +0 -0
  112. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/configs/storageClasses.yaml +0 -0
  113. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/datastore/__init__.py +0 -0
  114. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/datastore/_datastore.py +0 -0
  115. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/datastore/_transfer.py +0 -0
  116. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/datastore/cache_manager.py +0 -0
  117. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/datastore/composites.py +0 -0
  118. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/datastore/constraints.py +0 -0
  119. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/datastore/file_templates.py +0 -0
  120. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/datastore/generic_base.py +0 -0
  121. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/datastores/__init__.py +0 -0
  122. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/datastores/chainedDatastore.py +0 -0
  123. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/datastores/fileDatastore.py +0 -0
  124. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/datastores/file_datastore/__init__.py +0 -0
  125. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/datastores/file_datastore/get.py +0 -0
  126. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/datastores/file_datastore/retrieve_artifacts.py +0 -0
  127. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/datastores/file_datastore/transfer.py +0 -0
  128. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/datastores/inMemoryDatastore.py +0 -0
  129. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/ddl.py +0 -0
  130. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/delegates/__init__.py +0 -0
  131. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/delegates/arrowtable.py +0 -0
  132. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/dimensions/__init__.py +0 -0
  133. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/dimensions/_config.py +0 -0
  134. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/dimensions/_coordinate.py +0 -0
  135. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/dimensions/_data_coordinate_iterable.py +0 -0
  136. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/dimensions/_database.py +0 -0
  137. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/dimensions/_elements.py +0 -0
  138. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/dimensions/_governor.py +0 -0
  139. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/dimensions/_group.py +0 -0
  140. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/dimensions/_packer.py +0 -0
  141. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/dimensions/_record_table.py +0 -0
  142. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/dimensions/_records.py +0 -0
  143. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/dimensions/_schema.py +0 -0
  144. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/dimensions/_skypix.py +0 -0
  145. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/dimensions/_universe.py +0 -0
  146. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/dimensions/construction.py +0 -0
  147. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/dimensions/record_cache.py +0 -0
  148. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/direct_butler/__init__.py +0 -0
  149. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/direct_butler/_direct_butler.py +0 -0
  150. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/direct_butler/_direct_butler_collections.py +0 -0
  151. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/direct_query_driver/__init__.py +0 -0
  152. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/direct_query_driver/_driver.py +0 -0
  153. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/direct_query_driver/_postprocessing.py +0 -0
  154. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/direct_query_driver/_query_analysis.py +0 -0
  155. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/direct_query_driver/_query_builder.py +0 -0
  156. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/direct_query_driver/_result_page_converter.py +0 -0
  157. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/direct_query_driver/_sql_builders.py +0 -0
  158. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/direct_query_driver/_sql_column_visitor.py +0 -0
  159. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/formatters/__init__.py +0 -0
  160. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/formatters/astropyTable.py +0 -0
  161. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/formatters/file.py +0 -0
  162. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/formatters/json.py +0 -0
  163. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/formatters/logs.py +0 -0
  164. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/formatters/matplotlib.py +0 -0
  165. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/formatters/packages.py +0 -0
  166. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/formatters/parquet.py +0 -0
  167. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/formatters/pickle.py +0 -0
  168. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/formatters/typeless.py +0 -0
  169. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/formatters/yaml.py +0 -0
  170. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/json.py +0 -0
  171. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/logging.py +0 -0
  172. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/mapping_factory.py +0 -0
  173. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/name_shrinker.py +0 -0
  174. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/nonempty_mapping.py +0 -0
  175. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/persistence_context.py +0 -0
  176. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/progress.py +0 -0
  177. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/py.typed +0 -0
  178. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/pydantic_utils.py +0 -0
  179. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/queries/__init__.py +0 -0
  180. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/queries/_base.py +0 -0
  181. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/queries/_data_coordinate_query_results.py +0 -0
  182. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/queries/_dataset_query_results.py +0 -0
  183. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/queries/_dimension_record_query_results.py +0 -0
  184. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/queries/_expression_strings.py +0 -0
  185. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/queries/_general_query_results.py +0 -0
  186. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/queries/_identifiers.py +0 -0
  187. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/queries/_query.py +0 -0
  188. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/queries/convert_args.py +0 -0
  189. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/queries/driver.py +0 -0
  190. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/queries/expression_factory.py +0 -0
  191. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/queries/overlaps.py +0 -0
  192. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/queries/predicate_constraints_summary.py +0 -0
  193. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/queries/result_specs.py +0 -0
  194. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/queries/tree/__init__.py +0 -0
  195. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/queries/tree/_base.py +0 -0
  196. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/queries/tree/_column_expression.py +0 -0
  197. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/queries/tree/_column_literal.py +0 -0
  198. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/queries/tree/_column_reference.py +0 -0
  199. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/queries/tree/_column_set.py +0 -0
  200. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/queries/tree/_predicate.py +0 -0
  201. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/queries/tree/_query_tree.py +0 -0
  202. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/queries/visitors.py +0 -0
  203. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/__init__.py +0 -0
  204. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/_caching_context.py +0 -0
  205. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/_collection_record_cache.py +0 -0
  206. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/_collection_summary.py +0 -0
  207. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/_collection_summary_cache.py +0 -0
  208. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/_config.py +0 -0
  209. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/_defaults.py +0 -0
  210. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/_exceptions.py +0 -0
  211. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/_registry.py +0 -0
  212. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/_registry_factory.py +0 -0
  213. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/attributes.py +0 -0
  214. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/bridge/__init__.py +0 -0
  215. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/bridge/ephemeral.py +0 -0
  216. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/bridge/monolithic.py +0 -0
  217. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/collections/__init__.py +0 -0
  218. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/collections/_base.py +0 -0
  219. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/collections/nameKey.py +0 -0
  220. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/collections/synthIntKey.py +0 -0
  221. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/connectionString.py +0 -0
  222. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/databases/__init__.py +0 -0
  223. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/databases/postgresql.py +0 -0
  224. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/databases/sqlite.py +0 -0
  225. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/datasets/__init__.py +0 -0
  226. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/datasets/byDimensions/__init__.py +0 -0
  227. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/datasets/byDimensions/_dataset_type_cache.py +0 -0
  228. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/datasets/byDimensions/_manager.py +0 -0
  229. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/datasets/byDimensions/summaries.py +0 -0
  230. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/datasets/byDimensions/tables.py +0 -0
  231. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/dimensions/__init__.py +0 -0
  232. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/dimensions/static.py +0 -0
  233. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/interfaces/__init__.py +0 -0
  234. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/interfaces/_attributes.py +0 -0
  235. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/interfaces/_bridge.py +0 -0
  236. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/interfaces/_collections.py +0 -0
  237. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/interfaces/_database.py +0 -0
  238. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/interfaces/_database_explain.py +0 -0
  239. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/interfaces/_datasets.py +0 -0
  240. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/interfaces/_dimensions.py +0 -0
  241. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/interfaces/_obscore.py +0 -0
  242. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/interfaces/_opaque.py +0 -0
  243. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/interfaces/_versioning.py +0 -0
  244. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/managers.py +0 -0
  245. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/nameShrinker.py +0 -0
  246. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/obscore/__init__.py +0 -0
  247. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/obscore/_config.py +0 -0
  248. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/obscore/_manager.py +0 -0
  249. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/obscore/_records.py +0 -0
  250. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/obscore/_schema.py +0 -0
  251. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/obscore/_spatial.py +0 -0
  252. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/obscore/default_spatial.py +0 -0
  253. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/obscore/pgsphere.py +0 -0
  254. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/opaque.py +0 -0
  255. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/__init__.py +0 -0
  256. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/_builder.py +0 -0
  257. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/_query.py +0 -0
  258. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/_query_backend.py +0 -0
  259. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/_query_context.py +0 -0
  260. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/_readers.py +0 -0
  261. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/_results.py +0 -0
  262. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/_sql_query_backend.py +0 -0
  263. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/_sql_query_context.py +0 -0
  264. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/_structs.py +0 -0
  265. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/butler_sql_engine.py +0 -0
  266. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/expressions/__init__.py +0 -0
  267. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/expressions/_predicate.py +0 -0
  268. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/expressions/categorize.py +0 -0
  269. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/expressions/check.py +0 -0
  270. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/expressions/normalForm.py +0 -0
  271. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/expressions/parser/__init__.py +0 -0
  272. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/expressions/parser/exprTree.py +0 -0
  273. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/expressions/parser/parser.py +0 -0
  274. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/expressions/parser/parserLex.py +0 -0
  275. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/expressions/parser/parserYacc.py +0 -0
  276. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/expressions/parser/ply/__init__.py +0 -0
  277. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/expressions/parser/ply/lex.py +0 -0
  278. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/expressions/parser/ply/yacc.py +0 -0
  279. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/expressions/parser/treeVisitor.py +0 -0
  280. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/queries/find_first_dataset.py +0 -0
  281. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/sql_registry.py +0 -0
  282. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/tests/__init__.py +0 -0
  283. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/tests/_database.py +0 -0
  284. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/tests/_registry.py +0 -0
  285. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/versions.py +0 -0
  286. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/registry/wildcards.py +0 -0
  287. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/__init__.py +0 -0
  288. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/_collection_args.py +0 -0
  289. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/_config.py +0 -0
  290. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/_defaults.py +0 -0
  291. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/_errors.py +0 -0
  292. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/_factory.py +0 -0
  293. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/_get.py +0 -0
  294. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/_http_connection.py +0 -0
  295. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/_query_driver.py +0 -0
  296. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/_query_results.py +0 -0
  297. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/_ref_utils.py +0 -0
  298. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/_registry.py +0 -0
  299. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/_remote_butler.py +0 -0
  300. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/_remote_butler_collections.py +0 -0
  301. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/_remote_file_transfer_source.py +0 -0
  302. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/authentication/__init__.py +0 -0
  303. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/authentication/cadc.py +0 -0
  304. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/authentication/interface.py +0 -0
  305. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/authentication/rubin.py +0 -0
  306. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/registry/__init__.py +0 -0
  307. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/registry/_query_common.py +0 -0
  308. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/registry/_query_data_coordinates.py +0 -0
  309. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/registry/_query_datasets.py +0 -0
  310. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/registry/_query_dimension_records.py +0 -0
  311. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/server/__init__.py +0 -0
  312. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/server/_factory.py +0 -0
  313. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/server/_gafaelfawr.py +0 -0
  314. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/server/_telemetry.py +0 -0
  315. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/server/handlers/_external.py +0 -0
  316. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/server/handlers/_file_info.py +0 -0
  317. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/server/handlers/_internal.py +0 -0
  318. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/server/handlers/_query_serialization.py +0 -0
  319. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/server/handlers/_utils.py +0 -0
  320. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/remote_butler/server_models.py +0 -0
  321. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/repo_relocation.py +0 -0
  322. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/script/__init__.py +0 -0
  323. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/script/_associate.py +0 -0
  324. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/script/_pruneDatasets.py +0 -0
  325. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/script/butlerImport.py +0 -0
  326. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/script/certifyCalibrations.py +0 -0
  327. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/script/collectionChain.py +0 -0
  328. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/script/configDump.py +0 -0
  329. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/script/configValidate.py +0 -0
  330. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/script/createRepo.py +0 -0
  331. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/script/exportCalibs.py +0 -0
  332. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/script/ingest_files.py +0 -0
  333. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/script/ingest_zip.py +0 -0
  334. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/script/queryCollections.py +0 -0
  335. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/script/queryDataIds.py +0 -0
  336. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/script/queryDatasetTypes.py +0 -0
  337. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/script/queryDatasets.py +0 -0
  338. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/script/queryDimensionRecords.py +0 -0
  339. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/script/register_dataset_type.py +0 -0
  340. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/script/removeCollections.py +0 -0
  341. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/script/removeDatasetType.py +0 -0
  342. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/script/removeRuns.py +0 -0
  343. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/script/retrieveArtifacts.py +0 -0
  344. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/script/transferDatasets.py +0 -0
  345. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/__init__.py +0 -0
  346. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/_datasetsHelper.py +0 -0
  347. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/_dummyRegistry.py +0 -0
  348. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/_testRepo.py +0 -0
  349. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/butler_queries.py +0 -0
  350. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/cliCmdTestBase.py +0 -0
  351. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/cliLogTestBase.py +0 -0
  352. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/deferredFormatter.py +0 -0
  353. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/dict_convertible_model.py +0 -0
  354. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/hybrid_butler.py +0 -0
  355. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/hybrid_butler_collections.py +0 -0
  356. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/hybrid_butler_registry.py +0 -0
  357. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/postgresql.py +0 -0
  358. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/registry_data/__init__.py +0 -0
  359. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/registry_data/base.yaml +0 -0
  360. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/registry_data/ci_hsc-subset-skymap.yaml +0 -0
  361. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/registry_data/ci_hsc-subset.yaml +0 -0
  362. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/registry_data/datasets.yaml +0 -0
  363. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/registry_data/hsc-rc2-subset-v0.yaml +0 -0
  364. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/registry_data/spatial.py +0 -0
  365. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/registry_data/spatial.yaml +0 -0
  366. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/server_utils.py +0 -0
  367. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/testFormatters.py +0 -0
  368. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/tests/utils.py +0 -0
  369. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/time_utils.py +0 -0
  370. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/timespan_database_representation.py +0 -0
  371. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/transfers/__init__.py +0 -0
  372. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/transfers/_context.py +0 -0
  373. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/transfers/_interfaces.py +0 -0
  374. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/transfers/_yaml.py +0 -0
  375. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst/daf/butler/utils.py +0 -0
  376. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst_daf_butler.egg-info/SOURCES.txt +0 -0
  377. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst_daf_butler.egg-info/dependency_links.txt +0 -0
  378. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst_daf_butler.egg-info/entry_points.txt +0 -0
  379. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst_daf_butler.egg-info/requires.txt +0 -0
  380. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst_daf_butler.egg-info/top_level.txt +0 -0
  381. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/python/lsst_daf_butler.egg-info/zip-safe +0 -0
  382. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/setup.cfg +0 -0
  383. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_astropyTableFormatter.py +0 -0
  384. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_authentication.py +0 -0
  385. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_butler.py +0 -0
  386. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_butler_factory.py +0 -0
  387. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_cliCmdAssociate.py +0 -0
  388. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_cliCmdConfigDump.py +0 -0
  389. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_cliCmdConfigValidate.py +0 -0
  390. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_cliCmdCreate.py +0 -0
  391. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_cliCmdImport.py +0 -0
  392. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_cliCmdIngestFiles.py +0 -0
  393. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_cliCmdPruneDatasets.py +0 -0
  394. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_cliCmdQueryCollections.py +0 -0
  395. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_cliCmdQueryDataIds.py +0 -0
  396. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_cliCmdQueryDatasetTypes.py +0 -0
  397. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_cliCmdQueryDatasets.py +0 -0
  398. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_cliCmdQueryDimensionRecords.py +0 -0
  399. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_cliCmdRemoveCollections.py +0 -0
  400. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_cliCmdRemoveRuns.py +0 -0
  401. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_cliCmdRetrieveArtifacts.py +0 -0
  402. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_cliLog.py +0 -0
  403. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_cliPluginLoader.py +0 -0
  404. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_cliUtilSplitCommas.py +0 -0
  405. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_cliUtilSplitKv.py +0 -0
  406. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_cliUtilToUpper.py +0 -0
  407. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_cliUtils.py +0 -0
  408. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_column_spec.py +0 -0
  409. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_composites.py +0 -0
  410. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_config.py +0 -0
  411. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_connectionString.py +0 -0
  412. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_constraints.py +0 -0
  413. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_datastore.py +0 -0
  414. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_ddl.py +0 -0
  415. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_dimensions.py +0 -0
  416. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_exprParserLex.py +0 -0
  417. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_exprParserYacc.py +0 -0
  418. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_expressions.py +0 -0
  419. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_formatter.py +0 -0
  420. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_gafaelfawr.py +0 -0
  421. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_location.py +0 -0
  422. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_logFormatter.py +0 -0
  423. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_logging.py +0 -0
  424. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_matplotlibFormatter.py +0 -0
  425. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_nonempty_mapping.py +0 -0
  426. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_normalFormExpression.py +0 -0
  427. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_obscore.py +0 -0
  428. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_packages.py +0 -0
  429. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_parquet.py +0 -0
  430. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_postgresql.py +0 -0
  431. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_progress.py +0 -0
  432. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_pydantic_utils.py +0 -0
  433. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_quantum.py +0 -0
  434. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_query_direct_postgresql.py +0 -0
  435. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_query_direct_sqlite.py +0 -0
  436. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_query_interface.py +0 -0
  437. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_query_relations.py +0 -0
  438. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_query_remote.py +0 -0
  439. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_query_utilities.py +0 -0
  440. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_remote_butler.py +0 -0
  441. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_simpleButler.py +0 -0
  442. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_sqlite.py +0 -0
  443. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_templates.py +0 -0
  444. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_testRepo.py +0 -0
  445. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_thread_utils.py +0 -0
  446. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_time_utils.py +0 -0
  447. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_timespan.py +0 -0
  448. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_utils.py +0 -0
  449. {lsst_daf_butler-29.2025.3100 → lsst_daf_butler-29.2025.3300}/tests/test_versioning.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lsst-daf-butler
3
- Version: 29.2025.3100
3
+ Version: 29.2025.3300
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: BSD 3-Clause License
@@ -129,11 +129,6 @@ class LimitedButler(ABC):
129
129
  obj : `object`
130
130
  The dataset.
131
131
 
132
- Raises
133
- ------
134
- AmbiguousDatasetError
135
- Raised if the supplied `DatasetRef` is unresolved.
136
-
137
132
  Notes
138
133
  -----
139
134
  In a `LimitedButler` the only allowable way to specify a dataset is
@@ -326,7 +321,7 @@ class LimitedButler(ABC):
326
321
  Whether the dataset artifact exists in the datastore and can be
327
322
  retrieved.
328
323
  """
329
- return self._datastore.exists(ref)
324
+ return self.stored_many([ref])[ref]
330
325
 
331
326
  def stored_many(
332
327
  self,
@@ -39,6 +39,8 @@ from collections.abc import Callable, Collection, Mapping, Sequence, Set
39
39
  from threading import RLock
40
40
  from typing import Any
41
41
 
42
+ import pydantic
43
+
42
44
  from lsst.utils import doImportType
43
45
  from lsst.utils.classes import Singleton
44
46
  from lsst.utils.introspection import get_full_type_name
@@ -57,6 +59,18 @@ class StorageClassConfig(ConfigSubset):
57
59
  defaultConfigFile = "storageClasses.yaml"
58
60
 
59
61
 
62
+ class _StorageClassModel(pydantic.BaseModel):
63
+ """Model class used to validate storage class configuration."""
64
+
65
+ pytype: str | None = None
66
+ inheritsFrom: str | None = None
67
+ components: dict[str, str] = pydantic.Field(default_factory=dict)
68
+ derivedComponents: dict[str, str] = pydantic.Field(default_factory=dict)
69
+ parameters: list[str] = pydantic.Field(default_factory=list)
70
+ delegate: str | None = None
71
+ converters: dict[str, str] = pydantic.Field(default_factory=dict)
72
+
73
+
60
74
  class StorageClass:
61
75
  """Class describing how a label maps to a particular Python type.
62
76
 
@@ -81,17 +95,9 @@ class StorageClass:
81
95
  that python type to the valid type of this storage class.
82
96
  """
83
97
 
84
- _cls_name: str = "BaseStorageClass"
85
- _cls_components: dict[str, StorageClass] | None = None
86
- _cls_derivedComponents: dict[str, StorageClass] | None = None
87
- _cls_parameters: Set[str] | Sequence[str] | None = None
88
- _cls_delegate: str | None = None
89
- _cls_pytype: type | str | None = None
90
- _cls_converters: dict[str, str] | None = None
91
-
92
98
  def __init__(
93
99
  self,
94
- name: str | None = None,
100
+ name: str = "",
95
101
  pytype: type | str | None = None,
96
102
  components: dict[str, StorageClass] | None = None,
97
103
  derivedComponents: dict[str, StorageClass] | None = None,
@@ -99,23 +105,8 @@ class StorageClass:
99
105
  delegate: str | None = None,
100
106
  converters: dict[str, str] | None = None,
101
107
  ):
102
- if name is None:
103
- name = self._cls_name
104
- if pytype is None:
105
- pytype = self._cls_pytype
106
- if components is None:
107
- components = self._cls_components
108
- if derivedComponents is None:
109
- derivedComponents = self._cls_derivedComponents
110
- if parameters is None:
111
- parameters = self._cls_parameters
112
- if delegate is None:
113
- delegate = self._cls_delegate
114
-
115
108
  # Merge converters with class defaults.
116
109
  self._converters = {}
117
- if self._cls_converters is not None:
118
- self._converters.update(self._cls_converters)
119
110
  if converters:
120
111
  self._converters.update(converters)
121
112
 
@@ -634,7 +625,6 @@ class StorageClassFactory(metaclass=Singleton):
634
625
 
635
626
  def __init__(self, config: StorageClassConfig | str | None = None):
636
627
  self._storageClasses: dict[str, StorageClass] = {}
637
- self._configs: list[StorageClassConfig] = []
638
628
  self._lock = RLock()
639
629
 
640
630
  # Always seed with the default config
@@ -657,40 +647,15 @@ class StorageClassFactory(metaclass=Singleton):
657
647
 
658
648
  StorageClasses
659
649
  --------------
660
- {sep.join(f"{s}: {self._storageClasses[s]!r}" for s in sorted(self._storageClasses))}
650
+ {sep.join(f"{self._storageClasses[s]!r}" for s in sorted(self._storageClasses))}
661
651
  """
662
652
 
663
- def __contains__(self, storageClassOrName: StorageClass | str) -> bool:
664
- """Indicate whether the storage class exists in the factory.
665
-
666
- Parameters
667
- ----------
668
- storageClassOrName : `str` or `StorageClass`
669
- If `str` is given existence of the named StorageClass
670
- in the factory is checked. If `StorageClass` is given
671
- existence and equality are checked.
672
-
673
- Returns
674
- -------
675
- in : `bool`
676
- True if the supplied string is present, or if the supplied
677
- `StorageClass` is present and identical.
678
-
679
- Notes
680
- -----
681
- The two different checks (one for "key" and one for "value") based on
682
- the type of the given argument mean that it is possible for
683
- StorageClass.name to be in the factory but StorageClass to not be
684
- in the factory.
685
- """
653
+ def __contains__(self, storageClassOrName: object) -> bool:
686
654
  with self._lock:
687
655
  if isinstance(storageClassOrName, str):
688
656
  return storageClassOrName in self._storageClasses
689
- elif (
690
- isinstance(storageClassOrName, StorageClass)
691
- and storageClassOrName.name in self._storageClasses
692
- ):
693
- return storageClassOrName == self._storageClasses[storageClassOrName.name]
657
+ elif isinstance(storageClassOrName, StorageClass):
658
+ return storageClassOrName.name in self._storageClasses
694
659
  return False
695
660
 
696
661
  def addFromConfig(self, config: StorageClassConfig | Config | str) -> None:
@@ -708,68 +673,54 @@ StorageClasses
708
673
  # components or parents before their classes are defined
709
674
  # we have a helper function that we can call recursively
710
675
  # to extract definitions from the configuration.
711
- def processStorageClass(name: str, _sconfig: StorageClassConfig, msg: str = "") -> None:
712
- # Maybe we've already processed this through recursion
676
+ def processStorageClass(name: str, _sconfig: StorageClassConfig, msg: str = "") -> StorageClass:
677
+ # This might have already been processed through recursion, or
678
+ # already present in the factory.
713
679
  if name not in _sconfig:
714
- return
715
- info = _sconfig.pop(name)
716
-
717
- # Always create the storage class so we can ensure that
718
- # we are not trying to overwrite with a different definition
719
- components = None
720
-
721
- # Extract scalar items from dict that are needed for
722
- # StorageClass Constructor
723
- storageClassKwargs = {k: info[k] for k in ("pytype", "delegate", "parameters") if k in info}
724
-
725
- if "converters" in info:
726
- storageClassKwargs["converters"] = info["converters"].toDict()
727
-
728
- for compName in ("components", "derivedComponents"):
729
- if compName not in info:
730
- continue
731
- components = {}
732
- for cname, ctype in info[compName].items():
733
- if ctype not in self:
734
- processStorageClass(ctype, sconfig, msg)
735
- components[cname] = self.getStorageClass(ctype)
736
-
737
- # Fill in other items
738
- storageClassKwargs[compName] = components
739
-
740
- # Create the new storage class and register it
741
- baseClass = None
742
- if "inheritsFrom" in info:
743
- baseName = info["inheritsFrom"]
744
-
745
- # The inheritsFrom feature requires that the storage class
746
- # being inherited from is itself a subclass of StorageClass
747
- # that was created with makeNewStorageClass. If it was made
748
- # and registered with a simple StorageClass constructor it
749
- # cannot be used here and we try to recreate it.
750
- if baseName in self:
751
- baseClass = type(self.getStorageClass(baseName))
752
- if baseClass is StorageClass:
753
- log.warning(
754
- "Storage class %s is requested to inherit from %s but that storage class "
755
- "has not been defined to be a subclass of StorageClass and so can not "
756
- "be used. Attempting to recreate parent class from current configuration.",
757
- name,
758
- baseName,
759
- )
760
- processStorageClass(baseName, sconfig, msg)
761
- else:
762
- processStorageClass(baseName, sconfig, msg)
763
- baseClass = type(self.getStorageClass(baseName))
764
- if baseClass is StorageClass:
765
- raise TypeError(
766
- f"Configuration for storage class {name} requests to inherit from "
767
- f" storage class {baseName} but that class is not defined correctly."
768
- )
769
-
770
- newStorageClassType = self.makeNewStorageClass(name, baseClass, **storageClassKwargs)
771
- newStorageClass = newStorageClassType()
772
- self.registerStorageClass(newStorageClass, msg=msg)
680
+ return self.getStorageClass(name)
681
+ try:
682
+ model = _StorageClassModel.model_validate(_sconfig.pop(name))
683
+ except Exception as err:
684
+ err.add_note(msg)
685
+ raise
686
+ components: dict[str, StorageClass] = {}
687
+ derivedComponents: dict[str, StorageClass] = {}
688
+ parameters: set[str] = set()
689
+ delegate: str | None = None
690
+ converters: dict[str, str] = {}
691
+ if model.inheritsFrom is not None:
692
+ base = processStorageClass(model.inheritsFrom, _sconfig, msg + f"; processing base of {name}")
693
+ pytype = base._pytypeName
694
+ components.update(base.components)
695
+ derivedComponents.update(base.derivedComponents)
696
+ parameters.update(base.parameters)
697
+ delegate = base._delegateClassName
698
+ converters.update(base.converters)
699
+ if model.pytype is not None:
700
+ pytype = model.pytype
701
+ for k, v in model.components.items():
702
+ components[k] = processStorageClass(
703
+ v, _sconfig, msg + f"; processing component {k} of {name}"
704
+ )
705
+ for k, v in model.derivedComponents.items():
706
+ derivedComponents[k] = processStorageClass(
707
+ v, _sconfig, msg + f"; processing derivedCmponent {k} of {name}"
708
+ )
709
+ parameters.update(model.parameters)
710
+ if model.delegate is not None:
711
+ delegate = model.delegate
712
+ converters.update(model.converters)
713
+ result = StorageClass(
714
+ name=name,
715
+ pytype=pytype,
716
+ components=components,
717
+ derivedComponents=derivedComponents,
718
+ parameters=parameters,
719
+ delegate=delegate,
720
+ converters=converters,
721
+ )
722
+ self.registerStorageClass(result, msg=msg)
723
+ return result
773
724
 
774
725
  # In case there is a problem, construct a context message for any
775
726
  # error reporting.
@@ -778,68 +729,9 @@ StorageClasses
778
729
  log.debug("Adding definitions from config %s", ", ".join(files))
779
730
 
780
731
  with self._lock:
781
- self._configs.append(sconfig)
782
732
  for name in list(sconfig.keys()):
783
733
  processStorageClass(name, sconfig, context)
784
734
 
785
- @staticmethod
786
- def makeNewStorageClass(
787
- name: str, baseClass: type[StorageClass] | None = StorageClass, **kwargs: Any
788
- ) -> type[StorageClass]:
789
- """Create a new Python class as a subclass of `StorageClass`.
790
-
791
- Parameters
792
- ----------
793
- name : `str`
794
- Name to use for this class.
795
- baseClass : `type`, optional
796
- Base class for this `StorageClass`. Must be either `StorageClass`
797
- or a subclass of `StorageClass`. If `None`, `StorageClass` will
798
- be used.
799
- **kwargs
800
- Additional parameter values to use as defaults for this class.
801
- This can include ``components``, ``parameters``,
802
- ``derivedComponents``, and ``converters``.
803
-
804
- Returns
805
- -------
806
- newtype : `type` subclass of `StorageClass`
807
- Newly created Python type.
808
- """
809
- if baseClass is None:
810
- baseClass = StorageClass
811
- if not issubclass(baseClass, StorageClass):
812
- raise ValueError(f"Base class must be a StorageClass not {baseClass}")
813
-
814
- # convert the arguments to use different internal names
815
- clsargs = {f"_cls_{k}": v for k, v in kwargs.items() if v is not None}
816
- clsargs["_cls_name"] = name
817
-
818
- # Some container items need to merge with the base class values
819
- # so that a child can inherit but override one bit.
820
- # lists (which you get from configs) are treated as sets for this to
821
- # work consistently.
822
- for k in ("components", "parameters", "derivedComponents", "converters"):
823
- classKey = f"_cls_{k}"
824
- if classKey in clsargs:
825
- baseValue = getattr(baseClass, classKey, None)
826
- if baseValue is not None:
827
- currentValue = clsargs[classKey]
828
- if isinstance(currentValue, dict):
829
- newValue = baseValue.copy()
830
- else:
831
- newValue = set(baseValue)
832
- newValue.update(currentValue)
833
- clsargs[classKey] = newValue
834
-
835
- # If we have parameters they should be a frozen set so that the
836
- # parameters in the class can not be modified.
837
- pk = "_cls_parameters"
838
- if pk in clsargs:
839
- clsargs[pk] = frozenset(clsargs[pk])
840
-
841
- return type(f"StorageClass{name}", (baseClass,), clsargs)
842
-
843
735
  def getStorageClass(self, storageClassName: str) -> StorageClass:
844
736
  """Get a StorageClass instance associated with the supplied name.
845
737
 
@@ -111,6 +111,28 @@ class DatastoreRecordData:
111
111
  """Opaque table data, indexed by dataset ID and grouped by opaque table
112
112
  name."""
113
113
 
114
+ @staticmethod
115
+ def merge_mappings(*args: Mapping[str, DatastoreRecordData]) -> dict[str, DatastoreRecordData]:
116
+ """Merge mappings of datastore record data.
117
+
118
+ Parameters
119
+ ----------
120
+ *args : `~collections.abc.Mapping` [ `str`, `DatastoreRecordData` ]
121
+ Mappings of record data, keyed by datastore name.
122
+
123
+ Returns
124
+ -------
125
+ merged : `~collections.abc.Mapping` [ `str`, `DatastoreRecordData` ]
126
+ Merged mapping of record data, keyed by datastore name.
127
+ """
128
+ result: dict[str, DatastoreRecordData] = {}
129
+ for arg in args:
130
+ for datastore_name, record_data in arg.items():
131
+ if datastore_name not in result:
132
+ result[datastore_name] = DatastoreRecordData()
133
+ result[datastore_name].update(record_data)
134
+ return result
135
+
114
136
  def update(self, other: DatastoreRecordData) -> None:
115
137
  """Update contents of this instance with data from another instance.
116
138
 
@@ -32,7 +32,7 @@ __all__ = ("SerializedStoredFileInfo", "StoredDatastoreItemInfo", "StoredFileInf
32
32
  import inspect
33
33
  from collections.abc import Iterable, Mapping
34
34
  from dataclasses import dataclass
35
- from typing import TYPE_CHECKING, Any, ClassVar
35
+ from typing import TYPE_CHECKING, Any
36
36
 
37
37
  import pydantic
38
38
 
@@ -209,8 +209,6 @@ class StoredFileInfo(StoredDatastoreItemInfo):
209
209
  compatibility, it remains a positional argument with no default).
210
210
  """
211
211
 
212
- storageClassFactory: ClassVar[StorageClassFactory] = StorageClassFactory()
213
-
214
212
  def __init__(
215
213
  self,
216
214
  formatter: FormatterParameter,
@@ -268,7 +266,7 @@ class StoredFileInfo(StoredDatastoreItemInfo):
268
266
  @property
269
267
  def storageClass(self) -> StorageClass:
270
268
  """Storage class associated with this dataset."""
271
- return self.storageClassFactory.getStorageClass(self.storage_class_name)
269
+ return StorageClassFactory().getStorageClass(self.storage_class_name)
272
270
 
273
271
  def rebase(self, ref: DatasetRef) -> StoredFileInfo:
274
272
  """Return a copy of the record suitable for a specified reference.
@@ -753,7 +753,6 @@ class SerializableDimensionData(pydantic.RootModel):
753
753
  ]
754
754
 
755
755
 
756
- @dataclasses.dataclass
757
756
  class DimensionDataAttacher:
758
757
  """A helper class for attaching dimension records to data IDs.
759
758
 
@@ -786,7 +785,7 @@ class DimensionDataAttacher:
786
785
  dimensions: DimensionGroup | None = None,
787
786
  ):
788
787
  self.records = {record_set.element.name: record_set for record_set in records}
789
- self.deserializers = {}
788
+ self.deserializers: dict[str, DimensionRecordSetDeserializer] = {}
790
789
  for deserializer in deserializers:
791
790
  self.deserializers[deserializer.element.name] = deserializer
792
791
  if deserializer.element.name not in self.records:
@@ -851,6 +850,54 @@ class DimensionDataAttacher:
851
850
 
852
851
  return [r.data_id.expanded(r.done) for r in records]
853
852
 
853
+ def serialized(
854
+ self, *, ignore: Iterable[str] = (), ignore_cached: bool = False, include_skypix: bool = False
855
+ ) -> SerializableDimensionData:
856
+ """Serialize all dimension data in this attacher, with deduplication
857
+ across fully- and partially-deserialized records.
858
+
859
+ Parameters
860
+ ----------
861
+ ignore : `~collections.abc.Iterable` [ `str` ], optional
862
+ Names of dimension elements that should not be serialized.
863
+ ignore_cached : `bool`, optional
864
+ If `True`, ignore all dimension elements for which
865
+ `DimensionElement.is_cached` is `True`.
866
+ include_skypix : `bool`, optional
867
+ If `True`, include skypix dimensions. These are ignored by default
868
+ because they can always be recomputed from their IDs on-the-fly.
869
+
870
+ Returns
871
+ -------
872
+ serialized : `SerializedDimensionData`
873
+ Serialized dimension records.
874
+ """
875
+ from ._skypix import SkyPixDimension
876
+
877
+ ignore = set(ignore)
878
+ result = SerializableDimensionData()
879
+ for record_set in self.records.values():
880
+ if record_set.element.name in ignore:
881
+ continue
882
+ if not include_skypix and isinstance(record_set.element, SkyPixDimension):
883
+ continue
884
+ if ignore_cached and record_set.element.is_cached:
885
+ continue
886
+ serialized_records: dict[tuple[DataIdValue, ...], SerializedKeyValueDimensionRecord] = {}
887
+ if (deserializer := self.deserializers.get(record_set.element.name)) is not None:
888
+ for key, value in deserializer._mapping.items():
889
+ serialized_record = list(key)
890
+ serialized_record.extend(value)
891
+ serialized_records[key] = serialized_record
892
+ for key, record in record_set._by_required_values.items():
893
+ if key not in serialized_records:
894
+ serialized_records[key] = record.serialize_key_value()
895
+ result.root[record_set.element.name] = list(serialized_records.values())
896
+ if self.cache is not None and not ignore_cached:
897
+ for record_set in self.cache.values():
898
+ result.root[record_set.element.name] = record_set.serialize_records()
899
+ return result
900
+
854
901
 
855
902
  @dataclasses.dataclass
856
903
  class _InProgressRecordDicts:
@@ -30,6 +30,7 @@ from __future__ import annotations
30
30
  from collections.abc import Iterator
31
31
  from contextlib import contextmanager
32
32
  from functools import cache
33
+ from typing import Literal
33
34
 
34
35
  from pydantic import AnyHttpUrl, BaseModel
35
36
  from pydantic_settings import BaseSettings, SettingsConfigDict
@@ -57,9 +58,12 @@ class ButlerServerConfig(BaseSettings):
57
58
  repositories: dict[str, RepositoryConfig]
58
59
  """Mapping from repository name to configuration for the repository."""
59
60
 
60
- gafaelfawr_url: AnyHttpUrl
61
+ gafaelfawr_url: AnyHttpUrl | Literal["DISABLED"]
61
62
  """URL to the top-level HTTP path where Gafaelfawr can be found (e.g.
62
63
  "https://data-int.lsst.cloud").
64
+
65
+ This can instead be the special string "DISABLED" to turn off all features
66
+ requiring Gafaelfawr integration.
63
67
  """
64
68
 
65
69
  authentication: AuthenticationMode
@@ -69,6 +73,10 @@ class ButlerServerConfig(BaseSettings):
69
73
  as static files from the `configs/` HTTP route.
70
74
  """
71
75
 
76
+ @property
77
+ def gafaelfawr_enabled(self) -> bool:
78
+ return self.gafaelfawr_url != "DISABLED"
79
+
72
80
 
73
81
  _config: ButlerServerConfig | None = None
74
82
 
@@ -27,8 +27,8 @@
27
27
 
28
28
  from typing import Annotated
29
29
 
30
- from fastapi import Depends, HTTPException
31
- from safir.dependencies.gafaelfawr import auth_delegated_token_dependency, auth_dependency
30
+ from fastapi import Depends, Header, HTTPException
31
+ from safir.dependencies.gafaelfawr import auth_delegated_token_dependency
32
32
 
33
33
  from lsst.daf.butler import LabeledButlerFactory
34
34
 
@@ -65,9 +65,29 @@ async def authorizer_dependency() -> GafaelfawrGroupAuthorizer:
65
65
  return _authorizer
66
66
 
67
67
 
68
+ async def user_name_dependency(x_auth_request_user: Annotated[str | None, Header()] = None) -> str | None:
69
+ """Retrieve the user name from Gafaelfawr authentication headers.
70
+
71
+ Parameters
72
+ ----------
73
+ x_auth_request_user : FastAPI header
74
+ Header provided by FastAPI.
75
+
76
+ Returns
77
+ -------
78
+ user_name : `str` | `None`
79
+ The user name, if Gafaelfawr is available on this environment. `None`
80
+ if Gafaelfawr is not available.
81
+ """
82
+ if x_auth_request_user is None and load_config().gafaelfawr_enabled:
83
+ raise HTTPException(status_code=403, detail="Required X-Auth-Request-User header was not provided")
84
+
85
+ return x_auth_request_user
86
+
87
+
68
88
  async def repository_authorization_dependency(
69
89
  repository: str,
70
- user_name: Annotated[str, Depends(auth_dependency)],
90
+ user_name: Annotated[str | None, Depends(user_name_dependency)],
71
91
  user_token: Annotated[str, Depends(auth_delegated_token_dependency)],
72
92
  authorizer: Annotated[GafaelfawrGroupAuthorizer, Depends(authorizer_dependency)],
73
93
  ) -> None:
@@ -87,6 +107,7 @@ async def repository_authorization_dependency(
87
107
  authorizer : `GafaelfawrGroupAuthorizer`
88
108
  Authorization client that will be used to verify group membership.
89
109
  """
110
+ assert user_name is not None, "Gafaelfawr user name header should have been populated."
90
111
  if not await authorizer.is_user_authorized_for_repository(
91
112
  repository=repository, user_name=user_name, user_token=user_token
92
113
  ):
@@ -62,13 +62,16 @@ def create_app() -> FastAPI:
62
62
  # factory_dependency().
63
63
  default_api_path = "/api/butler"
64
64
  prefix = f"{default_api_path}/repo/{{repository}}"
65
+ auth_dependencies = [Depends(repository_authorization_dependency)]
66
+ if not config.gafaelfawr_enabled:
67
+ auth_dependencies = []
65
68
  for router in (external_router, query_router):
66
69
  app.include_router(
67
70
  router,
68
71
  prefix=prefix,
69
72
  # Verify that users have permission to access repository-specific
70
73
  # resources.
71
- dependencies=[Depends(repository_authorization_dependency)],
74
+ dependencies=auth_dependencies,
72
75
  # document that 422 responses will include a JSON-formatted error
73
76
  # message, from `butler_exception_handler()` below.
74
77
  responses={422: {"model": ErrorResponseModel}},
@@ -35,7 +35,6 @@ from typing import Annotated, NamedTuple
35
35
 
36
36
  from fastapi import APIRouter, Depends
37
37
  from fastapi.responses import StreamingResponse
38
- from safir.dependencies.gafaelfawr import auth_dependency
39
38
 
40
39
  from lsst.daf.butler import Butler, DataCoordinate, DimensionGroup
41
40
  from lsst.daf.butler.remote_butler.server_models import (
@@ -56,7 +55,7 @@ from ...._exceptions import InvalidQueryError
56
55
  from ...._query_all_datasets import QueryAllDatasetsParameters, query_all_datasets
57
56
  from ....queries import Query
58
57
  from ....queries.driver import QueryDriver, QueryTree
59
- from .._dependencies import factory_dependency
58
+ from .._dependencies import factory_dependency, user_name_dependency
60
59
  from .._factory import Factory
61
60
  from ._query_serialization import convert_query_page
62
61
  from ._query_streaming import StreamingQuery, execute_streaming_query
@@ -93,7 +92,7 @@ class _StreamQueryDriverExecute(StreamingQuery[_QueryContext]):
93
92
  async def query_execute(
94
93
  request: QueryExecuteRequestModel,
95
94
  factory: Annotated[Factory, Depends(factory_dependency)],
96
- user_name: Annotated[str, Depends(auth_dependency)],
95
+ user_name: Annotated[str | None, Depends(user_name_dependency)],
97
96
  ) -> StreamingResponse:
98
97
  query = _StreamQueryDriverExecute(request, factory)
99
98
  return await execute_streaming_query(query, user_name)
@@ -140,7 +139,7 @@ class _StreamQueryAllDatasets(StreamingQuery[_QueryAllDatasetsContext]):
140
139
  async def query_all_datasets_execute(
141
140
  request: QueryAllDatasetsRequestModel,
142
141
  factory: Annotated[Factory, Depends(factory_dependency)],
143
- user_name: Annotated[str, Depends(auth_dependency)],
142
+ user_name: Annotated[str | None, Depends(user_name_dependency)],
144
143
  ) -> StreamingResponse:
145
144
  query = _StreamQueryAllDatasets(request, factory)
146
145
  return await execute_streaming_query(query, user_name)
@@ -56,7 +56,7 @@ class QueryLimits:
56
56
  self._active_queries = 0
57
57
  self._active_users: Counter[str] = Counter()
58
58
 
59
- async def enforce_query_limits(self, user: str) -> None:
59
+ async def enforce_query_limits(self, user: str | None) -> None:
60
60
  if self._active_queries >= _MAXIMUM_CONCURRENT_STREAMING_QUERIES:
61
61
  await _block_retry_for_unit_test()
62
62
  raise HTTPException(
@@ -70,7 +70,7 @@ class QueryLimits:
70
70
  # replica, which is a non-deterministic but small number.
71
71
  # There will be some backpressure from the 429 responses as they
72
72
  # attempt to bounce to other replicas on retry.
73
- if self._active_users[user] >= 2:
73
+ if user is not None and self._active_users[user] >= 2:
74
74
  _LOG.warning(f"User '{user}' is running many queries simultaneously.")
75
75
  raise HTTPException(
76
76
  status_code=429, # too many requests
@@ -80,14 +80,16 @@ class QueryLimits:
80
80
  )
81
81
 
82
82
  @asynccontextmanager
83
- async def track_query(self, user: str) -> AsyncIterator[None]:
83
+ async def track_query(self, user: str | None) -> AsyncIterator[None]:
84
84
  try:
85
85
  self._active_queries += 1
86
- self._active_users[user] += 1
86
+ if user is not None:
87
+ self._active_users[user] += 1
87
88
  await _block_query_for_unit_test()
88
89
  yield
89
90
  finally:
90
- self._active_users[user] -= 1
91
+ if user is not None:
92
+ self._active_users[user] -= 1
91
93
  self._active_queries -= 1
92
94
 
93
95
 
@@ -73,7 +73,7 @@ class StreamingQuery(Protocol[_TContext]):
73
73
  """
74
74
 
75
75
 
76
- async def execute_streaming_query(query: StreamingQuery, user: str) -> StreamingResponse:
76
+ async def execute_streaming_query(query: StreamingQuery, user: str | None) -> StreamingResponse:
77
77
  """Run a query, streaming the response incrementally, one page at a time,
78
78
  as newline-separated chunks of JSON.
79
79
 
@@ -83,7 +83,7 @@ async def execute_streaming_query(query: StreamingQuery, user: str) -> Streaming
83
83
  Callers should define a class implementing the ``StreamingQuery``
84
84
  protocol to specify the inner logic that will be called during
85
85
  query execution.
86
- user : `str`
86
+ user : `str`, optional
87
87
  Name of user running the query -- used to enforce usage limits.
88
88
 
89
89
  Returns
@@ -125,7 +125,7 @@ async def execute_streaming_query(query: StreamingQuery, user: str) -> Streaming
125
125
  )
126
126
 
127
127
 
128
- async def _stream_query_pages(query: StreamingQuery, user: str) -> AsyncIterator[str]:
128
+ async def _stream_query_pages(query: StreamingQuery, user: str | None) -> AsyncIterator[str]:
129
129
  """Stream the query output with one page object per line, as
130
130
  newline-delimited JSON records in the "JSON Lines" format
131
131
  (https://jsonlines.org/).