dkist-header-validator 5.3.0__tar.gz → 5.4.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 (44) hide show
  1. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/.readthedocs.yml +2 -2
  2. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/PKG-INFO +12 -9
  3. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/bitbucket-pipelines.yml +39 -12
  4. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/dkist_header_validator/base_validator.py +85 -46
  5. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/dkist_header_validator/spec_validators.py +3 -0
  6. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/dkist_header_validator/tests/conftest.py +12 -13
  7. dkist_header_validator-5.4.0/dkist_header_validator/tests/test_dataset_extras_validation.py +12 -0
  8. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/dkist_header_validator/tests/test_spec122_translation.py +0 -1
  9. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/dkist_header_validator/tests/test_spec122_validation-.py +1 -1
  10. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/dkist_header_validator/tests/test_spec214_validation-.py +2 -2
  11. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/dkist_header_validator.egg-info/PKG-INFO +12 -9
  12. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/dkist_header_validator.egg-info/SOURCES.txt +2 -3
  13. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/dkist_header_validator.egg-info/requires.txt +2 -2
  14. dkist_header_validator-5.4.0/dkist_header_validator.egg-info/top_level.txt +4 -0
  15. dkist_header_validator-5.4.0/pyproject.toml +76 -0
  16. dkist_header_validator-5.4.0/setup.cfg +4 -0
  17. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/tox.ini +5 -16
  18. dkist_header_validator-5.3.0/dkist_header_validator/version.py +0 -8
  19. dkist_header_validator-5.3.0/dkist_header_validator.egg-info/top_level.txt +0 -1
  20. dkist_header_validator-5.3.0/setup.cfg +0 -68
  21. dkist_header_validator-5.3.0/setup.py +0 -22
  22. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/.gitignore +0 -0
  23. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/.pre-commit-config.yaml +0 -0
  24. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/.snyk +0 -0
  25. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/README.rst +0 -0
  26. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/dkist_header_validator/__init__.py +0 -0
  27. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/dkist_header_validator/api/__init__.py +0 -0
  28. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/dkist_header_validator/api/validate.py +0 -0
  29. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/dkist_header_validator/exceptions.py +0 -0
  30. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/dkist_header_validator/tests/__init__.py +0 -0
  31. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/dkist_header_validator/tests/test_base_validator.py +0 -0
  32. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/dkist_header_validator/tests/test_spec122_validation+.py +0 -0
  33. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/dkist_header_validator/tests/test_spec214_validation+.py +0 -0
  34. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/dkist_header_validator/tests/test_translator.py +0 -0
  35. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/dkist_header_validator/translator.py +0 -0
  36. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/dkist_header_validator/utils/__init__.py +0 -0
  37. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/dkist_header_validator/utils/expansions.py +0 -0
  38. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/dkist_header_validator.egg-info/dependency_links.txt +0 -0
  39. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/dkist_header_validator.egg-info/entry_points.txt +0 -0
  40. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/docs/Makefile +0 -0
  41. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/docs/conf.py +0 -0
  42. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/docs/index.rst +0 -0
  43. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/docs/make.bat +0 -0
  44. {dkist_header_validator-5.3.0 → dkist_header_validator-5.4.0}/docs/requirements.txt +0 -0
@@ -1,8 +1,8 @@
1
1
  version: 2
2
2
  build:
3
- os: ubuntu-20.04
3
+ os: ubuntu-24.04
4
4
  tools:
5
- python: "3.11"
5
+ python: "3.13"
6
6
  apt_packages:
7
7
  - libopenjp2-7
8
8
  - graphviz
@@ -1,27 +1,30 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dkist-header-validator
3
- Version: 5.3.0
3
+ Version: 5.4.0
4
4
  Summary: DKIST data validator
5
- Home-page: https://bitbucket.org/dkistdc/dkist-header-validator/src/main/
6
- Author: NSO / AURA
7
- Author-email: "aderks@nso.edu"
8
- License: MIT
5
+ Author-email: NSO / AURA <dkistdc@nso.edu>
6
+ License: BSD-3-Clause
7
+ Project-URL: Homepage, https://nso.edu/dkist/data-center/
8
+ Project-URL: Repository, https://bitbucket.org/dkistdc/dkist-header-validator
9
+ Project-URL: Help, https://nso.atlassian.net/servicedesk/customer/portals
9
10
  Classifier: Programming Language :: Python
10
11
  Classifier: Programming Language :: Python :: 3
11
- Classifier: Programming Language :: Python :: 3.10
12
12
  Classifier: Programming Language :: Python :: 3.11
13
- Requires-Python: >=3.10
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Requires-Python: >=3.11
16
+ Description-Content-Type: text/x-rst
14
17
  Requires-Dist: astropy>=5.0
15
18
  Requires-Dist: voluptuous<1.0.0,>=0.11.7
16
19
  Requires-Dist: pyyaml>=6.0
17
- Requires-Dist: dkist-fits-specifications>=4.1.0
20
+ Requires-Dist: dkist-fits-specifications>=4.23.0
18
21
  Provides-Extra: test
