imaging-server-kit 0.0.10__tar.gz → 0.0.12__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/PKG-INFO +1 -1
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/docs/sections/algorithm_server.md +8 -7
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/docs/sections/getting_started.md +2 -2
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/basic/auto_threshold.py +1 -1
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-skimage-log/main.py +8 -3
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/_version.py +2 -2
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/core/decorator.py +0 -2
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/core/geometry.py +16 -4
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/hub/multialgo_server.py +34 -30
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit.egg-info/PKG-INFO +1 -1
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/.dockerignore +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/.gitattributes +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/.github/workflows/deploy.yml +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/.github/workflows/publish.yml +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/.gitignore +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/Dockerfile +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/Dockerfile-GPU +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/LICENSE +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/MANIFEST.in +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/README.md +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/build.sh +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/docs/_config.yml +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/docs/_toc.yml +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/docs/assets/screenshot_napari_threshold.png +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/docs/assets/screenshot_running_server.png +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/docs/index.md +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/docs/logo.ico +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/docs/sections/api_endpoints.md +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/docs/sections/authentication.md +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/docs/sections/client_apps.md +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/docs/sections/docker.md +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/docs/sections/examples.md +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/docs/sections/multi_algo_server.md +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/basic/multi_algo.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/basic/sample_images/blobs.tif +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/basic/threshold.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/docker-compose.yml +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-cellpose/Dockerfile +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-cellpose/README.md +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-cellpose/docker-compose.yml +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-cellpose/main.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-cellpose/requirements.txt +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-cellpose/sample_images/nuclei_2d.tif +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-orientationpy/Dockerfile +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-orientationpy/README.md +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-orientationpy/docker-compose.yml +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-orientationpy/main.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-orientationpy/requirements.txt +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-orientationpy/sample_images/image1_from_OrientationJ.tif +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-rembg/Dockerfile +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-rembg/README.md +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-rembg/docker-compose.yml +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-rembg/main.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-rembg/requirements.txt +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-rembg/sample_images/astronaut.tif +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-skimage-log/Dockerfile +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-skimage-log/README.md +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-skimage-log/docker-compose.yml +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-skimage-log/requirements.txt +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-skimage-log/sample_images/blobs.tif +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-skimage-log/sample_images/tracks.tif +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-stardist/Dockerfile +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-stardist/README.md +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-stardist/docker-compose.yml +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-stardist/main.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-stardist/requirements.txt +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-stardist/sample_images/nuclei_2d.tif +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-trackpy/Dockerfile +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-trackpy/README.md +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-trackpy/docker-compose.yml +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-trackpy/main.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-trackpy/requirements.txt +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-trackpy/sample_images/tracks.tif +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/main.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/pyproject.toml +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/setup.cfg +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/__init__.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/auth/__init__.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/auth/authenticated_server.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/auth/static/css/login.css +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/auth/static/css/register.css +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/auth/static/js/login_script.js +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/auth/static/js/register_script.js +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/auth/templates/login.html +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/auth/templates/register.html +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/auth/utils/__init__.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/auth/utils/db.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/auth/utils/schemas.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/auth/utils/users.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/cli.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/client/__init__.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/client/client.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/core/__init__.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/core/encoding.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/core/errors.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/core/serialization.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/core/server.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/core/static/css/index.css +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/core/static/css/info.css +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/core/templates/index.html +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/core/templates/info.html +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/core/ui_library.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/demo/__init__.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/demo/sample_images/blobs.tif +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/demo/threshold.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/hub/__init__.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/hub/algorithm_hub.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/template/cookiecutter.json +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/template/serverkit-{{ cookiecutter.project_slug }}/.dockerignore +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/template/serverkit-{{ cookiecutter.project_slug }}/.gitignore +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/template/serverkit-{{ cookiecutter.project_slug }}/Dockerfile +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/template/serverkit-{{ cookiecutter.project_slug }}/README.md +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/template/serverkit-{{ cookiecutter.project_slug }}/docker-compose.yml +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/template/serverkit-{{ cookiecutter.project_slug }}/main.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/template/serverkit-{{ cookiecutter.project_slug }}/requirements.txt +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/template/serverkit-{{ cookiecutter.project_slug }}/sample_images/blobs.tif +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit.egg-info/SOURCES.txt +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit.egg-info/dependency_links.txt +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit.egg-info/entry_points.txt +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit.egg-info/requires.txt +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit.egg-info/top_level.txt +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/start_algorithm_hub.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/tests/test_error_paths.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/tests/test_import.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/tests/test_multialgo_server.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/tests/test_parameter_schema.py +0 -0
- {imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/tests/test_simple_server.py +0 -0
|
@@ -23,7 +23,7 @@ To turn this function into to an algorithm server, we first need to modify the f
|
|
|
23
23
|
|
|
24
24
|
## Make the function return a list of data tuples
|
|
25
25
|
|
|
26
|
-
The function should return a list of tuples
|
|
26
|
+
The function should return a list of tuples. Each tuple has three elements and represents a distinct output of the algorithm.
|
|
27
27
|
|
|
28
28
|
Our threshold algorithm only has one output: the segmentation mask resulting from thresholding.
|
|
29
29
|
|
|
@@ -36,22 +36,22 @@ def threshold_algo_server(image: np.ndarray, threshold: float):
|
|
|
36
36
|
The data tuples are inspired from Napari's [LayerDataTuple](https://napari.org/0.4.15/guides/magicgui.html?highlight=layerdatatuple) model. They include three elements:
|
|
37
37
|
|
|
38
38
|
- The *first element* is the **data**, usually in the form of a Numpy array. The shape and interpretation of the axes depends on what the output represents (cf. table below).
|
|
39
|
-
- The *second element* is
|
|
39
|
+
- The *second element* is a Python dictionary representing **metadata** associated with the output. It can be empty (`{}`). These metadata are used to affect how the output is displayed in client apps (e.g. Napari).
|
|
40
40
|
- The *third element* is the output type: a string identifying what the output represents.
|
|
41
41
|
|
|
42
42
|
| Output type | Description |
|
|
43
43
|
| ----------------- | ----------------------------------------------------------------------------------------------------- |
|
|
44
|
-
| `"image"` | An image or image-like data (incl. 3D and RGB) as a
|
|
45
|
-
| `"mask"` | A segmentation mask (2D, 3D) as integer
|
|
44
|
+
| `"image"` | An image or image-like data (incl. 3D and RGB) as a numpy array. |
|
|
45
|
+
| `"mask"` | A segmentation mask (2D, 3D) as integer numpy array. Integers represent the **object class**. |
|
|
46
46
|
| `"instance_mask"` | A segmentation mask (2D, 3D) as integer nD array. Integers represent **object instances**. |
|
|
47
47
|
| `"points"` | A collection of point coordinates (array of shape (N, 2) or (N, 3)). |
|
|
48
|
-
| `"boxes"` | A collection of boxes (array of shape (N, 4) representing the
|
|
48
|
+
| `"boxes"` | A collection of boxes (array of shape (N, 4, 2) representing the box corners). |
|
|
49
49
|
| `"vectors"` | Array of vectors in the Napari [Vectors](https://napari.org/stable/howtos/layers/vectors.html) format.|
|
|
50
50
|
| `"tracks"` | Array of tracks in the Napari [Tracks](https://napari.org/stable/howtos/layers/tracks.html) format. |
|
|
51
51
|
| `"class"` | A class label (for image classification). |
|
|
52
52
|
| `"text"` | A string of text (for example, for image captioning). |
|
|
53
53
|
|
|
54
|
-
The function can return
|
|
54
|
+
The function can return multiple outputs, following the pattern:
|
|
55
55
|
|
|
56
56
|
```
|
|
57
57
|
# Body of the function
|
|
@@ -68,10 +68,11 @@ The function parameters can only be **numpy arrays**, **numeric values** (`int`,
|
|
|
68
68
|
|
|
69
69
|
## Decorate the function with `@algorithm_server`
|
|
70
70
|
|
|
71
|
-
This
|
|
71
|
+
This has several purposes:
|
|
72
72
|
|
|
73
73
|
- It converts the python function to a FastAPI server with predefined routes (cf. [API Endpoints](api_endpoints)).
|
|
74
74
|
- It enables the server to validate algorithm parameters when receiving requests.
|
|
75
|
+
- It tells client apps (Napari, QuPath) how to render the parameters in the user interface.
|
|
75
76
|
- Optional info about the algorithm server can be added to populate its `info` page.
|
|
76
77
|
|
|
77
78
|
Below is our decorated threshold algorithm function:
|
|
@@ -10,7 +10,7 @@ serverkit demo
|
|
|
10
10
|
|
|
11
11
|
This will start a demo web server for a simple intensity threshold algorithm.
|
|
12
12
|
|
|
13
|
-
The server will be running on http://localhost:8000. Open your web browser and navigate to this page to check that the server is running. You should see a web page displaying information about the
|
|
13
|
+
The server will be running on http://localhost:8000. Open your web browser and navigate to this page to check that the server is running. You should see a web page displaying information about the threshold algorithm server.
|
|
14
14
|
|
|
15
15
|

|
|
16
16
|
|
|
@@ -42,7 +42,7 @@ You can also interact with the algorithm server via QuPath. To try it out, you n
|
|
|
42
42
|
|
|
43
43
|
## Usage from Python
|
|
44
44
|
|
|
45
|
-
It is also possible to connect to an algorithm server and run
|
|
45
|
+
It is also possible to connect to an algorithm server and run computations from Python directly:
|
|
46
46
|
|
|
47
47
|
```python
|
|
48
48
|
from imaging_server_kit import Client
|
|
@@ -127,9 +127,14 @@ def skimage_log_server(
|
|
|
127
127
|
}, # sigmas = numpy array representing the point size
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
130
|
+
if len(points):
|
|
131
|
+
return [
|
|
132
|
+
(points, points_params, "points"),
|
|
133
|
+
]
|
|
134
|
+
else:
|
|
135
|
+
return [
|
|
136
|
+
("No points were detected.", {}, "text")
|
|
137
|
+
]
|
|
133
138
|
|
|
134
139
|
|
|
135
140
|
if __name__ == "__main__":
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/core/decorator.py
RENAMED
|
@@ -11,7 +11,6 @@ from .encoding import decode_contents
|
|
|
11
11
|
class BaseParamsModel(BaseModel):
|
|
12
12
|
model_config = ConfigDict(extra="forbid")
|
|
13
13
|
|
|
14
|
-
|
|
15
14
|
def decode_image_array(cls, v, dimensionality) -> "np.ndarray":
|
|
16
15
|
image_array = decode_contents(v)
|
|
17
16
|
|
|
@@ -58,7 +57,6 @@ def parse_params(parameters: dict) -> BaseModel:
|
|
|
58
57
|
"widget_type"
|
|
59
58
|
] = param_details.widget_type
|
|
60
59
|
|
|
61
|
-
|
|
62
60
|
if param_details.widget_type in ["image", "mask"]:
|
|
63
61
|
validated_func = partial(
|
|
64
62
|
decode_image_array, dimensionality=param_details.dimensionality
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/core/geometry.py
RENAMED
|
@@ -27,7 +27,11 @@ def mask2features(segmentation_mask: np.ndarray) -> List[Feature]:
|
|
|
27
27
|
for detection_id, contour in enumerate(polygons.points, start=1):
|
|
28
28
|
coords = np.array(contour)
|
|
29
29
|
coords = np.vstack([coords, coords[0]]) # Close the polygon for QuPath
|
|
30
|
-
|
|
30
|
+
try:
|
|
31
|
+
geom = Polygon(coordinates=[coords.tolist()], validate=True)
|
|
32
|
+
except ValueError:
|
|
33
|
+
# TODO: not sure what to do when this happens (very occasionally)
|
|
34
|
+
print("Found an invalid polygon...")
|
|
31
35
|
feature = Feature(
|
|
32
36
|
geometry=geom,
|
|
33
37
|
properties={
|
|
@@ -75,7 +79,11 @@ def instance_mask2features(segmentation_mask: np.ndarray) -> List[Feature]:
|
|
|
75
79
|
for contour in polygons.points:
|
|
76
80
|
coords = np.array(contour)
|
|
77
81
|
coords = np.vstack([coords, coords[0]]) # Close the polygon for QuPath
|
|
78
|
-
|
|
82
|
+
try:
|
|
83
|
+
geom = Polygon(coordinates=[coords.tolist()], validate=True)
|
|
84
|
+
except ValueError:
|
|
85
|
+
# TODO: not sure what to do when this happens (very occasionally)
|
|
86
|
+
print("Found an invalid polygon...")
|
|
79
87
|
feature = Feature(
|
|
80
88
|
geometry=geom,
|
|
81
89
|
properties={
|
|
@@ -170,14 +178,18 @@ def boxes2features(boxes: np.ndarray) -> List[Feature]:
|
|
|
170
178
|
coords.append(
|
|
171
179
|
coords[0]
|
|
172
180
|
) # Add the first element at the end to close the Polygon
|
|
173
|
-
|
|
181
|
+
try:
|
|
182
|
+
geom = Polygon(coordinates=[coords], validate=True)
|
|
183
|
+
except ValueError:
|
|
184
|
+
print("Invalid box polygon found. Expected an array of shape (N, 4, D) representing the corners of the box.")
|
|
185
|
+
geom = None # TODO: should we handle this better?
|
|
174
186
|
features.append(Feature(geometry=geom, properties={"Detection ID": i}))
|
|
175
187
|
return features
|
|
176
188
|
|
|
177
189
|
|
|
178
190
|
def features2boxes(features):
|
|
179
191
|
boxes = np.array([feature["geometry"]["coordinates"] for feature in features])
|
|
180
|
-
boxes = np.
|
|
192
|
+
boxes = np.array([box[0] for box in boxes]) # We get back a shape of (N, 1, 5, 2) - so we remove dim. 1
|
|
181
193
|
boxes = boxes[:, :-1] # Remove the last element
|
|
182
194
|
boxes = boxes[:, :, ::-1] # Invert XY
|
|
183
195
|
return boxes
|
|
@@ -13,9 +13,15 @@ from contextlib import asynccontextmanager
|
|
|
13
13
|
import asyncio
|
|
14
14
|
import imaging_server_kit as serverkit
|
|
15
15
|
from imaging_server_kit import AlgorithmServer
|
|
16
|
-
from imaging_server_kit.core import
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
from imaging_server_kit.core import (
|
|
17
|
+
parse_algo_params_schema,
|
|
18
|
+
encode_contents,
|
|
19
|
+
decode_contents,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
templates_dir = importlib.resources.files("imaging_server_kit.core").joinpath(
|
|
23
|
+
"templates"
|
|
24
|
+
)
|
|
19
25
|
static_dir = importlib.resources.files("imaging_server_kit.core").joinpath("static")
|
|
20
26
|
|
|
21
27
|
templates = Jinja2Templates(directory=str(templates_dir))
|
|
@@ -31,7 +37,9 @@ class MultiAlgorithmServer: # TODO: could this inherit from algoserver somehow?
|
|
|
31
37
|
|
|
32
38
|
# Centralized exception handlers
|
|
33
39
|
@self.app.exception_handler(RequestValidationError)
|
|
34
|
-
async def validation_exception_handler(
|
|
40
|
+
async def validation_exception_handler(
|
|
41
|
+
request: Request, exc: RequestValidationError
|
|
42
|
+
):
|
|
35
43
|
return JSONResponse(
|
|
36
44
|
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
|
37
45
|
content={"error_type": "validation_error", "detail": exc.errors()},
|
|
@@ -40,12 +48,14 @@ class MultiAlgorithmServer: # TODO: could this inherit from algoserver somehow?
|
|
|
40
48
|
@self.app.exception_handler(Exception)
|
|
41
49
|
async def generic_exception_handler(request: Request, exc: Exception):
|
|
42
50
|
from fastapi import HTTPException
|
|
51
|
+
|
|
43
52
|
if isinstance(exc, HTTPException):
|
|
44
53
|
raise exc
|
|
45
54
|
return JSONResponse(
|
|
46
55
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
47
56
|
content={"error_type": "internal_server_error", "message": str(exc)},
|
|
48
57
|
)
|
|
58
|
+
|
|
49
59
|
self.app.mount("/static", StaticFiles(directory=str(static_dir)), name="static")
|
|
50
60
|
self.services = [server_name]
|
|
51
61
|
|
|
@@ -119,8 +129,10 @@ class MultiAlgorithmServer: # TODO: could this inherit from algoserver somehow?
|
|
|
119
129
|
request: Request = ...,
|
|
120
130
|
):
|
|
121
131
|
if algorithm_name not in self.algorithms:
|
|
122
|
-
raise HTTPException(
|
|
123
|
-
|
|
132
|
+
raise HTTPException(
|
|
133
|
+
status_code=status.HTTP_404_NOT_FOUND,
|
|
134
|
+
detail=f"Algorithm {algorithm_name} not found",
|
|
135
|
+
)
|
|
124
136
|
algo_info = self.algorithms[algorithm_name].get("algo_info")
|
|
125
137
|
algo_params_schema = get_algo_params(algorithm_name)
|
|
126
138
|
algo_params = parse_algo_params_schema(algo_params_schema)
|
|
@@ -142,8 +154,10 @@ class MultiAlgorithmServer: # TODO: could this inherit from algoserver somehow?
|
|
|
142
154
|
request: Request = ...,
|
|
143
155
|
):
|
|
144
156
|
if algorithm_name not in self.algorithms:
|
|
145
|
-
raise HTTPException(
|
|
146
|
-
|
|
157
|
+
raise HTTPException(
|
|
158
|
+
status_code=status.HTTP_404_NOT_FOUND,
|
|
159
|
+
detail=f"Algorithm {algorithm_name} not found",
|
|
160
|
+
)
|
|
147
161
|
|
|
148
162
|
parameters_model = self.algorithms.get(algorithm_name, {}).get(
|
|
149
163
|
"parameters_model"
|
|
@@ -156,34 +170,26 @@ class MultiAlgorithmServer: # TODO: could this inherit from algoserver somehow?
|
|
|
156
170
|
except ValidationError as e:
|
|
157
171
|
raise HTTPException(status_code=422, detail=e.errors())
|
|
158
172
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
elif "mask" in data.keys():
|
|
163
|
-
data["mask"] = decode_contents(data["mask"])
|
|
164
|
-
elif "points" in data.keys():
|
|
165
|
-
data["points"] = decode_contents(data["points"])
|
|
166
|
-
elif "vectors" in data.keys():
|
|
167
|
-
data["vectors"] = decode_contents(data["vectors"])
|
|
168
|
-
elif "shapes" in data.keys():
|
|
169
|
-
data["shapes"] = decode_contents(data["shapes"])
|
|
170
|
-
elif "tracks" in data.keys():
|
|
171
|
-
data["tracks"] = decode_contents(data["tracks"])
|
|
172
|
-
|
|
173
|
-
return await self._run_algo_logic(algorithm_name, data)
|
|
173
|
+
decoded_params = algo_params.dict()
|
|
174
|
+
|
|
175
|
+
return await self._run_algo_logic(algorithm_name, decoded_params)
|
|
174
176
|
|
|
175
177
|
@self.app.get("/{algorithm_name}/parameters", response_model=dict)
|
|
176
178
|
def get_algo_params(algorithm_name):
|
|
177
179
|
if algorithm_name not in self.algorithms:
|
|
178
|
-
raise HTTPException(
|
|
179
|
-
|
|
180
|
+
raise HTTPException(
|
|
181
|
+
status_code=status.HTTP_404_NOT_FOUND,
|
|
182
|
+
detail=f"Algorithm {algorithm_name} not found",
|
|
183
|
+
)
|
|
180
184
|
return self.get_algorithm_params(algorithm_name)
|
|
181
185
|
|
|
182
186
|
@self.app.get("/{algorithm_name}/sample_images", response_model=dict)
|
|
183
187
|
def get_sample_images(algorithm_name):
|
|
184
188
|
if algorithm_name not in self.algorithms:
|
|
185
|
-
raise HTTPException(
|
|
186
|
-
|
|
189
|
+
raise HTTPException(
|
|
190
|
+
status_code=status.HTTP_404_NOT_FOUND,
|
|
191
|
+
detail=f"Algorithm {algorithm_name} not found",
|
|
192
|
+
)
|
|
187
193
|
return self.get_algorithm_sample_images(algorithm_name)
|
|
188
194
|
|
|
189
195
|
async def _serialize_result_tuple(self, result_data_tuple):
|
|
@@ -228,7 +234,5 @@ class MultiAlgorithmServer: # TODO: could this inherit from algoserver somehow?
|
|
|
228
234
|
server = self.algorithms.get(algorithm_name)
|
|
229
235
|
load_funct = server.get("load_funct")
|
|
230
236
|
images = load_funct()
|
|
231
|
-
encoded_images = [
|
|
232
|
-
{"sample_image": encode_contents(image)} for image in images
|
|
233
|
-
]
|
|
237
|
+
encoded_images = [{"sample_image": encode_contents(image)} for image in images]
|
|
234
238
|
return {"sample_images": encoded_images}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/docs/assets/screenshot_napari_threshold.png
RENAMED
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/docs/assets/screenshot_running_server.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/basic/sample_images/blobs.tif
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-cellpose/main.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-rembg/Dockerfile
RENAMED
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-rembg/README.md
RENAMED
|
File without changes
|
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-rembg/main.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-stardist/main.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-trackpy/README.md
RENAMED
|
File without changes
|
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/examples/servers/serverkit-trackpy/main.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/auth/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/auth/utils/db.py
RENAMED
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/auth/utils/schemas.py
RENAMED
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/auth/utils/users.py
RENAMED
|
File without changes
|
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/client/__init__.py
RENAMED
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/client/client.py
RENAMED
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/core/__init__.py
RENAMED
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/core/encoding.py
RENAMED
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/core/errors.py
RENAMED
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/core/serialization.py
RENAMED
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/core/server.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/core/ui_library.py
RENAMED
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/demo/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/demo/threshold.py
RENAMED
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/hub/__init__.py
RENAMED
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit/hub/algorithm_hub.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{imaging_server_kit-0.0.10 → imaging_server_kit-0.0.12}/src/imaging_server_kit.egg-info/requires.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|