@@ -192,8 +192,8 @@ def build(
192192 self ._clean (modules )
193193 ext_map = self ._get_extension_map ()
194194 self ._save_modules (modules , ext_map )
195- self ._save_package ()
196195 self ._save_reference_file (ext_map )
196+ self ._save_package ()
197197 if self .lint :
198198 self ._run_linters ()
199199 except BlockingIOError :
@@ -2522,6 +2522,17 @@ def generate( # pylint: disable=too-many-positional-arguments # noqa: PLR0912
25222522 )
25232523 doc += "\n "
25242524 else :
2525+ primitive_types = {
2526+ "int" ,
2527+ "float" ,
2528+ "str" ,
2529+ "bool" ,
2530+ "list" ,
2531+ "dict" ,
2532+ "tuple" ,
2533+ "set" ,
2534+ }
2535+ type_name : str = ""
25252536 sections = (
25262537 SystemService ().system_settings .python_settings .docstring_sections
25272538 )
@@ -2534,8 +2545,8 @@ def generate( # pylint: disable=too-many-positional-arguments # noqa: PLR0912
25342545 doc_has_examples = bool (
25352546 re .search (r"^\s*Examples\s*\n[-=~`]{3,}" , doc , re .MULTILINE )
25362547 )
2537-
25382548 result_doc = doc .strip ("\n " )
2549+
25392550 if result_doc :
25402551 result_doc += "\n \n "
25412552
@@ -2557,6 +2568,7 @@ def generate( # pylint: disable=too-many-positional-arguments # noqa: PLR0912
25572568 continue
25582569
25592570 annotation = getattr (param , "_annotation" , None )
2571+
25602572 if isinstance (annotation , _AnnotatedAlias ):
25612573 p_type = annotation .__args__ [0 ] # type: ignore
25622574 metadata = getattr (annotation , "__metadata__" , [])
@@ -2570,8 +2582,8 @@ def generate( # pylint: disable=too-many-positional-arguments # noqa: PLR0912
25702582 type_str = cls .get_field_type (
25712583 p_type , param .default is Parameter .empty
25722584 )
2573-
25742585 param_section += f"{ create_indent (1 )} { param_name } : { type_str } \n "
2586+
25752587 if description and description .strip () != '""' :
25762588 param_section += f"{ create_indent (2 )} { description } \n "
25772589
@@ -2604,17 +2616,6 @@ def generate( # pylint: disable=too-many-positional-arguments # noqa: PLR0912
26042616 )
26052617
26062618 returns_section += f"{ type_name } \n "
2607-
2608- primitive_types = {
2609- "int" ,
2610- "float" ,
2611- "str" ,
2612- "bool" ,
2613- "list" ,
2614- "dict" ,
2615- "tuple" ,
2616- "set" ,
2617- }
26182619 is_primitive = type_name .lower () in primitive_types
26192620
26202621 if not is_primitive :
@@ -2643,6 +2644,7 @@ def generate( # pylint: disable=too-many-positional-arguments # noqa: PLR0912
26432644 returns_section += (
26442645 f"\n { create_indent (3 )} { description } "
26452646 )
2647+
26462648 except (AttributeError , TypeError ):
26472649 pass
26482650 else :
@@ -2653,6 +2655,37 @@ def generate( # pylint: disable=too-many-positional-arguments # noqa: PLR0912
26532655
26542656 doc = result_doc .rstrip ()
26552657
2658+ # Check response type for OBBject types to extract inner type
2659+ # Expand the docstring with the schema fields like in model-based commands
2660+ if type_name and "OBBject" in type_name :
2661+ type_str = str (return_annotation ).replace ("[T]" , "" )
2662+ match = re .search (r"OBBject\[(.*)\]" , type_str )
2663+ inner = match .group (1 ) if match else ""
2664+ # Extract from list[Type] or dict[str, Type]
2665+ type_match = re .search (r"\[([^\[\]]+)\]$" , inner )
2666+ extracted_type = type_match .group (1 ) if type_match else inner
2667+
2668+ if extracted_type and extracted_type .lower () not in primitive_types :
2669+ route_map = PathHandler .build_route_map ()
2670+ paths = ReferenceGenerator .get_paths (route_map )
2671+ route_path = paths .get (path , {}).get ("data" , {}).get ("standard" , [])
2672+
2673+ if route_path :
2674+ if doc and not doc .endswith ("\n \n " ):
2675+ doc += "\n \n "
2676+ doc += f"{ extracted_type } \n "
2677+ doc += f"{ '-' * len (extracted_type )} \n "
2678+
2679+ for field in route_path :
2680+ field_name = field .get ("name" , "" )
2681+ field_type = field .get ("type" , "Any" )
2682+ field_description = field .get ("description" , "" )
2683+ doc += f"{ create_indent (2 )} { field_name } : { field_type } \n "
2684+ if field_description :
2685+ doc += f"{ create_indent (3 )} { field_description } \n "
2686+
2687+ doc += "\n "
2688+
26562689 if "examples" in sections and not doc_has_examples :
26572690 if doc and not doc .endswith ("\n \n " ):
26582691 doc += "\n \n "
@@ -2980,8 +3013,7 @@ def _get_endpoint_examples(
29803013 func : Callable
29813014 Router endpoint function.
29823015 examples : Optional[List[Example]]
2983- List of Examples (APIEx or PythonEx type)
2984- for the endpoint.
3016+ List of Examples (APIEx or PythonEx type) for the endpoint.
29853017
29863018 Returns
29873019 -------
0 commit comments