diff --git a/api.py b/api.py index abd27bbfe85291362ae5d9e1691d6d3393154b09..45ee844fcd17d6f33a657b615aba446c02a6608f 100644 --- a/api.py +++ b/api.py @@ -1,10 +1,10 @@ from fastapi import FastAPI, HTTPException -from model_server.ilastik import IlastikImageToImageModel, IlastikPixelClassifierModel, IlastikObjectClassifierModel -from model_server.model import DummyImageToImageModel, ParameterExpectedError +from extensions.ilastik.models import IlastikImageToImageModel, IlastikPixelClassifierModel, IlastikObjectClassifierModel +from model_server.models import DummyImageToImageModel, ParameterExpectedError from model_server.session import Session -from model_server.workflow import infer_image_to_image -from model_server.workflow_ilastik import infer_px_then_ob_model +from model_server.workflows import infer_image_to_image +from extensions.ilastik.workflows import infer_px_then_ob_model app = FastAPI(debug=True) session = Session() diff --git a/extensions/__init__.py b/extensions/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/extensions/examples/__init__.py b/extensions/examples/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/examples/ilastik3d.py b/extensions/examples/ilastik3d.py similarity index 100% rename from examples/ilastik3d.py rename to extensions/examples/ilastik3d.py diff --git a/extensions/ilastik/__init__.py b/extensions/ilastik/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/conf/ilastik.py b/extensions/ilastik/conf.py similarity index 100% rename from conf/ilastik.py rename to extensions/ilastik/conf.py diff --git a/model_server/ilastik.py b/extensions/ilastik/models.py similarity index 91% rename from model_server/ilastik.py rename to extensions/ilastik/models.py index aad0f38cc3adba237fd3161f7f9badb4cc62a344..ddcb0db5d6f4496e70196781d485e4da2ab43257 100644 --- a/model_server/ilastik.py +++ b/extensions/ilastik/models.py @@ -4,9 +4,9 @@ from pathlib import Path import numpy as np import vigra -import conf.ilastik -from model_server.image import GenericImageDataAccessor, InMemoryDataAccessor -from model_server.model import ImageToImageModel, ParameterExpectedError +import extensions.ilastik.conf +from model_server.accessors import GenericImageDataAccessor, InMemoryDataAccessor +from model_server.models import ImageToImageModel, ParameterExpectedError class IlastikImageToImageModel(ImageToImageModel): @@ -14,7 +14,7 @@ class IlastikImageToImageModel(ImageToImageModel): def __init__(self, params, autoload=True): self.project_file = Path(params['project_file']) params['project_file'] = self.project_file.__str__() - pap = conf.ilastik.paths['project_files'] / self.project_file + pap = extensions.ilastik.conf.paths['project_files'] / self.project_file self.project_file_abspath = pap if not pap.exists(): raise FileNotFoundError(f'Project file does not exist: {pap}') @@ -53,7 +53,7 @@ class IlastikPixelClassifierModel(IlastikImageToImageModel): @staticmethod def get_workflow(): - from ilastik.workflows.pixelClassification import PixelClassificationWorkflow + from ilastik.workflows import PixelClassificationWorkflow return PixelClassificationWorkflow def infer(self, input_img: GenericImageDataAccessor) -> (np.ndarray, dict): diff --git a/extensions/ilastik/tests/__init__.py b/extensions/ilastik/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/test_ilastik.py b/extensions/ilastik/tests/test_ilastik.py similarity index 96% rename from tests/test_ilastik.py rename to extensions/ilastik/tests/test_ilastik.py index 747de17a76d1cd487dd3c304f002b1d4a1029b83..f8ec7e9e683e4a96c605a0c748e8d6ed1b5fd04a 100644 --- a/tests/test_ilastik.py +++ b/extensions/ilastik/tests/test_ilastik.py @@ -4,9 +4,9 @@ import unittest import numpy as np import conf.testing -from model_server.image import CziImageFileAccessor, InMemoryDataAccessor, write_accessor_data_to_file -from model_server.ilastik import IlastikObjectClassifierModel, IlastikPixelClassifierModel -from model_server.workflow import infer_image_to_image +from model_server.accessors import CziImageFileAccessor, InMemoryDataAccessor, write_accessor_data_to_file +from extensions.ilastik.models import IlastikObjectClassifierModel, IlastikPixelClassifierModel +from model_server.workflows import infer_image_to_image from tests.test_api import TestServerBaseClass class TestIlastikPixelClassification(unittest.TestCase): diff --git a/model_server/workflow_ilastik.py b/extensions/ilastik/workflows.py similarity index 88% rename from model_server/workflow_ilastik.py rename to extensions/ilastik/workflows.py index db412bb4b9b2ba1e33b0ba42d9d5108bbfcdce5d..45763ad7415600e6b6dc441c33dee4c0cc8dc647 100644 --- a/model_server/workflow_ilastik.py +++ b/extensions/ilastik/workflows.py @@ -2,13 +2,11 @@ Implementation of image analysis work behind API endpoints, without knowledge of persistent data in server session. """ from pathlib import Path -from time import perf_counter from typing import Dict -from model_server.ilastik import IlastikPixelClassifierModel, IlastikObjectClassifierModel -from model_server.image import generate_file_accessor, write_accessor_data_to_file -from model_server.model import Model -from model_server.workflow import Timer +from extensions.ilastik.models import IlastikPixelClassifierModel, IlastikObjectClassifierModel +from model_server.accessors import generate_file_accessor, write_accessor_data_to_file +from model_server.workflows import Timer from pydantic import BaseModel diff --git a/model_server/image.py b/model_server/accessors.py similarity index 100% rename from model_server/image.py rename to model_server/accessors.py diff --git a/model_server/model.py b/model_server/models.py similarity index 96% rename from model_server/model.py rename to model_server/models.py index a2d75c7b5453a8ad14092f6ea61a57d6860ea0fb..4285b49c4d8a55bb3b77135d9e578546ea851d4c 100644 --- a/model_server/model.py +++ b/model_server/models.py @@ -4,7 +4,7 @@ import os import numpy as np -from model_server.image import GenericImageDataAccessor, InMemoryDataAccessor +from model_server.accessors import GenericImageDataAccessor, InMemoryDataAccessor class Model(ABC): diff --git a/model_server/session.py b/model_server/session.py index eb82d1b6f089ccf990b4ca8fadff93f893e88a20..3d5db0bc16cb37fbb01f505ae143282294779e03 100644 --- a/model_server/session.py +++ b/model_server/session.py @@ -6,9 +6,9 @@ from time import strftime, localtime from typing import Dict import conf.defaults -from model_server.model import Model +from model_server.models import Model from model_server.share import SharedImageDirectory -from model_server.workflow import WorkflowRunRecord +from model_server.workflows import WorkflowRunRecord def create_manifest_json(): pass @@ -17,9 +17,6 @@ class Session(object): """ Singleton class for a server session that persists data between API calls """ - # inbound = SharedImageDirectory(conf.defaults.paths['inbound_images']) - # outbound = SharedImageDirectory(conf.defaults.paths['outbound_images']) - # where_records = conf.defaults.paths['logs'] def __new__(cls): if not hasattr(cls, 'instance'): @@ -31,8 +28,6 @@ class Session(object): self.models = {} # model_id : model object self.manifest = [] # paths to data as well as other metadata from each inference run self.paths = self.make_paths(root) - # self.session_id = self.create_session_id(self.paths['logs']) - # self.session_id = self.create_session_id(self.paths) self.session_log = self.paths['logs'] / f'session.log' self.log_event('Initialized session') self.manifest_json = self.paths['logs'] / f'manifest.json' diff --git a/model_server/share.py b/model_server/share.py index e270dea6d75bc59d2cf4fe5394775672b1aa509c..fad2b2f03d1a6c19909215a3f34c28867c37ac71 100644 --- a/model_server/share.py +++ b/model_server/share.py @@ -1,3 +1,8 @@ +""" +Classes that manage data sharing between server and outside processes. Currently just a directory on a shared +filesystem; but may expand to include data transfer over API, shared memory objects, etc. +""" + import os import pathlib diff --git a/model_server/workflow.py b/model_server/workflows.py similarity index 92% rename from model_server/workflow.py rename to model_server/workflows.py index 7c09bc46835eacb04a31871534a91786991267ec..c81d2afdc3e59e8153e1710524e286961ecd7746 100644 --- a/model_server/workflow.py +++ b/model_server/workflows.py @@ -5,8 +5,8 @@ from pathlib import Path from time import perf_counter from typing import Dict -from model_server.image import generate_file_accessor, write_accessor_data_to_file -from model_server.model import Model +from model_server.accessors import generate_file_accessor, write_accessor_data_to_file +from model_server.models import Model from pydantic import BaseModel diff --git a/simulate_automic.py b/simulate_automic.py deleted file mode 100644 index 94e042c8b0596aeb5bbb7ae493b1569fec4aedf8..0000000000000000000000000000000000000000 --- a/simulate_automic.py +++ /dev/null @@ -1,55 +0,0 @@ -from multiprocessing import Process -import os -import requests -import unittest - -import uvicorn - -import conf.server - -# run server in subprocess - -host = '127.0.0.1' -port = 5000 -server_process = Process( - target=uvicorn.run, - args=('api:app', ), - kwargs={'host': host, 'port': port, 'log_level': 'debug'}, - daemon=True -) -uri = f'http://{host}:{port}/' -server_process.start() - -# configure and validate folders etc. -paths = conf.server.paths -paths['automic_watch_folder'] = paths['images']['inbound'] -paths['test_source_files'] = '' - -# load models by API - -# prompt user start AutoMic loop - -# move files from one folder to another -def copy_one_input_image_files(copy=True): - pattern = '' - os.listdir(paths['test_source_files']) - - # order by increaseing alpha order? timestamp? - - - if copy: - # copy image from test source files to automic watch folder - else: - # move them - - # recursive repeat until nothign is left - -# point to server session logs - - -# shut down server -server_process.terminate() - - -# do something with the data? - diff --git a/tests/test_api.py b/tests/test_api.py index 40ecfd2985e6a9450fe1bf273eddd18a8890fb55..778c378f725c094e9472df0d76f6104bc9166975 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -4,7 +4,7 @@ import requests import unittest from conf.testing import czifile -from model_server.model import DummyImageToImageModel +from model_server.models import DummyImageToImageModel class TestServerBaseClass(unittest.TestCase): def setUp(self) -> None: diff --git a/tests/test_image.py b/tests/test_image.py index 6c085b6cb03b52cabbf7eb230792058e8618a966..3d590990062101a8ccfaa2420735f0ddc7532161 100644 --- a/tests/test_image.py +++ b/tests/test_image.py @@ -3,7 +3,7 @@ import unittest import numpy as np from conf.testing import czifile, output_path -from model_server.image import CziImageFileAccessor, DataShapeError, InMemoryDataAccessor, write_accessor_data_to_file +from model_server.accessors import CziImageFileAccessor, DataShapeError, InMemoryDataAccessor, write_accessor_data_to_file class TestCziImageFileAccess(unittest.TestCase): diff --git a/tests/test_model.py b/tests/test_model.py index a265cbe4bd9860b8b053ca9ad768a7ca41885554..661aeadf93825afc430e55f56326def0fe3f43b0 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -1,7 +1,7 @@ import unittest from conf.testing import czifile -from model_server.image import CziImageFileAccessor -from model_server.model import DummyImageToImageModel, CouldNotLoadModelError +from model_server.accessors import CziImageFileAccessor +from model_server.models import DummyImageToImageModel, CouldNotLoadModelError class TestCziImageFileAccess(unittest.TestCase): def setUp(self) -> None: diff --git a/tests/test_session.py b/tests/test_session.py index a03e1ad1b45a43ef5fe217935c5ed13a8431410c..fd4b79c94c64b6bd11fa679244d766a6671a3ceb 100644 --- a/tests/test_session.py +++ b/tests/test_session.py @@ -1,5 +1,5 @@ import unittest -from model_server.model import DummyImageToImageModel +from model_server.models import DummyImageToImageModel from model_server.session import Session class TestGetSessionObject(unittest.TestCase): @@ -38,7 +38,7 @@ class TestGetSessionObject(unittest.TestCase): def test_session_records_workflow(self): import json - from model_server.workflow import WorkflowRunRecord + from model_server.workflows import WorkflowRunRecord sesh = Session() di = WorkflowRunRecord( model_id='test_model', diff --git a/tests/test_workflow.py b/tests/test_workflow.py index 6bc8d56d88f960d63cdada4efe68e65c6ecd572f..2cab499d04c222651894d9064c1f7f990050d626 100644 --- a/tests/test_workflow.py +++ b/tests/test_workflow.py @@ -1,8 +1,8 @@ import unittest from conf.testing import czifile, output_path -from model_server.model import DummyImageToImageModel -from model_server.workflow import infer_image_to_image +from model_server.models import DummyImageToImageModel +from model_server.workflows import infer_image_to_image class TestGetSessionObject(unittest.TestCase):