Skip to content

Commit 9b1cefe

Browse files
Use NumPy-style for docstrings
1 parent 0eaded3 commit 9b1cefe

28 files changed

Lines changed: 903 additions & 318 deletions

‎src/imaging_server_kit/__init__.py‎

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,25 @@
4747

4848

4949
def convert(stack: Stack, to: str = "stack") -> Union[Stack, "napari.Viewer"]:
50-
"""
51-
Convert a result object into a different representation.
50+
"""Convert a stack into another representation.
5251
5352
Parameters
5453
----------
55-
stack : The result object to convert.
56-
to : The target representation to convert to. Supported values: ["stack", "napari"]
54+
stack : Stack
55+
The stack to convert.
56+
to : {"stack", "napari"}, default="stack"
57+
The target representation.
5758
5859
Returns
5960
-------
60-
The converted result object.
61-
- If `to == "stack"`, a Stack() object containing copies of the input layers.
62-
- If `to == "napari"` the napari.Viewer associated with the converted stack.
61+
Stack or napari.Viewer
62+
With `to="stack"`, a new stack with the same layers. With `to="napari"`, a new
63+
Napari viewer displaying the layers (requires the `napari` extra).
64+
65+
Raises
66+
------
67+
ValueError
68+
If `to` is not supported.
6369
"""
6470
supported = ["stack", "napari"]
6571
if not to in supported:
@@ -96,7 +102,21 @@ def run(
96102
domain: Optional[Domain] = None,
97103
**algo_params,
98104
) -> Union[Stack, "napari.Viewer"]: # type: ignore
99-
"""Allows the syntax `sk.run(...)` instead of runner.run(...)."""
105+
"""Run an algorithm. Equivalent to `runner.run(...)`.
106+
107+
See [`AlgorithmRunner.run`][imaging_server_kit.AlgorithmRunner.run] for the
108+
description of the parameters.
109+
110+
Parameters
111+
----------
112+
runner : AlgorithmRunner
113+
An algorithm, an algorithm collection, or a client.
114+
115+
Returns
116+
-------
117+
Stack or napari.Viewer
118+
The results, as returned by `runner.run(...)`.
119+
"""
100120
return runner.run(
101121
*args,
102122
algorithm=algorithm,
@@ -112,5 +132,13 @@ def run(
112132

113133

114134
def info(runner: AlgorithmRunner, algorithm: Optional[str] = None):
115-
"""Allow the syntax `sk.info(...)` instead of runner.info(...)."""
135+
"""Open the documentation page of an algorithm. Equivalent to `runner.info(...)`.
136+
137+
Parameters
138+
----------
139+
runner : AlgorithmRunner
140+
An algorithm, an algorithm collection, or a client.
141+
algorithm : str, optional
142+
Name of the algorithm (only needed with collections and clients).
143+
"""
116144
return runner.info(algorithm=algorithm)

‎src/imaging_server_kit/core/algorithm.py‎

Lines changed: 79 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -204,46 +204,54 @@ def _yields_then_return(gen: Generator) -> Generator[Any, None, None]:
204204

205205

206206
class Algorithm(AlgorithmRunner, Generic[P]):
207-
"""An algorithm built by wrapping a Python function. Usually created via the `@sk.algorithm(...)` decorator rather than instantiated directly.
207+
"""An algorithm built by wrapping a Python function.
208+
209+
Algorithms are usually created with the `@sk.algorithm` decorator rather than
210+
instantiated directly. They can still be called like the wrapped function, and
211+
also implement the shared [`AlgorithmRunner`][imaging_server_kit.AlgorithmRunner]
212+
interface (`run()`, `get_sample()`, `info()`, etc.).
208213
209214
Parameters
210215
----------
211-
run_algorithm_func: The Python function to convert.
212-
parameters: A dictionary of annotated parameters.
213-
name: A name for the algorithm (doesn't accept spaces and special characters).
214-
description: A short description to display on the algorithm doc page. Defaults to the docstring of the Python function.
215-
tags: A list of tags (arbitrary).
216-
project_url: A link to a related, or the original project (gets displayed on the algo doc page).
217-
metadata_file: A path to a metadata.yaml file with algorithm metadata.
218-
samples: A list of sample parameters for the algorithm, each represented as a dictionary mapping parameter_name to example_value. Sample images can be a Numpy array, a URL, or a local path to a file readable by `skimage.io.imread`.
219-
tileable: Whether to allow running the algorithm tile-by-tile.
220-
221-
Notes
222-
----------
223-
- Algorithms can be converted to FastAPI servers or PyQt widgets for Napari or QuPath.
224-
- Algorithms are associated with a Pydantic Schema that can be used to validate input parameters.
225-
- Algorithms can be run tile-by-tile (in most cases).
226-
- Algorithms can be run on a subset of the spatial domain defined by their inputs.
227-
- Algorithms can provide `samples` (example inputs).
228-
- Algorithm metadata can populate an `info` page.
216+
run_algorithm_func : callable
217+
The Python function to convert.
218+
parameters : dict, optional
219+
Parameter annotations, mapping parameter names to data layers (e.g.
220+
`{"sigma": sk.Float(min=0, default=1.0)}`). Parameters that are not annotated
221+
are resolved from type hints, default values, or variable names.
222+
name : str, optional
223+
A name for the algorithm. Defaults to the name of the function.
224+
description : str, optional
225+
A short description, displayed on the algorithm documentation page. Defaults
226+
to the docstring of the function.
227+
tags : list of str, optional
228+
A list of tags (arbitrary), displayed on the algorithm documentation page.
229+
project_url : str, optional
230+
A link to a related project, or to the original project, displayed on the
231+
algorithm documentation page.
232+
metadata_file : str, default="metadata.yaml"
233+
A path to a YAML file with algorithm metadata.
234+
samples : list of dict, optional
235+
Samples for the algorithm. Each sample is a dictionary mapping parameter
236+
names to example values. Sample images can be NumPy arrays, URLs, or paths to
237+
local files readable by `skimage.io.imread`.
238+
tileable : bool, default=False
239+
Whether the algorithm can be run tile-by-tile.
229240
230241
Attributes
231242
----------
232-
name: A name for the algorithm.
233-
parameters_model: A JSON schema representation of algorithm parameters.
234-
samples: A list of sample parameters, mapping parameter names to parameter values.
235-
algo_info: A dictionary of metadata about the algorithm.
236-
algorithms: A list containing the algorithm's name.
237-
238-
Methods
239-
----------
240-
run(): Execute the algorithm with a set of parameters.
241-
Set `tiled=True` for tiled inference.
242-
Raises a ValidationError when parameters are invalidated.
243-
get_n_samples(): Get the number of samples available.
244-
get_sample(): Get a sample by index.
245-
info(): Access algorithm documentation.
246-
get_parameters(): Get the algorithm parameters schema.
243+
name : str
244+
The name of the algorithm.
245+
parameters_model : pydantic.BaseModel
246+
A Pydantic model used to validate the algorithm parameters.
247+
samples : list of dict
248+
The samples of the algorithm.
249+
algo_info : dict
250+
Metadata about the algorithm.
251+
algorithms : list of str
252+
A list containing the name of the algorithm.
253+
tileable : bool
254+
Whether the algorithm can be run tile-by-tile.
247255
"""
248256

