Skip to content

_descriptions

_get_function_args_descriptions(*, package_name, module_path, function_name, verbose=False)

Extract argument descriptions from a function.

PARAMETER DESCRIPTION
package_name

Example fractal_tasks_core.

TYPE: Optional[str]

module_path

This must be an absolute path like /some/module.py (if package_name is None) or a relative path like something.py (if package_name is not None).

TYPE: str

function_name

Example create_ome_zarr.

TYPE: str

Source code in src/fractal_task_tools/_descriptions.py
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
def _get_function_args_descriptions(
    *,
    package_name: Optional[str],
    module_path: str,
    function_name: str,
    verbose: bool = False,
) -> dict[str, str]:
    """
    Extract argument descriptions from a function.

    Args:
        package_name: Example `fractal_tasks_core`.
        module_path:
            This must be an absolute path like `/some/module.py` (if
            `package_name` is `None`) or a relative path like `something.py`
            (if `package_name` is not `None`).
        function_name: Example `create_ome_zarr`.
    """

    # Extract docstring from ast.FunctionDef
    docstring = _get_function_docstring(
        package_name=package_name,
        module_path=module_path,
        function_name=function_name,
        verbose=verbose,
    )
    if verbose:
        logging.info(f"[_get_function_args_descriptions] {docstring}")

    # Parse docstring (via docstring_parser) and prepare output
    descriptions = {}
    if docstring is not None:
        parsed_docstring = docparse(docstring)
        for param in parsed_docstring.params:
            descriptions[param.arg_name] = _sanitize_description(param.description)
    logging.info(f"[_get_function_args_descriptions] END ({function_name=})")
    return descriptions

_get_function_docstring(*, package_name, module_path, function_name, verbose=False)

Extract docstring from a function.

PARAMETER DESCRIPTION
package_name

Example fractal_tasks_core.

TYPE: Optional[str]

module_path

This must be an absolute path like /some/module.py (if package_name is None) or a relative path like something.py (if package_name is not None).

TYPE: str

function_name

Example create_ome_zarr.

TYPE: str

Source code in src/fractal_task_tools/_descriptions.py
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
def _get_function_docstring(
    *,
    package_name: Optional[str],
    module_path: str,
    function_name: str,
    verbose: bool = False,
) -> str | None:
    """
    Extract docstring from a function.


    Args:
        package_name: Example `fractal_tasks_core`.
        module_path:
            This must be an absolute path like `/some/module.py` (if
            `package_name` is `None`) or a relative path like `something.py`
            (if `package_name` is not `None`).
        function_name: Example `create_ome_zarr`.
    """

    if not module_path.endswith(".py"):
        raise ValueError(f"Module {module_path} must end with '.py'")

    # Get the function ast.FunctionDef object
    if package_name is not None:
        if os.path.isabs(module_path):
            raise ValueError(
                "Error in _get_function_docstring: `package_name` is not "
                "None but `module_path` is absolute."
            )
        package_path = Path(import_module(package_name).__file__).parent
        module_path = (package_path / module_path).as_posix()
    else:
        if not os.path.isabs(module_path):
            raise ValueError(
                "Error in _get_function_docstring: `package_name` is None "
                "but `module_path` is not absolute."
            )

    if verbose:
        logging.info(f"[_get_function_docstring] {function_name=}")
        logging.info(f"[_get_function_docstring] {module_path=}")

    tree = ast.parse(Path(module_path).read_text())
    _function = next(
        f
        for f in ast.walk(tree)
        if (isinstance(f, ast.FunctionDef) and f.name == function_name)
    )

    # Extract docstring from ast.FunctionDef
    return ast.get_docstring(_function)

_insert_function_args_descriptions(*, schema, descriptions, verbose=False)

Merge the descriptions obtained via _get_args_descriptions into the properties of an existing JSON Schema.

PARAMETER DESCRIPTION
schema

TBD

TYPE: dict

descriptions

TBD

TYPE: dict

Source code in src/fractal_task_tools/_descriptions.py
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
def _insert_function_args_descriptions(
    *, schema: dict, descriptions: dict, verbose: bool = False
):
    """
    Merge the descriptions obtained via `_get_args_descriptions` into the
    properties of an existing JSON Schema.

    Args:
        schema: TBD
        descriptions: TBD
    """
    new_schema = schema.copy()
    new_properties = schema["properties"].copy()
    for key, value in schema["properties"].items():
        if "description" in value:
            # This branch covers e.g. the `Field(description="...")` case
            pass
        else:
            value["description"] = descriptions.get(key, "Missing description")
            new_properties[key] = value
            if verbose:
                logging.info(
                    f"[_insert_function_args_descriptions] Add {key=}, {value=}"
                )
    new_schema["properties"] = new_properties
    logging.info("[_insert_function_args_descriptions] END")
    return new_schema

_sanitize_description(string)

Sanitize a description string.

This is a provisional helper function that replaces newlines with spaces and reduces multiple contiguous whitespace characters to a single one. Future iterations of the docstrings format/parsing may render this function not-needed or obsolete.

PARAMETER DESCRIPTION
string

TBD

TYPE: str

Source code in src/fractal_task_tools/_descriptions.py
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
def _sanitize_description(string: str) -> str:
    """
    Sanitize a description string.

    This is a provisional helper function that replaces newlines with spaces
    and reduces multiple contiguous whitespace characters to a single one.
    Future iterations of the docstrings format/parsing may render this function
    not-needed or obsolete.

    Args:
        string: TBD
    """
    # Replace newline with space
    new_string = string.replace("\n", " ")
    # Replace N-whitespace characters with a single one
    while "  " in new_string:
        new_string = new_string.replace("  ", " ")
    return new_string