Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workflow #49

Merged
merged 19 commits into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions annotation-tool/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,14 @@
"labeling"
],
"description": "Use deployed neural network in labeling interface",
"docker_image": "supervisely/labeling:6.73.104",
"docker_image": "supervisely/labeling:6.73.123",
"min_instance_version": "6.9.22",
"main_script": "annotation-tool/src/main.py",
"gui_template": "annotation-tool/src/gui.html",
"task_location": "application_sessions",
"isolate": true,
"headless": false,
"integrated_into": [
"image_annotation_tool"
],
"integrated_into": ["image_annotation_tool"],
"icon": "https://i.imgur.com/nnB2BqW.png",
"icon_background": "#FFFFFF",
"hotkeys": [
Expand Down
24 changes: 19 additions & 5 deletions annotation-tool/src/main.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
import os
import yaml
import pathlib
import sys
from collections import defaultdict

import supervisely as sly
from supervisely.imaging.color import random_rgb, generate_rgb
import yaml
from supervisely.imaging.color import generate_rgb, random_rgb
from workflow import Workflow

root_source_path = str(pathlib.Path(sys.argv[0]).parents[2])
sly.logger.info(f"Root source directory: {root_source_path}")
sys.path.append(root_source_path)

import io

import ruamel.yaml
from dotenv import load_dotenv
from init_ui import init_ui

from shared_utils.connect import get_model_info
from shared_utils.inference import postprocess
from shared_utils.ui2 import set_error
from dotenv import load_dotenv
import ruamel.yaml
import io

if sly.is_development():
load_dotenv(os.path.expanduser("~/supervisely.env"))
Expand Down Expand Up @@ -125,6 +129,11 @@ def inference(api: sly.Api, task_id, context, state, app_logger):

project_meta = sly.ProjectMeta.from_json(api.project.get_meta(project_id))

# -------------------------------------- Add Workflow Input -------------------------------------- #
nn_workflow = Workflow(api)
nn_workflow.add_input(project_id, state)
# ----------------------------------------------- - ---------------------------------------------- #

if image_id not in ann_cache:
# keep only current image for simplicity
ann_cache.clear()
Expand Down Expand Up @@ -448,6 +457,10 @@ def inference(api: sly.Api, task_id, context, state, app_logger):
]
api.task.set_fields(task_id, fields)

# -------------------------------------- Add Workflow Output ------------------------------------- #
nn_workflow.add_output(project_id)
# ----------------------------------------------- - ---------------------------------------------- #


@my_app.callback("undo")
@sly.timeit
Expand All @@ -464,6 +477,7 @@ def undo(api: sly.Api, task_id, context, state, app_logger):
{"field": "state.processing", "payload": False},
]
api.task.set_fields(task_id, fields)
# ? do we need to add output project here, cuz undo will be for the same project


def main():
Expand Down
45 changes: 45 additions & 0 deletions annotation-tool/src/workflow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import supervisely as sly


def check_compatibility(func):
def wrapper(self, *args, **kwargs):
if self.is_compatible is None:
self.is_compatible = self.check_instance_ver_compatibility()
if not self.is_compatible:
return
return func(self, *args, **kwargs)

return wrapper


class Workflow:
def __init__(self, api: sly.Api, min_instance_version: str = None):
self.is_compatible = None
self.api = api
self._min_instance_version = (
"6.9.31" if min_instance_version is None else min_instance_version
)

def check_instance_ver_compatibility(self):
if not self.api.is_version_supported(self._min_instance_version):
sly.logger.info(
f"Supervisely instance version {self.api.instance_version} does not support workflow features."
)
if not sly.is_community():
sly.logger.info(
f"To use them, please update your instance to version {self._min_instance_version} or higher."
)
return False
return True

@check_compatibility
def add_input(self, project_id: int, state: dict):
if self.api.project.get_info_by_id(project_id).version: # to prevent cycled workflow
self.api.app.workflow.add_input_project(project_id)
self.api.app.workflow.add_input_task(int(state["sessionId"]))
sly.logger.debug(f"Workflow Input: Project ID - {project_id}, Session ID - {int(state["sessionId"])}")

