There are situations when you want your application to launch immediately and not require any manipulation in GUI, but with a possibility to change some parameters of a launched app later. For example serving app deploys the default model which can be changed later or a labeling app starts processing some test dataset before some big project is selected. For this purpose, a simple decorator @sly.app.call_on_autostart() was created.
Decorator functionality
Main
The decorator wraps the given function so that it can only be called if the special flag in the environment is setted. This flag can be set in the modal window of an application with a simple checkbox or any part of your code using sly.env.set_autostart("1") and removed with sly.env.set_autostart(None). If you want your application to always start with setted autostart flag, add this in config.json:
"modal_template_state": {
"autostart": true
}
Simple example
Let's create a simple app with an activate-deactivate button. Imagine that button launch some other program. We want to indicate a successful launch by changing of button color from blue to green.
import os
from dotenv import load_dotenv
import supervisely as sly
from supervisely.app.widgets import Container, Button, Card
load_dotenv("local.env")
load_dotenv(os.path.expanduser("~/supervisely.env"))
# blue button if not activated
activate_btn = Button("Activate")
# green button if activated successfully
deactivate_btn = Button("Deactivate", button_type="success")
deactivate_btn.hide()
At startup, we will see an inactive (blue) button which can be activated by clicking on it.
Now we would like to change the state of the button to active without interaction with GUI. Let's add activate_on_autostart() function, wrap it with sly.app.call_on_autostart() decorator and call at the end of our program.
Now our button will become active (green) immediately after start and we can control this behavior with autostart environment.
The final code:
import os
from dotenv import load_dotenv
import supervisely as sly
from supervisely.app.widgets import Container, Button, Card
load_dotenv("local.env")
load_dotenv(os.path.expanduser("~/supervisely.env"))
# blue button if not activated
activate_btn = Button("Activate")
# green button if activated successfully
deactivate_btn = Button("Deactivate", button_type="success")
deactivate_btn.hide()
# activation
@activate_btn.click
def activate_process():
# launch some background task
activate_btn.hide()
deactivate_btn.show()
#deactivation
@deactivate_btn.click
def deactivate_process():
# stop some background task
deactivate_btn.hide()
activate_btn.show()
btns = Container([activate_btn, deactivate_btn])
layout = Card("Activate-deactivate process", content=btns)
app = sly.Application(layout=layout)
@sly.app.call_on_autostart()
def activate_on_autostart():
# launch some background task
activate_btn.hide()
deactivate_btn.show()
sly.env.set_autostart("1")
activate_on_autostart()
Inference
if sly.is_production() and not os.environ.get("DEBUG_WITH_SLY_NET"):
m = ClickSegModel(use_gui=True, custom_inference_settings=inference_settings_path)
# Change default parameter from 0 to DEFAULT_ROW_IDX
m.gui._models_table.select_row(ClickSegModel.DEFAULT_ROW_IDX)
m.serve()
Every subclass of Inference class can already deploy some default model without interaction with GUI (if any). If you use default InferenceGUI (or your GUI inherits from it), all parameters will be taken from the default widget values while autostarting. To override default parameters you can use widget functionality. The example below is taken from application: we override the default value of the RadioTable widget by calling m.gui._models_table.select_row()