bfabric-web-apps 0.1.6__py3-none-any.whl → 0.1.7__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 +5 -2
- bfabric_web_apps/objects/BfabricInterface.py +1 -1
- bfabric_web_apps/utils/callbacks.py +1 -1
- bfabric_web_apps/utils/charging.py +40 -0
- bfabric_web_apps/utils/components.py +7 -1
- bfabric_web_apps/utils/config.py +3 -0
- bfabric_web_apps/utils/run_main_pipeline.py +54 -12
- {bfabric_web_apps-0.1.6.dist-info → bfabric_web_apps-0.1.7.dist-info}/METADATA +2 -1
- {bfabric_web_apps-0.1.6.dist-info → bfabric_web_apps-0.1.7.dist-info}/RECORD +11 -10
- {bfabric_web_apps-0.1.6.dist-info → bfabric_web_apps-0.1.7.dist-info}/LICENSE +0 -0
- {bfabric_web_apps-0.1.6.dist-info → bfabric_web_apps-0.1.7.dist-info}/WHEEL +0 -0
bfabric_web_apps/__init__.py
CHANGED
@@ -25,7 +25,7 @@ from .utils.callbacks import (
|
|
25
25
|
|
26
26
|
from .utils.config import settings as config
|
27
27
|
|
28
|
-
from. utils.run_main_pipeline import run_main_job
|
28
|
+
from. utils.run_main_pipeline import run_main_job, read_file_as_bytes
|
29
29
|
|
30
30
|
from .utils.resource_utilities import (
|
31
31
|
create_workunit,
|
@@ -34,6 +34,7 @@ from .utils.resource_utilities import (
|
|
34
34
|
create_resources
|
35
35
|
)
|
36
36
|
|
37
|
+
from .utils.charging import create_charge
|
37
38
|
from .utils.redis_worker_init import run_worker, test_job
|
38
39
|
from .utils.redis_queue import q
|
39
40
|
|
@@ -54,4 +55,6 @@ GSTORE_REMOTE_PATH = config.GSTORE_REMOTE_PATH
|
|
54
55
|
SCRATCH_PATH = config.SCRATCH_PATH
|
55
56
|
TRX_LOGIN = config.TRX_LOGIN
|
56
57
|
TRX_SSH_KEY = config.TRX_SSH_KEY
|
57
|
-
URL = config.URL
|
58
|
+
URL = config.URL
|
59
|
+
|
60
|
+
SERVICE_ID = config.SERVICE_ID
|
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
from bfabric_web_apps.utils.get_logger import get_logger
|
3
|
+
from bfabric_web_apps.utils.get_power_user_wrapper import get_power_user_wrapper
|
4
|
+
|
5
|
+
def create_charge(token_data, container_id, service_id):
|
6
|
+
"""
|
7
|
+
Create a charge in B-Fabric.
|
8
|
+
|
9
|
+
Args:
|
10
|
+
token_data (dict): Authentication token data.
|
11
|
+
container_id (int): Container ID (Order ID).
|
12
|
+
service_id (int): Service ID.
|
13
|
+
|
14
|
+
Returns:
|
15
|
+
list[dict]: List of charge data.
|
16
|
+
"""
|
17
|
+
|
18
|
+
# Get a logger and an api wrapper
|
19
|
+
L = get_logger(token_data)
|
20
|
+
wrapper = get_power_user_wrapper(token_data)
|
21
|
+
|
22
|
+
# Get the user ID from the token data to assign a charger
|
23
|
+
usr_id = wrapper.read("user", {"login": token_data.get("user_data")})[0]['id']
|
24
|
+
|
25
|
+
charge_data = {
|
26
|
+
"serviceid": service_id,
|
27
|
+
"containerid": container_id,
|
28
|
+
"chargerid": usr_id
|
29
|
+
}
|
30
|
+
|
31
|
+
# Create and log the charge
|
32
|
+
charge = L.logthis(
|
33
|
+
api_call=wrapper.save,
|
34
|
+
endpoint="charge",
|
35
|
+
obj=charge_data,
|
36
|
+
params=None,
|
37
|
+
flush_logs=True
|
38
|
+
)
|
39
|
+
|
40
|
+
return charge
|
@@ -1,4 +1,5 @@
|
|
1
1
|
from dash import html
|
2
|
+
import dash_daq as daq
|
2
3
|
|
3
4
|
DEVELOPER_EMAIL = "gwhite@fgcz.ethz.ch"
|
4
5
|
|
@@ -19,4 +20,9 @@ auth = [html.Div(id="auth-div")]
|
|
19
20
|
no_auth = [
|
20
21
|
html.P("You are not currently logged into an active session. Please log into bfabric to continue:"),
|
21
22
|
html.A('Login to Bfabric', href='https://fgcz-bfabric.uzh.ch/bfabric/')
|
22
|
-
]
|
23
|
+
]
|
24
|
+
|
25
|
+
charge_switch = [
|
26
|
+
daq.BooleanSwitch(id='charge_run', on=True, label="Charge project for run"),
|
27
|
+
html.Br()
|
28
|
+
]
|
bfabric_web_apps/utils/config.py
CHANGED
@@ -16,6 +16,8 @@ from .resource_utilities import (
|
|
16
16
|
create_resources
|
17
17
|
)
|
18
18
|
|
19
|
+
from .charging import create_charge
|
20
|
+
|
19
21
|
from .config import settings as config
|
20
22
|
from datetime import datetime as dt
|
21
23
|
|
@@ -25,11 +27,15 @@ TRX_LOGIN = config.TRX_LOGIN
|
|
25
27
|
TRX_SSH_KEY = config.TRX_SSH_KEY
|
26
28
|
URL = config.URL
|
27
29
|
|
28
|
-
def run_main_job(
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
def run_main_job(
|
31
|
+
files_as_byte_strings: dict,
|
32
|
+
bash_commands: list[str],
|
33
|
+
resource_paths: dict,
|
34
|
+
attachment_paths: list[dict],
|
35
|
+
token: str,
|
36
|
+
service_id: int = 0,
|
37
|
+
charge: bool = False,
|
38
|
+
):
|
33
39
|
"""
|
34
40
|
Main function to handle:
|
35
41
|
1) Save Files on Server
|
@@ -37,6 +43,7 @@ def run_main_job(files_as_byte_strings: dict,
|
|
37
43
|
3) Create workunits in B-Fabric
|
38
44
|
4) Register resources in B-Fabric
|
39
45
|
5) Attach additional gstore files (logs/reports/etc.) to entities in B-Fabric
|
46
|
+
6) Automatically charge the relevant container for the service
|
40
47
|
|
41
48
|
:param files_as_byte_strings: {destination_path: file as byte strings}
|
42
49
|
:param bash_commands: List of bash commands to execute
|
@@ -44,6 +51,8 @@ def run_main_job(files_as_byte_strings: dict,
|
|
44
51
|
:param attachment_paths: Dictionary mapping source file paths to their corresponding file names ({"path/test.txt": "name.txt"})
|
45
52
|
for attachment to a B-Fabric entity (e.g., logs, final reports, etc.)
|
46
53
|
:param token: Authentication token
|
54
|
+
:param service_id: ID of the service to charge
|
55
|
+
:param charge: Boolean indicating whether to charge the container for the service
|
47
56
|
|
48
57
|
|
49
58
|
Dev Notes:
|
@@ -75,6 +84,7 @@ Dev Notes:
|
|
75
84
|
summary = save_files_from_bytes(files_as_byte_strings, L)
|
76
85
|
L.log_operation("Success", f"File copy summary: {summary}", params=None, flush_logs=True)
|
77
86
|
print("Summary:", summary)
|
87
|
+
|
78
88
|
except Exception as e:
|
79
89
|
# If something unexpected blows up the entire process
|
80
90
|
L.log_operation("Error", f"Failed to copy files: {e}", params=None, flush_logs=True)
|
@@ -117,6 +127,27 @@ Dev Notes:
|
|
117
127
|
print("Error attaching extra files:", e)
|
118
128
|
|
119
129
|
|
130
|
+
# STEP 6: Charge the container for the service
|
131
|
+
if charge:
|
132
|
+
|
133
|
+
if service_id == 0:
|
134
|
+
print("Service ID not provided. Skipping charge creation.")
|
135
|
+
L.log_operation("Info", "Service ID not provided. Skipping charge creation.", params=None, flush_logs=True)
|
136
|
+
else:
|
137
|
+
container_ids = list(set(list(resource_paths.values())))
|
138
|
+
if not container_ids:
|
139
|
+
L.log_operation("Error", "No container IDs found for charging.", params=None, flush_logs=True)
|
140
|
+
print("Error: No container IDs found for charging.")
|
141
|
+
return
|
142
|
+
for container_id in container_ids:
|
143
|
+
charges = create_charge(token_data, container_id, service_id)
|
144
|
+
charge_id = charges[0].get("id")
|
145
|
+
L.log_operation("Success", f"Charge created for container {container_id} with service ID {service_id} and charge id {charge_id}", params=None, flush_logs=False)
|
146
|
+
print(f"Charge created with id {charge_id} for container {container_id} with service ID {service_id}")
|
147
|
+
L.flush_logs()
|
148
|
+
else:
|
149
|
+
L.log_operation("Info", "Charge creation skipped.", params=None, flush_logs=True)
|
150
|
+
print("Charge creation skipped.")
|
120
151
|
|
121
152
|
#---------------------------------------------------------------------------------------------------------------------
|
122
153
|
#---------------------------------------------------------------------------------------------------------------------
|
@@ -138,23 +169,23 @@ def save_files_from_bytes(files_as_byte_strings: dict, logger):
|
|
138
169
|
"""
|
139
170
|
results = {} # Store results: (destination) -> True (if success) or error message (if failure)
|
140
171
|
|
172
|
+
message = "All files saved successfully."
|
173
|
+
|
141
174
|
# First pass: attempt to write all files
|
142
175
|
for destination, file_bytes in files_as_byte_strings.items():
|
143
176
|
try:
|
144
|
-
# Ensure the directory exists
|
145
|
-
os.makedirs(os.path.dirname(destination), exist_ok=True)
|
146
|
-
|
147
177
|
# Write file from byte string
|
148
|
-
with open(destination, "wb") as f:
|
178
|
+
with open(destination, "+wb") as f:
|
149
179
|
f.write(file_bytes)
|
150
|
-
logger.log_operation("
|
151
|
-
return "All files saved successfully."
|
180
|
+
logger.log_operation(f"File saved", f"File {destination} saved successfully.", params=None, flush_logs=True)
|
152
181
|
|
153
182
|
except Exception as e:
|
154
183
|
error_msg = f"Error saving file: {destination}, Error: {str(e)}"
|
155
184
|
logger.log_operation("Error", error_msg, params=None, flush_logs=True)
|
156
185
|
print(error_msg)
|
157
|
-
|
186
|
+
message = f"Error saving some files."
|
187
|
+
|
188
|
+
return message
|
158
189
|
|
159
190
|
|
160
191
|
# -----------------------------------------------------------------------------
|
@@ -412,3 +443,14 @@ def create_api_link(token_data, logger, entity_class, entity_id, file_name, fold
|
|
412
443
|
logger.log_operation("Error", error_msg, params=None, flush_logs=True)
|
413
444
|
print(error_msg)
|
414
445
|
|
446
|
+
|
447
|
+
def read_file_as_bytes(file_path, max_size_mb=400):
|
448
|
+
"""Reads any file type and stores it as a byte string in a dictionary."""
|
449
|
+
file_size_mb = os.path.getsize(file_path) / (1024 * 1024) # Convert bytes to MB
|
450
|
+
if file_size_mb > max_size_mb:
|
451
|
+
raise ValueError(f"File {file_path} exceeds {max_size_mb}MB limit ({file_size_mb:.2f}MB).")
|
452
|
+
|
453
|
+
with open(file_path, "rb") as f: # Read as bytes
|
454
|
+
file_as_bytes = f.read()
|
455
|
+
|
456
|
+
return file_as_bytes
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: bfabric-web-apps
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.7
|
4
4
|
Summary: A package containing handy boilerplate utilities for developing bfabric web-applications
|
5
5
|
Author: Marc Zuber, Griffin White, GWC GmbH
|
6
6
|
Requires-Python: >=3.10,<4.0
|
@@ -10,6 +10,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
10
10
|
Requires-Dist: bfabric (>=1.13.23,<2.0.0)
|
11
11
|
Requires-Dist: dash (>=3.0.2,<4.0.0)
|
12
12
|
Requires-Dist: dash-bootstrap-components (>=2.0.0,<3.0.0)
|
13
|
+
Requires-Dist: dash-daq (>=0.6.0,<0.7.0)
|
13
14
|
Requires-Dist: pydantic-settings (>=2.8.1,<3.0.0)
|
14
15
|
Requires-Dist: pydantic[email] (>=2.10.6,<3.0.0)
|
15
16
|
Requires-Dist: rq (==1.15.1)
|
@@ -1,11 +1,12 @@
|
|
1
|
-
bfabric_web_apps/__init__.py,sha256=
|
1
|
+
bfabric_web_apps/__init__.py,sha256=9OSketawJ_bkCbCN0Q3KaM6_u1_zyE74oC7jtrznFP8,1503
|
2
2
|
bfabric_web_apps/layouts/layouts.py,sha256=z8gL4n4wwLdpLGomO9CftBLnGpc3r6OpmUc2-wBg8uo,14661
|
3
|
-
bfabric_web_apps/objects/BfabricInterface.py,sha256=
|
3
|
+
bfabric_web_apps/objects/BfabricInterface.py,sha256=2BNskMzV5K1a-tXFHQubcBk7Rt-8g9du7mNAJrGohMY,10170
|
4
4
|
bfabric_web_apps/objects/Logger.py,sha256=62LC94xhm7YG5LUw3yH46NqvJQsAX7wnc9D4zbY16rA,5224
|
5
5
|
bfabric_web_apps/utils/app_init.py,sha256=RCdpCXp19cF74bouYJLPe-KSETZ0Vwqtd02Ta2VXEF8,428
|
6
|
-
bfabric_web_apps/utils/callbacks.py,sha256=
|
7
|
-
bfabric_web_apps/utils/
|
8
|
-
bfabric_web_apps/utils/
|
6
|
+
bfabric_web_apps/utils/callbacks.py,sha256=tB1xtHl_ePY6KJWNz3erkrZw3HFhRneewGqZm9xIYtI,12687
|
7
|
+
bfabric_web_apps/utils/charging.py,sha256=oNNazH59SFkbxJKPvCel0IxdsRHC8xpJ0AXCLvI88FI,1069
|
8
|
+
bfabric_web_apps/utils/components.py,sha256=X3NRnv--LsHWMtWL83Pzr2whOZLSEJIwXTklQdAQpZE,984
|
9
|
+
bfabric_web_apps/utils/config.py,sha256=vJzhmc6ooFb46MM1Eg3m8gNrM4fJa-l5Tao2Py-SF_I,1115
|
9
10
|
bfabric_web_apps/utils/create_app_in_bfabric.py,sha256=eVk3cQDXxW-yo9b9n_zzGO6kLg_SLxYbIDECyvEPJXU,2752
|
10
11
|
bfabric_web_apps/utils/get_logger.py,sha256=0Y3SrXW93--eglS0_ZOc34NOriAt6buFPik5n0ltzRA,434
|
11
12
|
bfabric_web_apps/utils/get_power_user_wrapper.py,sha256=T33z64XjmJ0KSlmfEmrEP8eYpbpINCVD6Xld_V7PR2g,1027
|
@@ -13,8 +14,8 @@ bfabric_web_apps/utils/redis_connection.py,sha256=qXSPxW6m55Ogv44BhmPCl9ACuvzmpf
|
|
13
14
|
bfabric_web_apps/utils/redis_queue.py,sha256=MCx7z_I2NusJ4P42mcLvV7STtXBFMIIvun83fM8zOGI,168
|
14
15
|
bfabric_web_apps/utils/redis_worker_init.py,sha256=9SUc9bbgBeMbUdqJD9EkWPA4wcJjvyX6Tzanv5JfqEg,691
|
15
16
|
bfabric_web_apps/utils/resource_utilities.py,sha256=4LnV_eQjKkcpZJBsWFx--dmASyE7jfJfktk2hdHn5Fk,5856
|
16
|
-
bfabric_web_apps/utils/run_main_pipeline.py,sha256=
|
17
|
-
bfabric_web_apps-0.1.
|
18
|
-
bfabric_web_apps-0.1.
|
19
|
-
bfabric_web_apps-0.1.
|
20
|
-
bfabric_web_apps-0.1.
|
17
|
+
bfabric_web_apps/utils/run_main_pipeline.py,sha256=RG-Jb3-O1Ok8L0i1gddWVeAEqJT6REITtcD9XDoC_Dc,18766
|
18
|
+
bfabric_web_apps-0.1.7.dist-info/LICENSE,sha256=k0O_i2k13i9e35aO-j7FerJafAqzzu8x0kkBs0OWF3c,1065
|
19
|
+
bfabric_web_apps-0.1.7.dist-info/METADATA,sha256=Jf3A0eVEOXvoMzFJCmxpWnoGvKNnHd2ckHg4o9w6nm0,687
|
20
|
+
bfabric_web_apps-0.1.7.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
|
21
|
+
bfabric_web_apps-0.1.7.dist-info/RECORD,,
|
File without changes
|
File without changes
|