Deprecations & Upgrades
This document lists all current deprecations, with upgrade steps and planned removal. When the deprecation is removed with a major update, it will be moved under its corresponding header.
All available upgrades of the current SDK major version can be performed at once by using:
viktor-cli fix
Current version
U91 - Remove support for Python 3.9
- planned removal: October 2025
- automated code fix available: no
Current behaviour + reason for change
VIKTOR currently supports Python 3.9 - 3.13, however version 3.9 will soon reach its end-of-life. This means that the VIKTOR SDK will no longer be built for Python 3.9 in the future.
New behaviour
The VIKTOR SDK will no longer be available in combination with Python 3.9.
Conversion
Update the python_version
in the viktor.config.toml
file:
python_version = '3.13' # '3.13' | '3.12' | '3.11' | '3.10'
Please make sure to update your code in case you are using Python features that are no longer available in the Python version you are upgrading to.
U90 - GeometryView initial x-axis orientation will be to the right by default
- deprecated since: v14.8.0
- planned removal: v15
- automated code fix available: yes
Current behaviour + reason for change
Currently, the 3D GeometryView has its initial x-axis orientation to the left by default. In most other software, the convention is to have the x-axis point to the right.
New behaviour
In the new situation it is possible to set the initial x-axis orientation on the GeometryView
by means of the
x_axis_to_right
setting (currently only supported for view_mode='3D'
and up_axis='Z'
). The default will be
x_axis_to_right=True
.
Conversion
Update your GeometryView
with x_axis_to_right=False
to explicitly accept that the initial x-axis orientation is to
the left. This can be done automatically by using the CLI command viktor-cli fix -u 90
:
- @GeometryView(...)
+ @GeometryView(..., x_axis_to_right=False)
- @GeometryAndDataView(...)
+ @GeometryAndDataView(..., x_axis_to_right=False)
Alternatively, to change the initial orientation of the x-axis to point to the right you can set x_axis_to_right=True
(no automated code fix). If it is desired that the initial point of view of the geometry remains unchanged, rotate your
geometry accordingly to compensate for the change in orientation:
- @GeometryView(...)
+ @GeometryView(..., x_axis_to_right=True)
...
+ geometry = geometry.rotate(angle=-0.5*math.pi, direction=(0, 0, 1))
GeometryResult(geometry)
U89 - Remove support for Python 3.8
- planned removal: October 2024
- automated code fix available: no
Current behaviour + reason for change
VIKTOR currently supports Python 3.8 - 3.12, however version 3.8 will soon reach its end-of-life. This means that the VIKTOR SDK will no longer be built for Python 3.8 in the future.
New behaviour
The VIKTOR SDK will no longer be available in combination with Python 3.8.
Conversion
Update the python_version
in the viktor.config.toml
file:
python_version = '3.9' # '3.9' | '3.10' | '3.11' | '3.12'
Please make sure to update your code in case you are using Python features that will no longer be available in Python 3.9 or higher.
U88 - Remove always_available
from buttons
- deprecated since: v14.7.0
- planned removal: v15
- automated code fix available: yes
always_available
from buttonsCurrent behaviour + reason for change
The always_available
argument can be set on action buttons, but doesn't do anything. The argument could cause
confusion and makes the SDK reference less readable.
New behaviour
The always_available
argument will be removed. The following fields are affected:
DownloadButton
SetParamsButton
ActionButton
(AnalyseButton
)OptimizationButton
(OptimiseButton
)BooleanField
(ToggleButton
)
Conversion
The following conversion has to be performed, which can be done automatically by using the CLI command
viktor-cli fix -u 88
:
- download_button = DownloadButton("Download X", method="download_x", always_available=True)
+ download_button = DownloadButton("Download X", method="download_x")
U87 - Rename Material
threejs properties
- deprecated since: v14.5.0
- planned removal: v15
- automated code fix available: yes
Material
threejs propertiesCurrent behaviour + reason for change
On a Material
you can currently set the following properties that are prefixed with threejs_
:
threejs_metalness
threejs_opacity
threejs_roughness
threejs_type
Since material properties are not necessarily bound to ThreeJS, they will be renamed / removed.
New behaviour
The following renames will be applied:
threejs_metalness
->metalness
threejs_opacity
->opacity
threejs_roughness
->roughness
threejs_type
is no longer used and will be removed completely.
Conversion
The following conversion needs to be applied, which can be done automatically by using the CLI command
viktor-cli fix -u 87
:
- concrete = Material("Concrete", threejs_metalness=1, threejs_opacity=1, threejs_roughness=1, threejs_type="X")
+ concrete = Material("Concrete", metalness=1, opacity=1, roughness=1)
Removed in v14
U86 - Remove support for Python 3.7
- deprecated since: CLI v0.29.2
- automated code fix available: no
Current behaviour + reason for change
VIKTOR currently supports Python 3.7 - 3.11, however version 3.7 will soon reach its end-of-life. This means that the VIKTOR SDK will no longer be built for Python 3.7 in the future.
New behaviour
The VIKTOR SDK will no longer be available in combination with Python 3.7.
Conversion
Update the python_version
in the viktor.config.toml
file:
python_version = '3.11' # '3.8' | '3.9' | '3.10' | '3.11'
Please make sure to update your code in case you are using Python features that will no longer be available in Python 3.8 or higher.
U85 - Remove leading hashtag for viktor
dependency
- deprecated since: CLI v0.29.0
- automated code fix available: yes
viktor
dependencyCurrent behaviour + reason for change
Specifying viktor
as dependency in the requirements.txt file requires a leading hashtag, which differs from other
external dependencies. Since the viktor
package is now publicly available on PyPI, the leading hashtag is no longer
necessary.
New behaviour
Specifying # viktor
in the requirements.txt file will no longer be supported.
Conversion
The following conversion needs to be applied, which can be done automatically by submitting "yes" when the CLI asks to apply the diff:
- # viktor==X.X.X
+ viktor==X.X.X
U84 - UserException replaced by UserError
- deprecated since: v13.7.0
- automated code fix available: yes
Current behaviour + reason for change
A UserException
can be raised by the app to inform the user of an error. Since the term UserException
does not
adhere to the naming conventions, we decided to replace it by
UserError
. In addition, UserError
allows for marking of fields invalid in the interface, to improve user experience.
New behaviour
UserException
will no longer be available in the future, and will be replaced by UserError
.
Conversion
The following conversion needs to be applied, which can be done automatically by using the CLI command
viktor-cli fix -u 84
:
- from viktor import UserException
+ from viktor import UserError
- raise UserException("message")
+ raise UserError("message")
U83 - Violated field constraints block actions
- deprecated since: v13.7.0
- automated code fix available: partly
Current behaviour + reason for change
When a field constraint is violated by the user, he / she is still able to perform actions which potentially make use of the invalid value. This can lead to erroneous calculation results, which is undesired.
New behaviour
In order to protect and guide the user in a better way, violation of field constraints will block actions in the future. The constraints that are automatically assessed by the platform are:
- Numeric min/max boundary (
IntegerField
/NumberField
/DynamicArray
) - Non-existing option (
OptionField
/MultiSelectField
/AutocompleteField
) - Non-existing coordinate (
GeoPointField
/GeoPolylineField
/GeoPolygonField
) - Invalid date format (
DateField
)
By defining viktor_enforce_field_constraints = True
on the controller class, this behavior can be simulated:
class Controller(ViktorController):
viktor_enforce_field_constraints = True
Conversion
Add a viktor_enforce_field_constraints
class attribute on the Controller
and set it to True. This can be done
automatically by using the CLI command viktor-cli fix -u 83
:
class Controller(ViktorController):
+ viktor_enforce_field_constraints = True
Unfortunately we cannot automatically fix your app logic because we do not know the intentions of your code. If, for
example, exceeding of the max
value of a NumberField
is perfectly fine, you could log a warning to the user,
instead of using the max
constraint on the NumberField
itself:
def my_view(self, params, **kwargs):
if params.height > 5:
progress_message('WARNING: height should be smaller than 5!')
# optionally add a sleep to show the message for longer period of time
...
U82 - Specific image views replaced by ImageView
- deprecated since: v13.7.0
- automated code fix available: yes
ImageView
Current behaviour + reason for change
We currently offer a specific view per image type ('png' / 'jpg' / 'svg'). This inseparable relation between view and
image type makes implementation of these views limited and inflexible. For example, in case the type of a result image
can be either 'png' or 'jpg', you are forced to implement 2 views instead of 1. The individual views will therefore be
replaced by the generic ImageView
(and ImageAndDataView
). The corresponding results will be replaced by the generic
ImageResult
(and ImageAndDataResult
).
New behaviour
PNGView
,JPGView
, andSVGView
will be replaced byImageView
in the future.PNGAndDataView
,JPGAndDataView
, andSVGAndDataView
will be replaced byImageAndDataView
in the future.PNGResult
,JPGResult
, andSVGResult
will be replaced byImageResult
in the future.PNGAndDataResult
,JPGAndDataResult
, andSVGAndDataResult
will be replaced byImageAndDataResult
in the future.
Conversion
The following conversion needs to be applied, which can be done automatically by using the CLI command
viktor-cli fix -u 82
:
- from viktor.views import PNGView, PNGResult
+ from viktor.views import ImageView, ImageResult
- @PNGView(...)
+ @ImageView(...)
def my_view(self, params, **kwargs):
...
- return PNGResult(...)
+ return ImageResult(...)
A similar conversion is required for all other views that are listed above.
U81 - Remove open_ends
from CircularExtrusion
- deprecated since: v13.6.0
- automated code fix available: yes
open_ends
from CircularExtrusion
Current behaviour + reason for change
A CircularExtrusion
can have open or closed ends depending on the open_ends
argument:
open_ends=False
(default): the extrusion is a solidopen_ends=True
: the extrusion is a shell with zero thickness
It is not possible to create a shell with a certain thickness. The additional shell_thickness
can be used to
achieve this, which makes the open_ends
argument redundant.
New behaviour
The open_ends
argument will be removed in the future.
Conversion
The following conversion needs to be applied, which can be done automatically by using the CLI command
viktor-cli fix -u 81
:
- CircularExtrusion(..., open_ends=True)
+ CircularExtrusion(..., shell_thickness=0)
- CircularExtrusion(..., open_ends=False)
+ CircularExtrusion(..., shell_thickness=None)
U80 - Remove min_message
and max_message
from NumberField
/IntegerField
- deprecated since: v13.5.0
- automated code fix available: yes
min_message
and max_message
from NumberField
/IntegerField
Current behaviour + reason for change
The min_message
and max_message
arguments on NumberField
/IntegerField
currently do not work as expected (they
are ignored). We decided to not fix the problem, but remove the feature, since specific information can already be
provided by means of the description
argument.
New behaviour
min_message
and max_message
will be removed from NumberField
/IntegerField
in the future.
Conversion
The following conversion needs to be applied, which can be done automatically by using the CLI command
viktor-cli fix -u 80
:
- number = NumberField(..., min_message="...", max_message="...")
+ number = NumberField(...)
- integer = IntegerField(..., min_message="...", max_message="...")
+ integer = IntegerField(...)
U79 - Remove hex_to_rgb
and rgb_to_hex
from geometry module
- deprecated since: v13.5.0
- automated code fix available: yes
hex_to_rgb
and rgb_to_hex
from geometry moduleCurrent behaviour + reason for change
hex_to_rgb
and rgb_to_hex
that are present in the geometry module can be used for color conversion. These are legacy
functions and can be replaced by Color.hex_to_rgb
and Color.rgb_to_hex
respectively.
New behaviour
hex_to_rgb
and rgb_to_hex
will be removed in the future.
Conversion
The following conversion needs to be applied, which can be done automatically by using the CLI command
viktor-cli fix -u 79
:
- from viktor.geometry import hex_to_rgb, rgb_to_hex
+ from viktor.core import Color
- rgb = hex_to_rgb("FFFFFF")
+ rgb = Color.hex_to_rgb("FFFFFF")
- hex = rgb_to_hex(255, 255, 255)
+ hex = Color.rgb_to_hex(255, 255, 255)
U78 - viktor.config.toml requires app_type
entry
- deprecated since: v13.3.0
- automated code fix available: yes
app_type
entryCurrent behaviour + reason for change
Currently, it is relatively complex to create a simple app with only 1 entity type, as there should always exist a
second, top-level folder-like entity type. With the introduction of the app_type
entry in the viktor.config.toml
file, it becomes possible to define a 'simple' app-type, which allows for 1 (and only 1) entity type, instead of the
current behaviour (from now on called 'tree'). This app-type entry also allows to introduce other types at a later stage.
New behaviour
The app_type
entry in viktor.config.toml
is obligatory and defines the type of app you want to create. App
layout, requirements and corresponding feedback errors might differ depending on the chosen app type.
Conversion
Add the 'app_type' key to viktor.config.toml
('tree' represents the current behaviour). This can be done
automatically by using the CLI command viktor-cli fix -u 78
:
+ app_type = "tree"
U77 - Removal of manifest
- deprecated since: v13.2.0
- automated code fix available: yes
Current behaviour + reason for change
The entity type information is currently partly described in the corresponding Controller, but some data is defined in
the manifest.yml
. This manifest is a concept which is often hard to grasp for a starting developer. In order to
improve the onboarding of new developers, as well as consistency of where to define entity type information, we would
like to get rid of the manifest completely.
New behaviour
The manifest can be removed completely. This means that the following properties need to be removed / moved:
entity_types
show_properties
: Legacy key which can be removed.has_designer
: Redundant in most cases. In specific cases it could happen that the entity type has a parametrization, but thathas_designer
has been set to False explicitly. For these cases, you may sethide_editor
to True on the correspondingController
.- naming of the entity type controller will no longer be in format
{entity_type}Controller
, but simply{entity_type}
(e.g.from .my_entity_type.controller import MyEntityTypeController
becomesfrom .my_entity_type.controller import MyEntityTypeController as MyEntityType
, or rename the class and import withfrom .my_entity_type.controller import MyEntityType
)
entities
Initial entities are created by setting the initial_entities
variable in the app.__init__.py
file,
passing 1 or more InitialEntity
objects.
from .my_entity_type.controller import MyEntityType
from viktor import InitialEntity
initial_entities = [
InitialEntity('MyEntityType', name='My Entity', params=...),
...
]
metadata
welcome_text
: Moved to theviktor.config.toml
file.uses_privileged_api
: Moved to theviktor.config.toml
file.
Conversion
The following conversion needs to be applied, which can be done automatically by using the CLI command
viktor-cli fix -u 77
:
entity_types
manifest.yaml
- entity_types:
- EntityTypeA:
- show_properties: false
- has_designer: true
Import the controller in the app.__init__.py
with the updated format:
- from .entity_type_a.controller import EntityTypeAController
+ from .entity_type_a.controller import EntityTypeAController as EntityTypeA
In case of explicit hiding the editor, set the hide_editor
flag:
class EntityTypeController(ViktorController):
+ hide_editor = True
...
entities
manifest.yaml
- entities:
- - entity_type: SettingsDatabase
- properties: settings_database.json
- - entity_type: ProjectFolder
- properties:
- name: Projects
- children:
- - entity_type: Project
- properties: project_x.json
app.__init__.py
- from .settings_database.controller import SettingsDatabaseController
- from .project_folder.controller import ProjectFolderController
- from .project.controller import ProjectController
+ from .settings_database.controller import SettingsDatabaseController as SettingsDatabase
+ from .project_folder.controller import ProjectFolderController as ProjectFolder
+ from .project.controller import ProjectController as Project
+
+ from viktor import InitialEntity
+
+ initial_entities = [
+ InitialEntity('SettingsDatabase', name='Settings', params='settings_database.json'),
+ InitialEntity('ProjectFolder', name='Projects', children=[
+ InitialEntity('Project', name='Project X', params='project_x.json')
+ ])
+ ]
metadata
manifest.yaml
- metadata:
- welcome_text: file_path.md
- uses_privileged_api: true
viktor.config.toml
+ welcome_text = "manifest/file_path.md"
+ enable_privileged_api = true # true | false
Note that the welcome_text
file is defined in the manifest with respect to the manifest folder
(e.g. my-app/manifest/
), while in the viktor.config.toml file it should be defined with respect to the root folder
(e.g. my-app/
). You are also free to move the welcome_text
to any other location, for example directly in the root
folder. This way, you could remove the manifest folder completely.
U76 - v13 cleanup
- automated code fix available: yes
Current behaviour + reason for change
Previous upgrades that were necessary to migrate to v13 instructed to add several flags on, for example, the
Controller
of the relevant entity type. Since v13 these flags became redundant.
New behaviour
Previously set flags can be removed.
Conversion
See the specific sections below for the required conversion. This can be done automatically by using the CLI command
viktor-cli fix -u 76
:
Cleanup U65
class Controller(ViktorController):
- viktor_convert_entity_field = True
Cleanup U69
When autoselect_single_option
is set to False
, it can be removed (autoselect_single_option=True
is still valid):
class Parametrization(ViktorParametrization):
- options = OptionField("Options", options=dynamic_options, autoselect_single_option=False)
+ options = OptionField("Options", options=dynamic_options)
Cleanup U74
class Controller(ViktorController):
- viktor_store_table_option_field_value = True
Cleanup U75
class Controller(ViktorController):
- viktor_name_filename_in_params = False
Removed in v13
U75 - Remove name
and filename
from params
- deprecated since: v12.12.0
- automated code fix available: partly
name
and filename
from paramsCurrent behaviour + reason for change
Up to now you might have noticed a name
property that was always present in the params of an entity, even though you
had not specified a field referring to that position in the database. The entity name has been added to the signature
of each controller method or can be obtained by using the API (e.g. Entity.name
), which makes the name
property
redundant and will be removed. In case of file-upload entities, a filename
property can be observed which will
also be removed.
Furthermore, the name
and filename
keys will become reserved for internal use and can no longer be used as name
argument in parametrization fields.
In order to simulate the removal of these params, you can use the viktor_name_filename_in_params
controller flag:
class Controller(ViktorController):
viktor_name_filename_in_params = False
This upgrade affects the following parts:
- Parametrization + params
- Entity mutations
Entity.create_child()
/API.create_child_entity()
Entity.set_params()
/API.set_entity_params()
New behaviour
Both name
and filename
will no longer be present in the params, and cannot be used as name
argument of
parametrization fields.
Conversion
Add a viktor_name_filename_in_params
class attribute on the Controller
and set it to False. This can be done
automatically by using the CLI command viktor-cli fix -u 75
:
class Controller(ViktorController):
+ viktor_name_filename_in_params = False
Unfortunately we cannot automatically fix your app logic. The following sections will guide you through the manual conversion of the affected code.
Parametrization + params
There are two ways for a field to be positioned on the name
(or filename
) key in the database:
- using
name
as toplevel field name
- name = NumberField(...)
- using
name="name"
as field input argument
- tab.field = NumberField(..., name='name')
Also make sure to update all parts of the code where name
(or filename
) is obtained from the params. Instead,
the entity name can be obtained from the signature:
- def func(params, **kwargs):
+ def func(params, entity_name, **kwargs):
- entity_name = params.name
...
This also holds in case the property is taken from the last_saved_params
of a different entity:
- entity_name = entity.last_saved_params['name']
+ entity_name = entity.name
Entity mutations
In functions that involve entity mutation, the name
of the entity could have been stored in the params. This should
be added as explicit name
argument:
entity_name = "my_entity"
- params = {"name": entity_name, ...}
+ params = {...}
entity.create_child(..., name=entity_name, params=params)
U74 - Store table OptionField value in params
- deprecated since: v12.12.0
- automated code fix available: partly
Current behaviour + reason for change
When an OptionField
is used within a table, it is not possible to show the label
of the options in the dropdown
menu, while using the value
of the selected option in the params. This functionality will become available in the
future, creating consistency between regular option fields and option fields used within tables.
New behaviour
By setting the controller flag viktor_store_table_option_field_value
to True, the label
of options will be shown in
the interface, and the value
of the selected option will be returned in the params. This flag will be True by default
in the future.
Conversion
Add a viktor_store_table_option_field_value
class attribute on the Controller. This can be done automatically by
using the CLI command viktor-cli fix -u 74
:
class MyController(ViktorController):
+ viktor_store_table_option_field_value = True
Unfortunately we cannot automatically fix your app logic in case your app already defines both a value
and label
in options within a table dropdown (i.e. you ignored the warning). In that case you should update your code manually:
class MyParametrization(Parametrization):
...
table.option = OptionField(..., options=[OptionListElement('a', 'Option A'), OptionListElement('b', 'Option B')])
class MyController(ViktorController):
...
+ viktor_store_table_option_field_value = True
def func(params):
- if params.table.option == 'Option A':
+ if params.table.option == 'a':
...
U73 - GeometryResult visualization_group
parameter renamed to geometry
- deprecated since: v12.12.0
- automated code fix available: yes
visualization_group
parameter renamed to geometry
Current behaviour + reason for change
GeometryResult
and GeometryAndDataResult
accept the geometry to be visualized through a visualization_group
parameter. Since not only a Group
but all sorts of geometry (any (list of) TransformableObject
(s) or GLB file) can
be passed, the naming of this parameter is outdated.
New behaviour
GeometryResult visualization_group
parameter has been renamed to geometry
.
Conversion
The following conversion has to be performed, which can be done automatically by using the CLI command
viktor-cli fix -u 73
:
- GeometryResult(visualization_group=...)
- GeometryAndDataResult(visualization_group=...)
+ GeometryResult(geometry=...)
+ GeometryAndDataResult(geometry=...)
U72 - Remove viktor.api module
- deprecated since: v12.11.0
- automated code fix available: no
Current behaviour + reason for change
The viktor.api
module consists of (outdated) functions and classes that are superseded by the entity option fields
and functions from the viktor.api_v1
module, or provide insignificant value such that it's better to replace them
with simple app code.
New behaviour
All (useful) functionalities from the viktor.api
module can be mimicked by using the entity option fields and/or
functions from the viktor.api_v1
module. The viktor.api
module will be removed completely in the future.
Conversion
get_database_value_from_entity_id
/ get_entity_id_from_database_value
/ get_entity_option_list_for_designer
If the entities are all children/siblings, the OptionField
can be replaced with a Child/SiblingEntityOptionField
(or similar for its multi-select counterpart):
- options = get_entity_option_list_for_designer(entities)
- field = OptionField("...", options=options)
+ field = ChildEntityOptionField("...") # or similar field
...
- entity_id = get_entity_id_from_database_value(params['field'])
+ entity = params['field'] # obtain its id with entity.id if desired
API
, Entity
& EntityType
The classes API
, Entity
and EntityType
and all of its (useful) functionalities from the viktor.api
module have
a counterpart with equal or similar functionalities in the viktor.api_v1
module. Below are the main differences:
- from viktor.api import API
+ from viktor.api_v1 import API
...
api = API()
...
- API.verify_status_code(response, allowed=200) # check the response.status_code yourself
+ if response.status_code != 200:
+ ... # handle not allowed status code(s)
- entity = API().entity(entity_id) # from viktor.api
+ entity = API().get_entity(entity_id) # from viktor.api_v1
...
- entity_dict = entity.get()
+ entity_params = entity.last_saved_params # or any other attribute
...
- root_entities = entity.root_entities() # or entity.list()
+ root_entities = API().get_root_entities()
...
- parent_entity_dict = entity.parents()[0]
- parent_id = entity_parent_ids()[0]
+ parent_entity = entity.parent()
...
- entity.create_child(entity_dict)
+ entity.create_child(entity_type_name, name, params=params)
...
- entity.post_properties(new_params)
+ entity.set_params(new_params)
...
- entity.update_properties(new_params_subset)
+ params = entity.last_saved_params
+ params.update(new_params_subset)
+ entity.set_params(params)
...
- file_content = entity.download()
+ file = entity.get_file() # file.getvalue_binary() to obtain the binary content
- entity_type = API().entity_type(entity_type_id)
- entity_type.entities()
+ API().get_entities_by_type(entity_type_name)
Apps already using (unsupported!) code to create a file-type child entity using the viktor.api
module can make use of
the function generate_upload_url
to fully switch to the viktor.api_v1
module. This method should not be introduced
in an app other than for above-mentioned reason:
- result = requests.post(f".../entity_types/{entity_type_id}/upload/", headers=...).json()
+ result = API().generate_upload_url(entity_type_name)
- entity_properties = {"name": entity_name, "filename": result['fields']['key']}
- entity.create_child({"properties": entity_properties, "entity_type": entity_type_id})
+ entity.create_child(entity_type_name, name=entity_name, filename=result['fields']['key'], params={})
requests.post(result['url'], data=result['fields'], files={'file': ...})
An unused import of the viktor.api
module does not trigger any deprecation warning, but will crash the app when the
module is deleted in v13. Be sure to remove all such imports.
U71 - Remove manifest key background_image
- deprecated since: v12.11.0
- automated code fix available: yes
background_image
Current behaviour + reason for change
The background image of a single app was customizable using the manifest metadata key background_image
. This
custom background image is frozen since the migration of workspaces to a single organization environment, and can
now be changed through the administrator panel per workspace.
New behaviour
The background image can be customized per workspace through the administrator panel. This makes the
background_image
manifest key redundant.
Conversion
Remove the background_image
metadata key from the manifest, which can be done automatically by using the CLI command
viktor-cli fix -u 71
:
metadata:
welcome_text: file_path.txt
- background_image: file_path.jpg
- metadata:
- background_image: file_path.jpg
U70 - Removed Polyline.from_dict()
- deprecated since: v12.10.0
- automated code fix available: no
Polyline.from_dict()
Current behaviour + reason for change
A Polyline
can be instantiated using the class method from_dict
, however this should not be part of the
public api.
New behaviour
The class method will be removed.
Conversion
polyline_points = [...] # list of dictionaries
- polyline = Polyline.from_dict(polyline_points)
+ polyline = Polyline([Point(p['x'], p['y']) for p in polyline_points])
U69 - Autoselect single option in OptionField
- deprecated since: v12.10.0
- automated code fix available: yes
Current behaviour + reason for change
The list of available options in an OptionField may consist of a single entry. This can either be achieved by providing a static list of options, or when the options are created dynamically. In the latter case, a single option will automatically be selected in the interface (without user interaction). However, this could lead to unintended behavior. In the following example, the selected option is automatically changed without the user being aware of it:
Action | Options |
---|---|
enter the editor | ⚪ A, ⚪ B, ⚪ C |
options dynamically change to single option A | ⚫ A |
options dynamically change to multiple options | ⚫ A, ⚪ B, ⚪ C |
options dynamically change to single option B (user might not be aware!) | ⚫ B |
options dynamically change to multiple options, excluding the selected option | ⚪ A, ❌ B, ⚪ C (warning in interface) |
New behaviour
In the future, the new default will be to not automatically select a single option within an OptionField
. The
autoselect_single_option
flag has been added to explicitly set the behaviour of selecting a single option to
True
or False
.
options = OptionField("Options", options=dynamic_options, autoselect_single_option=False)
In case you want to keep the current behavior, this flag can be set to True.
Conversion
The following conversion has to be performed, which can be done automatically by using the CLI command
viktor-cli fix -u 69
:
- options = OptionField("Options", options=dynamic_options)
+ options = OptionField("Options", options=dynamic_options, autoselect_single_option=True)
U68 - Remove require_all_fields
on buttons
- deprecated since: v12.9.0
- automated code fix available: yes
require_all_fields
on buttonsCurrent behaviour + reason for change
The argument require_all_fields
can be specified on an action button, however it is not implemented in the platform.
This argument could cause confusion and makes the SDK reference less readable.
New behaviour
The require_all_fields
argument will be removed. The following fields are affected:
DownloadButton
SetParamsButton
ActionButton
(AnalyseButton
)OptimizationButton
(OptimiseButton
)
Conversion
The following conversion has to be performed, which can be done automatically by using the CLI command
viktor-cli fix -u 68
:
- download_button = DownloadButton("Download X", method="download_x", require_all_fields=True)
+ download_button = DownloadButton("Download X", method="download_x")
U67 - GEOLIB hosting by VIKTOR will be terminated
- deprecated since: v12.9.0
- automated code fix available: yes
Current behaviour + reason for change
Deltares' GEOLIB is currently hosted by VIKTOR to make it available for its clients. The GEOLIB (>= 0.1.6) has now become publicly available on pypi, removing the need to host it ourselves.
New behaviour
The GEOLIB can be installed directly from pypi by pointing to the correct package in the app's requirements.txt.
Conversion
In case you are not using the GEOLIB in your app, no action is required. Otherwise, update requirements.txt
which can
be done automatically by using the CLI command viktor-cli fix -u 67
:
# viktor==X.X.X
- geolib==0.1.6
+ d-geolib==0.1.6
...
GEOLIB is available on pypi from version >= 0.1.6. With the termination of the hosting by VIKTOR, older versions will become unavailable. If your app uses a version older than 0.1.6, please update your code accordingly.
U66 - NumberField.Variant replaced with str-type
- deprecated since: v12.8.0
- automated code fix available: yes
Current behaviour + reason for change
The variant of a NumberField
is currently set with NumberField.Variant
, which is of type Enum
. To make the
product easier to understand and use, also for starting programmers, this is updated to a simple str
-type.
New behaviour
The variant of a NumberField
can be set with a simple str
-type ('slider', 'standard').
Conversion
The following conversion has to be performed, which can be done automatically by using the CLI command
viktor-cli fix -u 66
:
- NumberField("MyField", min=10, max=20, variant=NumberField.Variant.SLIDER)
+ NumberField("MyField", min=10, max=20, variant='slider')
- NumberField("MyField", variant=NumberField.Variant.STANDARD)
+ NumberField("MyField", variant='standard') # or just NumberField("MyField")
U65 - Entity selection fields return Entity
object
- deprecated since: v12.8.0
- automated code fix available: partly
Entity
objectCurrent behaviour + reason for change
The value of the entity selection fields as returned in the params is of type integer. Returning objects in the params will become the standard behavior. This allows for already existing fields, such as the entity selection fields, to return more logical types.
New behaviour
Returned values in the params will be strictly of type Entity
in the future. By defining
viktor_convert_entity_field = True
on a controller, this behavior can be simulated.
The following fields are affected:
ChildEntityOptionField
SiblingEntityOptionField
ChildEntityMultiSelectField
SiblingEntityMultiSelectField
Note that if viktor_convert_entity_field
is defined, not only the params of the current controller are converted,
but also the params obtained from API calls. In the example below, the params of an entity of EntityTypeA are
converted when retrieved in an entity of EntityTypeB.
class ControllerA(ViktorController) # EntityTypeA
viktor_convert_entity_field = False
...
def func(self, params, **kwargs):
entity = params['child_entity_option_field'] # of type int!
class ControllerB(ViktorController) # EntityTypeB
viktor_convert_entity_field = True
...
def func(self, params, **kwargs):
params_entity_a = ... # API call to retrieve params of EntityTypeA
entity = params_entity_a['child_entity_option_field'] # of type Entity!
Conversion
Add a viktor_convert_entity_field
class attribute on the Controller
. This can be done automatically by using the
CLI command viktor-cli fix -u 65
:
class MyController(ViktorController):
+ viktor_convert_entity_field = True
Unfortunately we cannot automatically fix your app logic. Please update the affected code manually, for example:
entity = params.tab.section.child_entity
- entity = API().get_entity(entity)
An Entity
is not serializable meaning that it cannot be used as input of a memoized
function. In case you are
passing the complete params
as input, a conversion is required:
- memoized_func(params=params)
+ params_ = copy.deepcopy(params)
+ del params_['tab']['section']['child_entity']
+ memoized_func(params=params_)
U64 - Replace PrivilegedAPI by explicit privileged
flag
- deprecated since: v12.6.0
- automated code fix available: no
privileged
flagCurrent behaviour + reason for change
Privileged API calls are done by using the PrivilegedAPI
class. A danger of this approach is that the object may be
instantiated well in advance of the actual API call, such that it is no longer transparent whether that call is
privileged or not. Furthermore, PrivilegedAPI
and the default API
could be mixed within a method which can also
result in unwanted privileged calls.
New behaviour
The PrivilegedAPI
class will be removed and privileged API calls should be done by adding an explicit privileged
flag in the corresponding method (e.g. entity.children(privileged=True)
). The following methods are affected:
API.get_entity()
API.get_entity_file()
API.get_root_entities()
Entity.parent()
Entity.children()
Entity.siblings()
If not used properly, (confidential) information which SHOULD NOT be accessible by a user may
leak (for instance by including data in a view). Please consider the following when using the privileged
flag:
- Make sure the app's admin is aware that the code circumvents certain permissions at specific places.
- Make sure to test the implementation thoroughly, to ensure no confidential data is leaked.
Conversion
- api = PrivilegedAPI()
- privileged_root_entities = api.get_root_entities()
+ api = API()
+ privileged_root_entities = api.get_root_entities(privileged=True)
U63 - Remove prefix
and suffix
on DateField
- deprecated since: v12.5.0
- automated code fix available: no
prefix
and suffix
on DateFieldCurrent behaviour + reason for change
A prefix
and / or suffix
can be defined on a DateField, which is not relevant for this type of field. The
attributes will therefore be removed.
New behaviour
It will not be possible to use prefix
and suffix
on a DateField.
Conversion
- DateField('Some date', suffix='XYZ')
+ DateField('Some date (XYZ)')
U62 - Renamed threejs_visualisation()
to visualize_geometry()
- deprecated since: v12.5.0
- automated code fix available: yes
threejs_visualisation()
to visualize_geometry()
Current behaviour + reason for change
A SoilLayout2D
or SoilLayer2D
can be visualized by calling threejs_visualisation()
on the
corresponding object. The "threejs" part in this name is no longer relevant and might be unclear to the developer.
New behaviour
Both methods return the geometric representation of the object, which can be used in a GeometryView. Therefore the
methods are renamed to visualize_geometry()
:
SoilLayout2D.threejs_visualisation()
->SoilLayout2D.visualize_geometry()
SoilLayer2D.threejs_visualisation()
->SoilLayer2D.visualize_geometry()
Conversion
The following conversion has to be performed, which can be done automatically by using the CLI command
viktor-cli fix -u 62
:
layout = SoilLayout2D(...)
- geometry, labels = layout.threejs_visualisation(...)
+ geometry, labels = layout.visualize_geometry(...)
U61 - Move entity-type information from manifest to Controller
- deprecated since: v12.3.0
- automated code fix available: yes
Current behaviour + reason for change
The entity-type information is currently partly described in the corresponding Controller (parametrization / views / summary),
but some data is defined in the manifest.yml
(label, children, show_children_as). This manifest is a concept which is
often hard to grasp for a starting developer. In order to improve the onboarding of new developers, as well as
consistency of where to define entity-type information, we would like to get rid of the manifest completely.
The first step is to move the definition of the following keys to the corresponding controller:
label
(required)children
(if present)show_children_as
(if present)
New behaviour
The keys will become simple class attributes, similar as parametrization
and summary
:
class EntityTypeController(ViktorController):
label = 'Label of the entity-type'
children = ['SomeType', 'AnotherType']
show_children_as = 'Cards' # or 'Table'
If they are still present in the manifest, you may expect the following warning:
Entity.label is present in manifest.yml but is overwritten by the app logic. Remove entry from manifest.
Note, when you are defining label
on the Controller, the SDK will also try to get children
+ show_children_as
or use the default of "no children" if not found. Therefore you cannot define label
on the Controller, while
keeping children
and show_children_as
in the manifest!
Conversion
The following conversion has to be performed, which can be done automatically by using the CLI command
viktor-cli fix -u 61
:
# manifest.yml
version: '1'
entity_types:
EntityTypeA:
- label: This is A
- show_children_as: Cards
- children:
- - EntityTypeB
...
EntityTypeB:
- label: This is B
...
# entity_type_a/controller.py
class EntityTypeAController(ViktorController):
+ label = 'This is A'
+ children = ['EntityTypeB']
+ show_children_as = 'Cards'
...
# entity_type_b/controller.py
class EntityTypeBController(ViktorController):
+ label = 'This is B'
...