dkist 1.6.0__tar.gz → 1.7.0__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 (216) hide show
  1. {dkist-1.6.0 → dkist-1.7.0}/.cruft.json +1 -1
  2. {dkist-1.6.0 → dkist-1.7.0}/.github/workflows/codspeed.yml +1 -1
  3. {dkist-1.6.0 → dkist-1.7.0}/.github/workflows/prepare-release.yml +5 -2
  4. {dkist-1.6.0 → dkist-1.7.0}/.github/workflows/sub_package_update.yml +1 -6
  5. {dkist-1.6.0 → dkist-1.7.0}/.gitignore +1 -0
  6. {dkist-1.6.0 → dkist-1.7.0}/.pre-commit-config.yaml +3 -3
  7. {dkist-1.6.0 → dkist-1.7.0}/CHANGELOG.rst +16 -1
  8. {dkist-1.6.0/dkist.egg-info → dkist-1.7.0}/PKG-INFO +2 -2
  9. {dkist-1.6.0 → dkist-1.7.0}/dkist/_version.py +2 -2
  10. dkist-1.7.0/dkist/data/api_search_values.json +1 -0
  11. {dkist-1.6.0 → dkist-1.7.0}/dkist/dataset/tests/test_dataset.py +3 -8
  12. {dkist-1.6.0 → dkist-1.7.0}/dkist/net/attrs.py +4 -4
  13. {dkist-1.6.0 → dkist-1.7.0}/dkist/net/attrs_values.py +40 -28
  14. {dkist-1.6.0 → dkist-1.7.0}/dkist/net/tests/test_attrs_values.py +62 -36
  15. {dkist-1.6.0 → dkist-1.7.0}/dkist/utils/inventory.py +3 -2
  16. {dkist-1.6.0 → dkist-1.7.0/dkist.egg-info}/PKG-INFO +2 -2
  17. {dkist-1.6.0 → dkist-1.7.0}/dkist.egg-info/requires.txt +1 -0
  18. {dkist-1.6.0 → dkist-1.7.0}/pyproject.toml +2 -1
  19. {dkist-1.6.0 → dkist-1.7.0}/pytest.ini +12 -6
  20. {dkist-1.6.0 → dkist-1.7.0}/tox.ini +28 -19
  21. dkist-1.6.0/dkist/data/api_search_values.json +0 -1
  22. {dkist-1.6.0 → dkist-1.7.0}/.codecov.yaml +0 -0
  23. {dkist-1.6.0 → dkist-1.7.0}/.codespell-dict.txt +0 -0
  24. {dkist-1.6.0 → dkist-1.7.0}/.codespellrc +0 -0
  25. {dkist-1.6.0 → dkist-1.7.0}/.coveragerc +0 -0
  26. {dkist-1.6.0 → dkist-1.7.0}/.flake8 +0 -0
  27. {dkist-1.6.0 → dkist-1.7.0}/.github/ISSUE_TEMPLATE/BUG_REPORT.md +0 -0
  28. {dkist-1.6.0 → dkist-1.7.0}/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md +0 -0
  29. {dkist-1.6.0 → dkist-1.7.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  30. {dkist-1.6.0 → dkist-1.7.0}/.github/dependabot.yml +0 -0
  31. {dkist-1.6.0 → dkist-1.7.0}/.github/workflows/main.yml +0 -0
  32. {dkist-1.6.0 → dkist-1.7.0}/.gitmodules +0 -0
  33. {dkist-1.6.0 → dkist-1.7.0}/.isort.cfg +0 -0
  34. {dkist-1.6.0 → dkist-1.7.0}/.readthedocs.yaml +0 -0
  35. {dkist-1.6.0 → dkist-1.7.0}/.rtd-environment.yml +0 -0
  36. {dkist-1.6.0 → dkist-1.7.0}/.ruff.toml +0 -0
  37. {dkist-1.6.0 → dkist-1.7.0}/CODE_OF_CONDUCT.md +0 -0
  38. {dkist-1.6.0 → dkist-1.7.0}/CONTRIBUTING.md +0 -0
  39. {dkist-1.6.0 → dkist-1.7.0}/LICENSE.rst +0 -0
  40. {dkist-1.6.0 → dkist-1.7.0}/MANIFEST.in +0 -0
  41. {dkist-1.6.0 → dkist-1.7.0}/README.rst +0 -0
  42. {dkist-1.6.0 → dkist-1.7.0}/changelog/README.rst +0 -0
  43. {dkist-1.6.0 → dkist-1.7.0}/conftest.py +0 -0
  44. {dkist-1.6.0 → dkist-1.7.0}/dkist/__init__.py +0 -0
  45. {dkist-1.6.0 → dkist-1.7.0}/dkist/config/__init__.py +0 -0
  46. {dkist-1.6.0 → dkist-1.7.0}/dkist/conftest.py +0 -0
  47. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/README.rst +0 -0
  48. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/VISP_HEADER.hdr +0 -0
  49. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/__init__.py +0 -0
  50. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/sample.py +0 -0
  51. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/5d_gwcs.asdf +0 -0
  52. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/AGLKO-inv.ecsv +0 -0
  53. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/EIT/efz20040301.000010_s.fits +0 -0
  54. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/EIT/efz20040301.020010_s.fits +0 -0
  55. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/EIT/efz20040301.030011_s.fits +0 -0
  56. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/EIT/efz20040301.040010_s.fits +0 -0
  57. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/EIT/efz20040301.050010_s.fits +0 -0
  58. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/EIT/efz20040301.060010_s.fits +0 -0
  59. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/EIT/efz20040301.080010_s.fits +0 -0
  60. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/EIT/efz20040301.090010_s.fits +0 -0
  61. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/EIT/efz20040301.100010_s.fits +0 -0
  62. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/EIT/efz20040301.110010_s.fits +0 -0
  63. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/EIT/efz20040301.120010_s.fits +0 -0
  64. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/EIT/eit_test_dataset.asdf +0 -0
  65. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/__init__.py +0 -0
  66. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/eit_dataset-0.1.0.asdf +0 -0
  67. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/eit_dataset-0.2.0.asdf +0 -0
  68. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/eit_dataset-0.3.0.asdf +0 -0
  69. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/eit_dataset-1.0.0.asdf +0 -0
  70. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/eit_dataset-1.1.0.asdf +0 -0
  71. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/eit_dataset-1.2.0.asdf +0 -0
  72. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/globus_operation_ls_response.json +0 -0
  73. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/globus_search_response.json +0 -0
  74. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/large_visp.asdf.gz +0 -0
  75. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/small_visp/0.fits +0 -0
  76. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/small_visp/1.fits +0 -0
  77. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/small_visp/2.fits +0 -0
  78. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/small_visp/test_visp.asdf +0 -0
  79. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/test_old_wcs_BRMQY.asdf +0 -0
  80. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/test_tiled_dataset-1.0.0_dataset-1.0.0.asdf +0 -0
  81. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/test_tiled_dataset-1.0.0_dataset-1.1.0.asdf +0 -0
  82. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/test_tiled_dataset-1.0.0_dataset-1.2.0.asdf +0 -0
  83. {dkist-1.6.0 → dkist-1.7.0}/dkist/data/test/visp_no_headers.asdf.gz +0 -0
  84. {dkist-1.6.0 → dkist-1.7.0}/dkist/dataset/__init__.py +0 -0
  85. {dkist-1.6.0 → dkist-1.7.0}/dkist/dataset/dataset.py +0 -0
  86. {dkist-1.6.0 → dkist-1.7.0}/dkist/dataset/loader.py +0 -0
  87. {dkist-1.6.0 → dkist-1.7.0}/dkist/dataset/tests/__init__.py +0 -0
  88. {dkist-1.6.0 → dkist-1.7.0}/dkist/dataset/tests/test_load_dataset.py +0 -0
  89. {dkist-1.6.0 → dkist-1.7.0}/dkist/dataset/tests/test_plotting.py +0 -0
  90. {dkist-1.6.0 → dkist-1.7.0}/dkist/dataset/tests/test_tiled_dataset.py +0 -0
  91. {dkist-1.6.0 → dkist-1.7.0}/dkist/dataset/tiled_dataset.py +0 -0
  92. {dkist-1.6.0 → dkist-1.7.0}/dkist/dataset/utils.py +0 -0
  93. {dkist-1.6.0 → dkist-1.7.0}/dkist/dkist.cfg +0 -0
  94. {dkist-1.6.0 → dkist-1.7.0}/dkist/extern/__init__.py +0 -0
  95. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/__init__.py +0 -0
  96. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/__init__.py +0 -0
  97. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/converters/__init__.py +0 -0
  98. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/converters/dataset.py +0 -0
  99. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/converters/file_manager.py +0 -0
  100. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/converters/models.py +0 -0
  101. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/converters/tiled_dataset.py +0 -0
  102. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/entry_points.py +0 -0
  103. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/__init__.py +0 -0
  104. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/manifests/dkist-0.9.0.yaml +0 -0
  105. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/manifests/dkist-1.0.0.yaml +0 -0
  106. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/manifests/dkist-1.1.0.yaml +0 -0
  107. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/manifests/dkist-1.2.0.yaml +0 -0
  108. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/manifests/dkist-wcs-1.0.0.yaml +0 -0
  109. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/manifests/dkist-wcs-1.1.0.yaml +0 -0
  110. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/manifests/dkist-wcs-1.2.0.yaml +0 -0
  111. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/manifests/dkist-wcs-1.3.0.yaml +0 -0
  112. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/schemas/asymmetric_mapping_model-1.0.0.yaml +0 -0
  113. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/schemas/asymmetric_mapping_model-1.1.0.yaml +0 -0
  114. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/schemas/coupled_compound_model-1.0.0.yaml +0 -0
  115. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/schemas/coupled_compound_model-1.1.0.yaml +0 -0
  116. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/schemas/dataset-0.1.0.yaml +0 -0
  117. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/schemas/dataset-0.2.0.yaml +0 -0
  118. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/schemas/dataset-0.3.0.yaml +0 -0
  119. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/schemas/dataset-1.0.0.yaml +0 -0
  120. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/schemas/dataset-1.1.0.yaml +0 -0
  121. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/schemas/file_manager-1.0.0.yaml +0 -0
  122. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/schemas/ravel_model-1.0.0.yaml +0 -0
  123. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/schemas/ravel_model-1.1.0.yaml +0 -0
  124. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/schemas/tiled_dataset-0.1.0.yaml +0 -0
  125. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/schemas/tiled_dataset-1.0.0.yaml +0 -0
  126. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/schemas/varying_celestial_transform-1.0.0.yaml +0 -0
  127. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/resources/schemas/varying_celestial_transform-1.1.0.yaml +0 -0
  128. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/tests/__init__.py +0 -0
  129. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/tests/conftest.py +0 -0
  130. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/tests/test_dataset.py +0 -0
  131. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/tests/test_models.py +0 -0
  132. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/asdf/tests/test_tiled_dataset.py +0 -0
  133. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/dask_utils.py +0 -0
  134. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/file_manager.py +0 -0
  135. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/level_1_dataset_schema.yaml +0 -0
  136. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/loaders.py +0 -0
  137. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/tests/__init__.py +0 -0
  138. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/tests/test_file_manager.py +0 -0
  139. {dkist-1.6.0 → dkist-1.7.0}/dkist/io/tests/test_fits.py +0 -0
  140. {dkist-1.6.0 → dkist-1.7.0}/dkist/logger.py +0 -0
  141. {dkist-1.6.0 → dkist-1.7.0}/dkist/net/__init__.py +0 -0
  142. {dkist-1.6.0 → dkist-1.7.0}/dkist/net/attr_walker.py +0 -0
  143. {dkist-1.6.0 → dkist-1.7.0}/dkist/net/client.py +0 -0
  144. {dkist-1.6.0 → dkist-1.7.0}/dkist/net/globus/__init__.py +0 -0
  145. {dkist-1.6.0 → dkist-1.7.0}/dkist/net/globus/auth.py +0 -0
  146. {dkist-1.6.0 → dkist-1.7.0}/dkist/net/globus/endpoints.py +0 -0
  147. {dkist-1.6.0 → dkist-1.7.0}/dkist/net/globus/tests/__init__.py +0 -0
  148. {dkist-1.6.0 → dkist-1.7.0}/dkist/net/globus/tests/conftest.py +0 -0
  149. {dkist-1.6.0 → dkist-1.7.0}/dkist/net/globus/tests/test_auth.py +0 -0
  150. {dkist-1.6.0 → dkist-1.7.0}/dkist/net/globus/tests/test_endpoints.py +0 -0
  151. {dkist-1.6.0 → dkist-1.7.0}/dkist/net/globus/tests/test_transfer.py +0 -0
  152. {dkist-1.6.0 → dkist-1.7.0}/dkist/net/globus/transfer.py +0 -0
  153. {dkist-1.6.0 → dkist-1.7.0}/dkist/net/helpers.py +0 -0
  154. {dkist-1.6.0 → dkist-1.7.0}/dkist/net/tests/__init__.py +0 -0
  155. {dkist-1.6.0 → dkist-1.7.0}/dkist/net/tests/conftest.py +0 -0
  156. {dkist-1.6.0 → dkist-1.7.0}/dkist/net/tests/strategies.py +0 -0
  157. {dkist-1.6.0 → dkist-1.7.0}/dkist/net/tests/test_attr_walker.py +0 -0
  158. {dkist-1.6.0 → dkist-1.7.0}/dkist/net/tests/test_attrs.py +0 -0
  159. {dkist-1.6.0 → dkist-1.7.0}/dkist/net/tests/test_client.py +0 -0
  160. {dkist-1.6.0 → dkist-1.7.0}/dkist/net/tests/test_helpers.py +0 -0
  161. {dkist-1.6.0 → dkist-1.7.0}/dkist/tests/__init__.py +0 -0
  162. {dkist-1.6.0 → dkist-1.7.0}/dkist/tests/generate_aia_dataset.py +0 -0
  163. {dkist-1.6.0 → dkist-1.7.0}/dkist/tests/generate_eit_test_dataset.py +0 -0
  164. {dkist-1.6.0 → dkist-1.7.0}/dkist/tests/generate_eit_tiled_dataset.py +0 -0
  165. {dkist-1.6.0 → dkist-1.7.0}/dkist/tests/test_benchmarks.py +0 -0
  166. {dkist-1.6.0 → dkist-1.7.0}/dkist/tests/test_logger.py +0 -0
  167. {dkist-1.6.0 → dkist-1.7.0}/dkist/utils/__init__.py +0 -0
  168. {dkist-1.6.0 → dkist-1.7.0}/dkist/utils/_model_to_graphviz.py +0 -0
  169. {dkist-1.6.0 → dkist-1.7.0}/dkist/utils/decorators.py +0 -0
  170. {dkist-1.6.0 → dkist-1.7.0}/dkist/utils/exceptions.py +0 -0
  171. {dkist-1.6.0 → dkist-1.7.0}/dkist/utils/sysinfo.py +0 -0
  172. {dkist-1.6.0 → dkist-1.7.0}/dkist/utils/tests/__init__.py +0 -0
  173. {dkist-1.6.0 → dkist-1.7.0}/dkist/utils/tests/test_inventory.py +0 -0
  174. {dkist-1.6.0 → dkist-1.7.0}/dkist/utils/tests/test_sysinfo.py +0 -0
  175. {dkist-1.6.0 → dkist-1.7.0}/dkist/version.py +0 -0
  176. {dkist-1.6.0 → dkist-1.7.0}/dkist/wcs/__init__.py +0 -0
  177. {dkist-1.6.0 → dkist-1.7.0}/dkist/wcs/models.py +0 -0
  178. {dkist-1.6.0 → dkist-1.7.0}/dkist/wcs/tests/__init__.py +0 -0
  179. {dkist-1.6.0 → dkist-1.7.0}/dkist/wcs/tests/test_coupled_compound_model.py +0 -0
  180. {dkist-1.6.0 → dkist-1.7.0}/dkist/wcs/tests/test_models.py +0 -0
  181. {dkist-1.6.0 → dkist-1.7.0}/dkist.egg-info/SOURCES.txt +0 -0
  182. {dkist-1.6.0 → dkist-1.7.0}/dkist.egg-info/dependency_links.txt +0 -0
  183. {dkist-1.6.0 → dkist-1.7.0}/dkist.egg-info/entry_points.txt +0 -0
  184. {dkist-1.6.0 → dkist-1.7.0}/dkist.egg-info/not-zip-safe +0 -0
  185. {dkist-1.6.0 → dkist-1.7.0}/dkist.egg-info/top_level.txt +0 -0
  186. {dkist-1.6.0 → dkist-1.7.0}/docs/Makefile +0 -0
  187. {dkist-1.6.0 → dkist-1.7.0}/docs/conf.py +0 -0
  188. {dkist-1.6.0 → dkist-1.7.0}/docs/developer.rst +0 -0
  189. {dkist-1.6.0 → dkist-1.7.0}/docs/howto_guides/index.rst +0 -0
  190. {dkist-1.6.0 → dkist-1.7.0}/docs/howto_guides/reproject_vbi_mosaic.md +0 -0
  191. {dkist-1.6.0 → dkist-1.7.0}/docs/index.rst +0 -0
  192. {dkist-1.6.0 → dkist-1.7.0}/docs/installation.rst +0 -0
  193. {dkist-1.6.0 → dkist-1.7.0}/docs/logo/icon_square.jpg +0 -0
  194. {dkist-1.6.0 → dkist-1.7.0}/docs/make.bat +0 -0
  195. {dkist-1.6.0 → dkist-1.7.0}/docs/reference.rst +0 -0
  196. {dkist-1.6.0 → dkist-1.7.0}/docs/topic_guides/index.rst +0 -0
  197. {dkist-1.6.0 → dkist-1.7.0}/docs/topic_guides/level1data.rst +0 -0
  198. {dkist-1.6.0 → dkist-1.7.0}/docs/topic_guides/loading.rst +0 -0
  199. {dkist-1.6.0 → dkist-1.7.0}/docs/topic_guides/net.rst +0 -0
  200. {dkist-1.6.0 → dkist-1.7.0}/docs/topic_guides/usertools.rst +0 -0
  201. {dkist-1.6.0 → dkist-1.7.0}/docs/tutorial/1_astropy_and_sunpy.md +0 -0
  202. {dkist-1.6.0 → dkist-1.7.0}/docs/tutorial/1_astropy_and_sunpy_NOTES.md +0 -0
  203. {dkist-1.6.0 → dkist-1.7.0}/docs/tutorial/2_search_and_asdf_download.md +0 -0
  204. {dkist-1.6.0 → dkist-1.7.0}/docs/tutorial/2_search_and_asdf_download_NOTES.md +0 -0
  205. {dkist-1.6.0 → dkist-1.7.0}/docs/tutorial/3_the_dataset.md +0 -0
  206. {dkist-1.6.0 → dkist-1.7.0}/docs/tutorial/3_the_dataset_NOTES.md +0 -0
  207. {dkist-1.6.0 → dkist-1.7.0}/docs/tutorial/4_more_dataset.md +0 -0
  208. {dkist-1.6.0 → dkist-1.7.0}/docs/tutorial/5_downloading_data.md +0 -0
  209. {dkist-1.6.0 → dkist-1.7.0}/docs/tutorial/6_visualization.md +0 -0
  210. {dkist-1.6.0 → dkist-1.7.0}/docs/tutorial/index.md +0 -0
  211. {dkist-1.6.0 → dkist-1.7.0}/docs/whatsnew/1.0.rst +0 -0
  212. {dkist-1.6.0 → dkist-1.7.0}/docs/whatsnew/1.1.rst +0 -0
  213. {dkist-1.6.0 → dkist-1.7.0}/docs/whatsnew/changelog.rst +0 -0
  214. {dkist-1.6.0 → dkist-1.7.0}/docs/whatsnew/index.rst +0 -0
  215. {dkist-1.6.0 → dkist-1.7.0}/setup.cfg +0 -0
  216. {dkist-1.6.0 → dkist-1.7.0}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "template": "https://github.com/sunpy/package-template",
3
- "commit": "6d6729b22066ef890e70c37438da70cac33e03b4",
3
+ "commit": "4721cdbdc9577fbf66f5e0f30fd4133a7723aeb9",
4
4
  "checkout": null,
5
5
  "context": {
6
6
  "cookiecutter": {
@@ -15,7 +15,7 @@ jobs:
15
15
  - uses: actions/setup-python@v5
16
16
  with:
17
17
  python-version: '3.12'
18
- - run: python -m pip install .[tests] pytest-codspeed
18
+ - run: python -m pip install .[tests] pytest-codspeed 'numpy<2'
19
19
  - name: Run benchmarks
20
20
  uses: CodspeedHQ/action@v2
21
21
  with:
@@ -60,7 +60,7 @@ jobs:
60
60
 
61
61
  - name: Update attrs
62
62
  run: |
63
- python -c "from dkist.net.attrs_values import attempt_local_update; attempt_local_update(user_file='./dkist/data/api_search_values.json', silence_errors=False)"
63
+ python -c "from dkist.net.attrs_values import attempt_local_update; attempt_local_update(user_file='./dkist/data/api_search_values.json', silence_net_errors=False)"
64
64
 
65
65
  - name: Commit Attrs
66
66
  run: |
@@ -128,14 +128,17 @@ jobs:
128
128
  - name: Create draft GitHub Release
129
129
  uses: actions/github-script@v7
130
130
  id: create-release
131
+ env:
132
+ RELEASE_BODY: "${{ steps.markdown-changelog.outputs.content }}"
131
133
  with:
132
134
  script: |
135
+ const { RELEASE_BODY } = process.env
133
136
  return await github.rest.repos.createRelease({
134
137
  owner: context.repo.owner,
135
138
  repo: context.repo.repo,
136
139
  tag_name: "v${{ inputs.version }}",
137
140
  name: "v${{ inputs.version }}",
138
- body: `${{ steps.markdown-changelog.outputs.content }}`,
141
+ body: `${RELEASE_BODY}`,
139
142
  draft: true,
140
143
  prerelease: ${{ inputs.pre_release }}
141
144
  });
@@ -28,11 +28,6 @@ jobs:
28
28
  branch: cruft/update
29
29
  commit-message: "Automatic package template update"
30
30
  title: Updates from the package template
31
- - add-paths: .cruft.json
32
- body: reject these changes for this repo.
33
- branch: cruft/reject
34
- commit-message: "Reject this package template update"
35
- title: Reject new updates from package template
36
31
 
37
32
  steps:
38
33
  - uses: actions/checkout@v4
@@ -42,7 +37,7 @@ jobs:
42
37
  python-version: "3.11"
43
38
 
44
39
  - name: Install Cruft
45
- run: python -m pip install cruft
40
+ run: python -m pip install git+https://github.com/Cadair/cruft@patch-p1
46
41
 
47
42
  - name: Check if update is available
48
43
  continue-on-error: false
@@ -76,6 +76,7 @@ instance/
76
76
  docs/_build/
77
77
  # automodapi
78
78
  docs/api
79
+ docs/sg_execution_times.rst
79
80
 
80
81
  # PyBuilder
81
82
  .pybuilder/
@@ -1,7 +1,7 @@
1
1
  repos:
2
2
  # This should be before any formatting hooks like isort
3
3
  - repo: https://github.com/astral-sh/ruff-pre-commit
4
- rev: "v0.3.5"
4
+ rev: "v0.5.0"
5
5
  hooks:
6
6
  - id: ruff
7
7
  args: ["--fix"]
@@ -26,10 +26,10 @@ repos:
26
26
  - id: mixed-line-ending
27
27
  exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*|.asdf|.json|.hdr)$"
28
28
  - repo: https://github.com/codespell-project/codespell
29
- rev: v2.2.6
29
+ rev: v2.3.0
30
30
  hooks:
31
31
  - id: codespell
32
32
  args: [ "--write-changes", "-D", "-", "-D", ".codespell-dict.txt"]
33
33
  ci:
34
34
  autofix_prs: false
35
- autoupdate_schedule: "weekly"
35
+ autoupdate_schedule: "quarterly"
@@ -1,3 +1,18 @@
1
+ 1.7.0 (2024-07-11)
2
+ ==================
3
+
4
+ Features
5
+ --------
6
+
7
+ - Add "status" to the list of know dataset inventory fields. (`#417 <https://github.com/DKISTDC/dkist/pull/417>`_)
8
+
9
+
10
+ Bug Fixes
11
+ ---------
12
+
13
+ - Catch URLError when trying to download attr values in tests so that the existing file isn't assumed to be corrupted and therefore deleted. (`#407 <https://github.com/DKISTDC/dkist/pull/407>`_)
14
+
15
+
1
16
  1.6.0 (2024-05-20)
2
17
  ==================
3
18
 
@@ -378,7 +393,7 @@ Bug Fixes
378
393
  Trivial/Internal Changes
379
394
  ------------------------
380
395
 
381
- - Migate to the asdf 2.8+ ``Converter`` interface, this bumps various
396
+ - Migrate to the asdf 2.8+ ``Converter`` interface, this bumps various
382
397
  dependencies but should have no effect on reading or writing asdf files. (`#152 <https://github.com/DKISTDC/dkist/pull/152>`_)
383
398
 
384
399
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dkist
3
- Version: 1.6.0
3
+ Version: 1.7.0
4
4
  Summary: DKIST User Tools
5
5
  Author-email: NSO / AURA <stuart@cadair.com>
6
6
  Project-URL: repository, https://github.com/DKISTDC/dkist
@@ -30,12 +30,12 @@ Requires-Dist: pytest; extra == "tests"
30
30
  Requires-Dist: pytest-doctestplus; extra == "tests"
31
31
  Requires-Dist: pytest-cov; extra == "tests"
32
32
  Requires-Dist: pytest-remotedata; extra == "tests"
33
- Requires-Dist: pytest-cov; extra == "tests"
34
33
  Requires-Dist: pytest-mock; extra == "tests"
35
34
  Requires-Dist: pytest-mpl; extra == "tests"
36
35
  Requires-Dist: pytest-httpserver; extra == "tests"
37
36
  Requires-Dist: pytest-filter-subpackage; extra == "tests"
38
37
  Requires-Dist: pytest-benchmark; extra == "tests"
38
+ Requires-Dist: pytest-xdist; extra == "tests"
39
39
  Requires-Dist: hypothesis; extra == "tests"
40
40
  Requires-Dist: tox; extra == "tests"
41
41
  Requires-Dist: pydot; extra == "tests"
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '1.6.0'
16
- __version_tuple__ = version_tuple = (1, 6, 0)
15
+ __version__ = version = '1.7.0'
16
+ __version_tuple__ = version_tuple = (1, 7, 0)
@@ -0,0 +1 @@
1
+ {"parameterValues":[{"parameterName":"createDateMin","values":{"minValue":"2022-12-08T19:07:55.038280","maxValue":"2024-07-10T01:57:31.871849"}},{"parameterName":"createDateMax","values":{"minValue":"2022-12-08T19:07:55.038280","maxValue":"2024-07-10T01:57:31.871849"}},{"parameterName":"endTimeMin","values":{"minValue":"2022-02-23T20:48:55.393500","maxValue":"2024-06-27T17:38:39.129000"}},{"parameterName":"endTimeMax","values":{"minValue":"2022-02-23T20:48:55.393500","maxValue":"2024-06-27T17:38:39.129000"}},{"parameterName":"exposureTimeMin","values":{"minValue":0.037,"maxValue":1380.2332394366197}},{"parameterName":"exposureTimeMax","values":{"minValue":0.037,"maxValue":1380.2332394366197}},{"parameterName":"instrumentNames","values":{"categoricalValues":["VISP","VBI"]}},{"parameterName":"qualityAverageFriedParameterMin","values":{"minValue":0.01695005847191685,"maxValue":2.6520787500175156e+30}},{"parameterName":"qualityAverageFriedParameterMax","values":{"minValue":0.01695005847191685,"maxValue":2.6520787500175156e+30}},{"parameterName":"qualityAveragePolarimetricAccuracyMin","values":{"minValue":0.7510039715379637,"maxValue":1.3227079486518465}},{"parameterName":"qualityAveragePolarimetricAccuracyMax","values":{"minValue":0.7510039715379637,"maxValue":1.3227079486518465}},{"parameterName":"startTimeMin","values":{"minValue":"2022-02-23T19:05:32.338002","maxValue":"2024-06-27T17:28:18.528000"}},{"parameterName":"startTimeMax","values":{"minValue":"2022-02-23T19:05:32.338002","maxValue":"2024-06-27T17:28:18.528000"}},{"parameterName":"targetTypes","values":{"categoricalValues":["coronalhole","sunspot","spicules","quietsun","plages","unknown","filament"]}},{"parameterName":"averageDatasetSpectralSamplingMin","values":{"minValue":0.000540156130946172,"maxValue":0.002011144047143148}},{"parameterName":"averageDatasetSpectralSamplingMax","values":{"minValue":0.000540156130946172,"maxValue":0.002011144047143148}},{"parameterName":"averageDatasetSpatialSamplingMin","values":{"minValue":0.0,"maxValue":12388.04306084}},{"parameterName":"averageDatasetSpatialSamplingMax","values":{"minValue":0.0,"maxValue":12388.04306084}},{"parameterName":"averageDatasetTemporalSamplingMin","values":{"minValue":9.139998999987853,"maxValue":5263.145059399399}},{"parameterName":"averageDatasetTemporalSamplingMax","values":{"minValue":9.139998999987853,"maxValue":5263.145059399399}},{"parameterName":"highLevelSoftwareVersion","values":{"categoricalValues":["Alakai_6-0","Alakai_11.1.0","Alakai_8-0","Alakai_7-0","Alakai_10-0","Pono_6.1.5","Pono_2.1.0","Pono_7.0.0","Pono_1.0.0","Alakai_5-1","Pono_3.1.0","Alakai_3-0","Alakai_4-0"]}},{"parameterName":"workflowName","values":{"categoricalValues":["l0_to_l1_visp","l0_to_l1_vbi_summit-calibrated"]}},{"parameterName":"workflowVersion","values":{"categoricalValues":["2.7.4","2.10.3","1.1.7","0.16.0","1.1.10","2.15.0","2.7.2","2.10.15","2.7.0","2.10.1","2.0.2","1.12.1","2.10.12","2.7.3","1.11.1","1.1.5","1.2.1","2.6.1","2.10.13","2.7.5","2.0.1","1.4.8","1.8.2","2.9.0","2.10.7","2.3.1","2.3.0","2.10.0","1.13.0","1.0.0","1.4.11","2.13.1","1.4.1","1.2.0","2.10.2"]}},{"parameterName":"headerDataUnitCreationDateMin","values":{"minValue":"2022-12-08T17:25:51.965000","maxValue":"2024-07-09T20:27:25.260000"}},{"parameterName":"headerDataUnitCreationDateMax","values":{"minValue":"2022-12-08T17:25:51.965000","maxValue":"2024-07-09T20:27:25.260000"}},{"parameterName":"headerVersion","values":{"categoricalValues":["4.3.0","3.6.0","4.0.0","4.1.1","3.3.0","3.0.0","3.4.0","3.9.0","3.5.0","3.7.1","3.8.1","4.2.0"]}}]}
@@ -65,16 +65,11 @@ def test_wcs_roundtrip_3d(dataset_3d):
65
65
  assert_quantity_allclose(p[2], p2[2])
66
66
 
67
67
 
68
- def test_dimensions(dataset, dataset_3d):
69
- for ds in [dataset, dataset_3d]:
70
- assert_quantity_allclose(ds.dimensions, ds.data.shape*u.pix)
71
-
72
-
73
68
  def test_load_from_directory():
74
69
  ds = load_dataset(rootdir / "EIT")
75
70
  assert isinstance(ds.data, da.Array)
76
71
  assert isinstance(ds.wcs, gwcs.WCS)
77
- assert_quantity_allclose(ds.dimensions, (11, 128, 128)*u.pix)
72
+ assert_quantity_allclose(ds.data.shape, (11, 128, 128))
78
73
  assert ds.files.basepath == Path(rootdir / "EIT")
79
74
 
80
75
 
@@ -99,14 +94,14 @@ def test_load_with_old_methods():
99
94
  ds = Dataset.from_directory(rootdir / "EIT")
100
95
  assert isinstance(ds.data, da.Array)
101
96
  assert isinstance(ds.wcs, gwcs.WCS)
102
- assert_quantity_allclose(ds.dimensions, (11, 128, 128)*u.pix)
97
+ assert_quantity_allclose(ds.data.shape, (11, 128, 128))
103
98
  assert ds.files.basepath == Path(rootdir / "EIT")
104
99
 
105
100
  with pytest.warns(DKISTDeprecationWarning):
106
101
  ds = Dataset.from_asdf(rootdir / "EIT" / "eit_test_dataset.asdf")
107
102
  assert isinstance(ds.data, da.Array)
108
103
  assert isinstance(ds.wcs, gwcs.WCS)
109
- assert_quantity_allclose(ds.dimensions, (11, 128, 128)*u.pix)
104
+ assert_quantity_allclose(ds.data.shape, (11, 128, 128))
110
105
  assert ds.files.basepath == Path(rootdir / "EIT")
111
106
 
112
107
 
@@ -301,10 +301,10 @@ class BoundingBox(_DataAttr):
301
301
  bottom_left = bottom_left.transform_to(_Helioprojective(observer="earth"))
302
302
  top_right = top_right.transform_to(_Helioprojective(observer="earth"))
303
303
 
304
- self.hpc_bounding_box_arcsec = ((bottom_left.Tx.to_value(_u.arcsec),
305
- bottom_left.Ty.to_value(_u.arcsec)),
306
- (top_right.Tx.to_value(_u.arcsec),
307
- top_right.Ty.to_value(_u.arcsec)))
304
+ self.hpc_bounding_box_arcsec = ((float(bottom_left.Tx.to_value(_u.arcsec)),
305
+ float(bottom_left.Ty.to_value(_u.arcsec))),
306
+ (float(top_right.Tx.to_value(_u.arcsec)),
307
+ float(top_right.Ty.to_value(_u.arcsec))))
308
308
 
309
309
  self.search_type = search
310
310
 
@@ -37,6 +37,12 @@ INVENTORY_ATTR_MAP = {
37
37
  }
38
38
 
39
39
 
40
+ class UserCacheMissing(Exception):
41
+ """
42
+ An exception for when we have deleted the user cache.
43
+ """
44
+
45
+
40
46
  def _get_file_age(path: Path) -> dt.timedelta:
41
47
  last_modified = dt.datetime.fromtimestamp(path.stat().st_mtime)
42
48
  now = dt.datetime.now()
@@ -65,15 +71,19 @@ def _get_cached_json() -> list[Path, bool]:
65
71
  return return_file, update_needed
66
72
 
67
73
 
68
- def _fetch_values_to_file(filepath: Path, *, timeout: int = 1):
74
+ def _fetch_values(timeout: int = 1) -> bytes:
75
+ """
76
+ Make a request for new values.
77
+
78
+ This is a separate function mostly for mocking it in the tests.
79
+ """
69
80
  data = urllib.request.urlopen(
70
81
  net_conf.dataset_endpoint + net_conf.dataset_search_values_path, timeout=timeout
71
82
  )
72
- with open(filepath, "wb") as f:
73
- f.write(data.read())
83
+ return data.read()
74
84
 
75
85
 
76
- def attempt_local_update(*, timeout: int = 1, user_file: Path = None, silence_errors: bool = True) -> bool:
86
+ def attempt_local_update(*, timeout: int = 1, user_file: Path = None, silence_net_errors: bool = True) -> bool:
77
87
  """
78
88
  Attempt to update the local data copy of the values.
79
89
 
@@ -86,8 +96,8 @@ def attempt_local_update(*, timeout: int = 1, user_file: Path = None, silence_er
86
96
  user_file
87
97
  The file to save the updated attrs JSON to. If `None` platformdirs will
88
98
  be used to get the user data path.
89
- silence_errors
90
- If `True` catch all errors in this function.
99
+ silence_net_errors
100
+ If `True` catch all errors caused by downloading new values in this function.
91
101
 
92
102
  Returns
93
103
  -------
@@ -97,37 +107,35 @@ def attempt_local_update(*, timeout: int = 1, user_file: Path = None, silence_er
97
107
  if user_file is None:
98
108
  user_file = platformdirs.user_data_path("dkist") / "api_search_values.json"
99
109
  user_file = Path(user_file)
100
- user_file.parent.mkdir(exist_ok=True, parents=True)
110
+ if not user_file.exists():
111
+ user_file.parent.mkdir(exist_ok=True, parents=True)
101
112
 
102
113
  log.info(f"Fetching updated search values for the DKIST client to {user_file}")
103
114
 
104
- success = False
105
115
  try:
106
- _fetch_values_to_file(user_file, timeout=timeout)
107
- success = True
116
+ data = _fetch_values(timeout)
108
117
  except Exception as err:
109
- log.error("Failed to download new attrs values.")
118
+ log.error("Failed to download new dkist attrs values. attr values for dkist may be outdated.")
110
119
  log.debug(str(err))
111
- # If an error has occurred then remove the local file so it isn't
112
- # corrupted or invalid.
113
- user_file.unlink(missing_ok=True)
114
- if not silence_errors:
120
+ if not silence_net_errors:
115
121
  raise
122
+ return False
116
123
 
117
- return success
118
-
119
- # Test that the file we just saved can be parsed as json
120
124
  try:
125
+ # Save the data
126
+ with open(user_file, "wb") as f:
127
+ f.write(data)
128
+
129
+ # Test that the file we just saved can be parsed as json
121
130
  with open(user_file) as f:
122
131
  json.load(f)
123
- except Exception:
124
- log.error("Downloaded file is not valid JSON.")
125
- user_file.unlink(missing_ok=True)
126
- if not silence_errors:
127
- raise
128
- success = False
129
132
 
130
- return success
133
+ return True
134
+
135
+ except Exception as err:
136
+ log.error("Downloaded file could not be saved or is not valid JSON, removing cached file.")
137
+ user_file.unlink(missing_ok=True)
138
+ raise UserCacheMissing from err
131
139
 
132
140
 
133
141
  def get_search_attrs_values(*, allow_update: bool = True, timeout: int = 1) -> dict:
@@ -152,11 +160,15 @@ def get_search_attrs_values(*, allow_update: bool = True, timeout: int = 1) -> d
152
160
  """
153
161
  local_path, update_needed = _get_cached_json()
154
162
  if allow_update and update_needed:
155
- attempt_local_update(timeout=timeout)
163
+ try:
164
+ attempt_local_update(timeout=timeout)
165
+ except UserCacheMissing:
166
+ # if we have deleted the user cache we must use the file shipped with the package
167
+ local_path = importlib.resources.files(dkist.data) / "api_search_values.json"
156
168
 
157
169
  if not update_needed:
158
- log.debug("No update to attr values needed.")
159
- log.debug("Using attr values from %s", local_path)
170
+ log.debug("No update to dkist attr values needed.")
171
+ log.debug("Using dkist attr values from %s", local_path)
160
172
 
161
173
  with open(local_path) as f:
162
174
  search_values = json.load(f)
@@ -5,6 +5,7 @@ import logging
5
5
  import datetime
6
6
  import importlib
7
7
  from platform import system
8
+ from urllib.error import URLError
8
9
 
9
10
  import platformdirs
10
11
  import pytest
@@ -12,7 +13,7 @@ import pytest
12
13
  from sunpy.net import attrs as a
13
14
 
14
15
  import dkist.data
15
- from dkist.net.attrs_values import (_fetch_values_to_file, _get_cached_json,
16
+ from dkist.net.attrs_values import (UserCacheMissing, _fetch_values, _get_cached_json,
16
17
  attempt_local_update, get_search_attrs_values)
17
18
 
18
19
  PACKAGE_FILE = importlib.resources.files(dkist.data) / "api_search_values.json"
@@ -79,31 +80,25 @@ def test_get_cached_json_local_not_quite_out_of_date(tmp_homedir, values_in_home
79
80
 
80
81
 
81
82
  @pytest.mark.remote_data
82
- def test_fetch_values_to_file(tmp_path):
83
- json_file = tmp_path / "api_search_values.json"
84
-
85
- assert json_file.exists() is False
86
- _fetch_values_to_file(json_file)
87
- assert json_file.exists() is True
83
+ def test_fetch_values_to_file():
84
+ data = _fetch_values()
85
+ assert isinstance(data, bytes)
88
86
 
89
- # Check we can load the file as json and it looks very roughly like what we
90
- # would expect from the API response
91
- with open(json_file) as f:
92
- data = json.load(f)
93
- assert "parameterValues" in data.keys()
94
- assert isinstance(data["parameterValues"], list)
87
+ jdata = json.loads(data)
88
+ assert "parameterValues" in jdata.keys()
89
+ assert isinstance(jdata["parameterValues"], list)
95
90
 
96
91
 
97
- def _local_fetch_values(user_file, *, timeout):
98
- user_file.parent.mkdir(parents=True, exist_ok=True)
99
- shutil.copy(PACKAGE_FILE, user_file)
92
+ def _local_fetch_values(timeout):
93
+ with open(PACKAGE_FILE, "rb") as fobj:
94
+ return fobj.read()
100
95
 
101
96
 
102
97
  def test_attempt_local_update(mocker, tmp_path, caplog_dkist):
103
98
  json_file = tmp_path / "api_search_values.json"
104
- mocker.patch("dkist.net.attrs_values._fetch_values_to_file",
99
+ mocker.patch("dkist.net.attrs_values._fetch_values",
105
100
  new_callable=lambda: _local_fetch_values)
106
- success = attempt_local_update(user_file=json_file, silence_errors=False)
101
+ success = attempt_local_update(user_file=json_file, silence_net_errors=False)
107
102
  assert success
108
103
 
109
104
  assert caplog_dkist.record_tuples == [
@@ -116,39 +111,51 @@ def raise_error(*args, **kwargs):
116
111
 
117
112
 
118
113
  def test_attempt_local_update_error_download(mocker, caplog_dkist, tmp_homedir, user_file):
119
- mocker.patch("dkist.net.attrs_values._fetch_values_to_file",
114
+ mocker.patch("dkist.net.attrs_values._fetch_values",
120
115
  side_effect=raise_error)
121
- success = attempt_local_update(silence_errors=True)
116
+ success = attempt_local_update(silence_net_errors=True)
122
117
  assert not success
123
118
 
124
119
  assert caplog_dkist.record_tuples == [
125
120
  ("dkist", logging.INFO, f"Fetching updated search values for the DKIST client to {user_file}"),
126
- ("dkist", logging.ERROR, "Failed to download new attrs values."),
121
+ ("dkist", logging.ERROR, "Failed to download new dkist attrs values. attr values for dkist may be outdated."),
127
122
  ]
128
123
 
129
124
  with pytest.raises(ValueError, match="This is a value error"):
130
- success = attempt_local_update(silence_errors=False)
125
+ success = attempt_local_update(silence_net_errors=False)
131
126
 
132
127
 
133
- def _definately_not_json(user_file, *, timeout):
134
- with open(user_file, "w") as f:
135
- f.write("This is not json")
128
+ def _definitely_not_json(timeout):
129
+ return b"alskdjalskdjaslkdj!!"
136
130
 
137
131
 
138
- def test_attempt_local_update_fail_invalid_download(mocker, tmp_path, caplog_dkist):
132
+ def test_attempt_local_update_fail_invalid_json(mocker, user_file, tmp_path, caplog_dkist):
133
+ # test that the file is removed after
139
134
  json_file = tmp_path / "api_search_values.json"
140
- mocker.patch("dkist.net.attrs_values._fetch_values_to_file",
141
- new_callable=lambda: _definately_not_json)
142
- success = attempt_local_update(user_file=json_file, silence_errors=True)
143
- assert not success
135
+ mocker.patch("dkist.net.attrs_values._fetch_values",
136
+ new_callable=lambda: _definitely_not_json)
137
+ with pytest.raises(UserCacheMissing):
138
+ success = attempt_local_update(user_file=json_file)
139
+
140
+ # File should have been deleted if the update has got as far as returning this error
141
+ assert not json_file.exists()
142
+
143
+
144
+ def test_get_search_attrs_values_fail_invalid_download(mocker, user_file, values_in_home, tmp_path, caplog_dkist):
145
+ """
146
+ Given: An existing cache file
147
+ When: JSON is invalid
148
+ Then: File is removed, and attr values are still loaded
149
+ """
150
+ mocker.patch("dkist.net.attrs_values._fetch_values",
151
+ new_callable=lambda: _definitely_not_json)
152
+ ten_ago = (datetime.datetime.now() - datetime.timedelta(days=10)).timestamp()
153
+ os.utime(user_file, (ten_ago, ten_ago))
144
154
 
145
- assert caplog_dkist.record_tuples == [
146
- ("dkist", logging.INFO, f"Fetching updated search values for the DKIST client to {json_file}"),
147
- ("dkist", logging.ERROR, "Downloaded file is not valid JSON."),
148
- ]
155
+ attr_values = get_search_attrs_values()
156
+ assert not user_file.exists()
149
157
 
150
- with pytest.raises(json.JSONDecodeError):
151
- success = attempt_local_update(user_file=json_file, silence_errors=False)
158
+ assert {a.Instrument, a.dkist.HeaderVersion, a.dkist.WorkflowName}.issubset(attr_values.keys())
152
159
 
153
160
 
154
161
  @pytest.mark.parametrize(("user_file", "update_needed", "allow_update", "should_update"), [
@@ -172,3 +179,22 @@ def test_get_search_attrs_values(mocker, caplog_dkist, values_in_home, user_file
172
179
  assert isinstance(attr_values, dict)
173
180
  # Test that some known attrs are in the result
174
181
  assert {a.Instrument, a.dkist.HeaderVersion, a.dkist.WorkflowName}.issubset(attr_values.keys())
182
+
183
+
184
+ def _fetch_values_urlerror(*args):
185
+ raise URLError("it hates you")
186
+
187
+
188
+ def test_failed_download(mocker, caplog_dkist, user_file, values_in_home):
189
+ mock = mocker.patch("dkist.net.attrs_values._fetch_values",
190
+ new_callable=lambda: _fetch_values_urlerror)
191
+
192
+ ten_ago = (datetime.datetime.now() - datetime.timedelta(days=10)).timestamp()
193
+ os.utime(user_file, (ten_ago, ten_ago))
194
+
195
+ attr_values = get_search_attrs_values(allow_update=True)
196
+
197
+ assert caplog_dkist.record_tuples == [
198
+ ("dkist", logging.INFO, f"Fetching updated search values for the DKIST client to {user_file}"),
199
+ ("dkist", logging.ERROR, "Failed to download new dkist attrs values. attr values for dkist may be outdated."),
200
+ ]
@@ -72,12 +72,13 @@ INVENTORY_KEY_MAP: dict[str, str] = DefaultMap(None, {
72
72
  "headerVersion": "Header Specification Version",
73
73
  "headerDocumentationUrl": "Header Documentation URL",
74
74
  "infoUrl": "Info URL",
75
- "calibrationDocumentationUrl": "Calibration Documentation URL"
75
+ "calibrationDocumentationUrl": "Calibration Documentation URL",
76
+ "status": "Status",
76
77
  })
77
78
 
78
79
 
79
80
  def _key_clean(key):
80
- key = re.sub("[%s]" % re.escape(string.punctuation), "_", key)
81
+ key = re.sub(f"[{re.escape(string.punctuation)}]", "_", key)
81
82
  key = key.replace(" ", "_")
82
83
  key = "".join(char for char in key
83
84
  if char.isidentifier() or char.isnumeric())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dkist
3
- Version: 1.6.0
3
+ Version: 1.7.0
4
4
  Summary: DKIST User Tools
5
5
  Author-email: NSO / AURA <stuart@cadair.com>
6
6
  Project-URL: repository, https://github.com/DKISTDC/dkist
@@ -30,12 +30,12 @@ Requires-Dist: pytest; extra == "tests"
30
30
  Requires-Dist: pytest-doctestplus; extra == "tests"
31
31
  Requires-Dist: pytest-cov; extra == "tests"
32
32
  Requires-Dist: pytest-remotedata; extra == "tests"
33
- Requires-Dist: pytest-cov; extra == "tests"
34
33
  Requires-Dist: pytest-mock; extra == "tests"
35
34
  Requires-Dist: pytest-mpl; extra == "tests"
36
35
  Requires-Dist: pytest-httpserver; extra == "tests"
37
36
  Requires-Dist: pytest-filter-subpackage; extra == "tests"
38
37
  Requires-Dist: pytest-benchmark; extra == "tests"
38
+ Requires-Dist: pytest-xdist; extra == "tests"
39
39
  Requires-Dist: hypothesis; extra == "tests"
40
40
  Requires-Dist: tox; extra == "tests"
41
41
  Requires-Dist: pydot; extra == "tests"
@@ -41,6 +41,7 @@ pytest-mpl
41
41
  pytest-httpserver
42
42
  pytest-filter-subpackage
43
43
  pytest-benchmark
44
+ pytest-xdist
44
45
  hypothesis
45
46
  tox
46
47
  pydot
@@ -48,12 +48,12 @@ tests = [
48
48
  "pytest-doctestplus",
49
49
  "pytest-cov",
50
50
  "pytest-remotedata",
51
- "pytest-cov",
52
51
  "pytest-mock",
53
52
  "pytest-mpl",
54
53
  "pytest-httpserver",
55
54
  "pytest-filter-subpackage",
56
55
  "pytest-benchmark",
56
+ "pytest-xdist",
57
57
  "hypothesis",
58
58
  "tox",
59
59
  "pydot",
@@ -85,6 +85,7 @@ zip-safe = false
85
85
  include-package-data = true
86
86
 
87
87
  [tool.setuptools.packages.find]
88
+ exclude = ["dkist._dev*"]
88
89
 
89
90
  [tool.setuptools_scm]
90
91
  write_to = "dkist/_version.py"
@@ -14,17 +14,23 @@ norecursedirs =
14
14
  .history
15
15
  dkist/extern
16
16
  doctest_plus = enabled
17
- doctest_optionflags = NORMALIZE_WHITESPACE FLOAT_CMP ELLIPSIS
17
+ doctest_optionflags =
18
+ NORMALIZE_WHITESPACE
19
+ FLOAT_CMP
20
+ ELLIPSIS
18
21
  text_file_format = rst
19
- addopts = --doctest-rst -p no:unraisableexception -p no:threadexception
20
- markers =
21
- online: marks this test function as needing online connectivity.
22
- figure: marks this test function as using hash-based Matplotlib figure verification. This mark is not meant to be directly applied, but is instead automatically applied when a test function uses the @sunpy.tests.helpers.figure_test decorator.
23
- benchmark: marks this test as a benchmark
24
22
  # Disable internet access for tests not marked remote_data
25
23
  remote_data_strict = True
26
24
  asdf_schema_root = dkist/io/asdf/resources/
27
25
  asdf_schema_tests_enabled = true
26
+ markers =
27
+ online: marks this test function as needing online connectivity.
28
+ figure: marks this test function as using hash-based Matplotlib figure verification. This mark is not meant to be directly applied, but is instead automatically applied when a test function uses the @sunpy.tests.helpers.figure_test decorator.
29
+ benchmark: marks this test as a benchmark
30
+ addopts =
31
+ --doctest-rst
32
+ -p no:unraisableexception
33
+ -p no:threadexception
28
34
  filterwarnings =
29
35
  # Turn all warnings into errors so they do not pass silently.
30
36
  error