19
22
  Requires-Dist: pytest; extra == "test"
20
23
  Requires-Dist: pytest-cov; extra == "test"
21
24
  Requires-Dist: pytest-xdist; extra == "test"
22
25
  Requires-Dist: deepdiff; extra == "test"
23
26
  Requires-Dist: tox; extra == "test"
24
- Requires-Dist: dkist-data-simulator; extra == "test"
27
+ Requires-Dist: dkist-data-simulator==5.8.0; extra == "test"
25
28
  Provides-Extra: cli
26
29
  Requires-Dist: typer; extra == "cli"
27
30
  Provides-Extra: docs
@@ -1,5 +1,5 @@
1
1
  # Build Configuration for python package deployment to pypi
2
- image: python:3.10
2
+ image: python:3.13
3
3
 
4
4
  definitions:
5
5
  steps:
@@ -21,20 +21,43 @@ definitions:
21
21
  script:
22
22
  - ./ci_scripts/latest/execute_script.sh lint_python.sh
23
23
 
24
- - step: &test
25
- name: Test
24
+ - step: &scan
25
+ caches:
26
+ - pip
27
+ name: Scan
28
+ script:
29
+ - ./ci_scripts/latest/execute_script.sh scan_python.sh
30
+
31
+ - step: &test313
32
+ image: python:3.13
33
+ name: Test Python 3.13
34
+ caches:
35
+ - pip
26
36
  script:
27
37
  - pip install -U pip
28
- - pip install .[test]
29
- - pytest -v -n auto --cov dkist_header_validator --cov-report=xml --cov-report=term-missing
38
+ - pip install tox
39
+ - tox -e py313
30
40
  - ./ci_scripts/latest/execute_script.sh upload_coverage.sh
31
41
 
32
- - step: &scan
42
+ - step: &test312
43
+ image: python:3.12
44
+ name: Test Python 3.12
33
45
  caches:
34
46
  - pip
35
- name: Scan
36
47
  script:
37
- - ./ci_scripts/latest/execute_script.sh scan_python.sh
48
+ - pip install -U pip
49
+ - pip install tox
50
+ - tox -e py312
51
+
52
+ - step: &test311
53
+ image: python:3.11
54
+ name: Test Python 3.11
55
+ caches:
56
+ - pip
57
+ script:
58
+ - pip install -U pip
59
+ - pip install tox
60
+ - tox -e py311
38
61
 
39
62
  - step: &docs
40
63
  name: Build Docs
@@ -55,7 +78,9 @@ pipelines:
55
78
  - step: *download_execute_script
56
79
  - step: *lint
57
80
  - parallel:
58
- - step: *test
81
+ - step: *test313
82
+ - step: *test312
83
+ - step: *test311
59
84
  - step: *docs
60
85
  - step: *scan
61
86
  tags:
@@ -63,7 +88,9 @@ pipelines:
63
88
  - step: *download_execute_script
64
89
  - step: *lint
65
90
  - parallel:
66
- - step: *test
67
- - step: *docs
68
- - step: *scan
91
+ - step: *test313
92
+ - step: *test312
93
+ - step: *test311
94
+ - step: *docs
95
+ - step: *scan
69
96
  - step: *publish
@@ -3,7 +3,6 @@ Definition of the base objects for the creation of a spec validator
3
3
  """
4
4
 
5
5
  import logging
6
- import os
7
6
  from collections.abc import Mapping
8
7
  from io import BytesIO
9
8
  from numbers import Integral
@@ -12,7 +11,6 @@ from pathlib import Path
12
11
  from typing import IO
13
12
  from typing import Any
14
13
  from typing import Callable
15
- from typing import Optional
16
14
  from typing import Type
17
15
 
18
16
  import astropy.time as t
@@ -23,6 +21,7 @@ from astropy.io import fits
23
21
  from astropy.io.fits.hdu.hdulist import HDUList
24
22
  from dkist_fits_specifications import spec214
25
23
  from dkist_fits_specifications.utils import schema_type_hint
24
+ from numpy.typing import NDArray
26
25
  from voluptuous.error import Invalid
27
26
 
28
27
  from dkist_header_validator.exceptions import ReturnTypeException
@@ -40,7 +39,7 @@ __all__ = ["SpecValidator", "SpecSchema"]
40
39
 
41
40
  class FormatInvalid(Invalid):
42
41
  """
43
- An value which does not match the schema format.
42
+ A value which does not match the schema format.
44
43
  """
45
44
 
46
45
 
@@ -425,7 +424,9 @@ class SpecValidator:
425
424
  return headers
426
425
 
427
426
  def _validate_headers(
428
- self, input_headers: HDUList | dict | fits.header.Header, extra
427
+ self,
428
+ input_headers: HDUList | dict | fits.header.Header,
429
+ extra: bool,
429
430
  ) -> tuple[dict, dict]:
430
431
  """
431
432
  Validates open input headers against the instance spec_schema
