sdsstools 1.9.1__py3-none-any.whl → 1.9.3__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.
@@ -886,7 +886,7 @@ class yanny(OrderedDict):
886
886
  raise PydlutilsException("{0} exists, aborting write!".format(newfile))
887
887
  if comments is None:
888
888
  basefile = os.path.basename(newfile)
889
- timestamp = datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC")
889
+ timestamp = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%d %H:%M:%S UTC")
890
890
  comments = "#\n# {0}\n#\n# Created by pydl.pydlutils.yanny.yanny\n#\n# {1}\n#\n".format(
891
891
  basefile, timestamp
892
892
  )
@@ -968,7 +968,7 @@ class yanny(OrderedDict):
968
968
  raise ValueError(
969
969
  "Data to append is not of the correct type. " + "Use a dict!"
970
970
  )
971
- timestamp = datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC")
971
+ timestamp = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%d %H:%M:%S UTC")
972
972
  contents = ""
973
973
  #
974
974
  # Print any key/value pairs
@@ -330,7 +330,7 @@ class Configuration(RecursiveDict):
330
330
  if isinstance(config, dict):
331
331
  return config
332
332
  elif isinstance(config, (str, pathlib.Path)):
333
- return read_yaml_file(config)
333
+ return read_yaml_file(config, return_class=self.__class__)
334
334
  else:
335
335
  raise ValueError("Invalid config of type {}".format(type(config)))
336
336
 
@@ -392,9 +392,32 @@ def read_yaml_file(
392
392
  path: AnyPath,
393
393
  use_extends: bool = True,
394
394
  loader: Any = yaml.FullLoader,
395
- return_class: Type[ReturnClass] = Configuration,
395
+ return_class: Type[ReturnClass] = dict,
396
+ use_variables: bool = True,
396
397
  ) -> ReturnClass:
397
- """Read a YAML file and returns a dictionary."""
398
+ """Reads a YAML file and returns a dictionary.
399
+
400
+ Parameters
401
+ ----------
402
+ path
403
+ The path to the YAML file or a file-like object.
404
+ use_extends
405
+ If :obj:`True`, looks for lines starting with ``#!extends <basefile>`` and
406
+ merges the current file with the base file.
407
+ loader
408
+ The YAML loader to use.
409
+ return_class
410
+ The class of the returned object. Typically a subclass of :obj:`dict`.
411
+ use_variables
412
+ If :obj:`True`, looks for a ``variables`` section in the YAML file and
413
+ replaces occurrences of ``$(VARNAME)`` with the value of that variable.
414
+
415
+ Returns
416
+ -------
417
+ yaml_data
418
+ The YAML data as an object of type ``return_class``.
419
+
420
+ """
398
421
 
399
422
  if isinstance(path, (str, pathlib.Path)):
400
423
  fp = open(path, "r")
