Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,24 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "MUIO Server",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/API/app.py",
"console": "integratedTerminal",
"justMyCode": true
},
{
"name": "Python: Current File",
"type": "python",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
},
{
"name": "Python: Flask",
"type": "python",
"type": "debugpy",
"request": "launch",
"module": "flask",
"env": {
Expand All @@ -24,7 +32,6 @@
},
"args": [
"run",
//"--no-debugger",
"--no-reload"
],
"jinja": true
Expand Down
23 changes: 23 additions & 0 deletions API/Classes/Base/Response.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from flask import jsonify

def api_response(success=True, message=None, data=None, error=None, status_code=200):
"""
Standardized API response helper for MUIO.

Args:
success (bool): Whether the request was successful.
message (str, optional): A human-readable message.
data (dict|list, optional): The actual payload.
error (str|dict, optional): Detailed error information.
status_code (int): HTTP status code.

Returns:
tuple: (flask.Response, int) - A JSON response compatible with Flask's return type.
"""
response = {
"success": success,
"message": message,
"data": data,
"error": error
}
return jsonify(response), status_code
83 changes: 42 additions & 41 deletions API/Routes/Case/CaseRoute.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import pandas as pd
from Classes.Base import Config
from Classes.Base.FileClass import File
from Classes.Base.Response import api_response
from Classes.Case.CaseClass import Case
from Classes.Case.UpdateCaseClass import UpdateCase
from Classes.Case.ImportTemplate import ImportTemplate
Expand All @@ -22,21 +23,22 @@ def initSyncS3():
syncS3.downloadSync(case, Config.DATA_STORAGE, Config.S3_BUCKET)
#downoload param file from S3 bucket
syncS3.downloadSync('Parameters.json', Config.DATA_STORAGE, Config.S3_BUCKET)
response = {
"message": "Cases syncronized with S3 bucket!",
"status_code": "success"
}
return jsonify(response), 200
return api_response(
success=True,
message="Cases syncronized with S3 bucket!",
data={"status_code": "success"},
status_code=200
)
except(IOError):
return jsonify('No existing cases!'), 404
return api_response(success=False, message="No existing cases!", status_code=404)

@case_api.route("/getCases", methods=['GET'])
def getCases():
try:
cases = [ f.name for f in os.scandir(Config.DATA_STORAGE) if f.is_dir() ]
return jsonify(cases), 200
return api_response(success=True, data=cases, status_code=200)
except(IOError):
return jsonify('No existing cases!'), 404
return api_response(success=False, message="No existing cases!", status_code=404)

@case_api.route("/getResultCSV", methods=['POST'])
def getResultCSV():
Expand All @@ -48,9 +50,9 @@ def getResultCSV():
csvs = [ f.name for f in os.scandir(csvFolder) ]
else:
csvs = []
return jsonify(csvs), 200
return api_response(success=True, data=csvs, status_code=200)
except(IOError):
return jsonify('No existing cases!'), 404
return api_response(success=False, message="No existing cases!", status_code=404)

@case_api.route("/getDesc", methods=['POST'])
def getDesc():
Expand All @@ -62,9 +64,9 @@ def getDesc():
"message": "Get model description success",
"desc": genData['osy-desc']
}
return jsonify(response), 200
return api_response(success=True, message=response["message"], data=response, status_code=200)
except(IOError):
return jsonify('No existing cases!'), 404
return api_response(success=False, message="No existing cases!", status_code=404)

@case_api.route("/copyCase", methods=['POST'])
def copy():
Expand All @@ -81,6 +83,7 @@ def copy():
"message": 'Model <b>'+ case + '_copy</b> already exists, please rename existing model first!',
"status_code": "warning"
}
return api_response(success=False, message=response["message"], data=response, status_code=200)
else:
shutil.copytree(str(src), str(dest) )
#rename casename in genData
Expand All @@ -91,11 +94,11 @@ def copy():
"message": 'Model <b>'+ case + '</b> copied!',
"status_code": "success"
}
return(response)
return api_response(success=True, message=response["message"], data=response, status_code=200)
except(IOError):
raise IOError
return api_response(success=False, message="Error copying model", status_code=500)
except OSError:
raise OSError
return api_response(success=False, message="OS Error copying model", status_code=500)