@check_compatibility
def add_output(self, project_id: int):
self.api.app.workflow.add_output_project(project_id)
sly.logger.debug(f"Workflow Output: Project ID - {project_id}")
2 changes: 1 addition & 1 deletion dev_requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
supervisely==6.73.104
supervisely==6.73.123
matplotlib>=3.3.2, <4.0.0
imgaug>=0.4.0, <1.0.0
7 changes: 2 additions & 5 deletions project-dataset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"labeling"
],
"description": "NN Inference on images in project or dataset",
"docker_image": "supervisely/labeling:6.73.104",
"docker_image": "supervisely/labeling:6.73.123",
"min_instance_version": "6.9.22",
"entrypoint": "python -m uvicorn project-dataset.src.main:app --host 0.0.0.0 --port 8000",
"task_location": "workspace_tasks",
Expand All @@ -21,10 +21,7 @@
"icon": "https://i.imgur.com/KdCigmp.png",
"icon_background": "#FFFFFF",
"context_menu": {
"target": [
"images_project",
"images_dataset"
],
"target": ["images_project", "images_dataset"],
"context_root": "Neural Networks"
},
"poster": "https://user-images.githubusercontent.com/106374579/187227957-ea4fd452-35ef-4969-9e55-cd7a5a4873ee.png"
Expand Down
6 changes: 6 additions & 0 deletions project-dataset/src/globals.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import importlib
import os

import supervisely as sly
from dotenv import load_dotenv

w = importlib.import_module("project-dataset.src.workflow")

ABSOLUTE_PATH = os.path.dirname(os.path.abspath(__file__))
PARENT_DIR = os.path.dirname(ABSOLUTE_PATH)
STATIC_DIR = os.path.join(PARENT_DIR, "temp")
Expand All @@ -22,6 +25,9 @@
)

api = sly.Api.from_env()

workflow = w.Workflow(api)

if dataset_id:
dataset_info = api.dataset.get_info_by_id(dataset_id)
project_id = dataset_info.project_id
Expand Down
9 changes: 7 additions & 2 deletions project-dataset/src/ui/output_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ def apply_model():
)
g.api.project.update_meta(res_project.id, res_project_meta.to_json())

# -------------------------------------- Add Workflow Input -------------------------------------- #
g.workflow.add_input(project_id=g.selected_project, session_id=g.model_session_id)
# ----------------------------------------------- - ---------------------------------------------- #

try:
apply_model_ds(g.selected_project, res_project, inference_settings, res_project_meta)
except Exception as e:
Expand Down Expand Up @@ -249,10 +253,11 @@ def apply_model():
)
continue
pbar.update(len(batched_image_infos))

output_project_thumbnail.set(g.api.project.get_info_by_id(res_project.id))
output_project_thumbnail.show()

# -------------------------------------- Add Workflow Output ------------------------------------- #
g.workflow.add_output(project_id=res_project.id)
# ----------------------------------------------- - ---------------------------------------------- #
main = importlib.import_module("project-dataset.src.main")

main.app.stop()
47 changes: 47 additions & 0 deletions project-dataset/src/workflow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import supervisely as sly


def check_compatibility(func):
def wrapper(self, *args, **kwargs):
if self.is_compatible is None:
self.is_compatible = self.check_instance_ver_compatibility()
if not self.is_compatible:
return
return func(self, *args, **kwargs)

return wrapper


class Workflow:
def __init__(self, api: sly.Api, min_instance_version: str = None):
self.is_compatible = None
self.api = api
self._min_instance_version = (
"6.9.31" if min_instance_version is None else min_instance_version
)

def check_instance_ver_compatibility(self):
if not self.api.is_version_supported(self._min_instance_version):
sly.logger.info(
f"Supervisely instance version {self.api.instance_version} does not support workflow features."
)
if not sly.is_community():
sly.logger.info(
f"To use them, please update your instance to version {self._min_instance_version} or higher."
)
return False
return True

@check_compatibility
def add_input(self, project_id: int = None, session_id: int = None):
if session_id is not None:
sly.logger.debug(f"Workflow Input: Session ID - {session_id}")
self.api.app.workflow.add_input_task(int(session_id))
if project_id is not None:
sly.logger.debug(f"Workflow Input: Project ID - {project_id}")
self.api.app.workflow.add_input_project(project_id)

@check_compatibility
def add_output(self, project_id: int):
sly.logger.debug(f"Workflow Output: Project ID - {project_id}")
self.api.app.workflow.add_output_project(project_id)