/
config.py
109 lines (85 loc) · 3.11 KB
/
config.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
from datetime import datetime
from pathlib import Path
import sys
from typing import Optional, Tuple
from dateutil import tz
from pydantic import (
BaseModel,
StrictBool,
StrictInt,
StrictStr,
ValidationError,
validator,
)
import yaml
class App(BaseModel):
"""Configuration model class to store configuration regarding the FastAPI app"""
# Some options aren't mandatory when running the API in the production
host: Optional[StrictStr]
port: Optional[StrictInt]
reload: Optional[StrictBool]
class ImagesConfig(BaseModel):
# The dimensions will be stored as a list in the YAML file, but are cast to tuple
# using `typing.Tuple` because this is the type used by Pillow
image_thumbnail_size: Tuple[int, int]
waveform_thumbnail_size: Tuple[int, int]
# the system default colour map (used if no user preference is set)
default_colour_map: StrictStr
colourbar_height_pixels: StrictInt
class MongoDB(BaseModel):
"""Configuration model class to store MongoDB configuration details"""
mongodb_url: StrictStr
database_name: StrictStr
max_documents: StrictInt
image_store_directory: StrictStr
class AuthConfig(BaseModel):
"""Configuration model class to store authentication configuration details"""
private_key_path: StrictStr
public_key_path: StrictStr
jwt_algorithm: StrictStr
access_token_validity_mins: StrictInt
refresh_token_validity_days: StrictInt
fedid_server_url: StrictStr
fedid_server_ldap_realm: StrictStr
class ExperimentsConfig(BaseModel):
"""Configuration model class to store experiment configuration details"""
first_scheduler_contact_start_date: datetime
scheduler_background_task_enabled: StrictBool
scheduler_background_frequency: StrictStr
scheduler_background_timezone: StrictStr
scheduler_background_retry_mins: float
user_office_wsdl_url: StrictStr
username: StrictStr
password: StrictStr
scheduler_wsdl_url: StrictStr
instrument_name: StrictStr
worker_file_path: StrictStr
@validator("scheduler_background_timezone")
def check_timezone(cls, value): # noqa: B902, N805
if not tz.gettz(value):
sys.exit(f"scheduler_background_timezone is not a valid timezone: {value}")
else:
return value
class APIConfig(BaseModel):
"""
Class to store the API's configuration settings
"""
app: Optional[App]
mongodb: MongoDB
auth: AuthConfig
experiments: ExperimentsConfig
images: ImagesConfig
@classmethod
def load(cls, path=Path(__file__).parent.parent / "config.yml"):
"""
Load the config data from the .yml file and store it as a dict
"""
try:
with open(path, encoding="utf-8") as config_file:
config = yaml.safe_load(config_file)
return cls(**config)
except (IOError, ValidationError, yaml.YAMLError) as e:
sys.exit(f"An error occurred while loading the config data: {e}")
class Config:
"""Class containing config as a class variable so it can mocked during testing"""
config = APIConfig.load()