@@ -446,17 +447,17 @@ class SpecValidator:
446
447
  verified_headers = self.verify_headers(headers, extra)
447
448
  return verified_headers, fits_cards
448
449
 
449
- def _validate_file(self, input_headers: str | IO, extra) -> tuple[dict, dict, np.ndarray]:
450
+ def _validate_file(self, file: str | IO, extra: bool) -> tuple[dict, dict, np.ndarray]:
450
451
  """
451
452
  Validates files against the astropy and then instance spec_schema
452
- :param input_headers: The input headers to validate in the following formats:
453
+ :param file: The input headers to validate in the following formats:
453
454
  - string file path
454
455
  - File like object
455
456
  :param extra: switch for validation to allow extra keys in schema
456
457
  :return: dictionary of verified headers to be used later
457
458
  """
458
459
  try:
459
- with fits.open(input_headers) as hdul:
460
+ with fits.open(file) as hdul:
460
461
  # verify fits headers with astropy verify library
461
462
  hdul.verify("exception")
462
463
  # normalize headers into a dict
@@ -471,7 +472,7 @@ class SpecValidator:
471
472
  raise ValidationException("Cannot parse headers", errors={type(exc): str(exc)})
472
473
 
473
474
  @staticmethod
474
- def _return_HDU(validated_headers, data, fits_cards):
475
+ def _return_HDU(validated_headers: dict, data: NDArray, fits_cards: dict) -> fits.PrimaryHDU:
475
476
  """
476
477
  Returns validated headers as an HDU
477
478
  :param validated_headers: Already validated/translated headers to be written out
@@ -499,7 +500,7 @@ class SpecValidator:
499
500
  return new_hdu
500
501
 
501
502
  @classmethod
502
- def _return_hdulist(cls, validated_headers, fits_cards) -> HDUList:
503
+ def _return_hdulist(cls, validated_headers: dict, fits_cards: dict) -> HDUList:
503
504
  """
504
505
  Returns validated headers as an HDUList
505
506
  :param validated_headers: Already validated/translated headers to be written out into
@@ -515,7 +516,7 @@ class SpecValidator:
515
516
  return new_hdu_list
516
517
 
517
518
  @staticmethod
518
- def _return_dictionary(validated_headers, fits_cards) -> dict:
519
+ def _return_dictionary(validated_headers: dict, fits_cards: dict) -> dict:
519
520
  """
520
521
  Returns validated headers as a dictionary
521
522
  :param validated_headers: Already validated/translated headers to be written out into
@@ -528,60 +529,67 @@ class SpecValidator:
528
529
  return validated_headers
529
530
 
530
531
  @classmethod
531
- def _return_BytesIO(cls, validated_headers, input_headers, data, fits_cards) -> BytesIO:
532
+ def _return_BytesIO(cls, validated_headers: dict, data: NDArray, fits_cards: dict) -> BytesIO:
532
533
  """
533
534
  Returns validated headers as a BytesIO object
534
535
  :param validated_headers: Already validated/translated headers to be written out into
535
536
  the BytesIO object
536
- :param input_headers: original filepath or BytesIO object
537
537
  :param data: original data
538
538
  :param fits_cards: Any special cards to be included in the BytesIO object
539
539
  :return: BytesIO object
540
540
  """
541
541
  new_hdu = cls._return_HDU(validated_headers, data, fits_cards)
542
542
  new_hdu_list = fits.HDUList([new_hdu])
543
- return BytesIO(
544
- new_hdu_list.writeto(
545
- str(os.path.basename(input_headers)),
546
- overwrite=True,
547
- output_verify="exception",
548
- checksum=True,
549
- )
543
+ buffer = BytesIO()
544
+ new_hdu_list.writeto(
545
+ buffer,
546
+ overwrite=True,
547
+ output_verify="exception",
548
+ checksum=True,
550
549
  )
550
+ return buffer
551
551
 
552
552
  @classmethod
553
- def _return_file(cls, validated_headers, input_headers, data, fits_cards) -> (str, IO):
553
+ def _return_file(
554
+ cls, validated_headers: dict, file: str | Path, data: NDArray, fits_cards: dict
555
+ ) -> Path:
554
556
  """
555
- Returns validated headers as a FITS file
557
+ Returns the path of validated headers written to a FITS file
556
558
  :param validated_headers: Already validated/translated headers to be written out
557
559
  into a FITS file
558
- :param input_headers: original filepath or BytesIO object
560
+ :param file: original file path
559
561
  :param data: original data
560
562
  :param fits_cards: Any special cards to be included in the FITS file
