bfabric-web-apps 0.1.1__py3-none-any.whl → 0.1.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.
- bfabric_web_apps/__init__.py +72 -8
- bfabric_web_apps/layouts/layouts.py +76 -22
- bfabric_web_apps/objects/BfabricInterface.py +123 -23
- bfabric_web_apps/objects/Logger.py +3 -3
- bfabric_web_apps/utils/callbacks.py +44 -26
- bfabric_web_apps/utils/create_app_in_bfabric.py +86 -0
- bfabric_web_apps/utils/defaults.py +11 -0
- bfabric_web_apps/utils/get_logger.py +1 -1
- bfabric_web_apps/utils/get_power_user_wrapper.py +3 -5
- bfabric_web_apps/utils/resource_utilities.py +218 -0
- {bfabric_web_apps-0.1.1.dist-info → bfabric_web_apps-0.1.3.dist-info}/METADATA +1 -1
- bfabric_web_apps-0.1.3.dist-info/RECORD +16 -0
- bfabric_web_apps/utils/app_config.py +0 -27
- bfabric_web_apps-0.1.1.dist-info/RECORD +0 -14
- {bfabric_web_apps-0.1.1.dist-info → bfabric_web_apps-0.1.3.dist-info}/LICENSE +0 -0
- {bfabric_web_apps-0.1.1.dist-info → bfabric_web_apps-0.1.3.dist-info}/WHEEL +0 -0
bfabric_web_apps/__init__.py
CHANGED
@@ -1,25 +1,34 @@
|
|
1
|
+
import os
|
2
|
+
|
1
3
|
# Export objects and classes
|
2
4
|
from bfabric_web_apps.objects import BfabricInterface, Logger
|
3
5
|
|
4
6
|
# Export components
|
5
|
-
from .utils
|
7
|
+
from .utils import components
|
6
8
|
|
7
9
|
# Export layouts
|
8
10
|
from .layouts.layouts import get_static_layout
|
9
11
|
|
10
12
|
# Export app initialization utilities
|
11
13
|
from .utils.app_init import create_app
|
12
|
-
from .utils.app_config import load_config
|
13
14
|
from .utils.get_logger import get_logger
|
14
15
|
from .utils.get_power_user_wrapper import get_power_user_wrapper
|
16
|
+
from .utils.create_app_in_bfabric import create_app_in_bfabric
|
15
17
|
|
16
18
|
# Export callbacks
|
17
19
|
from .utils.callbacks import process_url_and_token, submit_bug_report
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
from .utils import defaults
|
22
|
+
|
23
|
+
from bfabric_web_apps.utils.resource_utilities import create_workunit, create_resource
|
24
|
+
HOST = os.getenv("HOST", defaults.HOST)
|
25
|
+
PORT = int(os.getenv("PORT", defaults.PORT)) # Convert to int since env variables are strings
|
26
|
+
DEV = os.getenv("DEV", str(defaults.DEV)).lower() in ["true", "1", "yes"] # Convert to bool
|
27
|
+
CONFIG_FILE_PATH = os.getenv("CONFIG_FILE_PATH", defaults.CONFIG_FILE_PATH)
|
28
|
+
|
29
|
+
DEVELOPER_EMAIL_ADDRESS = os.getenv("DEVELOPER_EMAIL_ADDRESS", defaults.DEVELOPER_EMAIL_ADDRESS)
|
30
|
+
BUG_REPORT_EMAIL_ADDRESS = os.getenv("BUG_REPORT_EMAIL_ADDRESS", defaults.BUG_REPORT_EMAIL_ADDRESS)
|
31
|
+
|
23
32
|
|
24
33
|
# Define __all__ for controlled imports
|
25
34
|
__all__ = [
|
@@ -28,9 +37,64 @@ __all__ = [
|
|
28
37
|
"components",
|
29
38
|
"get_static_layout",
|
30
39
|
"create_app",
|
31
|
-
"load_config",
|
32
40
|
"process_url_and_token",
|
33
41
|
"submit_bug_report",
|
34
42
|
'get_logger',
|
35
|
-
'get_power_user_wrapper'
|
43
|
+
'get_power_user_wrapper',
|
44
|
+
'HOST',
|
45
|
+
'PORT',
|
46
|
+
'DEV',
|
47
|
+
'CONFIG_FILE_PATH',
|
48
|
+
'DEVELOPER_EMAIL_ADDRESS',
|
49
|
+
'BUG_REPORT_EMAIL_ADDRESS',
|
50
|
+
'create_app_in_bfabric',
|
51
|
+
'create_workunit',
|
52
|
+
'create_resource'
|
36
53
|
]
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
'''
|
58
|
+
import os
|
59
|
+
from .utils import defaults
|
60
|
+
|
61
|
+
# Private variable for CONFIG_FILE_PATH
|
62
|
+
_CONFIG_FILE_PATH = os.getenv("CONFIG_FILE_PATH", defaults.CONFIG_FILE_PATH)
|
63
|
+
|
64
|
+
def set_config_file_path(path):
|
65
|
+
"""
|
66
|
+
Setter for the CONFIG_FILE_PATH variable.
|
67
|
+
"""
|
68
|
+
global _CONFIG_FILE_PATH
|
69
|
+
if not isinstance(path, str):
|
70
|
+
raise ValueError("CONFIG_FILE_PATH must be a string.")
|
71
|
+
_CONFIG_FILE_PATH = path
|
72
|
+
|
73
|
+
def get_config_file_path():
|
74
|
+
"""
|
75
|
+
Getter for the CONFIG_FILE_PATH variable.
|
76
|
+
"""
|
77
|
+
return _CONFIG_FILE_PATH
|
78
|
+
|
79
|
+
# Expose CONFIG_FILE_PATH as a read-only property
|
80
|
+
class Config:
|
81
|
+
@property
|
82
|
+
def CONFIG_FILE_PATH(self):
|
83
|
+
return get_config_file_path()
|
84
|
+
|
85
|
+
config = Config()
|
86
|
+
|
87
|
+
'''
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
'''
|
92
|
+
from bfabric import config
|
93
|
+
|
94
|
+
config.CONFIG_FILE_PATH
|
95
|
+
'''
|
96
|
+
|
97
|
+
'''
|
98
|
+
from bfabric import set_config_file_path
|
99
|
+
set_config_file_path("new/path/to/config.json")
|
100
|
+
'''
|
@@ -1,25 +1,38 @@
|
|
1
1
|
from dash import html, dcc
|
2
2
|
import dash_bootstrap_components as dbc
|
3
|
+
import bfabric_web_apps
|
3
4
|
|
4
|
-
def get_static_layout(base_title
|
5
|
+
def get_static_layout(base_title=None, main_content=None, documentation_content=None):
|
5
6
|
"""
|
6
7
|
Returns a layout with static tabs for Main, Documentation, and Report a Bug.
|
7
8
|
The main content is customizable, while the other tabs are generic.
|
9
|
+
|
10
|
+
Args:
|
11
|
+
base_title (str): The main title to be displayed in the banner.
|
12
|
+
main_content (html.Div): Content to be displayed in the "Main" tab.
|
13
|
+
documentation_content (html.Div): Content for the "Documentation" tab.
|
14
|
+
|
15
|
+
Returns:
|
16
|
+
html.Div: The complete static layout of the web app.
|
8
17
|
"""
|
9
18
|
return html.Div(
|
10
19
|
children=[
|
11
20
|
dcc.Location(id='url', refresh=False),
|
12
21
|
dcc.Store(id='token', storage_type='session'),
|
13
22
|
dcc.Store(id='entity', storage_type='session'),
|
23
|
+
dcc.Store(id='app_data', storage_type='session'),
|
14
24
|
dcc.Store(id='token_data', storage_type='session'),
|
25
|
+
dcc.Store(id='dynamic-link-store', storage_type='session'), # Store for dynamic job link
|
26
|
+
|
15
27
|
dbc.Container(
|
16
28
|
children=[
|
17
|
-
# Banner
|
29
|
+
# Banner Section
|
18
30
|
dbc.Row(
|
19
31
|
dbc.Col(
|
20
32
|
html.Div(
|
21
33
|
className="banner",
|
22
34
|
children=[
|
35
|
+
# Title
|
23
36
|
html.Div(
|
24
37
|
children=[
|
25
38
|
html.P(
|
@@ -35,30 +48,70 @@ def get_static_layout(base_title = None, main_content = None, documentation_cont
|
|
35
48
|
)
|
36
49
|
],
|
37
50
|
style={"background-color": "#000000", "border-radius": "10px"}
|
38
|
-
)
|
51
|
+
),
|
52
|
+
],
|
53
|
+
style={"position": "relative", "padding": "10px"}
|
54
|
+
),
|
55
|
+
),
|
56
|
+
),
|
57
|
+
|
58
|
+
# Page Title Section + View Logs Button (Aligned Right)
|
59
|
+
dbc.Row(
|
60
|
+
dbc.Col(
|
61
|
+
html.Div(
|
62
|
+
children=[
|
63
|
+
# Page Title (Aligned Left)
|
64
|
+
html.P(
|
65
|
+
id="page-title",
|
66
|
+
children=[str(" ")],
|
67
|
+
style={"font-size": "40px", "margin-left": "20px", "margin-top": "10px"}
|
68
|
+
),
|
69
|
+
|
70
|
+
# View Logs Button (Aligned Right)
|
71
|
+
html.Div(
|
72
|
+
children=[
|
73
|
+
html.A(
|
74
|
+
dbc.Button(
|
75
|
+
"View Logs",
|
76
|
+
id="dynamic-link-button",
|
77
|
+
color="secondary", # Greyish color
|
78
|
+
style={
|
79
|
+
"font-size": "18px",
|
80
|
+
"padding": "10px 20px",
|
81
|
+
"border-radius": "8px"
|
82
|
+
}
|
83
|
+
),
|
84
|
+
id="dynamic-link",
|
85
|
+
href="#", # Will be dynamically set in the callback
|
86
|
+
target="_blank"
|
87
|
+
)
|
88
|
+
],
|
89
|
+
style={
|
90
|
+
"position": "absolute",
|
91
|
+
"right": "20px",
|
92
|
+
"top": "10px", # Aligns with title
|
93
|
+
}
|
94
|
+
),
|
39
95
|
],
|
96
|
+
style={
|
97
|
+
"position": "relative", # Ensures absolute positioning works
|
98
|
+
"margin-top": "0px",
|
99
|
+
"min-height": "80px",
|
100
|
+
"height": "6vh",
|
101
|
+
"border-bottom": "2px solid #d4d7d9",
|
102
|
+
"display": "flex",
|
103
|
+
"align-items": "center",
|
104
|
+
"justify-content": "space-between", # Title left, button right
|
105
|
+
"padding-right": "20px" # Space between button & right edge
|
106
|
+
}
|
40
107
|
),
|
41
108
|
),
|
42
109
|
),
|
43
|
-
|
110
|
+
|
111
|
+
# Bug Report Alerts (Restored)
|
44
112
|
dbc.Row(
|
45
113
|
dbc.Col(
|
46
114
|
[
|
47
|
-
html.Div(
|
48
|
-
children=[
|
49
|
-
html.P(
|
50
|
-
id="page-title",
|
51
|
-
children=[str(" ")],
|
52
|
-
style={"font-size": "40px", "margin-left": "20px", "margin-top": "10px"}
|
53
|
-
)
|
54
|
-
],
|
55
|
-
style={
|
56
|
-
"margin-top": "0px",
|
57
|
-
"min-height": "80px",
|
58
|
-
"height": "6vh",
|
59
|
-
"border-bottom": "2px solid #d4d7d9"
|
60
|
-
}
|
61
|
-
),
|
62
115
|
dbc.Alert(
|
63
116
|
"Your bug report has been submitted. Thanks for helping us improve!",
|
64
117
|
id="alert-fade-bug-success",
|
@@ -86,7 +139,8 @@ def get_static_layout(base_title = None, main_content = None, documentation_cont
|
|
86
139
|
]
|
87
140
|
)
|
88
141
|
),
|
89
|
-
|
142
|
+
|
143
|
+
# Tabs Section
|
90
144
|
dbc.Tabs(
|
91
145
|
[
|
92
146
|
dbc.Tab(main_content, label="Main", tab_id="main"),
|
@@ -167,8 +221,8 @@ def get_report_bug_tab():
|
|
167
221
|
[
|
168
222
|
"Please use the form below to report a bug. If you have any questions, please email the developer at ",
|
169
223
|
html.A(
|
170
|
-
|
171
|
-
href="mailto:
|
224
|
+
bfabric_web_apps.DEVELOPER_EMAIL_ADDRESS,
|
225
|
+
href=f"mailto:{bfabric_web_apps.DEVELOPER_EMAIL_ADDRESS}",
|
172
226
|
),
|
173
227
|
]
|
174
228
|
),
|
@@ -5,10 +5,10 @@ import datetime
|
|
5
5
|
import bfabric
|
6
6
|
from bfabric import BfabricAuth
|
7
7
|
from bfabric import BfabricClientConfig
|
8
|
-
from
|
9
|
-
import dash_bootstrap_components as dbc
|
10
|
-
from bfabric_web_apps.objects.Logger import Logger
|
8
|
+
from bfabric_web_apps.utils.get_logger import get_logger
|
11
9
|
import os
|
10
|
+
import bfabric_web_apps
|
11
|
+
|
12
12
|
|
13
13
|
|
14
14
|
VALIDATION_URL = "https://fgcz-bfabric.uzh.ch/bfabric/rest/token/validate?token="
|
@@ -16,6 +16,8 @@ HOST = "fgcz-bfabric.uzh.ch"
|
|
16
16
|
|
17
17
|
|
18
18
|
class BfabricInterface( Bfabric ):
|
19
|
+
_instance = None # Singleton instance
|
20
|
+
_wrapper = None # Shared wrapper instance
|
19
21
|
"""
|
20
22
|
A class to interface with the Bfabric API, providing methods to validate tokens,
|
21
23
|
retrieve data, and send bug reports.
|
@@ -27,6 +29,30 @@ class BfabricInterface( Bfabric ):
|
|
27
29
|
"""
|
28
30
|
pass
|
29
31
|
|
32
|
+
def __new__(cls, *args, **kwargs):
|
33
|
+
"""Ensure only one instance exists (Singleton Pattern)."""
|
34
|
+
if cls._instance is None:
|
35
|
+
cls._instance = super(BfabricInterface, cls).__new__(cls)
|
36
|
+
return cls._instance
|
37
|
+
|
38
|
+
def _initialize_wrapper(self, token_data):
|
39
|
+
"""Internal method to initialize the Bfabric wrapper after token validation."""
|
40
|
+
if not token_data:
|
41
|
+
raise ValueError("Token data is required to initialize the wrapper.")
|
42
|
+
|
43
|
+
# Create and store the wrapper
|
44
|
+
if self._wrapper is None:
|
45
|
+
self._wrapper = self.token_response_to_bfabric(token_data)
|
46
|
+
|
47
|
+
|
48
|
+
def get_wrapper(self):
|
49
|
+
"""Return the existing wrapper or raise an error if not initialized."""
|
50
|
+
if self._wrapper is None:
|
51
|
+
raise RuntimeError("Bfabric wrapper is not initialized. Token validation must run first.")
|
52
|
+
return self._wrapper
|
53
|
+
|
54
|
+
|
55
|
+
|
30
56
|
def token_to_data(self, token):
|
31
57
|
"""
|
32
58
|
Validates the given token and retrieves its associated data.
|
@@ -70,6 +96,8 @@ class BfabricInterface( Bfabric ):
|
|
70
96
|
|
71
97
|
environment_dict = {"Production":"https://fgcz-bfabric.uzh.ch/bfabric","Test":"https://fgcz-bfabric-test.uzh.ch/bfabric"}
|
72
98
|
|
99
|
+
print('userinfo', userinfo)
|
100
|
+
|
73
101
|
token_data = dict(
|
74
102
|
environment = userinfo['environment'],
|
75
103
|
user_data = userinfo['user'],
|
@@ -83,6 +111,9 @@ class BfabricInterface( Bfabric ):
|
|
83
111
|
jobId = userinfo['jobId']
|
84
112
|
)
|
85
113
|
|
114
|
+
# Initialize the wrapper right after validating the token
|
115
|
+
self._initialize_wrapper(token_data)
|
116
|
+
|
86
117
|
return json.dumps(token_data)
|
87
118
|
|
88
119
|
|
@@ -110,7 +141,6 @@ class BfabricInterface( Bfabric ):
|
|
110
141
|
|
111
142
|
|
112
143
|
def entity_data(self, token_data: dict) -> str:
|
113
|
-
|
114
144
|
"""
|
115
145
|
Retrieves entity data associated with the provided token.
|
116
146
|
|
@@ -119,7 +149,7 @@ class BfabricInterface( Bfabric ):
|
|
119
149
|
|
120
150
|
Returns:
|
121
151
|
str: A JSON string containing entity data.
|
122
|
-
|
152
|
+
{}: If the retrieval fails or token_data is invalid.
|
123
153
|
"""
|
124
154
|
|
125
155
|
entity_class_map = {
|
@@ -132,24 +162,18 @@ class BfabricInterface( Bfabric ):
|
|
132
162
|
}
|
133
163
|
|
134
164
|
if not token_data:
|
135
|
-
return
|
136
|
-
|
137
|
-
wrapper = self.
|
165
|
+
return json.dumps({})
|
166
|
+
|
167
|
+
wrapper = self.get_wrapper()
|
138
168
|
entity_class = token_data.get('entityClass_data', None)
|
139
169
|
endpoint = entity_class_map.get(entity_class, None)
|
140
170
|
entity_id = token_data.get('entity_id_data', None)
|
141
171
|
jobId = token_data.get('jobId', None)
|
142
172
|
username = token_data.get("user_data", "None")
|
143
|
-
environment= token_data.get("environment", "None")
|
144
|
-
|
173
|
+
environment = token_data.get("environment", "None")
|
145
174
|
|
146
175
|
if wrapper and entity_class and endpoint and entity_id and jobId:
|
147
|
-
|
148
|
-
L = Logger(
|
149
|
-
jobid = jobId,
|
150
|
-
username= username,
|
151
|
-
environment= environment
|
152
|
-
)
|
176
|
+
L = get_logger(token_data)
|
153
177
|
|
154
178
|
# Log the read operation directly using Logger L
|
155
179
|
entity_data_dict = L.logthis(
|
@@ -157,9 +181,10 @@ class BfabricInterface( Bfabric ):
|
|
157
181
|
endpoint=endpoint,
|
158
182
|
obj={"id": entity_id},
|
159
183
|
max_results=None,
|
160
|
-
params
|
161
|
-
flush_logs
|
184
|
+
params=None,
|
185
|
+
flush_logs=True
|
162
186
|
)[0]
|
187
|
+
|
163
188
|
|
164
189
|
if entity_data_dict:
|
165
190
|
json_data = json.dumps({
|
@@ -171,18 +196,86 @@ class BfabricInterface( Bfabric ):
|
|
171
196
|
return json_data
|
172
197
|
else:
|
173
198
|
L.log_operation(
|
174
|
-
operation=
|
175
|
-
message=
|
199
|
+
operation="entity_data",
|
200
|
+
message="Entity data retrieval failed or returned None.",
|
176
201
|
params=None,
|
177
202
|
flush_logs=True
|
178
203
|
)
|
179
204
|
print("entity_data_dict is empty or None")
|
180
|
-
return
|
205
|
+
return json.dumps({})
|
181
206
|
|
182
207
|
else:
|
183
208
|
print("Invalid input or entity information")
|
184
|
-
return
|
209
|
+
return json.dumps({})
|
185
210
|
|
211
|
+
|
212
|
+
def app_data(self, token_data: dict) -> str:
|
213
|
+
"""
|
214
|
+
Retrieves application data (App Name and Description) associated with the provided token.
|
215
|
+
|
216
|
+
Args:
|
217
|
+
token_data (dict): The token data.
|
218
|
+
|
219
|
+
Returns:
|
220
|
+
str: A JSON string containing application data.
|
221
|
+
{}: If retrieval fails or token_data is invalid.
|
222
|
+
"""
|
223
|
+
|
224
|
+
if not token_data:
|
225
|
+
return json.dumps({}) # Return empty JSON if no token data
|
226
|
+
|
227
|
+
# Extract App ID from token
|
228
|
+
app_data_raw = token_data.get("application_data", None)
|
229
|
+
|
230
|
+
try:
|
231
|
+
app_id = int(app_data_raw)
|
232
|
+
except:
|
233
|
+
print("Invalid application_data format in token_data")
|
234
|
+
return json.dumps({}) # Return empty JSON if app_id is invalid
|
235
|
+
|
236
|
+
# Define API endpoint
|
237
|
+
endpoint = "application"
|
238
|
+
|
239
|
+
# Initialize Logger
|
240
|
+
L = get_logger(token_data)
|
241
|
+
|
242
|
+
# Get API wrapper
|
243
|
+
wrapper = self.get_wrapper()
|
244
|
+
if not wrapper:
|
245
|
+
print("Failed to get Bfabric API wrapper")
|
246
|
+
return json.dumps({})
|
247
|
+
|
248
|
+
# Make API Call
|
249
|
+
app_data_dict = L.logthis(
|
250
|
+
api_call=wrapper.read,
|
251
|
+
endpoint=endpoint,
|
252
|
+
obj={"id": app_id}, # Query using the App ID
|
253
|
+
max_results=None,
|
254
|
+
params=None,
|
255
|
+
flush_logs=True
|
256
|
+
)
|
257
|
+
|
258
|
+
# If API call fails, return empty JSON
|
259
|
+
if not app_data_dict or len(app_data_dict) == 0:
|
260
|
+
L.log_operation(
|
261
|
+
operation="app_data",
|
262
|
+
message=f"Failed to retrieve application data for App ID {app_id}",
|
263
|
+
params=None,
|
264
|
+
flush_logs=True
|
265
|
+
)
|
266
|
+
return json.dumps({})
|
267
|
+
|
268
|
+
# Extract App ID, Name, and Description
|
269
|
+
app_info = app_data_dict[0] # First (and only) result
|
270
|
+
print('app_info', app_info)
|
271
|
+
json_data = json.dumps({
|
272
|
+
"id": app_info.get("id", "Unknown"),
|
273
|
+
"name": app_info.get("name", "Unknown"),
|
274
|
+
"description": app_info.get("description", "No description available")
|
275
|
+
})
|
276
|
+
|
277
|
+
return json_data
|
278
|
+
|
186
279
|
|
187
280
|
def send_bug_report(self, token_data = None, entity_data = None, description = None):
|
188
281
|
"""
|
@@ -207,7 +300,7 @@ class BfabricInterface( Bfabric ):
|
|
207
300
|
"""
|
208
301
|
|
209
302
|
mail = f"""
|
210
|
-
echo "{mail_string}" | mail -s "Bug Report"
|
303
|
+
echo "{mail_string}" | mail -s "Bug Report" {bfabric_web_apps.BUG_REPORT_EMAIL_ADDRESS}
|
211
304
|
"""
|
212
305
|
|
213
306
|
print("MAIL STRING:")
|
@@ -220,3 +313,10 @@ class BfabricInterface( Bfabric ):
|
|
220
313
|
|
221
314
|
return True
|
222
315
|
|
316
|
+
|
317
|
+
|
318
|
+
|
319
|
+
# Create a globally accessible instance
|
320
|
+
bfabric_interface = BfabricInterface()
|
321
|
+
|
322
|
+
|
@@ -4,9 +4,8 @@ from typing import List
|
|
4
4
|
from bfabric import Bfabric
|
5
5
|
from datetime import datetime as dt
|
6
6
|
import base64
|
7
|
-
|
7
|
+
import bfabric_web_apps
|
8
8
|
|
9
|
-
CONFIG_FILE_PATH = load_config()["CONFIG_FILE_PATH"]
|
10
9
|
|
11
10
|
class Logger:
|
12
11
|
"""
|
@@ -23,6 +22,7 @@ class Logger:
|
|
23
22
|
"""
|
24
23
|
self.jobid = jobid
|
25
24
|
self.username = username
|
25
|
+
self.config_file_path = bfabric_web_apps.CONFIG_FILE_PATH
|
26
26
|
self.power_user_wrapper = self._get_power_user_wrapper(environment)
|
27
27
|
self.logs = []
|
28
28
|
|
@@ -37,7 +37,7 @@ class Logger:
|
|
37
37
|
Bfabric: An authenticated Bfabric instance.
|
38
38
|
"""
|
39
39
|
power_user_wrapper = Bfabric.from_config(
|
40
|
-
config_path = os.path.expanduser(
|
40
|
+
config_path = os.path.expanduser(self.config_file_path),
|
41
41
|
config_env = environment.upper()
|
42
42
|
)
|
43
43
|
return power_user_wrapper
|
@@ -2,25 +2,30 @@ from dash import Input, Output, State, html, dcc
|
|
2
2
|
from bfabric_web_apps.objects.BfabricInterface import BfabricInterface
|
3
3
|
import json
|
4
4
|
import dash_bootstrap_components as dbc
|
5
|
-
from bfabric_web_apps.objects.Logger import Logger
|
6
5
|
from datetime import datetime as dt
|
6
|
+
from bfabric_web_apps.utils.get_logger import get_logger
|
7
7
|
|
8
8
|
def process_url_and_token(url_params):
|
9
9
|
"""
|
10
10
|
Processes URL parameters to extract the token, validates it, and retrieves the corresponding data.
|
11
|
+
Additionally, it constructs a dynamic job link based on the environment and job ID.
|
11
12
|
|
12
13
|
Args:
|
13
14
|
url_params (str): The URL parameters containing the token.
|
14
|
-
base_title (str): The base title of the page.
|
15
15
|
|
16
16
|
Returns:
|
17
|
-
tuple: A tuple containing
|
18
|
-
|
17
|
+
tuple: A tuple containing:
|
18
|
+
- token (str): Authentication token.
|
19
|
+
- token_data (dict): Token metadata.
|
20
|
+
- entity_data (dict): Retrieved entity information.
|
21
|
+
- page_title (str): Title for the page header.
|
22
|
+
- session_details (list): HTML-formatted session details.
|
23
|
+
- job_link (str): Dynamically generated link to the job page.
|
19
24
|
"""
|
20
25
|
base_title = " "
|
21
26
|
|
22
27
|
if not url_params:
|
23
|
-
return None, None, None, base_title, None
|
28
|
+
return None, None, None, None, base_title, None, None
|
24
29
|
|
25
30
|
token = "".join(url_params.split('token=')[1:])
|
26
31
|
bfabric_interface = BfabricInterface()
|
@@ -28,43 +33,60 @@ def process_url_and_token(url_params):
|
|
28
33
|
|
29
34
|
if tdata_raw:
|
30
35
|
if tdata_raw == "EXPIRED":
|
31
|
-
return None, None, None, base_title, None
|
36
|
+
return None, None, None, None, base_title, None, None
|
32
37
|
else:
|
33
38
|
tdata = json.loads(tdata_raw)
|
34
39
|
else:
|
35
|
-
return None, None, None, base_title, None
|
40
|
+
return None, None, None, None, base_title, None, None
|
36
41
|
|
37
42
|
if tdata:
|
38
43
|
entity_data_json = bfabric_interface.entity_data(tdata)
|
44
|
+
app_data_json = bfabric_interface.app_data(tdata)
|
39
45
|
entity_data = json.loads(entity_data_json)
|
46
|
+
app_data = json.loads(app_data_json)
|
40
47
|
page_title = (
|
41
|
-
f"{tdata
|
42
|
-
f"({tdata
|
48
|
+
f"{tdata.get('entityClass_data', 'Unknown')} - {entity_data.get('name', 'Unknown')} "
|
49
|
+
f"({tdata.get('environment', 'Unknown')} System)"
|
43
50
|
) if tdata else "Bfabric App Interface"
|
44
51
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
52
|
+
environment = tdata.get("environment", "").strip().lower() # 'test' or 'prod'
|
53
|
+
job_id = tdata.get("jobId", None) # Extract job ID
|
54
|
+
|
55
|
+
job_link = None
|
56
|
+
if job_id:
|
57
|
+
if "test" in environment:
|
58
|
+
job_link = f"https://fgcz-bfabric-test.uzh.ch/bfabric/job/show.html?id={job_id}&tab=details"
|
59
|
+
else:
|
60
|
+
job_link = f"https://fgcz-bfabric.uzh.ch/bfabric/job/show.html?id={job_id}&tab=details"
|
61
|
+
|
62
|
+
session_details = [
|
49
63
|
html.P([
|
50
|
-
html.B("Entity Name: "), entity_data
|
64
|
+
html.B("Entity Name: "), entity_data.get('name', 'Unknown'),
|
65
|
+
html.Br(),
|
66
|
+
html.B("Entity Class: "), tdata.get('entityClass_data', 'Unknown'),
|
51
67
|
html.Br(),
|
52
|
-
html.B("
|
68
|
+
html.B("Environment: "), tdata.get('environment', 'Unknown'),
|
53
69
|
html.Br(),
|
54
|
-
html.B("
|
70
|
+
html.B("Entity ID: "), tdata.get('entity_id_data', 'Unknown'),
|
55
71
|
html.Br(),
|
56
|
-
html.B("
|
72
|
+
html.B("Job ID: "), job_id if job_id else "Unknown",
|
57
73
|
html.Br(),
|
58
|
-
html.B("User Name: "), tdata
|
74
|
+
html.B("User Name: "), tdata.get('user_data', 'Unknown'),
|
59
75
|
html.Br(),
|
60
|
-
html.B("Session Expires: "), tdata
|
76
|
+
html.B("Session Expires: "), tdata.get('token_expires', 'Unknown'),
|
77
|
+
html.Br(),
|
78
|
+
html.B("App Name: "), app_data.get("name", "Unknown"),
|
79
|
+
html.Br(),
|
80
|
+
html.B("App Description: "), app_data.get("description", "No description available"),
|
61
81
|
html.Br(),
|
62
82
|
html.B("Current Time: "), str(dt.now().strftime("%Y-%m-%d %H:%M:%S"))
|
63
83
|
])
|
64
84
|
]
|
65
|
-
|
85
|
+
|
86
|
+
return token, tdata, entity_data, app_data, page_title, session_details, job_link
|
66
87
|
else:
|
67
|
-
return None, None, None, base_title, None
|
88
|
+
return None, None, None, None, base_title, None, None
|
89
|
+
|
68
90
|
|
69
91
|
|
70
92
|
def submit_bug_report(n_clicks, bug_description, token, entity_data):
|
@@ -100,11 +122,7 @@ def submit_bug_report(n_clicks, bug_description, token, entity_data):
|
|
100
122
|
# Initialize the logger only if token_data is available
|
101
123
|
L = None
|
102
124
|
if token_data:
|
103
|
-
L =
|
104
|
-
jobid=jobId,
|
105
|
-
username=username,
|
106
|
-
environment=environment
|
107
|
-
)
|
125
|
+
L = get_logger(token_data)
|
108
126
|
|
109
127
|
if n_clicks:
|
110
128
|
# Log the operation only if the logger is initialized
|
@@ -0,0 +1,86 @@
|
|
1
|
+
from bfabric import Bfabric
|
2
|
+
|
3
|
+
def get_user_input():
|
4
|
+
"""Prompt user for necessary inputs."""
|
5
|
+
|
6
|
+
systems = {"TEST": "TEST", "PROD": "PRODUCTION"}
|
7
|
+
|
8
|
+
technologies = {
|
9
|
+
"TEST": {
|
10
|
+
"1": "Genomics / Transcriptomics",
|
11
|
+
"2": "Proteomics",
|
12
|
+
"4": "Metabolomics / Biophysics",
|
13
|
+
"6": "General",
|
14
|
+
"10": "New Tech"
|
15
|
+
},
|
16
|
+
"PRODUCTION": {
|
17
|
+
"1": "Genomics / Transcriptomics",
|
18
|
+
"2": "Proteomics",
|
19
|
+
"4": "Metabolomics / Biophysics",
|
20
|
+
"6": "General",
|
21
|
+
"10": "Bioinformatics"
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
# Get system input
|
26
|
+
system = input("In which system do you want to create the app? (Type 'TEST' for the test system or 'PROD' for the production system): ").strip().upper()
|
27
|
+
|
28
|
+
while system not in systems:
|
29
|
+
print("Invalid input! Please enter 'TEST' or 'PROD'.")
|
30
|
+
system = input("Enter system (TEST/PROD): ").strip().upper()
|
31
|
+
|
32
|
+
selected_system = systems[system] # Map input to full system name
|
33
|
+
|
34
|
+
# Display technology options based on selected system
|
35
|
+
print("\nAvailable Technologies:")
|
36
|
+
for key, value in technologies[selected_system].items():
|
37
|
+
print(f"{key}: {value}")
|
38
|
+
|
39
|
+
# Get technology ID from user
|
40
|
+
technologyid = input("\nEnter the number corresponding to your chosen application type: ").strip()
|
41
|
+
|
42
|
+
while technologyid not in technologies[selected_system]:
|
43
|
+
print("Invalid technology ID! Please select a valid number from the list.")
|
44
|
+
technologyid = input("Enter a valid technology ID: ").strip()
|
45
|
+
|
46
|
+
# Get remaining inputs
|
47
|
+
name = input("Enter app name: ")
|
48
|
+
weburl = input("Enter web URL: ")
|
49
|
+
description = input("Enter description: ")
|
50
|
+
|
51
|
+
return {
|
52
|
+
"system": selected_system,
|
53
|
+
"name": name,
|
54
|
+
"weburl": weburl,
|
55
|
+
"type": "WebApp",
|
56
|
+
"technologyid": technologyid,
|
57
|
+
"supervisorid": "2446",
|
58
|
+
"enabled": True,
|
59
|
+
"valid": True,
|
60
|
+
"hidden": False,
|
61
|
+
"description": description
|
62
|
+
}
|
63
|
+
|
64
|
+
def create_app_in_bfabric():
|
65
|
+
"""Create an app in B-Fabric using user inputs."""
|
66
|
+
# Get user input for parameters
|
67
|
+
user_input = get_user_input()
|
68
|
+
|
69
|
+
# Determine configuration environment based on user input
|
70
|
+
config_env = user_input.pop("system")
|
71
|
+
|
72
|
+
# Initialize Bfabric instance
|
73
|
+
bfabric = Bfabric.from_config(config_env=config_env)
|
74
|
+
|
75
|
+
# Set endpoint for app creation
|
76
|
+
endpoint = "application"
|
77
|
+
|
78
|
+
# Make API call to save the app
|
79
|
+
try:
|
80
|
+
result = bfabric.save(endpoint=endpoint, obj=user_input)
|
81
|
+
print("App created successfully:", result)
|
82
|
+
except Exception as e:
|
83
|
+
print("Failed to create app:", str(e))
|
84
|
+
|
85
|
+
if __name__ == "__main__":
|
86
|
+
create_app_in_bfabric()
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# defaults.py
|
2
|
+
CONFIG_FILE_PATH = "~/.bfabricpy.yml"
|
3
|
+
|
4
|
+
# Default values for application settings
|
5
|
+
HOST = "0.0.0.0"
|
6
|
+
PORT = 8050
|
7
|
+
DEV = False
|
8
|
+
|
9
|
+
# Developer and bug report email addresses
|
10
|
+
DEVELOPER_EMAIL_ADDRESS = "griffin@gwcustom.com"
|
11
|
+
BUG_REPORT_EMAIL_ADDRESS = "gwtools@fgcz.system"
|
@@ -1,8 +1,6 @@
|
|
1
1
|
import os
|
2
2
|
from bfabric import Bfabric
|
3
|
-
|
4
|
-
|
5
|
-
CONFIG_FILE_PATH = load_config()["CONFIG_FILE_PATH"]
|
3
|
+
import bfabric_web_apps
|
6
4
|
|
7
5
|
def get_power_user_wrapper(token_data):
|
8
6
|
"""
|
@@ -13,7 +11,7 @@ def get_power_user_wrapper(token_data):
|
|
13
11
|
determined by the `CONFIG_FILE_PATH` from the application's configuration.
|
14
12
|
|
15
13
|
Args:
|
16
|
-
token_data (dict): A dictionary containing token information
|
14
|
+
token_data (dict): A dictionary containing token information
|
17
15
|
The key "environment" is used to determine the environment
|
18
16
|
(default is "None" if not specified).
|
19
17
|
|
@@ -24,6 +22,6 @@ def get_power_user_wrapper(token_data):
|
|
24
22
|
environment = token_data.get("environment", "None")
|
25
23
|
|
26
24
|
return Bfabric.from_config(
|
27
|
-
config_path = os.path.expanduser(CONFIG_FILE_PATH),
|
25
|
+
config_path = os.path.expanduser(bfabric_web_apps.CONFIG_FILE_PATH),
|
28
26
|
config_env = environment.upper()
|
29
27
|
)
|
@@ -0,0 +1,218 @@
|
|
1
|
+
from bfabric_web_apps.utils.get_logger import get_logger
|
2
|
+
from bfabric_web_apps.objects.BfabricInterface import bfabric_interface
|
3
|
+
from bfabric_web_apps.utils.get_power_user_wrapper import get_power_user_wrapper
|
4
|
+
from bfabric_scripts.bfabric_upload_resource import bfabric_upload_resource
|
5
|
+
from pathlib import Path
|
6
|
+
|
7
|
+
def create_workunit(token_data, application_name, application_description, application_id, container_ids):
|
8
|
+
"""
|
9
|
+
Create a new workunit in B-Fabric for each container ID.
|
10
|
+
|
11
|
+
Args:
|
12
|
+
token_data (dict): Authentication token data.
|
13
|
+
application_name (str): Name of the application.
|
14
|
+
application_description (str): Description of the application.
|
15
|
+
application_id (int): Application ID.
|
16
|
+
container_ids (list): List of container IDs.
|
17
|
+
|
18
|
+
Returns:
|
19
|
+
list: List of created workunit IDs.
|
20
|
+
"""
|
21
|
+
L = get_logger(token_data)
|
22
|
+
wrapper = bfabric_interface.get_wrapper()
|
23
|
+
workunit_ids = []
|
24
|
+
|
25
|
+
# Ensure container_ids is a list
|
26
|
+
if not isinstance(container_ids, list):
|
27
|
+
container_ids = [container_ids] # Convert to list if single value
|
28
|
+
|
29
|
+
for container_id in container_ids:
|
30
|
+
workunit_data = {
|
31
|
+
"name": f"{application_name} - Order {container_id}",
|
32
|
+
"description": f"{application_description} for Order {container_id}",
|
33
|
+
"applicationid": int(application_id),
|
34
|
+
"containerid": container_id, # Assigning order ID dynamically
|
35
|
+
}
|
36
|
+
|
37
|
+
try:
|
38
|
+
workunit_response = L.logthis(
|
39
|
+
api_call=wrapper.save,
|
40
|
+
endpoint="workunit",
|
41
|
+
obj=workunit_data,
|
42
|
+
params=None,
|
43
|
+
flush_logs=True
|
44
|
+
)
|
45
|
+
workunit_id = workunit_response[0].get("id")
|
46
|
+
print(f"Created Workunit ID: {workunit_id} for Order ID: {container_id}")
|
47
|
+
workunit_ids.append(workunit_id)
|
48
|
+
|
49
|
+
except Exception as e:
|
50
|
+
L.log_operation(
|
51
|
+
"Error",
|
52
|
+
f"Failed to create workunit for Order {container_id}: {e}",
|
53
|
+
params=None,
|
54
|
+
flush_logs=True,
|
55
|
+
)
|
56
|
+
print(f"Failed to create workunit for Order {container_id}: {e}")
|
57
|
+
|
58
|
+
return workunit_ids # Returning a list of all created workunits
|
59
|
+
|
60
|
+
|
61
|
+
def create_resource(token_data, workunit_id, gz_file_path):
|
62
|
+
"""
|
63
|
+
Upload a .gz resource to an existing B-Fabric workunit.
|
64
|
+
|
65
|
+
Args:
|
66
|
+
token_data (dict): Authentication token data.
|
67
|
+
workunit_id (int): ID of the workunit to associate the resource with.
|
68
|
+
gz_file_path (str): Full path to the .gz file to upload.
|
69
|
+
|
70
|
+
Returns:
|
71
|
+
int: Resource ID if successful, None otherwise.
|
72
|
+
"""
|
73
|
+
L = get_logger(token_data)
|
74
|
+
wrapper = get_power_user_wrapper(token_data)
|
75
|
+
|
76
|
+
try:
|
77
|
+
file_path = Path(gz_file_path)
|
78
|
+
|
79
|
+
# Use the proper upload function
|
80
|
+
print("test", wrapper, file_path, workunit_id)
|
81
|
+
result = bfabric_upload_resource(wrapper, file_path, workunit_id)
|
82
|
+
|
83
|
+
if result:
|
84
|
+
print(f"Resource uploaded: {file_path.name}")
|
85
|
+
L.log_operation(
|
86
|
+
"upload_resource",
|
87
|
+
f"Resource uploaded successfully: {file_path.name}",
|
88
|
+
params=None,
|
89
|
+
flush_logs=True,
|
90
|
+
)
|
91
|
+
return result
|
92
|
+
else:
|
93
|
+
raise ValueError(f"Failed to upload resource: {file_path.name}")
|
94
|
+
|
95
|
+
except Exception as e:
|
96
|
+
L.log_operation(
|
97
|
+
"error",
|
98
|
+
f"Failed to upload resource: {e}",
|
99
|
+
params=None,
|
100
|
+
flush_logs=True,
|
101
|
+
)
|
102
|
+
print(f"Failed to upload resource: {e}")
|
103
|
+
return None
|
104
|
+
|
105
|
+
|
106
|
+
|
107
|
+
'''
|
108
|
+
|
109
|
+
|
110
|
+
|
111
|
+
# Upload a resource to the created workunit
|
112
|
+
resource_name = "example_resource.txt"
|
113
|
+
resource_content = b"This is an example resource content."
|
114
|
+
|
115
|
+
try:
|
116
|
+
resource_response = bfabric.upload_resource(
|
117
|
+
resource_name=resource_name,
|
118
|
+
content=resource_content,
|
119
|
+
workunit_id=workunit_id
|
120
|
+
)
|
121
|
+
print(f"Resource '{resource_name}' uploaded successfully.")
|
122
|
+
except Exception as e:
|
123
|
+
print(f"Failed to upload resource: {e}")
|
124
|
+
exit(1)
|
125
|
+
|
126
|
+
|
127
|
+
|
128
|
+
|
129
|
+
|
130
|
+
|
131
|
+
|
132
|
+
|
133
|
+
|
134
|
+
import subprocess
|
135
|
+
from zeep import Client
|
136
|
+
import os
|
137
|
+
from bfabric_web_apps.utils.get_logger import get_logger
|
138
|
+
|
139
|
+
BFABRIC_WORKUNIT_WSDL = "https://fgcz-bfabric-test.uzh.ch:443/bfabric/workunit?wsdl"
|
140
|
+
BFABRIC_RESOURCE_WSDL = "https://fgcz-bfabric-test.uzh.ch:443/bfabric/resource?wsdl"
|
141
|
+
|
142
|
+
def run_pipeline_and_register_in_bfabric(run_name: str, output_dir: str):
|
143
|
+
"""
|
144
|
+
Startet die Nextflow-Pipeline und speichert die Ergebnisse in B-Fabric.
|
145
|
+
|
146
|
+
:param run_name: Name des Sequenzierungslaufs
|
147
|
+
:param output_dir: Verzeichnis, in dem die FASTQ-Dateien gespeichert werden
|
148
|
+
"""
|
149
|
+
print(f"[INFO] Starte Nextflow-Pipeline für {run_name}...")
|
150
|
+
|
151
|
+
# Nextflow Pipeline starten
|
152
|
+
process = subprocess.run([
|
153
|
+
"nextflow", "run", "nf-core/bclconvert",
|
154
|
+
"-profile", "docker",
|
155
|
+
"--outdir", output_dir,
|
156
|
+
"-resume"
|
157
|
+
], capture_output=True, text=True)
|
158
|
+
|
159
|
+
if process.returncode != 0:
|
160
|
+
print(f"[ERROR] Nextflow Pipeline fehlgeschlagen: {process.stderr}")
|
161
|
+
return False
|
162
|
+
|
163
|
+
print(f"[INFO] Pipeline abgeschlossen. Ergebnisse werden registriert...")
|
164
|
+
|
165
|
+
# Workunit in B-Fabric anlegen
|
166
|
+
workunit_id = create_bfabric_workunit(run_name)
|
167
|
+
|
168
|
+
# Falls Workunit erfolgreich erstellt, dann Ressourcen speichern
|
169
|
+
if workunit_id:
|
170
|
+
register_fastq_files_in_bfabric(output_dir, workunit_id)
|
171
|
+
else:
|
172
|
+
print("[ERROR] Konnte Workunit nicht in B-Fabric registrieren!")
|
173
|
+
|
174
|
+
return True
|
175
|
+
|
176
|
+
def create_bfabric_workunit(run_name: str):
|
177
|
+
"""Erstellt eine Workunit in B-Fabric."""
|
178
|
+
try:
|
179
|
+
client = Client(BFABRIC_WORKUNIT_WSDL)
|
180
|
+
workunit_data = {
|
181
|
+
"name": run_name,
|
182
|
+
"description": "Illumina BCL zu FASTQ Konvertierung",
|
183
|
+
"status": "Completed"
|
184
|
+
}
|
185
|
+
L = get_logger({})
|
186
|
+
response = L.logthis(
|
187
|
+
api_call=client.service.createWorkunit,
|
188
|
+
obj=workunit_data
|
189
|
+
)[0]
|
190
|
+
print(f"[INFO] Workunit erstellt mit ID: {response}")
|
191
|
+
return response
|
192
|
+
except Exception as e:
|
193
|
+
print(f"[ERROR] Fehler beim Erstellen der Workunit: {e}")
|
194
|
+
return None
|
195
|
+
|
196
|
+
def register_fastq_files_in_bfabric(output_dir: str, workunit_id: int):
|
197
|
+
"""Registriert alle FASTQ-Dateien aus dem Output-Verzeichnis in B-Fabric."""
|
198
|
+
try:
|
199
|
+
client = Client(BFABRIC_RESOURCE_WSDL)
|
200
|
+
L = get_logger({})
|
201
|
+
for file_name in os.listdir(output_dir):
|
202
|
+
if file_name.endswith(".fastq.gz"):
|
203
|
+
file_path = os.path.join(output_dir, file_name)
|
204
|
+
resource_data = {
|
205
|
+
"name": file_name,
|
206
|
+
"description": "Erzeugt von nf-core/bclconvert",
|
207
|
+
"path": file_path,
|
208
|
+
"type": "FASTQ",
|
209
|
+
"workunitId": workunit_id
|
210
|
+
}
|
211
|
+
response = L.logthis(
|
212
|
+
api_call=client.service.createResource,
|
213
|
+
obj=resource_data
|
214
|
+
)[0]
|
215
|
+
print(f"[INFO] Ressource gespeichert mit ID: {response}")
|
216
|
+
except Exception as e:
|
217
|
+
print(f"[ERROR] Fehler beim Registrieren der Ressourcen: {e}")
|
218
|
+
'''
|
@@ -0,0 +1,16 @@
|
|
1
|
+
bfabric_web_apps/__init__.py,sha256=xqh-kddXaV4xblnMcDA73bTuy3zn5viucueuuIx41HM,2495
|
2
|
+
bfabric_web_apps/layouts/layouts.py,sha256=XoSLcQPcgMBhQz2VfxkUzNL23FLBXFRFvbCL2mNLfnk,11636
|
3
|
+
bfabric_web_apps/objects/BfabricInterface.py,sha256=YC6VimARZfG2t90TK5xhQDsNzgMNljwqbCOT8Qz_Uhs,10247
|
4
|
+
bfabric_web_apps/objects/Logger.py,sha256=62LC94xhm7YG5LUw3yH46NqvJQsAX7wnc9D4zbY16rA,5224
|
5
|
+
bfabric_web_apps/utils/app_init.py,sha256=RCdpCXp19cF74bouYJLPe-KSETZ0Vwqtd02Ta2VXEF8,428
|
6
|
+
bfabric_web_apps/utils/callbacks.py,sha256=PiP1ZJ-QxdrOAZ-Mt-MN-g9wJLSOoLkWkXwPq_TLqDI,6472
|
7
|
+
bfabric_web_apps/utils/components.py,sha256=V7ECGmF2XYy5O9ciDJVH1nofJYP2a_ELQF3z3X_ADbo,844
|
8
|
+
bfabric_web_apps/utils/create_app_in_bfabric.py,sha256=eVk3cQDXxW-yo9b9n_zzGO6kLg_SLxYbIDECyvEPJXU,2752
|
9
|
+
bfabric_web_apps/utils/defaults.py,sha256=B82j3JEbysLEU9JDZgoDBTX7WGvW3Hn5YMZaWAcjZew,278
|
10
|
+
bfabric_web_apps/utils/get_logger.py,sha256=0Y3SrXW93--eglS0_ZOc34NOriAt6buFPik5n0ltzRA,434
|
11
|
+
bfabric_web_apps/utils/get_power_user_wrapper.py,sha256=T33z64XjmJ0KSlmfEmrEP8eYpbpINCVD6Xld_V7PR2g,1027
|
12
|
+
bfabric_web_apps/utils/resource_utilities.py,sha256=AVaqIXEfmCdWZfXDt32QfkZ9ChTL8D8cm1lCHXfT4Nc,7317
|
13
|
+
bfabric_web_apps-0.1.3.dist-info/LICENSE,sha256=k0O_i2k13i9e35aO-j7FerJafAqzzu8x0kkBs0OWF3c,1065
|
14
|
+
bfabric_web_apps-0.1.3.dist-info/METADATA,sha256=gTd86dYPrHKfypKFPry0SKjYtydW1z17fA-tSxz8vuM,480
|
15
|
+
bfabric_web_apps-0.1.3.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
|
16
|
+
bfabric_web_apps-0.1.3.dist-info/RECORD,,
|
@@ -1,27 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
import importlib.util
|
3
|
-
|
4
|
-
def load_config(params_path="./PARAMS.py"):
|
5
|
-
"""Load configuration for the Dash app."""
|
6
|
-
if os.path.exists(params_path):
|
7
|
-
try:
|
8
|
-
# Dynamically import the PARAMS module
|
9
|
-
spec = importlib.util.spec_from_file_location("PARAMS", params_path)
|
10
|
-
params_module = importlib.util.module_from_spec(spec)
|
11
|
-
spec.loader.exec_module(params_module)
|
12
|
-
|
13
|
-
# Retrieve values with defaults
|
14
|
-
PORT = getattr(params_module, "PORT", 8050)
|
15
|
-
HOST = getattr(params_module, "HOST", "localhost")
|
16
|
-
DEV = getattr(params_module, "DEV", True)
|
17
|
-
CONFIG_FILE_PATH = getattr(params_module, "CONFIG_FILE_PATH", "~/.bfabricpy.yml")
|
18
|
-
except ImportError:
|
19
|
-
# Fallback to default values in case of import errors
|
20
|
-
PORT, HOST, DEV = 8050, 'localhost', True
|
21
|
-
CONFIG_FILE_PATH = "~/.bfabricpy.yml"
|
22
|
-
else:
|
23
|
-
# Fallback to default values if PARAMS.py is not found
|
24
|
-
PORT, HOST, DEV = 8050, 'localhost', True
|
25
|
-
CONFIG_FILE_PATH = "~/.bfabricpy.yml"
|
26
|
-
|
27
|
-
return {"PORT": PORT, "HOST": HOST, "DEV": DEV, "CONFIG_FILE_PATH": CONFIG_FILE_PATH}
|
@@ -1,14 +0,0 @@
|
|
1
|
-
bfabric_web_apps/__init__.py,sha256=XDzAg0boEE3nj3RXGB85YbVc0KgEeRNOcQfrSkJoV-0,880
|
2
|
-
bfabric_web_apps/layouts/layouts.py,sha256=oQHfT65PdoFU5js8JkEJqFhxfgNjwU0GRvD1xbkfYD4,8758
|
3
|
-
bfabric_web_apps/objects/BfabricInterface.py,sha256=pHse1UgC_XFD-PsYqOs0Ho3xTRMDRCvtRgsILVYy-0k,6919
|
4
|
-
bfabric_web_apps/objects/Logger.py,sha256=ikMJJZYDPhJZEmgCY63_htGmPvXv1ItSmfb_xiFFZMQ,5225
|
5
|
-
bfabric_web_apps/utils/app_config.py,sha256=u7lz8sonf9CSkJsVK0nhTzIls227FksGCOb_SzYE_fE,1204
|
6
|
-
bfabric_web_apps/utils/app_init.py,sha256=RCdpCXp19cF74bouYJLPe-KSETZ0Vwqtd02Ta2VXEF8,428
|
7
|
-
bfabric_web_apps/utils/callbacks.py,sha256=OlNelwAJUKsEtnaJ4OuTdrgyu9PhEgm4uqCde4NNKHA,5270
|
8
|
-
bfabric_web_apps/utils/components.py,sha256=V7ECGmF2XYy5O9ciDJVH1nofJYP2a_ELQF3z3X_ADbo,844
|
9
|
-
bfabric_web_apps/utils/get_logger.py,sha256=_cn0en-itaGEeeCDtws-nw2ubd36w2xc6VfDNoBMFu4,433
|
10
|
-
bfabric_web_apps/utils/get_power_user_wrapper.py,sha256=ZUrv-xNLEXtMVeFEpAwmPbPFUmcAxu3hITIuPY2dhF8,1078
|
11
|
-
bfabric_web_apps-0.1.1.dist-info/LICENSE,sha256=k0O_i2k13i9e35aO-j7FerJafAqzzu8x0kkBs0OWF3c,1065
|
12
|
-
bfabric_web_apps-0.1.1.dist-info/METADATA,sha256=R1zgL1bVK18CV4uPQc1vUABgBnOn6us0YBbcC6yqy0g,480
|
13
|
-
bfabric_web_apps-0.1.1.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
|
14
|
-
bfabric_web_apps-0.1.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|