def download_file_from_variable(self, variable_name: str) -> str:
        """
        For performance reasons, files are not retrieved automatically during `fetch workload`. If your task requires
        a file that is attached to a process instance, you need to download the file explicitly.

        Example:
            | ${variables} | *fetch workload* | _first_task_in_demo_ |
            | | *Dictionary Should Contain Key* | _${variables}_ | _my_file_ |
            | ${file} | *Download File From Variable* | ${variables}[my_file] | |
        """
        if not self.FETCH_RESPONSE:
            logger.warn(
                'Could not download file for variable. Maybe you did not fetch and lock a workitem before?'
            )
        else:
            with self._shared_resources.api_client as api_client:
                api_instance = openapi_client.ProcessInstanceApi(api_client)

                try:
                    response = api_instance.get_process_instance_variable_binary(
                        id=self.FETCH_RESPONSE.process_instance_id,
                        var_name=variable_name)
                    logger.debug(response)
                except ApiException as e:
                    raise ApiException(
                        f"Exception when calling ExternalTaskApi->get_process_instance_variable_binary: {e}\n"
                    )
                return response
 def throw_bpmn_error(self,
                      error_code: str,
                      error_message: str = None,
                      variables: Dict[str, Any] = None,
                      files: Dict = None):
     if not self.FETCH_RESPONSE:
         logger.warn(
             'No task to complete. Maybe you did not fetch and lock a workitem before?'
         )
     else:
         with self._shared_resources.api_client as api_client:
             api_instance = openapi_client.ExternalTaskApi(api_client)
             variables = CamundaResources.convert_dict_to_openapi_variables(
                 variables)
             openapi_files = CamundaResources.convert_file_dict_to_openapi_variables(
                 files)
             variables.update(openapi_files)
             bpmn_error = openapi_client.ExternalTaskBpmnError(
                 worker_id=self.WORKER_ID,
                 error_message=error_message,
                 error_code=error_code,
                 variables=variables)
             try:
                 logger.debug(f"Sending BPMN error for task:\n{bpmn_error}")
                 api_instance.handle_external_task_bpmn_error(
                     self.FETCH_RESPONSE.id,
                     external_task_bpmn_error=bpmn_error)
                 self.drop_fetch_response()
             except ApiException as e:
                 raise ApiException(
                     f"Exception when calling ExternalTaskApi->handle_external_task_bpmn_error: {e}\n"
                 )
    def fetch_and_lock_workloads(self, topic, **kwargs) -> Dict:
        """*DEPRECATED*

        Use `fetch workload`
        """
        logger.warn(
            'Keyword "Fetch and Lock workloads" is deprecated. Use "Fetch workload" instead.'
        )
        return self.fetch_workload(topic, **kwargs)
    def deploy_model_from_file(self, path_to_model):
        """*DEPRECATED*

        Use `Deploy`
        """
        logger.warn(
            'Keyword "Deploy Model From File" is deprecated. Use "Deploy" instead.'
        )
        return self.deploy(path_to_model)
    def complete_task(self,
                      result_set: Dict[str, Any] = None,
                      files: Dict = None):
        """
        Completes the task that was fetched before with `fetch workload`.

        *Requires `fetch workload` to run before this one, logs warning instead.*

        Additional variables can be provided as dictionary in _result_set_ .
        Files can be provided as dictionary of filename and patch.

        Examples:

            | _# fetch and immediately complete_ |
            | | *fetch workload* | _my_topic_ |
            | | *complete task* | |
            | |
            | _# fetch and complete with return values_ |
            | | *fetch workload* | _decide_on_dish_ |
            | ${new_variables} | *Create Dictionary* | _my_dish=salad_ |
            | | *complete task* | _result_set=${new_variables}_ |
            | |
            | _# fetch and complete with return values and files_ |
            | | *fetch workload* | _decide_on_haircut_ |
            | ${return_values} | *Create Dictionary* | _style=short hair_ |
            | ${files} | *Create Dictionary* | _should_look_like=~/favorites/beckham.jpg_ |
            | | *complete task* | _${return_values}_ | _${files}_ |
        """
        if not self.FETCH_RESPONSE:
            logger.warn(
                'No task to complete. Maybe you did not fetch and lock a workitem before?'
            )
        else:
            with self._shared_resources.api_client as api_client:
                api_instance = openapi_client.ExternalTaskApi(api_client)
                variables = CamundaResources.convert_dict_to_openapi_variables(
                    result_set)
                openapi_files = CamundaResources.convert_file_dict_to_openapi_variables(
                    files)
                variables.update(openapi_files)
                complete_task_dto = openapi_client.CompleteExternalTaskDto(
                    worker_id=self.WORKER_ID, variables=variables)
                try:
                    logger.debug(
                        f"Sending to Camunda for completing Task:\n{complete_task_dto}"
                    )
                    api_instance.complete_external_task_resource(
                        self.FETCH_RESPONSE.id,
                        complete_external_task_dto=complete_task_dto)
                    self.drop_fetch_response()
                except ApiException as e:
                    raise ApiException(
                        f"Exception when calling ExternalTaskApi->complete_external_task_resource: {e}\n"
                    )
 def reset_task_lock_duration(self):
     """
     Counter keyword for "Set Task Lock Duration". Resets lock duration to the default. The default is either
     environment variable CAMUNDA_TASK_LOCK_DURATION or 600000 (10 minutes).
     """
     try:
         lock_duration = int(
             os.environ.get('CAMUNDA_TASK_LOCK_DURATION', 600000))
     except ValueError as e:
         logger.warn(
             f'Failed to interpret "CAMUNDA_TASK_LOCK_DURATION". Environment variable does not seem to contain a valid integer:\t{e}'
         )
         lock_duration = 600000
     return lock_duration
 def unlock(self):
     """
     Unlocks recent task.
     """
     if not self.FETCH_RESPONSE:
         logger.warn(
             'No task to unlock. Maybe you did not fetch and lock a workitem before?'
         )
     else:
         with self._shared_resources.api_client as api_client:
             api_instance = openapi_client.ExternalTaskApi(api_client)
             try:
                 api_instance.unlock(self.FETCH_RESPONSE.id)
                 self.drop_fetch_response()
             except ApiException as e:
                 logger.error(
                     f"Exception when calling ExternalTaskApi->unlock: {e}\n"
                 )
    def download_file_from_variable(self, variable_name: str) -> str:
        if not self.FETCH_RESPONSE:
            logger.warn(
                'Could not download file for variable. Maybe you did not fetch and lock a workitem before?'
            )
        else:
            with self._shared_resources.api_client as api_client:
                api_instance = openapi_client.ProcessInstanceApi(api_client)

                try:
                    response = api_instance.get_process_instance_variable_binary(
                        id=self.FETCH_RESPONSE.process_instance_id,
                        var_name=variable_name)
                    logger.debug(response)
                except ApiException as e:
                    logger.error(
                        f"Exception when calling ExternalTaskApi->get_process_instance_variable_binary: {e}\n"
                    )
                return response
    def get_process_instance_id(self):
        """*DEPRECATED*
        _Use `get fetch response` instead and check for ``process_instance_id`` element on the fetch reponse:
        ``fetch_response[process_instance]``_

        Returns cached process instance id from previously called `fetch and lock workloads`.

        *Only this keyword can certainly tell, if workload has been fetched from Camunda*

        Example:
            | ${variables} | fetch and lock workloads | my_first_task_in_demo | |
            | Run keyword if | not ${variables} | log | No variables found, but is due to lack of variables or because no workload was available? Must check process instance |
            | ${process_instance} | get recent process instance | | |
            | Run keyword if | ${process_instance} | complete task | |
        """
        logger.warn('Method is deprecated. Use "Get fetch response"')
        if self.FETCH_RESPONSE:
            return self.FETCH_RESPONSE.process_instance_id
        return self.EMPTY_STRING
    def notify_failure(self, **kwargs):
        """
        Raises a failure to Camunda. When retry counter is less than 1, an incident is created by Camunda.

        You can specify number of retries with the *retries* argument. If current fetched process instance already has
        *retries* parameter set, the *retries* argument of this keyword is ignored. Instead, the retries counter will
        be decreased by 1.

        CamundaLibrary takes care of providing the worker_id and task_id. *retry_timeout* is equal to *lock_duration* for external tasks.
        Check for camunda client documentation for all parameters of the request body: https://noordsestern.gitlab.io/camunda-client-for-python/7-15-0/docs/ExternalTaskApi.html#handle_failure

        Example:
        | *notify failure* |  |  |
        | *notify failure* | retries=3 | error_message=Task failed due to... |
        """
        current_process_instance = self.FETCH_RESPONSE
        if not current_process_instance:
            logger.warn(
                'No task to notify failure for. Maybe you did not fetch and lock a workitem before?'
            )
        else:
            with self._shared_resources.api_client as api_client:
                api_instance = openapi_client.ExternalTaskApi(api_client)
                if 'retry_timeout' not in kwargs or None is kwargs[
                        'retry_timeout'] or not kwargs['retry_timeout']:
                    kwargs['retry_timeout'] = self.DEFAULT_LOCK_DURATION

                if None is not current_process_instance.retries:
                    kwargs['retries'] = current_process_instance.retries - 1

                external_task_failure_dto = ExternalTaskFailureDto(
                    worker_id=self.WORKER_ID, **kwargs)

                try:
                    api_instance.handle_failure(
                        id=current_process_instance.id,
                        external_task_failure_dto=external_task_failure_dto)
                    self.drop_fetch_response()
                except ApiException as e:
                    raise ApiException(
                        "Exception when calling ExternalTaskApi->handle_failure: %s\n"
                        % e)