bfabric-web-apps 0.1.2__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 +4 -1
- bfabric_web_apps/objects/BfabricInterface.py +40 -3
- bfabric_web_apps/utils/resource_utilities.py +218 -0
- {bfabric_web_apps-0.1.2.dist-info → bfabric_web_apps-0.1.3.dist-info}/METADATA +1 -1
- {bfabric_web_apps-0.1.2.dist-info → bfabric_web_apps-0.1.3.dist-info}/RECORD +7 -6
- {bfabric_web_apps-0.1.2.dist-info → bfabric_web_apps-0.1.3.dist-info}/LICENSE +0 -0
- {bfabric_web_apps-0.1.2.dist-info → bfabric_web_apps-0.1.3.dist-info}/WHEEL +0 -0
bfabric_web_apps/__init__.py
CHANGED
@@ -20,6 +20,7 @@ from .utils.callbacks import process_url_and_token, submit_bug_report
|
|
20
20
|
|
21
21
|
from .utils import defaults
|
22
22
|
|
23
|
+
from bfabric_web_apps.utils.resource_utilities import create_workunit, create_resource
|
23
24
|
HOST = os.getenv("HOST", defaults.HOST)
|
24
25
|
PORT = int(os.getenv("PORT", defaults.PORT)) # Convert to int since env variables are strings
|
25
26
|
DEV = os.getenv("DEV", str(defaults.DEV)).lower() in ["true", "1", "yes"] # Convert to bool
|
@@ -46,7 +47,9 @@ __all__ = [
|
|
46
47
|
'CONFIG_FILE_PATH',
|
47
48
|
'DEVELOPER_EMAIL_ADDRESS',
|
48
49
|
'BUG_REPORT_EMAIL_ADDRESS',
|
49
|
-
'create_app_in_bfabric'
|
50
|
+
'create_app_in_bfabric',
|
51
|
+
'create_workunit',
|
52
|
+
'create_resource'
|
50
53
|
]
|
51
54
|
|
52
55
|
|
@@ -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
|
|
@@ -133,7 +164,7 @@ class BfabricInterface( Bfabric ):
|
|
133
164
|
if not token_data:
|
134
165
|
return json.dumps({})
|
135
166
|
|
136
|
-
wrapper = self.
|
167
|
+
wrapper = self.get_wrapper()
|
137
168
|
entity_class = token_data.get('entityClass_data', None)
|
138
169
|
endpoint = entity_class_map.get(entity_class, None)
|
139
170
|
entity_id = token_data.get('entity_id_data', None)
|
@@ -209,7 +240,7 @@ class BfabricInterface( Bfabric ):
|
|
209
240
|
L = get_logger(token_data)
|
210
241
|
|
211
242
|
# Get API wrapper
|
212
|
-
wrapper = self.
|
243
|
+
wrapper = self.get_wrapper()
|
213
244
|
if not wrapper:
|
214
245
|
print("Failed to get Bfabric API wrapper")
|
215
246
|
return json.dumps({})
|
@@ -234,9 +265,11 @@ class BfabricInterface( Bfabric ):
|
|
234
265
|
)
|
235
266
|
return json.dumps({})
|
236
267
|
|
237
|
-
# Extract Name and Description
|
268
|
+
# Extract App ID, Name, and Description
|
238
269
|
app_info = app_data_dict[0] # First (and only) result
|
270
|
+
print('app_info', app_info)
|
239
271
|
json_data = json.dumps({
|
272
|
+
"id": app_info.get("id", "Unknown"),
|
240
273
|
"name": app_info.get("name", "Unknown"),
|
241
274
|
"description": app_info.get("description", "No description available")
|
242
275
|
})
|
@@ -283,3 +316,7 @@ class BfabricInterface( Bfabric ):
|
|
283
316
|
|
284
317
|
|
285
318
|
|
319
|
+
# Create a globally accessible instance
|
320
|
+
bfabric_interface = BfabricInterface()
|
321
|
+
|
322
|
+
|
@@ -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
|
+
'''
|
@@ -1,6 +1,6 @@
|
|
1
|
-
bfabric_web_apps/__init__.py,sha256=
|
1
|
+
bfabric_web_apps/__init__.py,sha256=xqh-kddXaV4xblnMcDA73bTuy3zn5viucueuuIx41HM,2495
|
2
2
|
bfabric_web_apps/layouts/layouts.py,sha256=XoSLcQPcgMBhQz2VfxkUzNL23FLBXFRFvbCL2mNLfnk,11636
|
3
|
-
bfabric_web_apps/objects/BfabricInterface.py,sha256=
|
3
|
+
bfabric_web_apps/objects/BfabricInterface.py,sha256=YC6VimARZfG2t90TK5xhQDsNzgMNljwqbCOT8Qz_Uhs,10247
|
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
6
|
bfabric_web_apps/utils/callbacks.py,sha256=PiP1ZJ-QxdrOAZ-Mt-MN-g9wJLSOoLkWkXwPq_TLqDI,6472
|
@@ -9,7 +9,8 @@ bfabric_web_apps/utils/create_app_in_bfabric.py,sha256=eVk3cQDXxW-yo9b9n_zzGO6kL
|
|
9
9
|
bfabric_web_apps/utils/defaults.py,sha256=B82j3JEbysLEU9JDZgoDBTX7WGvW3Hn5YMZaWAcjZew,278
|
10
10
|
bfabric_web_apps/utils/get_logger.py,sha256=0Y3SrXW93--eglS0_ZOc34NOriAt6buFPik5n0ltzRA,434
|
11
11
|
bfabric_web_apps/utils/get_power_user_wrapper.py,sha256=T33z64XjmJ0KSlmfEmrEP8eYpbpINCVD6Xld_V7PR2g,1027
|
12
|
-
bfabric_web_apps
|
13
|
-
bfabric_web_apps-0.1.
|
14
|
-
bfabric_web_apps-0.1.
|
15
|
-
bfabric_web_apps-0.1.
|
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,,
|
File without changes
|
File without changes
|