Skip to main content

Generic integration

VIKTOR offers a generic integration, which can be used to integrate with any software package that supports command-line interaction. The GenericAnalysis class is used for this, which requires one or multiple input files. Furthermore, you need to specify an executable_key to instruct the worker to call a specific task as defined in the configuration file (config.yaml).

VIKTOR's generic integration requires a Generic worker.

from viktor.external.generic import GenericAnalysis

# Generate the input file(s)
files = [
('input1.txt', file1),
('input2.txt', file2)
]

# Run the analysis and obtain the output file.
generic_analysis = GenericAnalysis(files=files, executable_key="some_executable", output_filenames=["output.txt"])
generic_analysis.execute(timeout=60)
output_file = generic_analysis.get_output_file("output.txt")

The executable_key in the example above refers to the "some_executable" command. This command should also be specified in the configuration file on the server, located in the same directory as the worker:

config.yaml

executables:
some_executable:
path: 'C:\path\to\executable.exe'
arguments:
- '-arg1'
- '-arg2'
- '-arg3'
workingDirectoryPath: 'C:\path\to\script'
maxParallelProcesses: 1 # must be 1 if any of the above workingDirectoryPath is not '' (stateful path)
note

If a fixed workingDirectoryPath is defined in the configuration file the maximum number of parallel processes should be 1. When the workingDirectoryPath is not specified a temporary directory will be created to run each job. This allows for a maxParallelProcesses > 1.

note

The worker reads the config file once during startup. So when you change the config file, you will need to restart the worker for your changes to take effect.

With this setup, we can basically run any third-party software which supports command-line execution. A few specific examples are provided in the guides below:

And many more!

Testing

New in v13.5.0

mock_GenericAnalysis decorator for easier testing of GenericAnalysis

GenericAnalysis.execute needs to be mocked within the context of (automated) testing.

The viktor.testing module provides the mock_GenericAnalysis decorator that facilitate mocking of workers:

import unittest

from viktor import File
from viktor.testing import mock_GenericAnalysis

from app.my_entity_type.controller import MyEntityTypeController

class TestMyEntityTypeController(unittest.TestCase):

@mock_GenericAnalysis(get_output_file={
'result.xml': File.from_path('test_file.xml'), # <name>: <File>
'result.json': File.from_path('test_file.json'),
...
})
def test_generic_analysis(self):
MyEntityTypeController().generic_analysis()

For the decorator's input parameters the following holds:

  • If a Sequence type is provided, the next entry is returned for each corresponding method call. When a call is performed on a depleted iterable, an Exception is raised.
  • If a single object is provided, the object is returned each time the corresponding method is called (endlessly).
  • If None is provided (default), a default File/BytesIO object (with empty content) is returned each time the corresponding method is called (endlessly).