| Conditions | 10 |
| Total Lines | 102 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 2 | ||
| Bugs | 0 | Features | 1 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like PythonRunner.run() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
| 1 | # Licensed to the StackStorm, Inc ('StackStorm') under one or more |
||
| 109 | def run(self, action_parameters): |
||
| 110 | LOG.debug('Running pythonrunner.') |
||
| 111 | LOG.debug('Getting pack name.') |
||
| 112 | pack = self.get_pack_ref() |
||
| 113 | pack_db = Pack.get_by_ref(pack) |
||
| 114 | LOG.debug('Getting user.') |
||
| 115 | user = self.get_user() |
||
| 116 | LOG.debug('Serializing parameters.') |
||
| 117 | serialized_parameters = json.dumps(action_parameters) if action_parameters else '' |
||
| 118 | LOG.debug('Getting virtualenv_path.') |
||
| 119 | virtualenv_path = get_sandbox_virtualenv_path(pack=pack) |
||
| 120 | LOG.debug('Getting python path.') |
||
| 121 | if self._sandbox: |
||
| 122 | python_path = get_sandbox_python_binary_path(pack=pack) |
||
| 123 | else: |
||
| 124 | python_path = sys.executable |
||
| 125 | |||
| 126 | LOG.debug('Checking virtualenv path.') |
||
| 127 | if virtualenv_path and not os.path.isdir(virtualenv_path): |
||
| 128 | format_values = {'pack': pack, 'virtualenv_path': virtualenv_path} |
||
| 129 | msg = PACK_VIRTUALENV_DOESNT_EXIST % format_values |
||
| 130 | LOG.error('virtualenv_path set but not a directory: %s', msg) |
||
| 131 | raise Exception(msg) |
||
| 132 | |||
| 133 | LOG.debug('Checking entry_point.') |
||
| 134 | if not self.entry_point: |
||
| 135 | LOG.error('Action "%s" is missing entry_point attribute' % (self.action.name)) |
||
| 136 | raise Exception('Action "%s" is missing entry_point attribute' % (self.action.name)) |
||
| 137 | |||
| 138 | # Note: We pass config as command line args so the actual wrapper process is standalone |
||
| 139 | # and doesn't need access to db |
||
| 140 | LOG.debug('Setting args.') |
||
| 141 | args = [ |
||
| 142 | python_path, |
||
| 143 | '-u', # unbuffered mode so streaming mode works as expected |
||
| 144 | WRAPPER_SCRIPT_PATH, |
||
| 145 | '--pack=%s' % (pack), |
||
| 146 | '--file-path=%s' % (self.entry_point), |
||
| 147 | '--parameters=%s' % (serialized_parameters), |
||
| 148 | '--user=%s' % (user), |
||
| 149 | '--parent-args=%s' % (json.dumps(sys.argv[1:])), |
||
| 150 | ] |
||
| 151 | |||
| 152 | if self._config: |
||
| 153 | args.append('--config=%s' % (json.dumps(self._config))) |
||
| 154 | |||
| 155 | if self._log_level != 'debug': |
||
| 156 | # We only pass --log-level parameter if non default log level value is specified |
||
| 157 | args.append('--log-level=%s' % (self._log_level)) |
||
| 158 | |||
| 159 | # We need to ensure all the st2 dependencies are also available to the |
||
| 160 | # subprocess |
||
| 161 | LOG.debug('Setting env.') |
||
| 162 | env = os.environ.copy() |
||
| 163 | env['PATH'] = get_sandbox_path(virtualenv_path=virtualenv_path) |
||
| 164 | |||
| 165 | sandbox_python_path = get_sandbox_python_path(inherit_from_parent=True, |
||
| 166 | inherit_parent_virtualenv=True) |
||
| 167 | pack_common_libs_path = get_pack_common_libs_path(pack_db=pack_db) |
||
| 168 | |||
| 169 | if self._enable_common_pack_libs and pack_common_libs_path: |
||
| 170 | env['PYTHONPATH'] = pack_common_libs_path + ':' + sandbox_python_path |
||
| 171 | else: |
||
| 172 | env['PYTHONPATH'] = sandbox_python_path |
||
| 173 | |||
| 174 | # Include user provided environment variables (if any) |
||
| 175 | user_env_vars = self._get_env_vars() |
||
| 176 | env.update(user_env_vars) |
||
| 177 | |||
| 178 | # Include common st2 environment variables |
||
| 179 | st2_env_vars = self._get_common_action_env_variables() |
||
| 180 | env.update(st2_env_vars) |
||
| 181 | datastore_env_vars = self._get_datastore_access_env_vars() |
||
| 182 | env.update(datastore_env_vars) |
||
| 183 | |||
| 184 | stdout = StringIO() |
||
| 185 | stderr = StringIO() |
||
| 186 | |||
| 187 | store_execution_stdout_line = functools.partial(store_execution_output_data, |
||
| 188 | output_type='stdout') |
||
| 189 | store_execution_stderr_line = functools.partial(store_execution_output_data, |
||
| 190 | output_type='stderr') |
||
| 191 | |||
| 192 | read_and_store_stdout = make_read_and_store_stream_func(execution_db=self.execution, |
||
| 193 | action_db=self.action, store_data_func=store_execution_stdout_line) |
||
| 194 | read_and_store_stderr = make_read_and_store_stream_func(execution_db=self.execution, |
||
| 195 | action_db=self.action, store_data_func=store_execution_stderr_line) |
||
| 196 | |||
| 197 | command_string = list2cmdline(args) |
||
| 198 | LOG.debug('Running command: PATH=%s PYTHONPATH=%s %s' % (env['PATH'], env['PYTHONPATH'], |
||
| 199 | command_string)) |
||
| 200 | exit_code, stdout, stderr, timed_out = run_command(cmd=args, stdout=subprocess.PIPE, |
||
| 201 | stderr=subprocess.PIPE, shell=False, |
||
| 202 | env=env, |
||
| 203 | timeout=self._timeout, |
||
| 204 | read_stdout_func=read_and_store_stdout, |
||
| 205 | read_stderr_func=read_and_store_stderr, |
||
| 206 | read_stdout_buffer=stdout, |
||
| 207 | read_stderr_buffer=stderr) |
||
| 208 | LOG.debug('Returning values: %s, %s, %s, %s' % (exit_code, stdout, stderr, timed_out)) |
||
| 209 | LOG.debug('Returning.') |
||
| 210 | return self._get_output_values(exit_code, stdout, stderr, timed_out) |
||
| 211 | |||
| 348 |