Coverage for middle_layer/common/__init__.py: 72.22%
54 statements
« prev ^ index » next coverage.py v7.10.5, created at 2026-04-13 06:13 +0000
« prev ^ index » next coverage.py v7.10.5, created at 2026-04-13 06:13 +0000
1# Copyright 2024 Associated Universities, Inc.
2#
3# This file is part of Telescope Time Allocation Tools (TTAT).
4#
5# TTAT is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# any later version.
9#
10# TTAT is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with TTAT. If not, see <https://www.gnu.org/licenses/>.
17#
18"""Contain utility functions used across middle_layer packages"""
19import os
20from pathlib import Path
22import astropy.units as u
23import pendulum
24from astropy.coordinates import Angle
25from astropy.units import Quantity, Unit
27ZERO_SECONDS = 0 * u.s
30def stringify_declination(declination: Quantity) -> str:
31 return Angle(declination).to_string(unit=Unit("degree"), sep=":")
34def stringify_right_ascension(right_ascension: Quantity) -> str:
35 return Angle(right_ascension).to_string(unit=Unit("degree"), sep=":")
38def sum_quantities(quants: list[Quantity]) -> Quantity:
39 """Preserve units even if sum() returns 0"""
40 return sum(quants, start=ZERO_SECONDS)
43def strtobool(a_string: str) -> bool:
44 if a_string.lower() == "true":
45 return True
46 elif a_string.lower() == "false":
47 return False
48 else:
49 raise ValueError("value must be a boolean. " + a_string)
52def parse_iso_8601_strings(string: str) -> pendulum.DateTime:
53 """Parse an ISO 8601 datetime string into a pendulum.DateTime
55 :param string: String to parse
56 :return: Parsed DateTime
57 :raises ValueError: If string is parsed successfully but isn't a DateTime
58 :raises ParserError: If Pendulum fails to parse string
59 """
60 result = pendulum.parse(string)
61 if isinstance(result, pendulum.DateTime):
62 return result
63 raise ValueError(f"String {string} parsed into {result}, which does not have type pendulum.DateTime")
66def get_parents_matching(directory: Path, query: str) -> list[Path]:
67 return [par for par in directory.parents if par.match(query)]
70def get_middle_layer() -> Path:
71 """Find the middle_layer directory in an efficient-ish manner"""
72 cwd = Path.cwd().resolve()
73 query = "middle_layer"
74 if cwd.match(query):
75 middle_layer = cwd
76 elif len(get_parents_matching(cwd, query)) == 1:
77 # In a child
78 middle_layer = get_parents_matching(cwd, query).pop()
79 elif cwd.match("ttat") or get_parents_matching(cwd, "ttat"):
80 # In a parent
81 if cwd.match("ttat"):
82 ttat = cwd
83 else:
84 # Don't restrict to one match since some people (like Sam) have `.../ttat/ttat` for their repo path
85 ttat = get_parents_matching(cwd, "ttat").pop()
86 middle_layer = [ml for ml in ttat.glob(f"**/{query}")][0] # Assume that all matches are parents of middle_layer
87 else:
88 # No idea where we are
89 middle_layer = [ml for ml in Path("/").glob(f"**/{query}") if ml.parent.match("ttat")].pop()
90 return middle_layer
93def get_application_base_url():
94 # Read the APP_ENV variable set in the Dockerfile (and by GitLab CI)
95 # Provide a default for local development if APP_ENV is not set
96 current_env = os.getenv("APP_ENV", "local_development")
98 if current_env == "prod":
99 return "https://tta.nrao.edu"
100 elif current_env == "test":
101 return "https://tta-test.nrao.edu"
102 elif current_env == "dev":
103 return "https://tta-dev.nrao.edu"
104 elif current_env == "local_backend": # For local backend-focused dev
105 return "http://localhost:5555"
106 elif current_env == "local_frontend": # For local frontend-focused dev
107 return "http://localhost:4200"
108 else: # Default for local_development or any other unspecified value
109 # You might want to log a warning if current_env is unexpected
110 print(f"Warning: APP_ENV is '{current_env}'. Defaulting base_url to http://localhost:5555")
111 return "http://localhost:5555" # Or any other suitable local default