/
config_defaults.py
188 lines (159 loc) · 7.37 KB
/
config_defaults.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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
from datetime import timedelta
import logging
from typing import List, Optional, Union, Dict, Tuple
"""
This lays out our configuration requirements and allows to set trivial defaults, per environment adjustable.
Anything confidential should be handled outside of source control (e.g. a SECRET KEY file is generated on first install,
and confidential settings can be set via the <app-env>-conf.py file.
"""
class Config(object):
"""
If there is a useful default value, set it here.
Otherwise, set to None, so that it can be set either by subclasses or the env-specific config script.
"""
DEBUG: bool = False
LOGGING_LEVEL: int = logging.WARNING
SECRET_KEY: Optional[str] = None
SQLALCHEMY_DATABASE_URI: Optional[str] = None
# https://stackoverflow.com/questions/33738467/how-do-i-know-if-i-can-disable-sqlalchemy-track-modifications
SQLALCHEMY_TRACK_MODIFICATIONS: bool = False
SQLALCHEMY_ENGINE_OPTIONS: dict = {
"pool_recycle": 299, # https://www.pythonanywhere.com/forums/topic/2599/
# "pool_timeout": 20,
"pool_pre_ping": True, # https://docs.sqlalchemy.org/en/13/core/pooling.html#disconnect-handling-pessimistic
"connect_args": {
"options": "-c timezone=utc"
}, # https://stackoverflow.com/a/59932909/13775459
}
MAIL_SERVER: Optional[str] = "localhost"
MAIL_PORT: Optional[int] = 25
MAIL_USE_TLS: Optional[bool] = False
MAIL_USE_SSL: Optional[bool] = False
MAIL_USERNAME: Optional[str] = None
MAIL_DEFAULT_SENDER = (
"FlexMeasures",
"no-reply@example.com",
) # tuple of name and email address
MAIL_PASSWORD: Optional[str] = None
SECURITY_REGISTERABLE = False
SECURITY_LOGIN_USER_TEMPLATE = "admin/login_user.html"
SECURITY_EMAIL_SUBJECT_PASSWORD_RESET = (
"Password reset instructions for your FlexMeasures account."
)
SECURITY_EMAIL_SUBJECT_PASSWORD_NOTICE = (
"Your FlexMeasures password has been reset."
)
SECURITY_FORGOT_PASSWORD_TEMPLATE = "admin/forgot_password.html"
SECURITY_RECOVERABLE = True
SECURITY_RESET_PASSWORD_TEMPLATE = "admin/reset_password.html"
SECURITY_RECOVERABLE = True
SECURITY_TOKEN_AUTHENTICATION_HEADER = "Authorization"
SECURITY_TOKEN_MAX_AGE = 60 * 60 * 6 # six hours
SECURITY_TRACKABLE = False # this is more in line with modern privacy law
SECURITY_PASSWORD_SALT: Optional[str] = None
# Allowed cross-origins. Set to "*" to allow all. For development (e.g. javascript on localhost) you might use "null" here
CORS_ORIGINS: Union[List[str], str] = []
# this can be a dict with all possible options as value per regex, see https://flask-cors.readthedocs.io/en/latest/configuration.html
CORS_RESOURCES: Union[dict, list, str] = [r"/api/*"]
CORS_SUPPORTS_CREDENTIALS: bool = True
OPENWEATHERMAP_API_KEY: Optional[str] = None
MAPBOX_ACCESS_TOKEN: Optional[str] = None
JSONIFY_PRETTYPRINT_REGULAR: bool = False
RQ_DASHBOARD_POLL_INTERVAL: int = (
3000 # Web interface poll period for updates in ms
)
SENTRY_DSN: Optional[str] = None
# Place additional Sentry config here.
# traces_sample_rate is for performance monitoring across all transactions,
# you probably want to adjust this.
FLEXMEASURES_SENTRY_CONFIG: dict = dict(traces_sample_rate=0.33)
FLEXMEASURES_PLATFORM_NAME: str = "FlexMeasures"
FLEXMEASURES_MODE: str = ""
FLEXMEASURES_TIMEZONE: str = "Asia/Seoul"
FLEXMEASURES_HIDE_NAN_IN_UI: bool = False
FLEXMEASURES_PUBLIC_DEMO_CREDENTIALS: Optional[Tuple] = None
FLEXMEASURES_DEMO_YEAR: Optional[int] = None
# Configuration used for entity addressing:
# This setting contains the domain on which FlexMeasures runs
# and the first month when the domain was under the current owner's administration
FLEXMEASURES_HOSTS_AND_AUTH_START: dict = {"flexmeasures.io": "2021-01"}
FLEXMEASURES_PLUGIN_PATHS: List[str] = []
FLEXMEASURES_PROFILE_REQUESTS: bool = False
FLEXMEASURES_DB_BACKUP_PATH: str = "migrations/dumps"
FLEXMEASURES_LISTED_VIEWS: List[str] = [
"dashboard",
"analytics",
"portfolio",
"assets",
"users",
]
FLEXMEASURES_LP_SOLVER: str = "cbc"
FLEXMEASURES_PLANNING_HORIZON: timedelta = timedelta(hours=2 * 24)
FLEXMEASURES_PLANNING_TTL: timedelta = timedelta(
days=7
) # Time to live for UDI event ids of successful scheduling jobs. Set a negative timedelta to persist forever.
FLEXMEASURES_TASK_CHECK_AUTH_TOKEN: Optional[str] = None
FLEXMEASURES_REDIS_URL: str = "localhost"
FLEXMEASURES_REDIS_PORT: int = 6379
FLEXMEASURES_REDIS_DB_NR: int = 0 # Redis per default has 16 databases, [0-15]
FLEXMEASURES_REDIS_PASSWORD: Optional[str] = None
FLEXMEASURES_JS_VERSIONS: dict = dict(
vega="5",
vegaembed="6.17.0",
vegalite="5.0.0",
# todo: expand with other js versions used in FlexMeasures
)
# names of settings which cannot be None
# SECRET_KEY is also required but utils.app_utils.set_secret_key takes care of this better.
required: List[str] = ["SQLALCHEMY_DATABASE_URI"]
# settings whose absence should trigger a warning
mail_warning = "Without complete mail settings, FlexMeasures will not be able to send mails to users, e.g. for password resets!"
redis_warning = "Without complete redis connection settings, FlexMeasures will not be able to run forecasting and scheduling job queues."
warnable: Dict[str, str] = {
"MAIL_SERVER": mail_warning,
"MAIL_PORT": mail_warning,
"MAIL_USE_TLS": mail_warning,
"MAIL_USE_SSL": mail_warning,
"MAIL_USERNAME": mail_warning,
"MAIL_DEFAULT_SENDER": mail_warning,
"MAIL_PASSWORD": mail_warning,
"FLEXMEASURES_REDIS_URL": redis_warning,
"FLEXMEASURES_REDIS_PORT": redis_warning,
"FLEXMEASURES_REDIS_DB_NR": redis_warning,
"FLEXMEASURES_REDIS_PASSWORD": redis_warning,
}
class ProductionConfig(Config):
DEBUG = False
LOGGING_LEVEL = logging.ERROR
class StagingConfig(Config):
DEBUG = False
LOGGING_LEVEL = logging.WARNING
class DevelopmentConfig(Config):
DEBUG = True
LOGGING_LEVEL = logging.DEBUG
SQLALCHEMY_ECHO = False
PROPAGATE_EXCEPTIONS = True
# PRESERVE_CONTEXT_ON_EXCEPTION = False # might need this to make our transaction handling work in debug mode
JSONIFY_PRETTYPRINT_REGULAR = True
FLEXMEASURES_MODE = "development"
FLEXMEASURES_PROFILE_REQUESTS: bool = True
class TestingConfig(Config):
DEBUG = True # this seems to be important for logging in, not sure why
LOGGING_LEVEL = logging.INFO
WTF_CSRF_ENABLED = False # also necessary for logging in during tests
SECURITY_PASSWORD_SALT = "$2b$19$abcdefghijklmnopqrstuv"
SQLALCHEMY_DATABASE_URI = (
"postgresql://flexmeasures_test:flexmeasures_test@localhost/flexmeasures_test"
)
# SQLALCHEMY_ECHO = True
FLEXMEASURES_TASK_CHECK_AUTH_TOKEN = "test-task-check-token"
# These can speed up tests due to less hashing work (I saw ~165s -> ~100s)
# (via https://github.com/mattupstate/flask-security/issues/731#issuecomment-362186021)
SECURITY_HASHING_SCHEMES = ["hex_md5"]
SECURITY_DEPRECATED_HASHING_SCHEMES: List[str] = []
FLEXMEASURES_MODE = "test"
FLEXMEASURES_PLANNING_HORIZON = timedelta(
hours=2 * 24
) # if more than 2 days, consider setting up more days of price data for tests
class DocumentationConfig(Config):
pass