561
- :return: FITS file
563
+ :return: path to the FITS file
562
564
  """
563
565
  new_hdu = cls._return_HDU(validated_headers, data, fits_cards)
564
566
  new_hdu_list = fits.HDUList([new_hdu])
567
+ filepath = Path(file)
565
568
  new_hdu_list.writeto(
566
- str(os.path.basename(input_headers)),
569
+ filepath,
567
570
  overwrite=True,
568
571
  output_verify="exception",
569
572
  checksum=True,
570
573
  )
571
- return Path(os.path.basename(input_headers))
574
+ return filepath
572
575
 
573
576
  def _format_output(
574
- self, return_type, validated_headers, input_headers=None, data=None, fits_cards=None
577
+ self,
578
+ return_type,
579
+ validated_headers: dict,
580
+ file: str | None = None,
581
+ data: NDArray | None = None,
582
+ fits_cards: dict | None = None,
575
583
  ):
576
584
  fits_cards = fits_cards or {}
577
585
  if return_type == Path:
578
586
  if data is None:
579
587
  raise ReturnTypeException("No data. Cannot write file.")
580
- return self._return_file(validated_headers, input_headers, data, fits_cards)
588
+ return self._return_file(validated_headers, file, data, fits_cards)
581
589
  if return_type == BytesIO:
582
590
  if data is None:
583
591
  raise ReturnTypeException("No data. Cannot write BytesIO object.")
584
- return self._return_BytesIO(validated_headers, input_headers, data, fits_cards)
592
+ return self._return_BytesIO(validated_headers, data, fits_cards)
585
593
  if return_type == dict:
586
594
  return self._return_dictionary(validated_headers, fits_cards)
587
595
  if return_type == HDUList:
@@ -593,7 +601,7 @@ class SpecValidator:
593
601
  raise ReturnTypeException("No data. Cannot write PrimaryHDU.")
594
602
  return self._return_HDU(validated_headers, data, fits_cards)
595
603
 
596
- def _capture_fits_cards(self, validated_headers) -> dict:
604
+ def _capture_fits_cards(self, validated_headers: dict) -> dict:
597
605
  """
598
606
  Pull special fits cards out of validated_headers dict.
599
607
  This is necessary for astropy header formatting.
@@ -647,13 +655,29 @@ class SpecValidator:
647
655
  ------
648
656
  dkist_header_validator.SpecValidationException or subclass
649
657
  """
650
- if isinstance(input_headers, (dict, fits.header.Header, HDUList)):
651
- validated_headers, fits_cards = self._validate_headers(input_headers, extra)
652
- return self._format_output(
653
- return_type, validated_headers, input_headers, None, fits_cards
654
- )
655
- validated_headers, fits_cards, data = self._validate_file(input_headers, extra)
656
- return self._format_output(return_type, validated_headers, input_headers, data, fits_cards)
658
+ match input_headers:
659
+ case dict() | fits.header.Header() | HDUList():
660
+ validated_headers, fits_cards = self._validate_headers(
661
+ input_headers=input_headers, extra=extra
662
+ )
663
+ return self._format_output(
664
+ return_type=return_type,
665
+ validated_headers=validated_headers,
666
+ fits_cards=fits_cards,
667
+ )
668
+ case str() | Path() | BytesIO():
669
+ validated_headers, fits_cards, data = self._validate_file(
670
+ file=input_headers, extra=extra
671
+ )
672
+ return self._format_output(
673
+ return_type=return_type,
674
+ validated_headers=validated_headers,
675
+ file=input_headers,
676
+ data=data,
677
+ fits_cards=fits_cards,
678
+ )
679
+ case _:
680
+ raise ValidationException(f"{type(input_headers)} is not supported")
657
681
 
658
682
  def validate_and_translate_to_214_l0(self, input_headers, return_type=HDUList, extra=True):
659
683
  """
@@ -689,16 +713,31 @@ class SpecValidator:
689
713
  ------
690
714
  dkist_header_validator.SpecValidationException or subclass
691
715
  """
692
- if isinstance(input_headers, (dict, fits.header.Header, HDUList)):
693
- validated_headers, fits_cards = self._validate_headers(input_headers, extra)
694
- translated_headers = translate_spec122_to_spec214_l0(validated_headers)
695
- return self._format_output(return_type, translated_headers, None, None, fits_cards)
696
- else:
697
- validated_headers, fits_cards, data = self._validate_file(input_headers, extra)
698
- translated_headers = translate_spec122_to_spec214_l0(validated_headers)
699
- return self._format_output(
700
- return_type, translated_headers, input_headers, data, fits_cards
701
- )
716
+ match input_headers:
717
+ case dict() | fits.header.Header() | HDUList():
718
+ validated_headers, fits_cards = self._validate_headers(
719
+ input_headers=input_headers, extra=extra
720
+ )
721
+ translated_headers = translate_spec122_to_spec214_l0(validated_headers)
722
+ return self._format_output(
723
+ return_type=return_type,
724
+ validated_headers=translated_headers,
725
+ fits_cards=fits_cards,
726
+ )
727
+ case str() | Path() | BytesIO():
728
+ validated_headers, fits_cards, data = self._validate_file(
729
+ file=input_headers, extra=extra
730
+ )
731
+ translated_headers = translate_spec122_to_spec214_l0(validated_headers)
732
+ return self._format_output(
733
+ return_type=return_type,
734
+ validated_headers=translated_headers,
735
+ file=input_headers,
736
+ data=data,
737
+ fits_cards=fits_cards,
738
+ )
739
+ case _:
740
+ raise ValidationException(f"{type(input_headers)} is not supported")
702
741
 
703
742
 
704
743
  class ProcessedSpecValidator(SpecValidator):
@@ -16,6 +16,7 @@ __all__ = [
16
16
  "spec214_validator",
17
17
  "spec214_l0_validator",
18
18
  "Spec214ValidationException",
19
+ "spec_extras_validator",
19
20
  ]
20
21
 
21
22
 
@@ -39,6 +40,8 @@ spec122_validator = ProcessedSpecValidator(
39
40
  ############
40
41
  # SPEC-214 #
41
42
  ############
43
+
44
+
42
45
  class Spec214ValidationException(SpecValidationException):
43
46
  """
