define_app
Full signature, parameters, and behaviour of the define_app decorator, plus the AppType enum that controls which base class is used.
scinexus.composable.define_app(klass=None, *, app_type=GENERIC, skip_not_completed=True, cite=None)
define_app(
klass: type[Any] | Callable[..., Any],
) -> type[ComposableApp[Any, Any]]
define_app(
klass: None = None,
*,
app_type: Literal[
AppType.NON_COMPOSABLE, "non_composable"
],
skip_not_completed: bool = ...,
cite: Citation | None = ...,
) -> Callable[
[type[Any] | Callable[..., Any]],
type[AppBase[Any, Any]],
]
define_app(
klass: None = None,
*,
app_type: Literal[AppType.WRITER, "writer"],
skip_not_completed: bool = ...,
cite: Citation | None = ...,
) -> Callable[
[type[Any] | Callable[..., Any]],
type[WriterApp[Any, Any]],
]
define_app(
klass: None = None,
*,
app_type: AppType
| Literal[
"loader", "writer", "generic", "non_composable"
] = ...,
skip_not_completed: bool = ...,
cite: Citation | None = ...,
) -> Callable[
[type[Any] | Callable[..., Any]],
type[ComposableApp[Any, Any]],
]
decorator for building callable apps
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
klass
|
type[Any] | Callable[..., Any] | None
|
either a class or a function. If a function, it is converted to a class with the function bound as a static method. |
None
|
app_type
|
AppType | Literal['loader', 'writer', 'generic', 'non_composable']
|
what type of app, typically you just want GENERIC. |
GENERIC
|
skip_not_completed
|
bool
|
if True (default), NotCompleted instances are returned without being passed to the app. |
True
|
cite
|
Citation | None
|
a Citation instance describing the software or algorithm. If provided,
its |
None
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If the decorated class defines any method name reserved by the app framework. The reserved names depend on the app type. All app types: Composable apps (GENERIC, LOADER, WRITER) additionally:
Writer apps additionally: |
Examples:
An example app definition.
>>> from scinexus.composable import define_app
>>> @define_app
... class noop:
... def main(self, data: int) -> int:
... return data
Notes
Instances of scinexus apps are callable. If an exception occurs,
the app returns a NotCompleted instance with logging information.
Apps defined with app_type LOADER, GENERIC or WRITER can be
"composed" (summed together) to produce a single callable that
sequentially invokes the composed apps. For example, the independent
usage of app instances app1 and app2 as
app2(app1(data))
is equivalent to
combined = app1 + app2
combined(data)
The app_type attribute is used to constrain how apps can be composed.
LOADER and WRITER are special cases. If included, a LOADER
must always be first, e.g.
app = a_loader + a_generic
If included, a WRITER must always be last, e.g.
app = a_generic + a_writer
Changing the order for either of the above will result in a TypeError.
There are no constraints on ordering of GENERIC aside from compatability of
their input and return types (see below).
In order to be decorated with @define_app a class must
- implement a method called
main - type hint the first argument of
main - type hint the return type for
main
While you can have more than one argument in main, this is currently not
supported in composable apps.
Overlap between the return type hint and first argument hint is required for two apps to be composed together.
define_app adds a __call__ method which checks an input value prior
to passing it to app.main() as a positional argument. The data checking
results in NotCompleted being returned immediately, unless
skip_not_completed==False. If the input value type is consistent with
the type hint on the first argument of main it is passed to app.main().
If it does not match, a new NotCompleted instance is returned.
scinexus.composable.AppType
Bases: Enum