Skip to content

Commit 43db108

Browse files
authored
Merge pull request #58 from Strexas/JTE/PKFE-46
JTE/PKFE-46
2 parents 1c7e137 + 7f112e8 commit 43db108

File tree

12 files changed

+516
-213
lines changed

12 files changed

+516
-213
lines changed

app/back-end/src/constants.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@
3434
WORKSPACE_DELETE_ROUTE = "/workspace/delete"
3535
WORKSPACE_AGGREGATE_ROUTE = "/workspace/aggregate"
3636
WORKSPACE_IMPORT_ROUTE = "/workspace/import"
37+
WORKSPACE_EXPORT_ROUTE = "/workspace/export"
3738

3839
# Events
3940
CONSOLE_FEEDBACK_EVENT = "console_feedback"
4041
WORKSPACE_FILE_SAVE_FEEDBACK_EVENT = "workspace_file_save_feedback"
4142
WORKSPACE_UPDATE_FEEDBACK_EVENT = "workspace_update_feedback"
43+
WOKRSPACE_EXPORT_FEEDBACK_EVENT = "workspace_export_feedback"

app/back-end/src/events/workspace_event.py

Lines changed: 0 additions & 95 deletions
This file was deleted.
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
"""
2+
Module for handling Socket.IO events related to workspace file exports.
3+
4+
This module sets up the event handler for the `WOKRSPACE_EXPORT_FEEDBACK_EVENT` event using
5+
Socket.IO. It processes feedback about file export operations and sends appropriate real-time
6+
feedback messages to the user's console based on the status of the export operation.
7+
8+
Imports:
9+
- socketio: The Socket.IO instance for handling real-time communication.
10+
- socketio_emit_to_user_session: Utility function for emitting messages to a user's session.
11+
- WOKRSPACE_EXPORT_FEEDBACK_EVENT: Constant defining the event name for file export feedback.
12+
- CONSOLE_FEEDBACK_EVENT: Constant defining the event name for console feedback.
13+
14+
Functions:
15+
- workspace_export_event_handler: Registers the Socket.IO event handler for file export
16+
feedback.
17+
"""
18+
19+
# pylint: disable=import-error
20+
21+
from src.setup.extensions import socketio
22+
from src.utils.helpers import socketio_emit_to_user_session
23+
from src.constants import WOKRSPACE_EXPORT_FEEDBACK_EVENT, CONSOLE_FEEDBACK_EVENT
24+
25+
26+
def workspace_export_event_handler():
27+
"""
28+
Sets up the event handler for the `WOKRSPACE_EXPORT_FEEDBACK_EVENT` event in Socket.IO.
29+
30+
This function registers an event handler for the `WOKRSPACE_EXPORT_FEEDBACK_EVENT` event,
31+
which is triggered during file export operations in the workspace. The event handler processes
32+
the feedback based on the status of the file export operation and sends appropriate feedback
33+
messages to the user's console.
34+
35+
This function does not return any value. It directly interacts with the Socket.IO event system
36+
to provide real-time feedback to users.
37+
38+
Side Effects:
39+
- Registers the `handle_workspace_export_feedback` function as an event handler for
40+
`WOKRSPACE_EXPORT_FEEDBACK_EVENT` using Socket.IO.
41+
"""
42+
43+
@socketio.on(WOKRSPACE_EXPORT_FEEDBACK_EVENT)
44+
def handle_workspace_export_feedback(data):
45+
"""
46+
Handles the `WOKRSPACE_EXPORT_FEEDBACK_EVENT` event by providing feedback about the
47+
file export operation.
48+
49+
This function listens for Socket.IO events related to workspace file exports and processes
50+
the feedback based on the status provided in the event data. It then sends a message to the
51+
user's console indicating whether the file export was successful or not.
52+
53+
Args:
54+
data (dict): The event data containing feedback about the file export operation.
55+
It should include:
56+
- `status` (str): The status of the file export operation ("success" or "failure").
57+
- `uuid` (str): The unique identifier for the user's session.
58+
- `sid` (str): The session identifier used for emitting real-time feedback.
59+
- `fileName` (str): The name of the file that is being exported.
60+
61+
Emits:
62+
- Success message to the user's console if the status is "success".
63+
- Error message to the user's console if the status is "failure".
64+
65+
Side Effects:
66+
- Sends real-time feedback to the user's console using `socketio_emit_to_user_session`.
67+
"""
68+
69+
if data["status"] == "success":
70+
socketio_emit_to_user_session(
71+
CONSOLE_FEEDBACK_EVENT,
72+
{"type": "succ", "message": f"File '{data['filePath']}' export was completed successfully."},
73+
data["uuid"],
74+
data["sid"],
75+
)
76+
else:
77+
socketio_emit_to_user_session(
78+
CONSOLE_FEEDBACK_EVENT,
79+
{"type": "errr", "message": f"File '{data['filePath']}' export failed."},
80+
data["uuid"],
81+
data["sid"],
82+
)

app/back-end/src/routes/workspace_aggregate_route.py

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,29 @@
1+
"""
2+
This module defines the routes for aggregating data from user workspaces in a Flask application.
3+
It provides two main routes for performing column-level calculations on CSV files stored in the
4+
user's workspace. The supported operations include summing, averaging, counting, finding the
5+
minimum, and finding the maximum values in specified columns.
6+
7+
The module emits real-time feedback to the user’s session via Socket.IO, providing status updates
8+
on the calculations, handling skipped cells due to invalid data, and notifying the user of errors
9+
such as file not found, permission denied, or unexpected issues.
10+
11+
Routes:
12+
- get_workspace_aggregate_all(relative_path):
13+
Calculates aggregate values (sum, avg, min, max, cnt) for multiple columns in a CSV file.
14+
15+
- get_workspace_aggregate(relative_path):
16+
Calculates an aggregate value (sum, avg, min, max, cnt) for a single column in a CSV file.
17+
18+
Exceptions are handled to provide feedback through the user’s console using Socket.IO.
19+
"""
20+
121
# pylint: disable=import-error
222

