Skip to content

Commit

Permalink
Improved node docs (#1902)
Browse files Browse the repository at this point in the history
* Improved node docs

* leftover

* type error

* Removed custom links

* Fixed tooltips

---------

Co-authored-by: Joey Ballentine <[email protected]>
  • Loading branch information
RunDevelopment and joeyballentine authored Jul 2, 2023
1 parent 60da0ef commit 2b31e83
Show file tree
Hide file tree
Showing 21 changed files with 267 additions and 201 deletions.
27 changes: 19 additions & 8 deletions backend/src/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import importlib
import os
from dataclasses import dataclass, field
from typing import Callable, Dict, Iterable, List, Tuple, TypedDict, TypeVar, Union
from typing import Callable, Dict, Iterable, List, Tuple, TypedDict, TypeVar

from sanic.log import logger

Expand All @@ -24,14 +24,14 @@
GB = 1024**3


def _process_inputs(base_inputs: Iterable[Union[BaseInput, NestedGroup]]):
def _process_inputs(base_inputs: Iterable[BaseInput | NestedGroup]):
inputs: List[BaseInput] = []
groups: List[NestedIdGroup] = []

def add_inputs(
current: Iterable[Union[BaseInput, NestedGroup]]
) -> List[Union[InputId, NestedIdGroup]]:
layout: List[Union[InputId, NestedIdGroup]] = []
current: Iterable[BaseInput | NestedGroup],
) -> List[InputId | NestedIdGroup]:
layout: List[InputId | NestedIdGroup] = []

for x in current:
if isinstance(x, Group):
Expand Down Expand Up @@ -69,13 +69,14 @@ class DefaultNode(TypedDict):
class NodeData:
schema_id: str
description: str
see_also: List[str]
name: str
icon: str
type: NodeType

inputs: List[BaseInput]
outputs: List[BaseOutput]
group_layout: List[Union[InputId, NestedIdGroup]]
group_layout: List[InputId | NestedIdGroup]

side_effects: bool
deprecated: bool
Expand All @@ -101,16 +102,25 @@ def register(
self,
schema_id: str,
name: str,
description: str,
inputs: List[Union[BaseInput, NestedGroup]],
description: str | List[str],
inputs: List[BaseInput | NestedGroup],
outputs: List[BaseOutput],
icon: str = "BsQuestionCircleFill",
node_type: NodeType = "regularNode",
side_effects: bool = False,
deprecated: bool = False,
default_nodes: List[DefaultNode] | None = None,
decorators: List[Callable] | None = None,
see_also: List[str] | str | None = None,
):
if not isinstance(description, str):
description = "\n\n".join(description)

if see_also is None:
see_also = []
if isinstance(see_also, str):
see_also = [see_also]

def inner_wrapper(wrapped_func: T) -> T:
p_inputs, group_layout = _process_inputs(inputs)
p_outputs = _process_outputs(outputs)
Expand All @@ -136,6 +146,7 @@ def inner_wrapper(wrapped_func: T) -> T:
schema_id=schema_id,
name=name,
description=description,
see_also=see_also,
icon=icon,
type=node_type,
inputs=p_inputs,
Expand Down
9 changes: 3 additions & 6 deletions backend/src/nodes/base_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from dataclasses import dataclass
from enum import Enum
from typing import Any, List, Literal, Optional, Type, TypedDict, Union
from typing import List, Literal, Optional, Type, TypedDict, Union

import navi
from base_types import InputId
Expand Down Expand Up @@ -89,7 +89,6 @@ def __init__(

# Optional documentation
self.description: str | None = None
self.examples: List[Any] | None = None

# This is the method that should be created by each input
def enforce(self, value: object):
Expand Down Expand Up @@ -137,16 +136,14 @@ def toDict(self):
"optional": self.optional,
"hasHandle": self.has_handle,
"description": self.description,
"examples": [str(e) for e in self.examples] if self.examples else None,
}

def with_id(self, input_id: InputId | int):
self.id = InputId(input_id)
return self

def with_documentation(self, description: str, examples: List[Any] | None = None):
self.description = description
self.examples = examples
def with_docs(self, *description: str):
self.description = "\n\n".join(description)
return self

def make_optional(self):
Expand Down
9 changes: 3 additions & 6 deletions backend/src/nodes/base_output.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from typing import Any, List, Literal, Type, Union
from typing import Literal, Type, Union

