metameq 2026.1.2__py3-none-any.whl → 2026.2.2__py3-none-any.whl

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.
@@ -5,7 +5,8 @@ from metameq.src.util import \
5
5
  SAMPLE_TYPE_SPECIFIC_METADATA_KEY, DEFAULT_KEY, \
6
6
  ALIAS_KEY, BASE_TYPE_KEY, ALLOWED_KEY, ANYOF_KEY, TYPE_KEY, \
7
7
  STUDY_SPECIFIC_METADATA_KEY, LEAVE_REQUIREDS_BLANK_KEY, \
8
- OVERWRITE_NON_NANS_KEY, REQUIRED_KEY, SAMPLE_TYPE_KEY, QIITA_SAMPLE_TYPE
8
+ OVERWRITE_NON_NANS_KEY, REQUIRED_KEY, SAMPLE_TYPE_KEY, QIITA_SAMPLE_TYPE, \
9
+ HOSTTYPE_COL_OPTIONS_KEY, SAMPLETYPE_COL_OPTIONS_KEY
9
10
  from metameq.src.metadata_configurator import \
10
11
  combine_stds_and_study_config, \
11
12
  _make_combined_stds_and_study_host_type_dicts, \
@@ -16,7 +17,8 @@ from metameq.src.metadata_configurator import \
16
17
  _id_sample_type_definition, \
17
18
  update_wip_metadata_dict, \
18
19
  build_full_flat_config_dict, \
19
- _resolve_sample_type_aliases_and_bases
20
+ _resolve_sample_type_aliases_and_bases, \
21
+ _push_global_settings_into_top_host
20
22
 
21
23
 
22
24
  class TestMetadataConfigurator(TestCase):
