mirror of
https://github.com/sasjs/server.git
synced 2026-01-03 21:10:05 +00:00
feat: implement the logic for running python stored programs
This commit is contained in:
@@ -4,9 +4,9 @@ import { createFolder, fileExists, folderExists, isWindows } from '@sasjs/utils'
|
||||
import { RunTimeType } from './verifyEnvVariables'
|
||||
|
||||
export const getDesktopFields = async () => {
|
||||
const { SAS_PATH, NODE_PATH } = process.env
|
||||
const { SAS_PATH, NODE_PATH, PYTHON_PATH } = process.env
|
||||
|
||||
let sasLoc, nodeLoc
|
||||
let sasLoc, nodeLoc, pythonLoc
|
||||
|
||||
if (process.runTimes.includes(RunTimeType.SAS)) {
|
||||
sasLoc = SAS_PATH ?? (await getSASLocation())
|
||||
@@ -16,7 +16,11 @@ export const getDesktopFields = async () => {
|
||||
nodeLoc = NODE_PATH ?? (await getNodeLocation())
|
||||
}
|
||||
|
||||
return { sasLoc, nodeLoc }
|
||||
if (process.runTimes.includes(RunTimeType.JS)) {
|
||||
pythonLoc = PYTHON_PATH ?? (await getPythonLocation())
|
||||
}
|
||||
|
||||
return { sasLoc, nodeLoc, pythonLoc }
|
||||
}
|
||||
|
||||
const getDriveLocation = async (): Promise<string> => {
|
||||
@@ -91,3 +95,25 @@ const getNodeLocation = async (): Promise<string> => {
|
||||
|
||||
return targetName
|
||||
}
|
||||
|
||||
const getPythonLocation = async (): Promise<string> => {
|
||||
const validator = async (filePath: string) => {
|
||||
if (!filePath) return 'Path to Python executable is required.'
|
||||
|
||||
if (!(await fileExists(filePath))) {
|
||||
return 'No file found at provided path.'
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
const defaultLocation = isWindows() ? 'C:\\Python' : '/usr/bin/python'
|
||||
|
||||
const targetName = await getString(
|
||||
'Please enter full path to a Python executable: ',
|
||||
validator,
|
||||
defaultLocation
|
||||
)
|
||||
|
||||
return targetName
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { RunTimeType } from '.'
|
||||
|
||||
export const getRunTimeAndFilePath = async (programPath: string) => {
|
||||
const ext = path.extname(programPath)
|
||||
// If programPath (_program) is provided with a ".sas" or ".js" extension
|
||||
// If programPath (_program) is provided with a ".sas", ".js" or ".py" extension
|
||||
// we should use that extension to determine the appropriate runTime
|
||||
if (ext && Object.values(RunTimeType).includes(ext.slice(1) as RunTimeType)) {
|
||||
const runTime = ext.slice(1)
|
||||
|
||||
@@ -28,11 +28,13 @@ export const setProcessVariables = async () => {
|
||||
if (MODE === ModeType.Server) {
|
||||
process.sasLoc = process.env.SAS_PATH
|
||||
process.nodeLoc = process.env.NODE_PATH
|
||||
process.pythonLoc = process.env.PYTHON_PATH
|
||||
} else {
|
||||
const { sasLoc, nodeLoc } = await getDesktopFields()
|
||||
const { sasLoc, nodeLoc, pythonLoc } = await getDesktopFields()
|
||||
|
||||
process.sasLoc = sasLoc
|
||||
process.nodeLoc = nodeLoc
|
||||
process.pythonLoc = pythonLoc
|
||||
}
|
||||
|
||||
const { SASJS_ROOT } = process.env
|
||||
|
||||
@@ -126,9 +126,34 @@ export const generateFileUploadJSCode = async (
|
||||
}
|
||||
})
|
||||
|
||||
if (fileCount) {
|
||||
uploadCode = `\nconst _WEBIN_FILE_COUNT = ${fileCount}` + uploadCode
|
||||
}
|
||||
uploadCode += `\nconst _WEBIN_FILE_COUNT = ${fileCount}`
|
||||
|
||||
return uploadCode
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the python code that references uploaded files in the concurrent request
|
||||
* @param filesNamesMap object that maps hashed file names and original file names
|
||||
* @param sessionFolder name of the folder that is created for the purpose of files in concurrent request
|
||||
* @returns generated python code
|
||||
*/
|
||||
export const generateFileUploadPythonCode = async (
|
||||
filesNamesMap: FilenamesMap,
|
||||
sessionFolder: string
|
||||
) => {
|
||||
let uploadCode = ''
|
||||
let fileCount = 0
|
||||
|
||||
const sessionFolderList: string[] = await listFilesInFolder(sessionFolder)
|
||||
sessionFolderList.forEach(async (fileName) => {
|
||||
if (fileName.includes('req_file')) {
|
||||
fileCount++
|
||||
uploadCode += `\n_WEBIN_FILENAME${fileCount} = '${filesNamesMap[fileName].originalName}'`
|
||||
uploadCode += `\n_WEBIN_NAME${fileCount} = '${filesNamesMap[fileName].fieldName}'`
|
||||
}
|
||||
})
|
||||
|
||||
uploadCode += `\n_WEBIN_FILE_COUNT = ${fileCount}`
|
||||
|
||||
return uploadCode
|
||||
}
|
||||
|
||||
@@ -28,7 +28,8 @@ export enum LOG_FORMAT_MORGANType {
|
||||
|
||||
export enum RunTimeType {
|
||||
SAS = 'sas',
|
||||
JS = 'js'
|
||||
JS = 'js',
|
||||
PY = 'py'
|
||||
}
|
||||
|
||||
export enum ReturnCode {
|
||||
@@ -228,7 +229,7 @@ const verifyRUN_TIMES = (): string[] => {
|
||||
|
||||
const verifyExecutablePaths = () => {
|
||||
const errors: string[] = []
|
||||
const { RUN_TIMES, SAS_PATH, NODE_PATH, MODE } = process.env
|
||||
const { RUN_TIMES, SAS_PATH, NODE_PATH, PYTHON_PATH, MODE } = process.env
|
||||
|
||||
if (MODE === ModeType.Server) {
|
||||
const runTimes = RUN_TIMES?.split(',')
|
||||
@@ -240,6 +241,10 @@ const verifyExecutablePaths = () => {
|
||||
if (runTimes?.includes(RunTimeType.JS) && !NODE_PATH) {
|
||||
errors.push(`- NODE_PATH is required for ${RunTimeType.JS} run time`)
|
||||
}
|
||||
|
||||
if (runTimes?.includes(RunTimeType.PY) && !PYTHON_PATH) {
|
||||
errors.push(`- PYTHON_PATH is required for ${RunTimeType.PY} run time`)
|
||||
}
|
||||
}
|
||||
|
||||
return errors
|
||||
|
||||
Reference in New Issue
Block a user