import navi
from base_types import OutputId
Expand Down Expand Up @@ -28,7 +28,6 @@ def __init__(

# Optional documentation
self.description: str | None = None
self.examples: List[Any] | None = None

def toDict(self):
return {
Expand All @@ -39,7 +38,6 @@ def toDict(self):
"kind": self.kind,
"hasHandle": self.has_handle,
"description": self.description,
"examples": [str(e) for e in self.examples] if self.examples else None,
}

def with_id(self, output_id: OutputId | int):
Expand All @@ -50,9 +48,8 @@ def with_never_reason(self, reason: str):
self.never_reason = reason
return self

def with_documentation(self, description: str, examples: List[Any] | None = None):
self.description = description
self.examples = examples
def with_docs(self, *description: str):
self.description = "\n\n".join(description)
return self

def __repr__(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def ModelFileIteratorLoadModelNode(
@batch_processing_group.register(
schema_id="chainner:ncnn:model_file_iterator",
name="Model File Iterator",
description="Iterate over all files in a directory and run the provided nodes on just the NCNN model files (.param/.bin). Supports the same models as [](#chainner:ncnn:load_model).",
description="Iterate over all files in a directory and run the provided nodes on just the NCNN model files (.param/.bin). Supports the same models as `chainner:ncnn:load_model`.",
icon="MdLoop",
inputs=[
DirectoryInput(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def ModelFileIteratorLoadModelNode(
@batch_processing_group.register(
schema_id="chainner:onnx:model_file_iterator",
name="Model File Iterator",
description="Iterate over all files in a directory and run the provided nodes on just the ONNX model files (.onnx). Supports the same models as [](#chainner:onnx:load_model).",
description="Iterate over all files in a directory and run the provided nodes on just the ONNX model files (.onnx). Supports the same models as `chainner:onnx:load_model`.",
icon="MdLoop",
inputs=[
DirectoryInput(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def ModelFileIteratorLoadModelNode(
@batch_processing_group.register(
schema_id="chainner:pytorch:model_file_iterator",
name="Model File Iterator",
description="Iterate over all files in a directory and run the provided nodes on just the PyTorch model files (.pth). Supports the same models as [](#chainner:pytorch:load_model).",
description="Iterate over all files in a directory and run the provided nodes on just the PyTorch model files (.pth). Supports the same models as `chainner:pytorch:load_model`.",
icon="MdLoop",
inputs=[
DirectoryInput(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def ImageFileIteratorLoadImageNode(
@batch_processing_group.register(
schema_id="chainner:image:file_iterator",
name="Image File Iterator",
description="Iterate over all files in a directory and run the provided nodes on just the image files. Supports the same file types as [](#chainner:image:load).",
description="Iterate over all files in a directory and run the provided nodes on just the image files. Supports the same file types as `chainner:image:load`.",
icon="MdLoop",
node_type="iterator",
inputs=[
Expand Down
9 changes: 5 additions & 4 deletions backend/src/packages/chaiNNer_standard/image/io/load_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,14 @@ def _for_ext(ext: str | Iterable[str], decoder: _Decoder) -> _Decoder:
description="Load image from specified file. This node will output the loaded image, the directory of the image file, and the name of the image file (without file extension).",
icon="BsFillImageFill",
inputs=[
ImageFileInput(primary_input=True).with_documentation(
description=f"Select the path of an image file. Supports the following image formats: {', '.join(valid_formats)}"
ImageFileInput(primary_input=True).with_docs(
"Select the path of an image file.",
f"Supports the following image formats: {', '.join(valid_formats)}",
)
],
outputs=[
LargeImageOutput().with_documentation(
description="The node will display a preview of the selected image as well as type information for it. Connect this output to the input of another node to pass the image to it."
LargeImageOutput().with_docs(
"The node will display a preview of the selected image as well as type information for it. Connect this output to the input of another node to pass the image to it."
),
DirectoryOutput("Image Directory", of_input=0),
FileNameOutput("Image Name", of_input=0),
Expand Down
12 changes: 10 additions & 2 deletions backend/src/packages/chaiNNer_standard/image/io/save_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,16 @@ class JpegSubsampling(Enum):
inputs=[
ImageInput(),
DirectoryInput(has_handle=True),
TextInput("Subdirectory Path").make_optional(),
TextInput("Image Name"),
TextInput("Subdirectory Path")
.make_optional()
.with_docs(
"An optional subdirectory path. Use this to save the image to a subdirectory of the specified directory. If the subdirectory does not exist, it will be created. Multiple subdirectories can be specified by separating them with a forward slash (`/`).",
"Example: `foo/bar`",
),
TextInput("Image Name").with_docs(
"The name of the image file **without** the file extension. If the file already exists, it will be overwritten.",
"Example: `my-image`",
),
ImageExtensionDropdown().with_id(4),
if_enum_group(4, ["jpg", "webp"])(
SliderInput(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ def lens_blur(
default=5,
precision=0,
controls_step=1,
).with_docs(
"This controls the quality of the lens blur. More components will result in a more realistic blur, but will also be slower to compute."
),
SliderInput(
"Exposure Gamma",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@
@miscellaneous_group.register(
schema_id="chainner:image:high_pass",
name="High Pass",
description="Apply High Pass filter on image",
description=[
"Apply High Pass filter on image.",
"A high pass filter is a filter will remove all low-frequency detail below a certain threshold. This will result in an image that is mostly edges and high-frequency detail.",
"Note: This node will leave the alpha channel of the image (if it has one) unchanged.",
],
icon="MdOutlineAutoFixHigh",
inputs=[
ImageInput(channels=[1, 3, 4]),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class KernelType(Enum):
schema_id="chainner:image:sharpen_hbf",
name="High Boost Filter",
description="Apply sharpening to an image using a high boost filter.",
see_also="chainner:image:sharpen",
icon="MdBlurOff",
inputs=[
ImageInput(),
Expand All @@ -35,7 +36,12 @@ class KernelType(Enum):
controls_step=1,
scale="log",
),
BoolInput("Contrast Adaptive", default=False).with_id(3),
BoolInput("Contrast Adaptive", default=False)
.with_id(3)
.with_docs(
"Enable contrast adaptive sharpening.",
"This will sharpen the image more evenly and prevents over-sharpening in dark areas and areas that are already quite sharp.",
),
if_enum_group(3, 1)(
SliderInput(
"Contrast Adaptive Bias",
Expand All @@ -45,6 +51,9 @@ class KernelType(Enum):
precision=2,
controls_step=0.1,
slider_step=0.1,
).with_docs(
"A bias that controls the strength of the contrast adaptiveness. A bias of 2 is recommended, because it offers a good trade-off between sharpening and contrast adaptiveness.",
"A high bias will result in more sharpening but lose contrast adaptiveness. The bias is bounded between 1 and 3 because values higher than 3 effectively disable the contrast adaptiveness. A bias less than 2 will result in noticeable less sharpening, but apply that sharpening very evenly.",
)
),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
schema_id="chainner:image:sharpen",
name="Unsharp Mask",
description="Apply sharpening to an image using an unsharp mask.",
see_also="chainner:image:sharpen_hbf",
icon="MdBlurOff",
inputs=[
ImageInput(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ class MathOperation(Enum):
schema_id="chainner:utility:math",
name="Math",
description="Perform mathematical operations on numbers.",
see_also=[
"chainner:utility:math_round",
"chainner:utility:number",
],
icon="MdCalculate",
inputs=[
NumberInput(
Expand Down
1 change: 1 addition & 0 deletions backend/src/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ async def nodes(_request: Request):
g.toDict() if isinstance(g, Group) else g for g in node.group_layout
],
"description": node.description,
"seeAlso": node.see_also,
"icon": node.icon,
"subcategory": sub.name,
"nodeType": node.type,
Expand Down
1 change: 1 addition & 0 deletions src/common/SchemaMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const BLANK_SCHEMA: NodeSchema = {
subcategory: '',
name: '',
description: '',
seeAlso: [],
nodeType: 'regularNode',
schemaId: '' as SchemaId,
hasSideEffects: false,
Expand Down
3 changes: 1 addition & 2 deletions src/common/common-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ interface InputBase {
readonly optional: boolean;
readonly hasHandle: boolean;
readonly description?: string;
readonly examples?: readonly string[] | null;
}
export interface InputOption {
option: string;
Expand Down Expand Up @@ -144,7 +143,6 @@ export interface Output {
readonly kind: OutputKind;
readonly hasHandle: boolean;
readonly description?: string | null;
readonly examples?: readonly string[] | null;
}

export type Condition = AndCondition | OrCondition | NotCondition | EnumCondition | TypeCondition;
Expand Down Expand Up @@ -237,6 +235,7 @@ export interface NodeSchema {
readonly category: string;
readonly subcategory: string;
readonly description: string;
readonly seeAlso: readonly SchemaId[];
readonly icon: string;
readonly nodeType: NodeType;
readonly inputs: readonly Input[];
Expand Down
Loading

0 comments on commit 2b31e83

Please sign in to comment.