44
47
  Exception when validating a spec 214 file
@@ -6,6 +6,7 @@ import numpy as np
6
6
  import pytest
7
7
  from astropy.io import fits
8
8
  from astropy.wcs import WCS
9
+ from dkist_data_simulator.dataset_extras import DatasetExtraBase
9
10
  from dkist_data_simulator.spec122 import Spec122Dataset
10
11
  from dkist_data_simulator.spec214 import Spec214Dataset
11
12
  from dkist_fits_specifications.spec122 import load_spec122
@@ -47,8 +48,10 @@ def get_fits_object(
47
48
  ]
48
49
  data = np.ones(shape=ds.array_shape)
49
50
  hdu = fits.PrimaryHDU(data=data)
51
+
50
52
  for key, value in header_dict.items():
51
- hdu.header[key] = value
53
+ if key not in {"PCOUNT", "GCOUNT"}:
54
+ hdu.header[key] = value
52
55
 
53
56
  if object_type == "fits":
54
57
  file_name = tmpdir / f"{uuid4().hex}.fits"
@@ -244,10 +247,7 @@ class InvalidInstrumentTableSpec122Dataset(BaseSpec122Dataset):
244
247
  super().__init__(instrument=instrument)
245
248
 
246
249
  # Remove a random key from the instrument table
247
- glob_name = instrument.lower().replace(
248
- "-", ""
249
- ) # For cryo and dl b/c the yamls don't have dashes
250
- instrument_keys = load_spec122(glob=glob_name)[glob_name]
250
+ instrument_keys = load_spec122(glob=instrument)[instrument]
251
251
  removal_candidates = [k for k, v in instrument_keys.items() if "instrument_required" in v]
252
252
  removed_key = choice(removal_candidates)
253
253
  self.add_remove_key(removed_key)
@@ -401,10 +401,7 @@ class InvalidInstrumentTableSpec214l0Dataset(BaseSpec214l0Dataset):
401
401
  super().__init__(instrument=instrument)
402
402
 
403
403
  # Remove a random key from the instrument table
404
- glob_name = instrument.lower().replace(
405
- "-", ""
406
- ) # For cryo and dl b/c the yamls don't have dashes
407
- instrument_keys = load_level0_spec214(glob=glob_name)[glob_name]
404
+ instrument_keys = load_level0_spec214(glob=instrument)[instrument]
408
405
  removal_candidates = [k for k, v in instrument_keys.items() if "instrument_required" in v]
409
406
  removed_key = choice(removal_candidates)
410
407
  self.add_remove_key(removed_key)
@@ -623,10 +620,7 @@ class InvalidInstrumentTableSpec214Dataset(BaseSpec214Dataset):
623
620
  super().__init__(instrument=instrument)
624
621
 
625
622
  # Remove a random key from the instrument table
626
- glob_name = instrument.lower().replace(
627
- "-", ""
628
- ) # For cryo and dl b/c the yamls don't have dashes
629
- instrument_keys = load_spec214(glob=glob_name)[glob_name]
623
+ instrument_keys = load_spec214(glob=instrument)[instrument]
630
624
  removal_candidates = [k for k, v in instrument_keys.items() if "instrument_required" in v]
631
625
  removed_key = choice(removal_candidates)
632
626
  self.add_remove_key(removed_key)
@@ -637,3 +631,8 @@ class InvalidInstrumentTableSpec214Dataset(BaseSpec214Dataset):
637
631
  def invalid_instrument_table_spec_214_object(tmpdir, request, instrument):
638
632
  dataset = InvalidInstrumentTableSpec214Dataset(instrument)
639
633
  yield get_fits_object(object_type=request.param, tmpdir=tmpdir, ds=dataset), dataset.removed_key
