2024-08-31 01:29:39 +00:00
import os
from flask import Blueprint , request , jsonify , current_app
from werkzeug . utils import secure_filename
2024-09-05 02:59:01 +00:00
from src . services . sop_generator import ( SopGenerator , SopGeneratorDocument ,
SopPersonalAssessment )
2024-08-31 01:29:39 +00:00
from src . utils . utils import delete_all_files_in_directory
from src . utils . document_loader import load_document
import json
# Initialize the Blueprint
sops_bp = Blueprint ( ' sops ' , __name__ )
# Initialize SopGenerator
sop_generator = SopGenerator ( )
ALLOWED_EXTENSIONS = { ' pdf ' , ' doc ' , ' docx ' }
def allowed_file ( filename ) :
""" Check if the file has an allowed extension. """
return ' . ' in filename and filename . rsplit ( ' . ' , 1 ) [ 1 ] . lower ( ) in ALLOWED_EXTENSIONS
@sops_bp.route ( ' /get_roles ' , methods = [ ' POST ' ] )
def get_roles ( ) :
# Check if the post request has the file part
if ' document ' not in request . files :
return jsonify ( { " error " : " No file part " , " message " : " Please upload a file with the key ' document ' . " } ) , 400
file = request . files [ ' document ' ]
# If the user does not select a file, the browser may also submit an empty part without filename
if file . filename == ' ' :
return jsonify ( { " error " : " No selected file " , " message " : " A file was not selected for upload. Please select a valid file. " } ) , 400
if file and allowed_file ( file . filename ) :
filename = secure_filename ( file . filename )
upload_folder = current_app . config [ ' UPLOAD_FOLDER ' ]
file_path = os . path . join ( upload_folder , filename )
# Save the file to the upload folder
file . save ( file_path )
try :
# Use the utility function to generate docs from the file
docs = load_document ( file_path )
# Generate roles from the docs
roles = sop_generator . get_roles ( docs ) [ " roles " ]
# Cleanup: Delete all files in the upload directory after processing
delete_all_files_in_directory ( upload_folder )
return jsonify ( { " roles " : roles , " message " : " Roles successfully extracted from the document. " } ) , 200
except Exception as e :
# Cleanup: Delete all files in the upload directory if an error occurs
delete_all_files_in_directory ( upload_folder )
return jsonify ( { " error " : " Processing error " , " message " : f " An error occurred while processing the document: { str ( e ) } " } ) , 500
return jsonify ( { " error " : " File type not allowed " , " message " : " The uploaded file type is not allowed. Please upload a PDF, DOC, or DOCX file. " } ) , 400
2024-09-05 02:59:01 +00:00
@sops_bp.route ( ' /generate_questions_from_doc ' , methods = [ ' POST ' ] )
def generate_questions_from_sop ( ) :
2024-08-31 01:29:39 +00:00
# Check if the POST request has the file part
if ' document ' not in request . files :
return jsonify ( { " error " : " No file part " , " message " : " Please upload a file with the key ' document ' . " } ) , 400
print ( " Running................ " )
file = request . files [ ' document ' ]
roles_json = request . form . get ( ' roles ' ) # Get the roles as a JSON string
if not roles_json :
return jsonify ( { " error " : " No roles provided " , " message " : " Please provide a list of roles in the ' roles ' field. " } ) , 400
try :
roles = json . loads ( roles_json ) # Parse the roles from JSON string to a list
print ( f " Roles are: { roles } " )
except json . JSONDecodeError :
return jsonify ( { " error " : " Invalid JSON " , " message " : " The ' roles ' field contains invalid JSON. " } ) , 400
# If the user does not select a file, the browser may also submit an empty part without a filename
if file . filename == ' ' :
return jsonify ( { " error " : " No selected file " , " message " : " A file was not selected for upload. Please select a valid file. " } ) , 400
if file and allowed_file ( file . filename ) :
filename = secure_filename ( file . filename )
upload_folder = current_app . config [ ' UPLOAD_FOLDER ' ]
file_path = os . path . join ( upload_folder , filename )
# Save the file to the upload folder
file . save ( file_path )
try :
# Use the utility function to generate docs from the file
docs = load_document ( file_path )
# Check if the document can generate SOPs for the roles
status_check = sop_generator . check_role_sop ( roles = roles , docs = docs )
if not status_check [ " status " ] :
return jsonify ( { " error " : " Document cannot extract SOPs " , " message " : status_check [ " message " ] } ) , 400
# Generate SOPs based on the roles provided
2024-09-05 02:59:01 +00:00
sop_generator = SopGeneratorDocument ( )
sops = sop_generator . generate_sops_from_doc ( docs )
# Cleanup: Delete all files in the upload directory after processing
delete_all_files_in_directory ( upload_folder )
return jsonify ( { " sops " : sops , " message " : " SOPs successfully generated for the roles from the document. " } ) , 200
except Exception as e :
# Cleanup: Delete all files in the upload directory if an error occurs
delete_all_files_in_directory ( upload_folder )
return jsonify ( { " error " : " Processing error " , " message " : f " An error occurred while processing the document: { str ( e ) } " } ) , 500
return jsonify ( { " error " : " File type not allowed " , " message " : " The uploaded file type is not allowed. Please upload a PDF, DOC, or DOCX file. " } ) , 400
@sops_bp.route ( ' /generate_sops_from_doc ' , methods = [ ' POST ' ] )
def generate_sops ( ) :
# Check if the POST request has the file part
if ' document ' not in request . files :
return jsonify ( { " error " : " No file part " , " message " : " Please upload a file with the key ' document ' . " } ) , 400
print ( " Running................ " )
file = request . files [ ' document ' ]
# If the user does not select a file, the browser may also submit an empty part without a filename
if file . filename == ' ' :
return jsonify ( { " error " : " No selected file " , " message " : " A file was not selected for upload. Please select a valid file. " } ) , 400
if file and allowed_file ( file . filename ) :
filename = secure_filename ( file . filename )
upload_folder = current_app . config [ ' UPLOAD_FOLDER ' ]
file_path = os . path . join ( upload_folder , filename )
# Save the file to the upload folder
file . save ( file_path )
try :
# Use the utility function to generate docs from the file
docs = load_document ( file_path )
2024-08-31 01:29:39 +00:00
2024-09-05 02:59:01 +00:00
# Generate SOPs based on the roles provided
sop_generator = SopGeneratorDocument ( )
sops = sop_generator . extract_sops_from_doc ( docs )
2024-08-31 01:29:39 +00:00
# Cleanup: Delete all files in the upload directory after processing
delete_all_files_in_directory ( upload_folder )
2024-09-05 02:59:01 +00:00
if not sops :
return jsonify ( { " error " : " Error in generating sops " } )
2024-08-31 01:29:39 +00:00
return jsonify ( { " sops " : sops , " message " : " SOPs successfully generated for the roles from the document. " } ) , 200
except Exception as e :
# Cleanup: Delete all files in the upload directory if an error occurs
delete_all_files_in_directory ( upload_folder )
return jsonify ( { " error " : " Processing error " , " message " : f " An error occurred while processing the document: { str ( e ) } " } ) , 500
return jsonify ( { " error " : " File type not allowed " , " message " : " The uploaded file type is not allowed. Please upload a PDF, DOC, or DOCX file. " } ) , 400
2024-09-04 01:22:36 +00:00
2024-09-05 02:59:01 +00:00
@sops_bp.route ( ' /personal_assessment/generate_sops_from_questionnaire ' , methods = [ ' POST ' ] )
def generate_sops_from_questionnaire ( ) :
2024-09-04 01:22:36 +00:00
"""
2024-09-05 02:59:01 +00:00
Generate SOPs based on the questionnaire data provided in the request body.
The request body is expected to contain plain-text information for vision, roles, responsibilities, and project details.
2024-09-04 01:22:36 +00:00
"""
try :
2024-09-05 02:59:01 +00:00
# Get the questionnaire data from the request body
questionnaire_data = request . json
# Validate the required fields in the questionnaire data
if not questionnaire_data . get ( ' vision ' ) or not questionnaire_data . get ( ' roles ' ) or not questionnaire_data . get ( ' responsibilities ' ) :
return jsonify ( {
" error " : " Missing required fields " ,
" message " : " Please provide ' vision ' , ' roles ' , and ' responsibilities ' in the request body. "
} ) , 400
# Step 1: Call the function from the sop_generator
sop_generator = SopPersonalAssessment ( )
sops_response = sop_generator . extract_sops_from_questionnaire ( questionnaire_data )
# Step 2: Return the SOPs if the extraction is successful
if not sops_response :
return jsonify ( {
" error " : " SOP generation failed " ,
" message " : " Failed to generate SOPs based on the provided questionnaire data. "
} ) , 500
return jsonify ( {
" sops " : sops_response ,
" message " : " SOPs successfully generated based on the provided questionnaire data. "
} ) , 200
2024-09-04 01:22:36 +00:00
except Exception as e :
2024-09-05 02:59:01 +00:00
return jsonify ( {
" error " : " Processing error " ,
" message " : f " An error occurred while generating SOPs: { str ( e ) } "
} ) , 500
2024-09-04 01:22:36 +00:00
2024-09-05 02:59:01 +00:00
@sops_bp.route ( ' /personal_assessment/generate_sops_by_roles_and_areas ' , methods = [ ' POST ' ] )
def generate_sops_by_roles_and_areas ( ) :
"""
Generate SOPs based on the roles, SOP types (will, shall, must), and areas provided in the request body.
"""
2024-09-04 01:22:36 +00:00
try :
2024-09-05 02:59:01 +00:00
# Get the roles data from the request body
roles = request . json . get ( ' roles ' , None )
sop_generator = SopPersonalAssessment ( )
2024-09-04 01:22:36 +00:00
2024-09-05 02:59:01 +00:00
# Validate the presence of roles data
if not roles or not isinstance ( roles , list ) :
return jsonify ( { " error " : " Invalid input " , " message " : " The ' roles ' field should be a non-empty list. " } ) , 400
2024-09-04 01:22:36 +00:00
2024-09-05 02:59:01 +00:00
# Generate SOPs for all roles at once
sops_response = sop_generator . generate_sops_by_role_and_area ( roles = roles )
return jsonify ( {
" sops " : sops_response ,
" message " : " SOPs successfully generated for all provided roles. "
} ) , 200
except Exception as e :
return jsonify ( {
" error " : " Processing error " ,
" message " : f " An error occurred while generating SOPs: { str ( e ) } "
} ) , 500
2024-09-04 01:22:36 +00:00
@sops_bp.route ( ' /executive/generate_sops_from_questionnaire ' , methods = [ ' POST ' ] )
def generate_executive_sops_from_questionnaire ( ) :
try :
# Get data from the request body
data = request . json
# Generate SOPs based on the questionnaire answers
sops_response = sop_generator . generate_executive_sops_from_questionnaire ( data )
return jsonify ( { " sops " : sops_response , " message " : " SOPs successfully generated from the questionnaire. " } ) , 200
except Exception as e :
return jsonify ( { " error " : " Processing error " , " message " : f " An error occurred while generating SOPs: { str ( e ) } " } ) , 500
@sops_bp.route ( ' /executive/generate_sops_from_doc ' , methods = [ ' POST ' ] )
def generate_executive_sops_from_doc ( ) :
"""
Generate SOPs for executives based on a document containing vision and mission.
"""
# Check if the POST request has the file part
if ' document ' not in request . files :
return jsonify ( { " error " : " No file part " , " message " : " Please upload a file with the key ' document ' . " } ) , 400
file = request . files [ ' document ' ]
# If the user does not select a file, the browser may also submit an empty part without filename
if file . filename == ' ' :
return jsonify ( { " error " : " No selected file " , " message " : " A file was not selected for upload. Please select a valid file. " } ) , 400
if file and allowed_file ( file . filename ) :
filename = secure_filename ( file . filename )
upload_folder = current_app . config [ ' UPLOAD_FOLDER ' ]
file_path = os . path . join ( upload_folder , filename )
# Save the file to the upload folder
file . save ( file_path )
try :
# Use the utility function to generate docs from the file
docs = load_document ( file_path )
# Use LLM to extract Vision and Mission sections from the document
vision_section , mission_section = sop_generator . extract_vision_and_mission ( docs )
if not vision_section or not mission_section :
# Cleanup: Delete all files in the upload directory if parsing fails
delete_all_files_in_directory ( upload_folder )
return jsonify ( { " error " : " Missing Vision and Mission " , " message " : " The document does not contain or properly define the company ' s vision and mission. " } ) , 400
# Organize extracted data
extracted_data = {
" role " : " Executive " ,
" organization vision " : [ vision_section ] ,
" organization strategic goals " : [ mission_section ]
}
# Generate SOPs based on the extracted vision and goals
sops_response = sop_generator . generate_executive_sops_from_questionnaire ( extracted_data )
# Cleanup: Delete all files in the upload directory after processing
delete_all_files_in_directory ( upload_folder )
return jsonify ( { " sops " : sops_response , " message " : " SOPs successfully generated from the document. " } ) , 200
except Exception as e :
# Cleanup: Delete all files in the upload directory if an error occurs
delete_all_files_in_directory ( upload_folder )
return jsonify ( { " error " : " Processing error " , " message " : f " An error occurred while processing the document: { str ( e ) } " } ) , 500
return jsonify ( { " error " : " File type not allowed " , " message " : " The uploaded file type is not allowed. Please upload a PDF, DOC, or DOCX file. " } ) , 400