Skip to content

JTE/PKFE-46 #58

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Sep 10, 2024
2 changes: 2 additions & 0 deletions app/back-end/src/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@
WORKSPACE_DELETE_ROUTE = "/workspace/delete"
WORKSPACE_AGGREGATE_ROUTE = "/workspace/aggregate"
WORKSPACE_IMPORT_ROUTE = "/workspace/import"
WORKSPACE_EXPORT_ROUTE = "/workspace/export"

# Events
CONSOLE_FEEDBACK_EVENT = "console_feedback"
WORKSPACE_FILE_SAVE_FEEDBACK_EVENT = "workspace_file_save_feedback"
WORKSPACE_UPDATE_FEEDBACK_EVENT = "workspace_update_feedback"
WOKRSPACE_EXPORT_FEEDBACK_EVENT = "workspace_export_feedback"
95 changes: 0 additions & 95 deletions app/back-end/src/events/workspace_event.py

This file was deleted.

81 changes: 81 additions & 0 deletions app/back-end/src/events/workspace_export_event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
"""
Module for handling Socket.IO events related to workspace file exports.

This module sets up the event handler for the `WOKRSPACE_EXPORT_FEEDBACK_EVENT` event using
Socket.IO. It processes feedback about file export operations and sends appropriate real-time
feedback messages to the user's console based on the status of the export operation.

Imports:
- socketio: The Socket.IO instance for handling real-time communication.
- socketio_emit_to_user_session: Utility function for emitting messages to a user's session.
- WOKRSPACE_EXPORT_FEEDBACK_EVENT: Constant defining the event name for file export feedback.
- CONSOLE_FEEDBACK_EVENT: Constant defining the event name for console feedback.

Functions:
- workspace_export_event_handler: Registers the Socket.IO event handler for file export
feedback.
"""

# pylint: disable=import-error

from src.setup.extensions import socketio
from src.utils.helpers import socketio_emit_to_user_session
from src.constants import WOKRSPACE_EXPORT_FEEDBACK_EVENT, CONSOLE_FEEDBACK_EVENT


def workspace_export_event_handler():
"""
Sets up the event handler for the `WOKRSPACE_EXPORT_FEEDBACK_EVENT` event in Socket.IO.

This function registers an event handler for the `WOKRSPACE_EXPORT_FEEDBACK_EVENT` event,
which is triggered during file export operations in the workspace. The event handler processes
the feedback based on the status of the file export operation and sends appropriate feedback
messages to the user's console.

This function does not return any value. It directly interacts with the Socket.IO event system
to provide real-time feedback to users.

Side Effects:
- Registers the `handle_workspace_export_feedback` function as an event handler for
`WOKRSPACE_EXPORT_FEEDBACK_EVENT` using Socket.IO.
"""

@socketio.on(WOKRSPACE_EXPORT_FEEDBACK_EVENT)
def handle_workspace_export_feedback(data):
"""
Handles the `WOKRSPACE_EXPORT_FEEDBACK_EVENT` event by providing feedback about the
file export operation.

This function listens for Socket.IO events related to workspace file exports and processes
the feedback based on the status provided in the event data. It then sends a message to the
user's console indicating whether the file export was successful or not.

Args:
data (dict): The event data containing feedback about the file export operation.
It should include:
- `status` (str): The status of the file export operation ("success" or "failure").
- `uuid` (str): The unique identifier for the user's session.
- `sid` (str): The session identifier used for emitting real-time feedback.

Emits:
- Success message to the user's console if the status is "success".
- Error message to the user's console if the status is "failure".

Side Effects:
- Sends real-time feedback to the user's console using `socketio_emit_to_user_session`.
"""

if data["status"] == "success":
socketio_emit_to_user_session(
CONSOLE_FEEDBACK_EVENT,
{"type": "succ", "message": "File export completed successfully."},
data["uuid"],
data["sid"],
)
else:
socketio_emit_to_user_session(
CONSOLE_FEEDBACK_EVENT,
{"type": "errr", "message": "File export failed."},
data["uuid"],
data["sid"],
)
100 changes: 97 additions & 3 deletions app/back-end/src/routes/workspace_aggregate_route.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,29 @@
"""
This module defines the routes for aggregating data from user workspaces in a Flask application.
It provides two main routes for performing column-level calculations on CSV files stored in the
user's workspace. The supported operations include summing, averaging, counting, finding the
minimum, and finding the maximum values in specified columns.

The module emits real-time feedback to the user’s session via Socket.IO, providing status updates
on the calculations, handling skipped cells due to invalid data, and notifying the user of errors
such as file not found, permission denied, or unexpected issues.

Routes:
- get_workspace_aggregate_all(relative_path):
Calculates aggregate values (sum, avg, min, max, cnt) for multiple columns in a CSV file.

- get_workspace_aggregate(relative_path):
Calculates an aggregate value (sum, avg, min, max, cnt) for a single column in a CSV file.

Exceptions are handled to provide feedback through the user’s console using Socket.IO.
"""

