Skip to main content
Version: 13

viktor.utils

memoize

viktor.utils.memoize(fun)

Decorator that applies memoization to a function. This can increase performance when the function is called multiple times with identical input.

When using multiple decorators, this should be the last decorator.

Warning

memoized keys will differ depending on parameters being passed as args or kwargs, which can cause a (unexpected) cache miss! For example, f(1, y=2) and f(x=1, y=2) will be treated as two different entries. Prefer to use functions with kwargs only to prevent this.

Example:

# In this example, a DataView performs a long-running calculation when
# calling `func`. When the user changes input in the editor and updates
# the view again, `func` will only be evaluated again if either one of
# `param_a`, `param_b`, or `param_c` is changed in-between jobs.

@memoize
def func(*, param_a, param_b, param_c):
    # perform lengthy calculation
    return result

class Controller(ViktorController):
    ...

    @DataView("Results", duration_guess=30)
    def get_data_view(self, params, **kwargs):
        ...
        result = func(param_a=..., param_b=..., param_c=...)
        ...

        return DataResult(...)

CAUTION: Only use this function when you are 100% sure of the following:

  • The function is a pure function (e.g. @staticmethod) meaning:

    • It always returns the same result for a given input. 1

    • It does not depend on other data and does not have side effects such as API calls or calls to others objects that persist state. 2

  • If part of the returning data contains a modified input, it must not be a problem that the memory reference is lost and a new object is returned.

  • The input of the function is serializable. 3

  • The output of the function is serializable. 3

  • During memoization, tuples in the input are casted to lists before determining uniqueness.

  • During memoization, tuples in the output are casted to lists before returning.

  • In the design of your application you should take into account that the application should not fail in timeouts/unresponsiveness if the memoization does not work. It should be a bonus if it works.

  • The function name is unique within the Python file.

1

Variables/objects/functions defined outside of the memoized function are not used in the memoized function.

2

The function should only return results. Any other actions defined in the function are not performed if the function call is memoized.

3(1,2)

‘Serializable’ in this context means the data is any of the following types: boolean, dictionary, float, int, list, none, string, tuple. Types as returned in the ‘params’ are also allowed (e.g. GeoPoint, FileResource, datetime.date, etc.) with the exception of Entity. When data is nested, the nesting can only contain any of the aforementioned types.

Practical uses of this are, but not limited to, function calls with input and output that is relatively small compared to the amount of time required for the evaluation.

Note

When using the memoization decorator on your development environment the cache is stored locally. The local storage is limited to 10 function calls. If the limit is exceeded, cached results are cleared based on a first in, first out approach. In production the storage is not limited to 10 function calls.

Parameters

fun (Callable) – original function

Return type

Callable

render_jinja_template

viktor.utils.render_jinja_template(template, variables)

Render a template using Jinja.

Example usage:

with open("path/to/template.jinja", 'rb') as template:
    result = render_jinja_template(template, {'name': 'John Doe'})

Note

This method needs to be mocked in (automated) unit and integration tests.

Parameters
  • template (BinaryIO) – Jinja template file.

  • variables (dict) – set of variables to fill the template with.

Return type

File

Returns

File object containing the rendered template

merge_pdf_files

viktor.utils.merge_pdf_files(*files)

This method can be used to merge several PDFs into one document. BinaryIO objects can be directly used as arguments in the method. The merged document is returned as a File object. The order of the input files is preserved in the resulting document.

Example usages:

from viktor.core import File

# using File object
file1 = File.from_path(Path(__file__).parent / "pdf1.pdf")
file2 = File.from_path(Path(__file__).parent / "pdf2.pdf")
with file1.open_binary() as f1, file2.open_binary() as f2:
    merged_pdf = merge_pdf_files(f1, f2)

# using built-in `open()`
with open(Path(__file__).parent / "pdf1.pdf", "rb") as f1, open(Path(__file__).parent / "pdf2.pdf", "rb") as f2:
    merged_pdf = merge_pdf_files(f1, f2)

Note

This method needs to be mocked in (automated) unit and integration tests.

Return type

File

Returns

File object containing merged document.

convert_word_to_pdf

viktor.utils.convert_word_to_pdf(file)

Convert a Word document to PDF.

Example usages:

from viktor.core import File

# using File object
file1 = File.from_path(Path(__file__).parent / "mydocument.docx")
with file1.open_binary() as f1:
    pdf = convert_word_to_pdf(f1)

# using built-in `open()`
with open(Path(__file__).parent / "mydocument.docx", "rb") as f1:
    pdf = convert_word_to_pdf(f1)

Note

This method needs to be mocked in (automated) unit and integration tests.

Parameters

file (BinaryIO) – Document to be converted.

Return type

File

Returns

File object containing converted document.

convert_excel_to_pdf

viktor.utils.convert_excel_to_pdf(file)

Convert an Excel document to PDF.

Example usages:

from viktor.core import File

# using File object
file1 = File.from_path(Path(__file__).parent / "mydocument.xlsx")
with file1.open_binary() as f1:
    pdf = convert_excel_to_pdf(f1)

# using built-in `open()`
with open(Path(__file__).parent / "mydocument.xlsx", "rb") as f1:
    pdf = convert_excel_to_pdf(f1)

Note

This method needs to be mocked in (automated) unit and integration tests.

Parameters

file (BinaryIO) – Document to be converted.

Return type

File

Returns

File object containing converted document.

convert_svg_to_pdf

viktor.utils.convert_svg_to_pdf(file)

Convert a SVG document to PDF.

Example usages:

from viktor.core import File

# using File object
file1 = File.from_path(Path(__file__).parent / "mydocument.svg")
with file1.open_binary() as f1:
    pdf = convert_svg_to_pdf(f1)

# using built-in `open()`
with open(Path(__file__).parent / "mydocument.svg", "rb") as f1:
    pdf = convert_svg_to_pdf(f1)

Note

This method needs to be mocked in (automated) unit and integration tests.

Parameters

file (BinaryIO) – Document to be converted.

Return type

File

Returns

File object containing converted document.