-
Notifications
You must be signed in to change notification settings - Fork 6
/
configuration.py
126 lines (110 loc) · 4.54 KB
/
configuration.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import locale
import os
from typing import Any, Optional, Sequence
class Setting:
__slots__ = ('name', 'description', 'unit', 'value_type', 'default_value', 'optional', 'value')
def __init__(
self,
name: str,
*,
description: str,
unit: Optional[Sequence[str]] = None,
value_type: Optional[type] = None,
default_value: Any = None,
optional: Optional[bool] = None,
):
self.name = name
self.description = description
self.unit = unit
self.value_type = value_type or (type(default_value) if default_value is not None else str)
self.default_value = default_value
self.optional = optional or default_value is not None
def __repr__(self) -> str:
return (
'Setting('
f'name={self.name}, description={self.description}, unit={self.unit},'
f'value_type={self.value_type}, default_value={self.default_value}'
')'
)
def __str__(self) -> str:
return f'{self.description}: {self.human_value()}'
def human_value(self) -> str:
if self.value is None:
return 'brak'
elif self.unit is not None:
return f'{self.value} {self.unit}'
else:
return str(self.value)
def set_value_with_env(self):
value_obtained = os.environ.get(self.name.upper())
if not value_obtained:
if self.optional:
self.value = self.default_value
else:
raise Exception(
f'mandatory setting {self.name.upper()} could not be loaded from os.environ nor from .env'
)
else:
self.value = self._convert_value_to_type(value_obtained)
def _convert_value_to_type(self, value: Any) -> Any:
if value is None:
return None
if self.value_type == int:
try:
return locale.atoi(value)
except ValueError:
return int(value)
if self.value_type == float:
try:
return locale.atof(value)
except ValueError:
return float(value)
return self.value_type(value)
class Configuration:
__slots__ = ('settings',)
def __init__(self, settings: Sequence[Setting]):
for setting in settings:
setting.set_value_with_env()
self.settings = {setting.name: setting for setting in settings}
def __getitem__(self, key: str) -> Any:
try:
return self.settings[key].value
except KeyError:
try:
return os.environ[key.upper()]
except KeyError:
raise KeyError(f'{key.upper()} is neither recognized nor set as an environment variable')
def get(self, key: str) -> Any:
try:
return self[key]
except KeyError:
return None
SETTINGS = (
Setting('discord_token', description='Token bota'),
Setting('command_prefix', description='Domyślny prefiks komend', default_value='!'),
Setting(
'command_cooldown_per_user_in_seconds',
description='Cooldown wywołania komendy przez użytkownika',
unit='s',
default_value=1.0,
),
Setting('database_url', description='URL Postgresa'),
Setting('redis_url', description='URL Redisa'),
Setting('clickhouse_url', description='URL ClickHouse'),
Setting('clickhouse_user', description='Nazwa użytkownika ClickHouse'),
Setting('clickhouse_password', description='Hasło użytkownika ClickHouse'),
Setting('clickhouse_database', description='Baza danych ClickHouse', default_value='somsiad'),
Setting('sentry_dsn', description='DSN Sentry', optional=True),
Setting('google_key', description='Klucz API Google', optional=True),
Setting('google_custom_search_engine_id', description='Identyfikator CSE Google', optional=True),
Setting('wolfram_alpha_app_id', description='Identyfikator aplikacji Wolfram Alpha', optional=True),
Setting('goodreads_key', description='Klucz API Goodreads', optional=True),
Setting('tmdb_key', description='Klucz API TMDb', optional=True),
Setting('last_fm_key', description='Klucz API Last.fm', optional=True),
Setting('openai_api_key', description='Klucz API OpenAI', optional=True),
Setting('perplexity_api_key', description='Klucz API Perplexity', optional=True),
Setting(
'disco_max_file_size_in_mib', description='Maksymalny rozmiar pliku utworu disco', unit='MiB', default_value=16
),
)
configuration = Configuration(SETTINGS)