249257
def __init__(
@@ -489,23 +497,49 @@ def algorithm(
489497
samples: Optional[List[Dict[str, Any]]] = None,
490498
tileable: bool = False,
491499
) -> Union[Algorithm[P], Callable[[Callable[P, Any]], Algorithm[P]]]:
492-
"""Wrap a Python function as an algorithm (sk.Algorithm). Typically used as the `@sk.algorithm(...)` decorator.
500+
"""Convert a Python function into an algorithm.
501+
502+
Typically used as a decorator, with or without arguments: `@sk.algorithm` or
503+
`@sk.algorithm(...)`.
493504
494505
Parameters
495506
----------
496-
func : The Python function to convert.
497-
parameters : A dictionary of annotated parameters.
498-
name: A name for the algorithm (doesn't accept spaces and special characters).
499-
description: A short description to display on the algorithm doc page. Defaults to the docstring of the Python function.
500-
tags: A list of tags (arbitrary).
501-
project_url: A link to a related, or the original project (gets displayed on the algo doc page).
502-
metadata_file: A path to a metadata.yaml file with algorithm metadata.
503-
samples: A list of sample parameters for the algorithm, each represented as a dictionary mapping parameter_name to example_value. Sample images can be a Numpy array, a URL, or a local path to a file readable by `skimag.io.imread`.
504-
tileable: Whether to allow running the algorithm tile-by-tile.
507+
func : callable, optional
508+
The Python function to convert. Passed implicitly when used as a decorator.
509+
parameters : dict, optional
510+
Parameter annotations, mapping parameter names to data layers (e.g.
511+
`{"sigma": sk.Float(min=0, default=1.0)}`). Parameters that are not annotated
512+
are resolved from type hints, default values, or variable names.
513+
name : str, optional
514+
A name for the algorithm. Defaults to the name of the function.
515+
description : str, optional
516+
A short description, displayed on the algorithm documentation page. Defaults
517+
to the docstring of the function.
518+
tags : list of str, optional
519+
A list of tags (arbitrary), displayed on the algorithm documentation page.
520+
project_url : str, optional
521+
A link to a related project, or to the original project, displayed on the
522+
algorithm documentation page.
523+
metadata_file : str, default="metadata.yaml"
524+
A path to a YAML file with algorithm metadata.
525+
samples : list of dict, optional
526+
Samples for the algorithm. Each sample is a dictionary mapping parameter
527+
names to example values. Sample images can be NumPy arrays, URLs, or paths to
528+
local files readable by `skimage.io.imread`.
529+
tileable : bool, default=False
530+
Whether the algorithm can be run tile-by-tile.
505531
506532
Returns
507533
-------
508-
An algorithm instance (sk.Algorithm).
534+
Algorithm
535+
The algorithm. When called with keyword arguments only, a decorator
536+
returning the algorithm.
537+
538+
Examples
539+
--------
540+
>>> @sk.algorithm(parameters={"threshold": sk.Integer(min=0, max=255, default=128)})
541+
... def threshold_algo(image, threshold):
542+
... return sk.Mask(image > threshold)
509543
"""
510544

511545
def _decorate(run_algorithm_func: Callable[P, Any]) -> Algorithm[P]:

‎src/imaging_server_kit/core/domain.py‎

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,35 @@
55

66

77
class Domain:
8-
"""A nD-domain defined by a size and position in global pixel space. Used to represent tile extents, and to restrict an algorithm's computation to a specific region.
8+
"""An n-D box defined by a size and a position in global pixel coordinates.
9+
10+
Domains represent regions of interest and tile extents, and are used to restrict
11+
the computation of an algorithm to a region.
912
1013
Parameters
1114
----------
12-
size: Size of the domain in pixels, one value per dimension.
13-
position: Position of the domain's top-left corner in global pixel space. Defaults to the origin (all zeros) if only `size` is provided.
15+
size : tuple, optional
16+
Size of the domain in pixels, one value per dimension.
17+
position : tuple, optional
18+
Position of the lower corner of the domain (top-left in 2D), in global pixel
19+
coordinates. Defaults to the origin if only `size` is provided.
1420
1521
Attributes
1622
----------
17-
size: Size of the domain in pixels.
18-
coords_min: The position of the top-left corner of the domain.
19-
coords_max: The position of the bottom-right corner of the domain.
20-
ndim: Number of dimensions.
21-
22-
Methods
23-
----------
24-
serialize(): Convert the domain to a dictionary format.
25-
copy(): Copy the domain.
26-
merge(): Merge another domain.
23+
size : tuple
24+
Size of the domain in pixels.
25+
coords_min : tuple
26+
Lower corner of the domain (top-left in 2D).
27+
coords_max : tuple
28+
Upper corner of the domain (bottom-right in 2D).
29+
ndim : int
30+
Number of dimensions.
31+
32+
Examples
33+
--------
34+
>>> roi = sk.Domain(position=(20, 30), size=(60, 80))
35+
>>> roi.coords_max
36+
(80.0, 110.0)
2737
"""
2838

2939
def __init__(

‎src/imaging_server_kit/core/multialgo.py‎

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,27 @@
77

88

99
class MultiAlgorithm(AlgorithmRunner):
10-
"""A collection of algorithms exposed under a single interface, with the target algorithm selected by name at call time. Usually created via the `sk.combine()` function rather than instantiated directly.
10+
"""A collection of algorithms exposed under a single interface.
11+
12+
Collections are usually created with `sk.combine()` rather than instantiated
13+
directly. They implement the shared
14+
[`AlgorithmRunner`][imaging_server_kit.AlgorithmRunner] interface, where methods
15+
take an `algorithm` argument to select an algorithm by name.
1116
1217
Parameters
1318
----------
14-
algorithms: A list of algorithm instances in the collection.
15-
name: A name for the algorithm collection.
19+
algorithms : list of Algorithm
20+
The algorithms in the collection. If several algorithms have the same name,
21+
only the last one is kept.
22+
name : str, default="algorithms"
23+
A name for the collection.
1624
1725
Attributes
1826
----------
19-
algorithms_dict: A dictionary mapping algorithm names to instances in the collection.
20-
algorithms: A list of algorithm names in the collection.
21-
22-
Methods
23-
----------
24-
This class implements the same methods as the Algorithm class (via AlgorithmRunner),
25-
but methods take an extra argument `algorithm` to identify the algorithm to use.
27+
algorithms_dict : dict
28+
A dictionary mapping algorithm names to algorithms.
29+
algorithms : list of str
30+
The names of the algorithms in the collection.
2631
"""
2732

2833
def __init__(self, algorithms: List[Algorithm], name: str = "algorithms"):
@@ -86,17 +91,23 @@ def _stream(self, algorithm: str, params_stack: Stack):
8691

8792

8893
def combine(algorithms: List[Algorithm], name: str = "algorithms") -> MultiAlgorithm:
89-
"""
90-
Combine multiple algorithms, or plain Python functions, into a single algorithm collection.
94+
"""Combine algorithms, or plain Python functions, into a collection.
9195
9296
Parameters
9397
----------
94-
algorithms : A list of algorithm objects, or python functions. Python functions are converted to algorithms directly.
95-
name : The name of the algorithm collection.
98+
algorithms : list of Algorithm or callable
99+
The algorithms to combine. Plain Python functions are converted to algorithms.
100+
name : str, default="algorithms"
101+
A name for the collection.
96102
97103
Returns
98104
-------
99-
An algorithm collection (sk.MultiAlgorithm).
105+
MultiAlgorithm
106+
The algorithm collection.
107+
108+
Examples
109+
--------
110+
>>> multi_algo = sk.combine([threshold_algo, gaussian_algo], name="my-algorithms")
100111
"""
101112
parsed_algorithms = []
102113
for algorithm in algorithms:

0 commit comments

Comments
 (0)