@@ -402,9 +425,19 @@ def read_yaml_file(
402
425
  fp = path
403
426
 
404
427
  fp.seek(0)
405
- config: Union[ConfigType, None] = yaml.load(fp, Loader=loader)
428
+ yaml_data: Union[ConfigType, None] = yaml.load(fp, Loader=loader)
429
+
430
+ if yaml_data is not None and use_variables:
431
+ variables = yaml_data.get("variables", {})
432
+
433
+ fp.seek(0)
434
+ file_content = fp.read()
435
+
436
+ for var, value in variables.items():
437
+ file_content = re.sub(rf"\$\(\s*{var}\s*\)", str(value), file_content)
438
+ yaml_data = yaml.load(file_content, Loader=loader)
406
439
 
407
- if config is None or config == {}:
440
+ if yaml_data is None or yaml_data == {}:
408
441
  return return_class({})
409
442
 
410
443
  if use_extends:
@@ -418,10 +451,10 @@ def read_yaml_file(
418
451
  raise FileExistsError(f"cannot find !extends file {base_file}.")
419
452
 
420
453
  base = read_yaml_file(base_file, use_extends=False, return_class=dict)
421
- new_config = merge_config(base, config)
454
+ new_config = merge_config(base, yaml_data)
422
455
  return return_class(new_config)
423
456
 
424
457
  elif line.strip().startswith("#") or line.strip() == "":
425
458
  continue
426
459
 
427
- return return_class(config)
460
+ return return_class(yaml_data)
sdsstools/logger.py CHANGED
@@ -426,7 +426,7 @@ class SDSSLogger(logging.Logger):
426
426
  os.makedirs(logdir)
427
427
 
428
428
  if os.path.exists(log_file_path) and rotating and rollover:
429
- now = datetime.datetime.utcnow()
429
+ now = datetime.datetime.now(datetime.timezone.utc)
430
430
  dst = str(log_file_path) + "." + now.strftime(SUFFIX)
431
431
  shutil.move(str(log_file_path), dst)
432
432
 
sdsstools/time.py CHANGED
@@ -142,7 +142,7 @@ def get_sjd(
142
142
  """
143
143
 
144
144
  if date is None:
145
- date = datetime.datetime.utcnow()
145
+ date = datetime.datetime.now(datetime.timezone.utc)
146
146
 
147
147
  jd = datetime2jd(date)
148
148
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sdsstools
3
- Version: 1.9.1
3
+ Version: 1.9.3
4
4
  Summary: Small tools for SDSS products
5
5
  Project-URL: Homepage, https://github.com/sdss/sdsstools
6
6
  Project-URL: Repository, https://github.com/sdss/sdsstools
@@ -141,6 +141,25 @@ you can use `read_yaml_file` to parse the result
141
141
 
142
142
  The path to the base file must be absolute or relative to the location of the file to be extended.
143
143
 
144
+ ### Using variables in YAML files
145
+
146
+ `read_yaml_file` and `get_config` support the use of variables in YAML files. A special section `variables` can be defined at the top level of the YAML file, and any `$(VAR)` string in the file will be replaced by the value of the variable. For example
147
+
148
+ ```yaml
149
+ variables:
150
+ greeting: hello
151
+
152
+ cat1:
153
+ key1: $(greeting) world
154
+ ```
155
+
156
+ ```python
157
+ >>> read_yaml_file('file.yaml', use_variables=True)
158
+ {'cat1': {'key1': 'hello world'}, 'variables': {'greeting': 'hello'}}
159
+ ```
160
+
161
+ Environment variables can also be used by including a `${ENV_VAR}` string in the YAML file, which will be replaced with the content of the `$ENV_VAR` environment variable.
162
+
144
163
  ### The `Configuration` class
145
164
 
146
165
  By default `get_config()` and `read_yaml_file()` return a `Configuration` instance. For the most part a `Configuration` object is the same as a dictionary, and it can be used as such. It has two main differences:
@@ -1,22 +1,22 @@
1
1
  sdsstools/__init__.py,sha256=G8u94gRu4THFJvptEITykK0Q_3jHqhQY9p01j9QCQH4,744
2
2
  sdsstools/_tasks.py,sha256=U7fvxk9IExzE6voNjio2QqRTw-H9Upu1d0zKQlQFs5I,4263
3
3
  sdsstools/cli.py,sha256=e4BS4b1cJThCj5tytajr_VMUvmVP1xYq_r90EtEscg8,1348
4
- sdsstools/configuration.py,sha256=i2KkrjS5hE4o-d4VDwzWZKacxO-rNKewgDKoeqE3uuQ,13417
4
+ sdsstools/configuration.py,sha256=lvutpHf7wYIVOoFXd3NMkbh-zJrTTi2q6HVkWQOH9ns,14496
5
5
  sdsstools/daemonizer.py,sha256=TMzq3RgD0KqY6jmeeJASlCsw7CjDpLmF8QrENaxCHBU,7796
6
- sdsstools/logger.py,sha256=L_ZfTCbV22gNtqBhLNYHAu1a5SQ3jpN7b9rodrvKjqA,18364
6
+ sdsstools/logger.py,sha256=nGAC_hDK0dWVMAS-a-vBsw0oSCxAwx-ZsJUE5GMzILs,18382
7
7
  sdsstools/metadata.py,sha256=LZWO0KI-gVvzdJNIaVlIn4bBBHxbglU8BLW-MdlxOFA,3268
8
- sdsstools/time.py,sha256=6LsJpF0k2LUI8gCXZGznAu4ZCVuX7X_7OQHwfEWMlDo,4588
8
+ sdsstools/time.py,sha256=cqLrch0ZUCt3ShagN1v-5GhgLyNjzPXgaQRem4j7vAk,4606
9
9
  sdsstools/utils.py,sha256=kl3FtvJdw3uEZye7gcBI9Ksvd1rk0EwkriiDkuyvlrU,5077
10
10
  sdsstools/_vendor/__init__.py,sha256=sy3LqhCDgkFjMQY7mLQolVOgvD7y9LM6DuWp2ylG0vc,282
11
11
  sdsstools/_vendor/color_print.py,sha256=lD3qS-U77cw1OR_XoA7pV7qOqH0Rql5cScPdAYZnstg,6457
12
- sdsstools/_vendor/yanny.py,sha256=qCq32FZUqZijXTUJZC_7RVWAi9LDWScTpbvSSCMtdg0,48667
12
+ sdsstools/_vendor/yanny.py,sha256=ur40GkJ3pG50kLQPsXfnF_2I3McS5K9Fg1K1RUGK3A8,48703
13
13
  sdsstools/_vendor/toml/__init__.py,sha256=l1rGAaRKxb8_tQtToqdVmvS6zWXtWj-Gw5PC2TPRE4c,705
14
14
  sdsstools/_vendor/toml/decoder.py,sha256=hWUJ3UQ43MGVER35rSUUj7Hdh85Vat8Od_B4HeFdp3w,38050
15
15
  sdsstools/_vendor/toml/encoder.py,sha256=OBRwH2tRUhRI8nJgKBwKbkyQnBAuhcUf60r3wykjPco,9989
16
16
  sdsstools/_vendor/toml/ordered.py,sha256=aW5woa5xOqR4BjIz9t10_lghxyhF54KQ7FqUNVv7WJ0,334
17
17
  sdsstools/_vendor/toml/tz.py,sha256=8TAiXrTqU08sE0ruz2TXH_pFY2rlwNKE47MSE4rDo8Y,618
18
- sdsstools-1.9.1.dist-info/METADATA,sha256=WF2fVOdt6z9KDGnTOZF80BInwyMDg3KKOLgFoMDirYc,15027
19
- sdsstools-1.9.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
20
- sdsstools-1.9.1.dist-info/entry_points.txt,sha256=H1UefQFMHyzmGcdNib_qxiOfFSx3351wr4c2ax0PJbQ,87
21
- sdsstools-1.9.1.dist-info/licenses/LICENSE.md,sha256=_7dAUQQ5Ph_x1hcFXhi9aHBcqq9H11zco12eO4B3Cyg,1504
22
- sdsstools-1.9.1.dist-info/RECORD,,
18
+ sdsstools-1.9.3.dist-info/METADATA,sha256=IwrO_J-v0fUFPfaByUchYYoc_2bmYSni--E4RQnHg34,15701
19
+ sdsstools-1.9.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
20
+ sdsstools-1.9.3.dist-info/entry_points.txt,sha256=H1UefQFMHyzmGcdNib_qxiOfFSx3351wr4c2ax0PJbQ,87
21
+ sdsstools-1.9.3.dist-info/licenses/LICENSE.md,sha256=_7dAUQQ5Ph_x1hcFXhi9aHBcqq9H11zco12eO4B3Cyg,1504
22
+ sdsstools-1.9.3.dist-info/RECORD,,