634
+
635
+
636
+ @pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
637
+ def valid_dataset_extra_object(tmpdir, request):
638
+ yield get_fits_object(object_type=request.param, tmpdir=tmpdir, ds=DatasetExtraBase())
@@ -0,0 +1,12 @@
1
+ from dkist_header_validator import spec_extras_validator
2
+
3
+
4
+ def test_dataset_extras(valid_dataset_extra_object):
5
+ """
6
+ Validates a fits header against the dataset extra schema
7
+ Given: A valid dataset extra fits header
8
+ When: Validating headers
9
+ Then: Do not raise an exception
10
+ """
11
+ # raises exception on failure
12
+ spec_extras_validator.validate(valid_dataset_extra_object, extra=False)
@@ -3,7 +3,6 @@ from pathlib import Path
3
3
 
4
4
  import pytest
5
5
  from astropy.io import fits
6
- from astropy.io.fits.hdu.hdulist import HDUList
7
6
 
8
7
  from dkist_header_validator import ReturnTypeException
9
8
  from dkist_header_validator import Spec122ValidationException
@@ -104,7 +104,7 @@ def test_toomanyHDUs_validate(valid_spec_122_too_many_HDUs):
104
104
  spec122_validator.validate(valid_spec_122_too_many_HDUs)
105
105
 
106
106
 
107
- @pytest.mark.parametrize("instrument", ["cryo-nirsp", "dlnirsp", "vbi", "visp", "vtf"])
107
+ @pytest.mark.parametrize("instrument", ["cryonirsp", "dlnirsp", "vbi", "visp", "vtf"])
108
108
  def test_instrument_required_key_missing(invalid_instrument_table_spec_122_object):
109
109
  """
110
110
  Given: Headers from a specific instrument, but with one of the required header keys removed
@@ -93,7 +93,7 @@ def test_spec214_invalid_headers(invalid_spec_214_object):
93
93
  spec214_validator.validate(invalid_spec_214_object)
94
94
 
95
95
 
96
- @pytest.mark.parametrize("instrument", ["cryo-nirsp", "dlnirsp", "vbi", "visp", "vtf"])
96
+ @pytest.mark.parametrize("instrument", ["cryonirsp", "dlnirsp", "vbi", "visp", "vtf"])
97
97
  def test_spec214l0_instrument_required_key_missing(invalid_instrument_table_spec_214l0_object):
98
98
  """
99
99
  Given: Headers from a specific instrument, but with one of the required header keys removed
@@ -197,7 +197,7 @@ def test_polarimetric_required_key_missing(invalid_polarimetric_spec_214_object)
197
197
  spec214_validator.validate(invalid_polarimetric_spec_214_object)
198
198
 
199
199
 
200
- @pytest.mark.parametrize("instrument", ["cryo-nirsp", "dlnirsp", "vbi", "visp", "vtf"])
200
+ @pytest.mark.parametrize("instrument", ["cryonirsp", "dlnirsp", "vbi", "visp", "vtf"])
201
201
  def test_instrument_required_key_missing(invalid_instrument_table_spec_214_object):