@case_api.route("/deleteCase", methods=['POST'])
def deleteCase():
Expand All @@ -116,11 +119,11 @@ def deleteCase():
"message": 'Model <b>'+ case + '</b> deleted!',
"status_code": "success"
}
return jsonify(response), 200
return api_response(success=True, message=response["message"], data=response, status_code=200)
except(IOError):
return jsonify('No existing cases!'), 404
return api_response(success=False, message="No existing cases!", status_code=404)
except OSError:
raise OSError
return api_response(success=False, message="Error deleting case", status_code=500)

@case_api.route("/getResultData", methods=['POST'])
def getResultData():
Expand All @@ -131,23 +134,21 @@ def getResultData():
dataPath = Path(Config.DATA_STORAGE,casename,'view',dataJson)
data = File.readFile(dataPath)
response = data

else:
response = None
return jsonify(response), 200
return api_response(success=True, data=response, status_code=200)
except(IOError):
return jsonify('No existing cases!'), 404
return api_response(success=False, message="No existing cases!", status_code=404)

@case_api.route("/getParamFile", methods=['POST'])
def getParamFile():
try:
dataJson = request.json['dataJson']
configPath = Path(Config.DATA_STORAGE, dataJson)
ConfigFile = File.readParamFile(configPath)
response = ConfigFile
return jsonify(response), 200
return api_response(success=True, data=ConfigFile, status_code=200)
except(IOError):
return jsonify('No existing cases!'), 404
return api_response(success=False, message="No existing cases!", status_code=404)

@case_api.route("/resultsExists", methods=['POST'])
def resultsExists():
Expand All @@ -168,9 +169,9 @@ def resultsExists():
else:
response = False
#response = True
return jsonify(response), 200
return api_response(success=True, data=response, status_code=200)
except(IOError):
return jsonify('No existing cases!'), 404
return api_response(success=False, message="No existing cases!", status_code=404)

@case_api.route("/saveParamFile", methods=['POST'])
def saveParamFile():
Expand All @@ -187,9 +188,9 @@ def saveParamFile():
"status_code": "success"
}

return jsonify(response), 200
return api_response(success=True, message=response["message"], data=response, status_code=200)
except(IOError):
return jsonify('No existing cases!'), 404
return api_response(success=False, message="No existing cases!", status_code=404)

@case_api.route("/saveScOrder", methods=['POST'])
def saveScOrder():
Expand All @@ -205,9 +206,9 @@ def saveScOrder():
"status_code": "success"
}

return jsonify(response), 200
return api_response(success=True, message=response["message"], data=response, status_code=200)
except(IOError):
return jsonify('No existing cases!'), 404
return api_response(success=False, message="No existing cases!", status_code=404)

@case_api.route("/updateData", methods=['POST'])
def updateData():
Expand All @@ -226,9 +227,9 @@ def updateData():
"message": "Your data has been saved!",
"status_code": "success"
}
return jsonify(response), 200
return api_response(success=True, message=response["message"], data=response, status_code=200)
except(IOError):
return jsonify('No existing cases!'), 404
return api_response(success=False, message="No existing cases!", status_code=404)

@case_api.route("/saveCase", methods=['POST'])
def saveCase():
Expand Down Expand Up @@ -376,15 +377,15 @@ def saveCase():
"message": "Your model configuration has been saved!",
"status_code": "created"
}
else:
response = {
"message": "Model with same name already exists!",
"status_code": "exist"
}
return api_response(success=False, message=response["message"], data=response, status_code=200)

return jsonify(response), 200
return api_response(success=True, message=response["message"], data=response, status_code=200)
except(IOError):
return jsonify('Error saving model IOError!'), 404
return api_response(success=False, message="Error saving model IOError!", status_code=404)

@case_api.route("/prepareCSV", methods=['POST'])
def prepareCSV():
Expand All @@ -410,10 +411,10 @@ def prepareCSV():
"message": 'CSV data downloaded!',
"status_code": "success"
}
return jsonify(response), 200
return api_response(success=True, message=response["message"], data=response, status_code=200)

except(IOError):
return jsonify('No existing cases!'), 404
return api_response(success=False, message="No existing cases!", status_code=404)