@@ -3846,6 +3848,9 @@ class TestMetadataConfigurator(TestCase):
3846
3848
  HOST_TYPE_SPECIFIC_METADATA_KEY: {
3847
3849
  # base: top level in test_standards.yml, no default
3848
3850
  "base": {
3851
+ DEFAULT_KEY: "software_default",
3852
+ LEAVE_REQUIREDS_BLANK_KEY: True,
3853
+ OVERWRITE_NON_NANS_KEY: False,
3849
3854
  METADATA_FIELDS_KEY: {
3850
3855
  # sample_name defined at base level
3851
3856
  "sample_name": {
@@ -3864,6 +3869,8 @@ class TestMetadataConfigurator(TestCase):
3864
3869
  "host_associated": {
3865
3870
  # default defined at host_associated level
3866
3871
  DEFAULT_KEY: "not provided",
3872
+ LEAVE_REQUIREDS_BLANK_KEY: True,
3873
+ OVERWRITE_NON_NANS_KEY: False,
3867
3874
  METADATA_FIELDS_KEY: {
3868
3875
  # description defined at host_associated level
3869
3876
  "description": {
@@ -3918,6 +3925,8 @@ class TestMetadataConfigurator(TestCase):
3918
3925
  "human": {
3919
3926
  # default inherited from host_associated
3920
3927
  DEFAULT_KEY: "not provided",
3928
+ LEAVE_REQUIREDS_BLANK_KEY: True,
3929
+ OVERWRITE_NON_NANS_KEY: False,
3921
3930
  METADATA_FIELDS_KEY: {
3922
3931
  # custom_field added from study_specific_metadata
3923
3932
  "custom_field": {
@@ -4036,6 +4045,8 @@ class TestMetadataConfigurator(TestCase):
4036
4045
  "mouse": {
4037
4046
  # default inherited from host_associated
4038
4047
  DEFAULT_KEY: "not provided",
4048
+ LEAVE_REQUIREDS_BLANK_KEY: True,
4049
+ OVERWRITE_NON_NANS_KEY: False,
4039
4050
  METADATA_FIELDS_KEY: {
4040
4051
  # description inherited from host_associated (not overridden)
4041
4052
  "description": {
@@ -4102,6 +4113,7 @@ class TestMetadataConfigurator(TestCase):
4102
4113
  }
4103
4114
  }
4104
4115
  }
4116
+
4105
4117
  self.assertEqual(expected, result)
4106
4118
 
4107
4119
  def test_build_full_flat_config_dict_without_study_config(self):
@@ -4129,6 +4141,9 @@ class TestMetadataConfigurator(TestCase):
4129
4141
  HOST_TYPE_SPECIFIC_METADATA_KEY: {
4130
4142
  # base: top level, no default, just sample_name/sample_type
4131
4143
  "base": {
4144
+ DEFAULT_KEY: "software_default",
4145
+ LEAVE_REQUIREDS_BLANK_KEY: True,
4146
+ OVERWRITE_NON_NANS_KEY: False,
4132
4147
  METADATA_FIELDS_KEY: {
4133
4148
  "sample_name": {
4134
4149
  REQUIRED_KEY: True,
@@ -4144,6 +4159,8 @@ class TestMetadataConfigurator(TestCase):
4144
4159
  # host_associated: inherits from base, adds default and description
4145
4160
  "host_associated": {
4146
4161
  DEFAULT_KEY: "not provided",
4162
+ LEAVE_REQUIREDS_BLANK_KEY: True,
4163
+ OVERWRITE_NON_NANS_KEY: False,
4147
4164
  METADATA_FIELDS_KEY: {
4148
4165
  "description": {
4149
4166
  DEFAULT_KEY: "host associated sample",
@@ -4193,6 +4210,8 @@ class TestMetadataConfigurator(TestCase):
4193
4210
  # human: inherits from host_associated, overrides description
4194
4211
  "human": {
4195
4212
  DEFAULT_KEY: "not provided",
4213
+ LEAVE_REQUIREDS_BLANK_KEY: True,
4214
+ OVERWRITE_NON_NANS_KEY: False,
4196
4215
  METADATA_FIELDS_KEY: {
4197
4216
  "description": {
4198
4217
  DEFAULT_KEY: "human sample",
@@ -4290,6 +4309,8 @@ class TestMetadataConfigurator(TestCase):
4290
4309
  # mouse: inherits from host_associated, keeps parent description
4291
4310
  "mouse": {
4292
4311
  DEFAULT_KEY: "not provided",
4312
+ LEAVE_REQUIREDS_BLANK_KEY: True,
4313
+ OVERWRITE_NON_NANS_KEY: False,
4293
4314
  METADATA_FIELDS_KEY: {
4294
4315
  "description": {
4295
4316
  DEFAULT_KEY: "host associated sample",
@@ -4394,6 +4415,12 @@ class TestMetadataConfigurator(TestCase):
4394
4415
  # Flattened host types
4395
4416
  HOST_TYPE_SPECIFIC_METADATA_KEY: {
4396
4417
  "base": {
4418
+ # default from study_config overrides software_config
4419
+ DEFAULT_KEY: "study_default",
4420
+ # leave_requireds_blank from study_config overrides software_config
4421
+ LEAVE_REQUIREDS_BLANK_KEY: True,
4422
+ # overwrite_non_nans from software_config (not overridden by study)
4423
+ OVERWRITE_NON_NANS_KEY: True,
4397
4424
  METADATA_FIELDS_KEY: {
4398
4425
  "sample_name": {
4399
4426
  REQUIRED_KEY: True,
@@ -4408,6 +4435,10 @@ class TestMetadataConfigurator(TestCase):
4408
4435
  },
4409
4436
  "host_associated": {
4410
4437
  DEFAULT_KEY: "not provided",
4438
+ # leave_requireds_blank from study_config overrides software_config
4439
+ LEAVE_REQUIREDS_BLANK_KEY: True,
4440
+ # overwrite_non_nans from software_config (not overridden by study)
4441
+ OVERWRITE_NON_NANS_KEY: True,
4411
4442
  METADATA_FIELDS_KEY: {
4412
4443
  "description": {
4413
4444
  DEFAULT_KEY: "host associated sample",
@@ -4456,6 +4487,10 @@ class TestMetadataConfigurator(TestCase):
4456
4487
  },
4457
4488
  "human": {
4458
4489
  DEFAULT_KEY: "not provided",
4490
+ # leave_requireds_blank from study_config overrides software_config
4491
+ LEAVE_REQUIREDS_BLANK_KEY: True,
4492
+ # overwrite_non_nans from software_config (not overridden by study)
4493
+ OVERWRITE_NON_NANS_KEY: True,
4459
4494
  METADATA_FIELDS_KEY: {
4460
4495
  "description": {
4461
4496
  DEFAULT_KEY: "human sample",
@@ -4552,6 +4587,10 @@ class TestMetadataConfigurator(TestCase):
4552
4587
  },
4553
4588
  "mouse": {
4554
4589
  DEFAULT_KEY: "not provided",
4590
+ # leave_requireds_blank from study_config overrides software_config
4591
+ LEAVE_REQUIREDS_BLANK_KEY: True,
4592
+ # overwrite_non_nans from software_config (not overridden by study)
4593
+ OVERWRITE_NON_NANS_KEY: True,
4555
4594
  METADATA_FIELDS_KEY: {
4556
4595
  "description": {
4557
4596
  DEFAULT_KEY: "host associated sample",
@@ -4643,9 +4682,14 @@ class TestMetadataConfigurator(TestCase):
4643
4682
  DEFAULT_KEY: "not applicable",
4644
4683
  LEAVE_REQUIREDS_BLANK_KEY: False,
4645
4684
  OVERWRITE_NON_NANS_KEY: False,
4685
+ HOSTTYPE_COL_OPTIONS_KEY: ["host_common_name"],
4686
+ SAMPLETYPE_COL_OPTIONS_KEY: ["sample_type"],
4646
4687
  # Flattened host types
4647
4688
  HOST_TYPE_SPECIFIC_METADATA_KEY: {
4648
4689
  "base": {
4690
+ DEFAULT_KEY: "not applicable",
4691
+ LEAVE_REQUIREDS_BLANK_KEY: False,
4692
+ OVERWRITE_NON_NANS_KEY: False,
4649
4693
  METADATA_FIELDS_KEY: {
4650
4694
  "sample_name": {
4651
4695
  REQUIRED_KEY: True,
@@ -4660,6 +4704,8 @@ class TestMetadataConfigurator(TestCase):
4660
4704
  },
4661
4705
  "host_associated": {
4662
4706
  DEFAULT_KEY: "not provided",
4707
+ LEAVE_REQUIREDS_BLANK_KEY: False,
4708
+ OVERWRITE_NON_NANS_KEY: False,
4663
4709
  METADATA_FIELDS_KEY: {
4664
4710
  "description": {
4665
4711
  DEFAULT_KEY: "host associated sample",
@@ -4708,6 +4754,8 @@ class TestMetadataConfigurator(TestCase):
4708
4754
  },
4709
4755
  "human": {
4710
4756
  DEFAULT_KEY: "not provided",
4757
+ LEAVE_REQUIREDS_BLANK_KEY: False,
4758
+ OVERWRITE_NON_NANS_KEY: False,
4711
4759
  METADATA_FIELDS_KEY: {
4712
4760
  "description": {
4713
4761
  DEFAULT_KEY: "human sample",
@@ -4804,6 +4852,8 @@ class TestMetadataConfigurator(TestCase):
4804
4852
  },
4805
4853
  "mouse": {
4806
4854
  DEFAULT_KEY: "not provided",
4855
+ LEAVE_REQUIREDS_BLANK_KEY: False,
4856
+ OVERWRITE_NON_NANS_KEY: False,
4807
4857
  METADATA_FIELDS_KEY: {
4808
4858
  "description": {
4809
4859
  DEFAULT_KEY: "host associated sample",
@@ -4864,4 +4914,140 @@ class TestMetadataConfigurator(TestCase):
4864
4914
  }
4865
4915
  }
4866
4916
  }
4917
+
4918
+ self.assertEqual(expected, result)
4919
+
4920
+ # Tests for _push_global_settings_into_top_host
4921
+
4922
+ def test__push_global_settings_into_top_host_single_setting(self):
4923
+ """Test pushing a single global setting into the top-level host."""
4924
+ nested_hosts_dict = {
4925
+ HOST_TYPE_SPECIFIC_METADATA_KEY: {
4926
+ "base": {
4927
+ METADATA_FIELDS_KEY: {
4928
+ "field1": {TYPE_KEY: "string"}
4929
+ }
4930
+ }
4931
+ }
4932
+ }
4933
+ flat_config_dict = {
4934
+ DEFAULT_KEY: "custom_default"
4935
+ }
4936
+
4937
+ expected = {
4938
+ HOST_TYPE_SPECIFIC_METADATA_KEY: {
4939
+ "base": {
4940
+ DEFAULT_KEY: "custom_default",
4941
+ METADATA_FIELDS_KEY: {
4942
+ "field1": {TYPE_KEY: "string"}
4943
+ }
4944
+ }
4945
+ }
4946
+ }
4947
+
4948
+ result = _push_global_settings_into_top_host(
4949
+ nested_hosts_dict, flat_config_dict)
4950
+
4951
+ self.assertEqual(expected, result)
4952
+ # Original should be unchanged
4953
+ self.assertNotIn(
4954
+ DEFAULT_KEY,
4955
+ nested_hosts_dict[HOST_TYPE_SPECIFIC_METADATA_KEY]["base"])
4956
+
4957
+ def test__push_global_settings_into_top_host_multiple_settings(self):
4958
+ """Test pushing multiple global settings into the top-level host."""
4959
+ nested_hosts_dict = {
4960
+ HOST_TYPE_SPECIFIC_METADATA_KEY: {
4961
+ "base": {
4962
+ METADATA_FIELDS_KEY: {
4963
+ "field1": {TYPE_KEY: "string"}
4964
+ }
4965
+ }
4966
+ }
4967
+ }
4968
+ flat_config_dict = {
4969
+ DEFAULT_KEY: "custom_default",
4970
+ LEAVE_REQUIREDS_BLANK_KEY: True,
4971
+ OVERWRITE_NON_NANS_KEY: True
4972
+ }
4973
+
4974
+ expected = {
4975
+ HOST_TYPE_SPECIFIC_METADATA_KEY: {
4976
+ "base": {
4977
+ DEFAULT_KEY: "custom_default",
4978
+ LEAVE_REQUIREDS_BLANK_KEY: True,
4979
+ OVERWRITE_NON_NANS_KEY: True,
4980
+ METADATA_FIELDS_KEY: {
4981
+ "field1": {TYPE_KEY: "string"}
4982
+ }
4983
+ }
4984
+ }
4985
+ }
4986
+
4987
+ result = _push_global_settings_into_top_host(
4988
+ nested_hosts_dict, flat_config_dict)
4989
+
4867
4990
  self.assertEqual(expected, result)
4991
+
4992
+ def test__push_global_settings_into_top_host_no_settings(self):
4993
+ """Test that function returns copy when no global settings present."""
4994
+ nested_hosts_dict = {
4995
+ HOST_TYPE_SPECIFIC_METADATA_KEY: {
4996
+ "base": {
4997
+ METADATA_FIELDS_KEY: {
4998
+ "field1": {TYPE_KEY: "string"}
4999
+ }
5000
+ }
5001
+ }
5002
+ }
5003
+ flat_config_dict = {
5004
+ "some_other_key": "value"
5005
+ }
5006
+
5007
+ expected = {
5008
+ HOST_TYPE_SPECIFIC_METADATA_KEY: {
5009
+ "base": {
5010
+ METADATA_FIELDS_KEY: {
5011
+ "field1": {TYPE_KEY: "string"}
5012
+ }
5013
+ }
5014
+ }
5015
+ }
5016
+
5017
+ result = _push_global_settings_into_top_host(
5018
+ nested_hosts_dict, flat_config_dict)
5019
+
5020
+ self.assertEqual(expected, result)
5021
+
5022
+ def test__push_global_settings_into_top_host_raises_on_zero_hosts(self):
5023
+ """Test that ValueError is raised when no top-level hosts exist."""
5024
+ nested_hosts_dict = {
5025
+ HOST_TYPE_SPECIFIC_METADATA_KEY: {}
5026
+ }
5027
+ flat_config_dict = {
5028
+ DEFAULT_KEY: "custom_default"
5029
+ }
5030
+
5031
+ with self.assertRaisesRegex(
5032
+ ValueError,
5033
+ r"Expected exactly one top-level key.*found: \[\]"):
5034
+ _push_global_settings_into_top_host(
5035
+ nested_hosts_dict, flat_config_dict)
5036
+
5037
+ def test__push_global_settings_into_top_host_raises_on_multiple_hosts(self):
5038
+ """Test that ValueError is raised when multiple top-level hosts exist."""
5039
+ nested_hosts_dict = {
5040
+ HOST_TYPE_SPECIFIC_METADATA_KEY: {
5041
+ "host1": {METADATA_FIELDS_KEY: {}},
5042
+ "host2": {METADATA_FIELDS_KEY: {}}
5043
+ }
5044
+ }
5045
+ flat_config_dict = {
5046
+ DEFAULT_KEY: "custom_default"
5047
+ }
5048
+
5049
+ with self.assertRaisesRegex(
5050
+ ValueError,
5051
+ r"Expected exactly one top-level key"):
5052
+ _push_global_settings_into_top_host(
5053
+ nested_hosts_dict, flat_config_dict)