# pylint: disable=import-error

import os
import csv
from flask import Blueprint, request, jsonify
from ast import literal_eval
from flask import Blueprint, request, jsonify

from src.setup.extensions import logger
from src.utils.helpers import socketio_emit_to_user_session, is_number
Expand All @@ -18,6 +38,39 @@
f"{WORKSPACE_AGGREGATE_ROUTE}/all/<path:relative_path>", methods=["GET"]
)
def get_workspace_aggregate_all(relative_path):
"""
Route to calculate aggregate values (e.g., sum, avg, min, max, cnt) for multiple columns
in a CSV file located in the user's workspace. The columns and their aggregation actions
are specified in the request's query parameters.

Args:
relative_path (str): The relative path to the CSV file inside the user's workspace.

Request Headers:
- uuid: A unique identifier for the user's session.
- sid: A session identifier for emitting real-time console feedback via Socket.IO.

Query Parameters:
- columnsAggregation (str): A stringified dictionary where the keys are column names and
the values are dictionaries with an "action" key specifying the aggregation operation
('sum', 'avg', 'min', 'max', or 'cnt').

Returns:
Response (JSON):
- On success: A JSON object with aggregated results for each specified column.
- On error: A JSON object with an error message and appropriate HTTP status code.

Emits:
- Real-time console feedback using Socket.IO via the `socketio_emit_to_user_session`
function. Feedback includes the start, completion, and any warnings or errors during
the aggregation process.

Possible Errors:
- FileNotFoundError: The specified CSV file does not exist.
- PermissionError: Insufficient permissions to read the CSV file.
- UnexpectedError: Any other unexpected error during the aggregation process.
"""

uuid = request.headers.get("uuid")
sid = request.headers.get("sid")

Expand Down Expand Up @@ -140,7 +193,8 @@ def get_workspace_aggregate_all(relative_path):
CONSOLE_FEEDBACK_EVENT,
{
"type": "warn",
"message": f"The following columns had cells skipped due to non-numeric values: {', '.join(skipped_columns_info)}",
"message": "The following columns had cells skipped due to non-numeric "
+ f"values: {', '.join(skipped_columns_info)}",
},
uuid,
sid,
Expand Down Expand Up @@ -203,6 +257,45 @@ def get_workspace_aggregate_all(relative_path):
f"{WORKSPACE_AGGREGATE_ROUTE}/<path:relative_path>", methods=["GET"]
)
def get_workspace_aggregate(relative_path):
"""
Route to calculate an aggregate value (e.g., sum, avg, min, max, cnt) for a single column
in a CSV file located in the user's workspace. The column and the aggregation action
are specified in the request's query parameters.

Args:
relative_path (str): The relative path to the CSV file inside the user's workspace.

Request Headers:
- uuid: A unique identifier for the user's session.
- sid: A session identifier for emitting real-time console feedback via Socket.IO.

Query Parameters:
- field (str): The name of the column to perform the aggregation on.
- action (str): The type of aggregation action to perform
('sum', 'avg', 'min', 'max', or 'cnt').

Returns:
Response (JSON):
- On success: A JSON object with the aggregated result for the specified column.
- On error: A JSON object with an error message and appropriate HTTP status code.

Emits:
- Real-time console feedback using Socket.IO via the `socketio_emit_to_user_session`
function.Feedback includes the start, completion, and any warnings or errors during the
aggregation process.

Possible Errors:
- FileNotFoundError: The specified CSV file does not exist.
- PermissionError: Insufficient permissions to read the CSV file.
- UnexpectedError: Any other unexpected error during the aggregation process.

Notes:
- If the column contains non-numeric values, those cells are skipped and a warning is sent
via Socket.IO.
- The result is formatted as "N/A" if no valid numeric data is found or if the specified
action is invalid for the data present in the column.
"""

uuid = request.headers.get("uuid")
sid = request.headers.get("sid")

Expand Down Expand Up @@ -289,7 +382,8 @@ def get_workspace_aggregate(relative_path):
CONSOLE_FEEDBACK_EVENT,
{
"type": "warn",
"message": f"At column '{field}' {skipped_count} cells were skipped because they contain non-numeric values.",
"message": f"At column '{field}' {skipped_count} cells "
+ "were skipped because they contain non-numeric values.",
},
uuid,
sid,
Expand Down
Loading
Loading