@case_api.route("/downloadCSV", methods=['GET'])
def downloadCSV():
Expand All @@ -425,7 +426,7 @@ def downloadCSV():
return send_file(dataFile.resolve(), as_attachment=True,mimetype='application/csv', max_age=0)
#return send_from_directory(dir, 'export.csv', as_attachment=True)
except(IOError):
return jsonify('No existing cases!'), 404
return api_response(success=False, message="No existing cases!", status_code=404)

@case_api.route("/importTemplate", methods=['POST'])
def run():
Expand All @@ -434,11 +435,11 @@ def run():
template = ImportTemplate(data["osy-template"])
response = template.importProcess(data)

return jsonify(response), 200
return api_response(success=True, data=response, status_code=200)
except(IOError):
return jsonify('No existing cases!'), 404
return api_response(success=False, message="No existing cases!", status_code=404)
except(IndexError):
return jsonify('No existing cases!'), 404
return api_response(success=False, message="Index Error during import", status_code=500)


####################################################################################OBSOLETE AND SyncS3###################################################
Expand Down
31 changes: 16 additions & 15 deletions API/Routes/Case/SyncS3Route.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import shutil
from Classes.Base import Config
from Classes.Base.SyncS3 import SyncS3
from Classes.Base.Response import api_response

syncs3_api = Blueprint('SyncS3Route', __name__)

Expand All @@ -21,11 +22,11 @@ def deleteResultsPreSync():
"message": 'Case <b>'+ case + '</b> deleted!',
"status_code": "success"
}
return jsonify(response), 200
return api_response(success=True, message=response["message"], data=response, status_code=200)
except(IOError):
return jsonify('No existing cases!'), 404
return api_response(success=False, message="No existing cases!", status_code=404)
except OSError:
raise OSError
return api_response(success=False, message="OS Error during sync deletion", status_code=500)

@syncs3_api.route("/uploadSync", methods=['POST'])
def uploadSync():
Expand All @@ -40,11 +41,11 @@ def uploadSync():
"message": 'Case <b>'+ case + '</b> syncronized!',
"status_code": "success"
}
return jsonify(response), 200
return api_response(success=True, message=response["message"], data=response, status_code=200)
except(IOError):
return jsonify('No existing cases!'), 404
return api_response(success=False, message="No existing cases!", status_code=404)
except OSError:
raise OSError
return api_response(success=False, message="OS Error during sync upload", status_code=500)

@syncs3_api.route("/deleteSync", methods=['POST'])
def deleteSync():
Expand All @@ -58,11 +59,11 @@ def deleteSync():
"message": 'Case <b>'+ case + '</b> deleted!',
"status_code": "success"
}
return jsonify(response), 200
return api_response(success=True, message=response["message"], data=response, status_code=200)
except(IOError):
return jsonify('No existing cases!'), 404
return api_response(success=False, message="No existing cases!", status_code=404)
except OSError:
raise OSError
return api_response(success=False, message="OS Error during sync deletion", status_code=500)

@syncs3_api.route("/updateSync", methods=['POST'])
def updateSync():
Expand All @@ -78,11 +79,11 @@ def updateSync():
"message": 'Case <b>'+ case + '</b> deleted!',
"status_code": "success"
}
return jsonify(response), 200
return api_response(success=True, message=response["message"], data=response, status_code=200)
except(IOError):
return jsonify('No existing cases!'), 404
return api_response(success=False, message="No existing cases!", status_code=404)
except OSError:
raise OSError
return api_response(success=False, message="OS Error during sync update", status_code=500)

@syncs3_api.route("/updateSyncParamFile", methods=['GET'])
def updateSyncParamFile():
Expand All @@ -98,8 +99,8 @@ def updateSyncParamFile():
"message": 'Case <b>'+ case + '</b> deleted!',
"status_code": "success"
}
return jsonify(response), 200
return api_response(success=True, message=response["message"], data=response, status_code=200)
except(IOError):
return jsonify('No existing cases!'), 404
return api_response(success=False, message="No existing cases!", status_code=404)
except OSError:
raise OSError
return api_response(success=False, message="OS Error during sync param update", status_code=500)
Loading