202
202
  """
203
203
  Given: Headers from a specific instrument, but with one of the required header keys removed
@@ -1,27 +1,30 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dkist-header-validator
3
- Version: 5.3.0
3
+ Version: 5.4.0
4
4
  Summary: DKIST data validator
5
- Home-page: https://bitbucket.org/dkistdc/dkist-header-validator/src/main/
6
- Author: NSO / AURA
7
- Author-email: "aderks@nso.edu"
8
- License: MIT
5
+ Author-email: NSO / AURA <dkistdc@nso.edu>
6
+ License: BSD-3-Clause
7
+ Project-URL: Homepage, https://nso.edu/dkist/data-center/
8
+ Project-URL: Repository, https://bitbucket.org/dkistdc/dkist-header-validator
9
+ Project-URL: Help, https://nso.atlassian.net/servicedesk/customer/portals
9
10
  Classifier: Programming Language :: Python
10
11
  Classifier: Programming Language :: Python :: 3
11
- Classifier: Programming Language :: Python :: 3.10
12
12
  Classifier: Programming Language :: Python :: 3.11
13
- Requires-Python: >=3.10
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Requires-Python: >=3.11
16
+ Description-Content-Type: text/x-rst
14
17
  Requires-Dist: astropy>=5.0
15
18
  Requires-Dist: voluptuous<1.0.0,>=0.11.7
16
19
  Requires-Dist: pyyaml>=6.0
17
- Requires-Dist: dkist-fits-specifications>=4.1.0
20
+ Requires-Dist: dkist-fits-specifications>=4.23.0
18
21
  Provides-Extra: test
19
22
  Requires-Dist: pytest; extra == "test"
20
23
  Requires-Dist: pytest-cov; extra == "test"
21
24
  Requires-Dist: pytest-xdist; extra == "test"
22
25
  Requires-Dist: deepdiff; extra == "test"
23
26
  Requires-Dist: tox; extra == "test"
24
- Requires-Dist: dkist-data-simulator; extra == "test"
27
+ Requires-Dist: dkist-data-simulator==5.8.0; extra == "test"
25
28
  Provides-Extra: cli
26
29
  Requires-Dist: typer; extra == "cli"
27
30
  Provides-Extra: docs
@@ -4,15 +4,13 @@
4
4
  .snyk
5
5
  README.rst
6
6
  bitbucket-pipelines.yml
7
- setup.cfg
8
- setup.py
7
+ pyproject.toml
9
8
  tox.ini
10
9
  dkist_header_validator/__init__.py
11
10
  dkist_header_validator/base_validator.py
12
11
  dkist_header_validator/exceptions.py
13
12
  dkist_header_validator/spec_validators.py
14
13
  dkist_header_validator/translator.py
15
- dkist_header_validator/version.py
16
14
  dkist_header_validator.egg-info/PKG-INFO
17
15
  dkist_header_validator.egg-info/SOURCES.txt
18
16
  dkist_header_validator.egg-info/dependency_links.txt
@@ -24,6 +22,7 @@ dkist_header_validator/api/validate.py
24
22
  dkist_header_validator/tests/__init__.py
25
23
  dkist_header_validator/tests/conftest.py
26
24
  dkist_header_validator/tests/test_base_validator.py
25
+ dkist_header_validator/tests/test_dataset_extras_validation.py
27
26
  dkist_header_validator/tests/test_spec122_translation.py
28
27
  dkist_header_validator/tests/test_spec122_validation+.py
29
28
  dkist_header_validator/tests/test_spec122_validation-.py
@@ -1,7 +1,7 @@
1
1
  astropy>=5.0
2
2
  voluptuous<1.0.0,>=0.11.7
3
3
  pyyaml>=6.0
4
- dkist-fits-specifications>=4.1.0
4
+ dkist-fits-specifications>=4.23.0
5
5
 
6
6
  [cli]
7
7
  typer
@@ -21,4 +21,4 @@ pytest-cov
21
21
  pytest-xdist
22
22
  deepdiff
23
23
  tox
24
- dkist-data-simulator
24
+ dkist-data-simulator==5.8.0
@@ -0,0 +1,4 @@
1
+ ci_scripts
2
+ dkist_header_validator
3
+ docs
4
+ wheelhouse
@@ -0,0 +1,76 @@
1
+ [build-system]
2
+ requires = ["setuptools>=64", "setuptools_scm>=8", "wheel", "build"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [tool.setuptools.packages.find]
6
+ exclude = ["build*"]
7
+
8
+ [tool.setuptools_scm]
9
+
10
+ [tool.dkist-dev-tools]
11
+
12
+ [project]
13
+ dynamic = ["version"]
14
+ name = "dkist-header-validator"
15
+ requires-python = ">=3.11"
16
+ description = "DKIST data validator"
17
+ readme = "README.rst"
18
+ authors = [ {name = "NSO / AURA", email = "dkistdc@nso.edu"} ]
19
+ license = {text = "BSD-3-Clause"}
20
+ classifiers = [
21
+ "Programming Language :: Python",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Programming Language :: Python :: 3.13",
26
+ ]
27
+ dependencies = [
28
+ "astropy >= 5.0",
29
+ "voluptuous >=0.11.7, < 1.0.0",
30
+ "pyyaml >=6.0",
31
+ "dkist-fits-specifications >= 4.23.0",
32
+ ]
33
+ [project.urls]
34
+ Homepage = "https://nso.edu/dkist/data-center/"
35
+ Repository = "https://bitbucket.org/dkistdc/dkist-header-validator"
36
+ Help = "https://nso.atlassian.net/servicedesk/customer/portals"
37
+
38
+ [project.optional-dependencies]
39
+ test = [
40
+ "pytest",
41
+ "pytest-cov",
42
+ "pytest-xdist",
43
+ "deepdiff",
44
+ "tox",
45
+ "dkist-data-simulator == 5.8.0",
46
+ ]
47
+ cli = [
48
+ "typer",
49
+ ]
50
+ docs = [
51
+ "sphinx",
52
+ "sphinx-astropy",
53
+ "sphinx-changelog",
54
+ "sphinx-autoapi",
55
+ "pytest",
56
+ "towncrier",
57
+ "dkist-sphinx-theme",
58
+ ]
59
+
60
+ [tool.coverage.run]
61
+ omit = [
62
+ "dkist_header_validator/tests/*",
63
+ "dkist_header_validator/__init__.py",
64
+ ]
65
+
66
+ [tool.black]
67
+ line-length = 100
68
+
69
+ [tool.isort]
70
+ profile = "black"
71
+ force_single_line = true
72
+ combine_as_imports = false
73
+ line_length = 100
74
+
75
+ [project.scripts]
76
+ dkist-header-validator = "dkist_header_validator.api.validate:main"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -1,21 +1,19 @@
1
1
  [tox]
2
2
  envlist =
3
- py{38,39}-test
4
- build_docs
5
- codestyle
3
+ py{311,312,313}-test
6
4
  isolated_build = true
7
5
  # This is included for testing of the template. You can remove it safely.
8
- skip_missing_interpreters = True
6
+ skip_missing_interpreters = false
9
7
 
10
8
  [testenv]
11
- # Pass through the following environemnt variables which may be needed for the CI
9
+ # Pass through the following environment variables which may be needed for the CI
12
10
  passenv = HOME, WINDIR, LC_ALL, LC_CTYPE, CC, CI, TRAVIS
13
11
 
14
12
  # Run the tests in a temporary directory to make sure that we don't import
15
13
  # the package from the source tree
16
14
  changedir = .tmp/{envname}
17
15
 
18
- # tox environments are constructued with so-called 'factors' (or terms)
16
+ # tox environments are constructed with so-called 'factors' (or terms)
19
17
  # separated by hyphens, e.g. test-devdeps-cov. Lines below starting with factor:
20
18
  # will only take effect if that factor is included in the environment name. To
21
19
  # see a list of example environments that can be run, along with a description,
@@ -29,16 +27,7 @@ description =
29
27
  # The following indicates which extras_require from setup.cfg will be installed
30
28
  extras =
31
29
  test
32
- alldeps: all
33
30
 
34
31
  commands =
35
32
  pip freeze
36
- pytest --pyargs dkist_header_validator {toxinidir}/docs --cov dkist_header_validator --cov-config={toxinidir}/setup.cfg {posargs}
37
-
38
- [testenv:build_docs]
39
- changedir = docs
40
- description = invoke sphinx-build to build the HTML docs
41
- extras = docs
42
- commands =
43
- pip freeze
44
- sphinx-build -W -b html . _build/html {posargs}
33
+ pytest -n auto --pyargs dkist_header_validator {toxinidir}/docs --cov dkist_header_validator --cov-config={toxinidir}/pyproject.toml {posargs}
@@ -1,8 +0,0 @@
1
- # Note that we need to fall back to the hard-coded version if either
2
- # setuptools_scm can't be imported or setuptools_scm can't determine the
3
- # version, so we catch the generic 'Exception'.
4
- try:
5
- from setuptools_scm import get_version
6
- __version__ = get_version(root='..', relative_to=__file__)
7
- except Exception:
8
- __version__ = '5.3.0'
@@ -1 +0,0 @@
1
- dkist_header_validator
@@ -1,68 +0,0 @@
1
- [metadata]
2
- name = dkist-header-validator
3
- description = DKIST data validator
4
- long_description = file: README.rst
5
- author = NSO / AURA
6
- author_email = "aderks@nso.edu"
7
- license = MIT
8
- url = https://bitbucket.org/dkistdc/dkist-header-validator/src/main/
9
- edit_on_github = False
10
- classifiers =
11
- Programming Language :: Python
12
- Programming Language :: Python :: 3
13
- Programming Language :: Python :: 3.10
14
- Programming Language :: Python :: 3.11
15
-
16
- [options]
17
- python_requires = >=3.10
18
- setup_requires = setuptools_scm
19
- packages = find:
20
- include_package_data = True
21
- install_requires =
22
- astropy >= 5.0
23
- voluptuous >=0.11.7, < 1.0.0
24
- pyyaml >=6.0
25
- dkist-fits-specifications >= 4.1.0
26
-
27
- [options.extras_require]
28
- test =
29
- pytest
30
- pytest-cov
31
- pytest-xdist
32
- deepdiff
33
- tox
34
- dkist-data-simulator
35
- cli =
36
- typer
37
- docs =
38
- sphinx
39
- sphinx-astropy
40
- sphinx-changelog
41
- sphinx-autoapi
42
- pytest
43
- towncrier
44
- dkist-sphinx-theme
45
-
46
- [tool:pytest]
47
- minversion = 3.0
48
- testpaths = "dkist_header_validator/tests"
49
- norecursedirs = ".tox" "build" "docs[\/]_build" "docs[\/]generated" "*.egg-info" "examples"
50
-
51
- [coverage:run]
52
- source = dkist_header_validator/
53
- omit = dkist_header_validator/tests/*
54
-
55
- [options.entry_points]
56
- console_scripts =
57
- dkist-header-validator = dkist_header_validator.api.validate:main
58
-
59
- [tool:isort]
60
- profile = black
61
- force_single_line = true
62
- combine_as_imports = false
63
- line_length = 100
64
-
65
- [egg_info]
66
- tag_build =
67
- tag_date = 0
68
-
@@ -1,22 +0,0 @@
1
- #!/usr/bin/env python
2
- import os
3
-
4
- from setuptools import setup
5
-
6
- VERSION_TEMPLATE = """
7
- # Note that we need to fall back to the hard-coded version if either
8
- # setuptools_scm can't be imported or setuptools_scm can't determine the
9
- # version, so we catch the generic 'Exception'.
10
- try:
11
- from setuptools_scm import get_version
12
- __version__ = get_version(root='..', relative_to=__file__)
13
- except Exception:
14
- __version__ = '{version}'
15
- """.lstrip()
16
-
17
- setup(
18
- use_scm_version={
19
- "write_to": os.path.join("dkist_header_validator", "version.py"),
20
- "write_to_template": VERSION_TEMPLATE,
21
- },
22
- )