323
import os
424
import csv
5-
from flask import Blueprint, request, jsonify
625
from ast import literal_eval
26+
from flask import Blueprint, request, jsonify
727

828
from src.setup.extensions import logger
929
from src.utils.helpers import socketio_emit_to_user_session, is_number
@@ -18,6 +38,39 @@
1838
f"{WORKSPACE_AGGREGATE_ROUTE}/all/<path:relative_path>", methods=["GET"]
1939
)
2040
def get_workspace_aggregate_all(relative_path):
41+
"""
42+
Route to calculate aggregate values (e.g., sum, avg, min, max, cnt) for multiple columns
43+
in a CSV file located in the user's workspace. The columns and their aggregation actions
44+
are specified in the request's query parameters.
45+
46+
Args:
47+
relative_path (str): The relative path to the CSV file inside the user's workspace.
48+
49+
Request Headers:
50+
- uuid: A unique identifier for the user's session.
51+
- sid: A session identifier for emitting real-time console feedback via Socket.IO.
52+
53+
Query Parameters:
54+
- columnsAggregation (str): A stringified dictionary where the keys are column names and
55+
the values are dictionaries with an "action" key specifying the aggregation operation
56+
('sum', 'avg', 'min', 'max', or 'cnt').
57+
58+
Returns:
59+
Response (JSON):
60+
- On success: A JSON object with aggregated results for each specified column.
61+
- On error: A JSON object with an error message and appropriate HTTP status code.
62+
63+
Emits:
64+
- Real-time console feedback using Socket.IO via the `socketio_emit_to_user_session`
65+
function. Feedback includes the start, completion, and any warnings or errors during
66+
the aggregation process.
67+
68+
Possible Errors:
69+
- FileNotFoundError: The specified CSV file does not exist.
70+
- PermissionError: Insufficient permissions to read the CSV file.
71+
- UnexpectedError: Any other unexpected error during the aggregation process.
72+
"""
73+
2174
uuid = request.headers.get("uuid")
2275
sid = request.headers.get("sid")
2376

@@ -140,7 +193,8 @@ def get_workspace_aggregate_all(relative_path):
140193
CONSOLE_FEEDBACK_EVENT,
141194
{
142195
"type": "warn",
143-
"message": f"The following columns had cells skipped due to non-numeric values: {', '.join(skipped_columns_info)}",
196+
"message": "The following columns had cells skipped due to non-numeric "
197+
+ f"values: {', '.join(skipped_columns_info)}",
144198
},
145199
uuid,
146200
sid,
@@ -203,6 +257,45 @@ def get_workspace_aggregate_all(relative_path):
203257
f"{WORKSPACE_AGGREGATE_ROUTE}/<path:relative_path>", methods=["GET"]
204258
)
205259
def get_workspace_aggregate(relative_path):
260+
"""
261+
Route to calculate an aggregate value (e.g., sum, avg, min, max, cnt) for a single column
262+
in a CSV file located in the user's workspace. The column and the aggregation action
263+
are specified in the request's query parameters.
264+
265+
Args:
266+
relative_path (str): The relative path to the CSV file inside the user's workspace.
267+
268+
Request Headers:
269+
- uuid: A unique identifier for the user's session.
270+
- sid: A session identifier for emitting real-time console feedback via Socket.IO.
271+
272+
Query Parameters:
273+
- field (str): The name of the column to perform the aggregation on.
274+
- action (str): The type of aggregation action to perform
275+
('sum', 'avg', 'min', 'max', or 'cnt').
276+
277+
Returns:
278+
Response (JSON):
279+
- On success: A JSON object with the aggregated result for the specified column.
280+
- On error: A JSON object with an error message and appropriate HTTP status code.
281+
282+
Emits:
283+
- Real-time console feedback using Socket.IO via the `socketio_emit_to_user_session`
284+
function.Feedback includes the start, completion, and any warnings or errors during the
285+
aggregation process.
286+
287+
Possible Errors:
288+
- FileNotFoundError: The specified CSV file does not exist.
289+
- PermissionError: Insufficient permissions to read the CSV file.
290+
- UnexpectedError: Any other unexpected error during the aggregation process.
291+
292+
Notes:
293+
- If the column contains non-numeric values, those cells are skipped and a warning is sent
294+
via Socket.IO.
295+
- The result is formatted as "N/A" if no valid numeric data is found or if the specified
296+
action is invalid for the data present in the column.
297+
"""
298+
206299
uuid = request.headers.get("uuid")
207300
sid = request.headers.get("sid")
208301

@@ -289,7 +382,8 @@ def get_workspace_aggregate(relative_path):
289382
CONSOLE_FEEDBACK_EVENT,
290383
{
291384
"type": "warn",
292-
"message": f"At column '{field}' {skipped_count} cells were skipped because they contain non-numeric values.",
385+
"message": f"At column '{field}' {skipped_count} cells "
386+
+ "were skipped because they contain non-numeric values.",
293387
},
294388
uuid,
295389
sid,

0 commit comments

Comments
 (0)