import { injectable } from 'inversify' ; import { ErrorUtils } from '../errors/errorUtils' ; import { ModuleNotInstalledError } from '../errors/moduleNotInstalledError' ; import { ExecutionResult , IProcessService , IPythonExecutionService , SpawnOptions } from './types' ; @ injectable ( ) export class PythonExecutionService implements IPythonExecutionService { constructor ( private readonly procService , private readonly pythonPath ) { } public async isModuleInstalled ( moduleName , env ? ) { return this . procService . exec ( this . pythonPath , [ '-c' , `import ${ moduleName }` ] , { throwOnStdErr : true , env } ) . then ( ( ) => true ) . catch ( ( ) => false ) ; } public async exec ( args , options ) { const opts = { ... options } ; return this . procService . exec ( this . pythonPath , args , opts ) ; } public async execModule ( moduleName , args , options ) { const opts = { ... options } ; const result = await this . procService . exec ( this . pythonPath , [ '-m' , moduleName , ... args ] , opts ) ; if ( moduleName && ErrorUtils . outputHasModuleNotInstalledError ( moduleName ! , result . stderr ) ) { const isInstalled = await this . isModuleInstalled ( moduleName ! ) ; if ( ! isInstalled ) { throw new ModuleNotInstalledError ( moduleName ! ) ; } } return result ; } }